在x86_64 linux中重定位程序超过2GB的链接器错误?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了在x86_64 linux中重定位程序超过2GB的链接器错误?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7138字,纯文字阅读大概需要11分钟。
内容图文
![在x86_64 linux中重定位程序超过2GB的链接器错误?](/upload/InfoBanner/zyjiaocheng/971/05ab17ddd70c44a8861098a8e8806fc8.jpg)
我有一个用户程序,通常编译为在0x400460有一个入口点,我必须重新定位,以便在Linux中加载的共享库的2GB内有一个入口点.例如linux-vdso.so.1 => (0x00007fff109cd000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007fcd195e6000)
/lib64/ld-linux-x86-64.so.2(0x00007fcd199af000)
我使用gcc命令行参数-Wl,-Ttext = 0x80000000来指定.text segemnt的起始地址.
问题是当我在这个参数中给出一个大于2GB的地址时,我收到一个链接器错误,它是:
gcc test.c -ggdb -Wl,-Ttext=0x80000000 -o test1
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 10
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 4 has invalid symbol index 10
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 5 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 6 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 7 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 8 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 9 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 10 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 11 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 12 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 13 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 14 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 15 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 16 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 17 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 18 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 19 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 20 has invalid symbol index 20
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x12): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_fini' defined in .text section in /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x19): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_init' defined in .text section in /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): relocation truncated to fit: R_X86_64_32S against symbol `main' defined in .text section in /tmp/ccFshK69.o
/var/services/homes/adabral/elider/gc/a1/lib/gcc/x86_64-unknown-linux- gnu/4.8.2/crtbegin.o: In function `deregister_tm_clones':
crtstuff.c:(.text+0x8): relocation truncated to fit: R_X86_64_32S against `.tm_clone_table'
/var/services/homes/adabral/elider/gc/a1/lib/gcc/x86_64-unknown-linux- gnu/4.8.2/crtbegin.o: In function `register_tm_clones':
crtstuff.c:(.text+0x38): relocation truncated to fit: R_X86_64_32S against `.tm_clone_table'
collect2: error: ld returned 1 exit status
:据我所知,在经过几个SO问题和论坛之后我可以得出这个原因,其中一些部分仍然映射到低2GB的地址空间.
这是readelf -a的输出,用于编译文本段低于2GB(在0x79990000)的二进制文件.
Dynamic section at offset 0x190310 contains 24 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x4003f0
0x000000000000000d (FINI) 0x79990204
0x0000000000000019 (INIT_ARRAY) 0x79b902f8
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x79b90300
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x0000000000000004 (HASH) 0x400278
0x0000000000000005 (STRTAB) 0x400318
0x0000000000000006 (SYMTAB) 0x4002a0
0x000000000000000a (STRSZ) 72 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x79b904e8
0x0000000000000002 (PLTRELSZ) 72 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x4003a8
0x0000000000000007 (RELA) 0x400390
0x0000000000000008 (RELASZ) 24 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x400370
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x400360
0x0000000000000000 (NULL) 0x0
您可以看到INIT和其他一些部分仍然从低2GB地址空间开始.因此,动态链接器无法在运行时偏移重定位地址,因为重定位类型为R_X86_64_32.
>所以我尝试用gcc -mcmodel = large flag编译我的代码,但我仍然得到相同的链接器错误.使用大型模型应该已经纠正了这个错误,但事实并非如此.
>我被困在这一点上,任何帮助都非常感激.
(我正在使用x86_64 ubuntu机器.gcc versio 4.8.2)
谢谢
解决方法:
您应该首先了解x86_64的ABI有几个不同的“模型”:小型,内核,中型和大型.这些在GCC -mcmodel选项下描述:http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86-64-Options.html
您所遇到的是crt1.o,这个启动代码链接到每个负责获取初始ELF寄存器/堆栈状态并将它们传递到最终调用main的libc启动代码的程序中,似乎使用的是模型.你可以在这里看到:
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): relocation truncated to fit: R_X86_64_32S against symbol `main' defined in .text section in /tmp/ccFshK69.o
发生的事情是crt1.o对main的地址进行了重定位,只允许填充32位地址.(注意:即使main在共享库中定义而不是可执行文件,也会有可执行文件中的PLT条目,此PLT条目的地址将是重定位将被解析的main的官方地址.)
要解决此问题,您需要一个可以处理完整64位地址的crt1.o.获得此功能的一种方法可能是使用Scrt1.o,它通常仅用于PIE可执行文件,而不是crt1.o.您可以使用-nostartfiles并在链接命令行上手动指定所有启动文件来实现此目的.可能值得提交针对glibc的错误报告,请求将x86_64 crt1.o转换为“大型模型”,以便它可以与未在32位范围内链接的主程序一起使用.
请注意,对于所有自己的代码,您可能还需要-mcmodel = large(或者可能是-fPIE可以工作),以使其链接并在高地址处正常工作.这可能会使它变得更大更慢.您可能想重新考虑为什么要这样做,以及您是否真的需要.
内容总结
以上是互联网集市为您收集整理的在x86_64 linux中重定位程序超过2GB的链接器错误?全部内容,希望文章能够帮你解决在x86_64 linux中重定位程序超过2GB的链接器错误?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。