我正在使用-ffunction-sections和-gc-sections选项来优化应用程序,但ld无法链接并返回错误:
/home/yunxing.cyx/china-gcc-10.2.0/libexec/gcc/x86_64-pc-linux-gnu/10.2.0/collect2
-plugin /home/yunxing.cyx/china-gcc-10.2.0/libexec/gcc/x86_64-pc-linux-gnu/10.2.0/liblto_plugin.so
-plugin-opt=/home/yunxing.cyx/china-gcc-10.2.0/libexec/gcc/x86_64-pc-linux-gnu/10.2.0/lto-wrapper
-plugin-opt=-fresolution=/.vos/.ob-compile/tmp/yunxing.cyx/ccRgBV8r.res
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh --eh-frame-hdr -m elf_x86_64 -shared -o libmyapp.so -z noexecstack /lib/../lib64/crti.o /home/yunxing.cyx/china-gcc-10.2.0/lib/gcc/x86_64-pc-linux-gnu/10.2.0/crtbeginS.o @/.vos/.ob-compile/tmp/yunxing.cyx/ccX1Yrmq
-L/home/yunxing.cyx/work/myapp/rpm/.compile -L/home/yunxing.cyx/china-gcc-10.2.0/lib/gcc/x86_64-pc-linux-gnu/10.2.0
-L/home/yunxing.cyx/china-gcc-10.2.0/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib64
-L/lib/../lib64 -L/usr/lib/../lib64 -L/home/yunxing.cyx/china-gcc-10.2.0/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../.. @/.vos/.ob-compile/tmp/yunxing.cyx/ccvpSZzo
-lgcc -lgcc_eh -lc -lgcc -lgcc_eh /home/yunxing.cyx/china-gcc-10.2.0/lib/gcc/x86_64-pc-linux-gnu/10.2.0/crtendS.o /lib/../lib64/crtn.o
ld: error: section: .data.rel.ro is not contiguous with other relro sections
ld: error: section: .dynamic is not contiguous with other relro sections
ld: error: section: .got is not contiguous with other relro sections
collect2: error: ld returned 1 exit status
make[2]: *** [src/myserver/libmyapp.so] Error 1
make[1]: *** [src/myserver/CMakeFiles/myapp.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[100%] Built target myapp_static
make: *** [all] Error 2发布于 2020-12-09 20:57:52
glibc动态加载器只支持一个relro部分,所以我能想到的唯一可能的解决方案(除了不使用-ffunction-sections或完全禁用PIE之外)就是禁用relro hardening:-Wl,-z,norelro
至于原因,如果我们检查dl-support.c,我们会看到如下代码
if (_dl_phdr != NULL)
for (const ElfW(Phdr) *ph = _dl_phdr; ph < &_dl_phdr[_dl_phnum]; ++ph)
switch (ph->p_type)
{
// . . .
case PT_GNU_RELRO:
_dl_main_map.l_relro_addr = ph->p_vaddr;
_dl_main_map.l_relro_size = ph->p_memsz;
break;
}
/* Setup relro on the binary itself. */
if (_dl_main_map.l_relro_size != 0)
_dl_protect_relro (&_dl_main_map);因此,只有最后的PT_GNU_RELRO PHDR将受到保护。知道这一点,LD throws一个错误,以防止一个潜在的安全问题。
向glibc发出拉取请求以改进relro处理总是受欢迎的。
https://stackoverflow.com/questions/65216792
复制相似问题