【问题标题】:gcc 6.2.0 is attempting to create shared object when it shouldn't?gcc 6.2.0 正在尝试创建不应该的共享对象?
【发布时间】:2016-10-25 17:24:50
【问题描述】:

在 gcc 6.2.0 之前,使用不可重定位的汇编代码链接从来都不是问题。我不知道盯着这个的确切版本,但是使用 gcc 5.4.0(及更低版本)这个工作:

$ gcc -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto

但是,使用 gcc 6.2.0:

$ gcc -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto
/usr/bin/ld: ../../../lib/libribs2_ssl.a(context_asm.o): relocation R_X86_64_32S against symbol `current_ctx' 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

试图强制静态链接会产生另一个问题:

$ gcc -static -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto -ldl
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x11): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
../obj/httpget.o: In function `main':
/home/nir/ribs2/examples/httpget/src/httpget.c:194: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

并且在使用 gethostbyname() 时程序会出现段错误(但可以正常工作)

同时尝试混合静态和动态也行不通。

$ gcc -o httpget -Wl,-Bstatic ../obj/httpget.o ../../../lib/libribs2_ssl.a -Wl,-Bdynamic -lssl -lcrypto
/usr/bin/ld: ../../../lib/libribs2_ssl.a(context_asm.o): relocation R_X86_64_32S against symbol `current_ctx' 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

有什么想法吗?项目链接:https://github.com/niryeffet/ribs2

【问题讨论】:

  • 我猜它可能想默认创建一个 PIE?尽管根据 gcc.godbolt.org 的说法,情况并非如此。无论如何,你可能想尝试添加-fno-PIE,也可能编译一个不同的测试程序,看看输出是否是PIE。
  • 谢谢你,-no-pie 链接时做到了。
  • 这个问题从何而来?我通过升级我的系统遇到了这个问题......
  • @Saroupille,请参阅下面的更新。我猜其他发行版也在做同样的事情。

标签: gcc assembly dynamic static gcc6


【解决方案1】:

感谢@Jester 的提示:向 LDFLAGS 添加 -no-pie(不是 -fno-PIE)解决了问题。

gcc -no-pie -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto

此更改也适用于 gcc 5.4。似乎默认值已更改。

更新:

这就解释了。来自https://wiki.ubuntu.com/SecurityTeam/PIE

在 Ubuntu 16.10 中,作为额外的编译器强化措施,我们已经 在 amd64 和 ppc64le 上默认启用 PIE 和立即绑定。 这大大提高了 ASLR 在这些平台上的有效性。

【讨论】:

    猜你喜欢
    • 2011-12-29
    • 2021-07-03
    • 2016-06-22
    • 1970-01-01
    • 2017-04-08
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    相关资源
    最近更新 更多