【问题标题】:gcc -fPIC -fPIE: difference betweenn gcc-4 and gcc-6gcc -fPIC -fPIE:gcc-4 和 gcc-6 之间的区别
【发布时间】:2017-06-13 18:59:55
【问题描述】:

序言:这个问题不是关于 Oracle,而是我想了解 gcc-4 和 gcc-6 在处理 Position Independent 方面的根本区别代码。

所以我决定尝试在 Debian stretch 上安装 Oracle 12c。

在与 gcc-6 的链接阶段,会发出如下错误消息:

/usr/bin/ld: /opt/oracle/product/12.2.0/lib/libpls12.a(pci.o):
  relocation R_X86_64_32S against `.rodata.str1.4' can not be used when making a shared object;
  recompile with -fPIC.

但是,如果我将编译器切换为使用 gcc-4.9,则所有链接都可以顺利完成。

因此我的 2 个问题:

  • gcc 版本 4 和 6 之间的 -fPIC 和 -fPIE 的默认值是否有变化?很可能是的,版本 6 似乎默认使用这 2 个选项。
  • 对我来说更重要的是:gcc 版本 6 是否可以选择使用版本 4 的行为来生成与位置无关的代码? (或者我迟早会因为 gcc-4 不再可用而无法链接到 old 库?)

【问题讨论】:

    标签: gcc gcc4 gcc6


    【解决方案1】:

    gcc-6 链接器很可能默认创建与位置无关的可执行文件。该问题可以重现如下,并通过添加链接器标志-no-pie来解决:

    UNIX # gcc-6 -g -Wall -fno-pic -c helloworld.c -o helloworld.o
    
    UNIX # gcc-6 -g -Wall helloworld.o -o helloworld
    /usr/bin/ld: helloworld.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
    /usr/bin/ld: final link failed: Nonrepresentable section on output
    collect2: error: ld returned 1 exit status
    
    UNIX # gcc-6 -g -Wall -no-pie helloworld.o -o helloworld
    

    确实,在 Oracle 使用的 gcc 选项中添加 -no-pie 后,链接工作没有任何错误。

    【讨论】:

      【解决方案2】:

      broeni 的解决方案效果很好。我做了一些额外的步骤来使它工作:

      在安装过程中,我修改了oracle的默认链接器工具,编辑了文件

      /opt/oracle/product/12.2.0/db1/bin/orald  
      

      在第一行中,我强制使用 GCC 链接器,并添加了 -no-pie 选项:

      #if [ -z "$BASH_VERSION" -o -n "$ORALD_USE_GCC" ] ; then
        exec gcc -no-pie "$@"
        exit 1
      #fi
      

      标签:oracle 12c debian stretch

      【讨论】:

      • 你,先生,让我很开心。谢谢!
      猜你喜欢
      • 2011-04-02
      • 2011-05-31
      • 2013-11-10
      • 2010-12-03
      • 1970-01-01
      • 2020-09-26
      • 2016-08-01
      • 2016-11-09
      • 2012-11-11
      相关资源
      最近更新 更多