我正在尝试使用更新版本的gcc构建cromwell(原始Xbox合法固件替换),但稍微更改项目编译设置后,ld会抛出以下错误:
ld:section .text.unlikely loading [0000000000000000,0000000000000669]重叠部分.text加载于[0000000000000000,0000000000021515]
如果要查看,可以从此处克隆项目:https://github.com/not404/cromwell
首先,我想提一下我能够在x32 linux VM上使用gcc-3.3和在cygwin x86上使用gcc-4.1成功构建和运行此项目(在我的Xbox上)(为目标i686-linux构建gcc) -gnu)。我不得不在主Makefile中删除-Werror
cflag,以便在gcc-3.3中成功构建它。在修改makefile后,尝试在x32 VM上使用gcc-4.8.2构建它,导致上面提到的错误。
为了到达那里,我在项目的根目录中修改了Makefile中的CFLAGS。我仍然从CLAGS中删除了-Werror
。我必须在-fno-stack-protector
和CFLAGS
中添加ETH_CFLAGS
个标记才能超过undefined reference to '__stack_chk_fail'
错误。我认为这种解决方法非常无害。较旧的gcc版本不支持这种堆栈粉碎保护机制,因此禁用它不会造成问题。
在对Makefile进行修改之后,我看到了关于段重叠的链接器错误。我读到.text.unlikely
部分是在gcc 4.6附近添加的,所以很明显在cromwell项目积极开发时没有考虑到它!
所以,为了克服这个错误,我试图在" ldscript-crom.ld"中明确定义.text.unlikely
部分。链接器脚本。最初,脚本包含以下内容:
.text LOW_ROM : AT ( 0 ){
_start_low_rom = . ;
*(.text);
_end_low_rom = . ;
}
我把它改为:
.text LOW_ROM : AT ( 0 ){
_start_low_rom = . ;
*(.text);
*(.text.unlikely);
_end_low_rom = . ;
}
在此更改后,我又出现了另一个错误:
ld:加载在[0000000000000000,00000000000062b3]的.eh_frame部分重叠了。[0000000000000000,0000000000021b7f]加载的.text文件
根据我在互联网上看到的内容,.eh_frame
部分仅与异常处理相关,并且针对C ++来捕获异常。
我能够通过在主Makefile中向CFLAGS和EHT_CFLAGS添加以下标志来解决这个问题:
-fno-reorder-functions -fno-unwind-tables -fno-asynchronous-unwind-tables
毕竟,我终于得到了一个输出文件。不幸的是,执行中存在错误。它似乎开始很好,但我没有视频和执行似乎在某些时候崩溃。
我尝试打印链接文件的地图,但我看不到任何相关内容。我不会在这里发布2张地图(使用gcc-3.3和gcc-4.8,相同的ld),因为它们非常大。以下是包含.text.unlikely
部分定义(来自gcc-4.8)的地图部分:
0x0000000003a216f0 disable
*fill* 0x0000000003a2170e 0x2
.text 0x0000000003a21710 0x165 /home/cromwelldev/workspace/cromwell/obj/xbox_main.o
0x0000000003a21710 loadkernel
0x0000000003a21870 cleanup
*fill* 0x0000000003a21875 0xb
.text 0x0000000003a21880 0x2b5 /home/cromwelldev/workspace/cromwell/obj/elf.o
0x0000000003a21880 prepare_boot_params
0x0000000003a21b20 elf_start
*fill* 0x0000000003a21b35 0xb
.text 0x0000000003a21b40 0x46 /home/cromwelldev/workspace/cromwell/obj/exec_elf.o
0x0000000003a21b40 try_elf_boot
*(.text.unlikely)
0x0000000003a21b86 _end_low_rom = .
.iplt 0x0000000000000000 0x0
.iplt 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rel.dyn 0x0000000000000000 0x0
.rel.iplt 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rel.text 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rel.data 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rodata 0x0000000003a21b86 0x108b1 load address 0x0000000000021b86
*(.rodata)
*fill* 0x0000000003a21b86 0x2
这里是gcc-3.3的相同部分:
0x0000000003a1f7a0 disable
*fill* 0x0000000003a1f7c2 0xe
.text 0x0000000003a1f7d0 0x165 /home/cromwelldev/workspace/cromwell/obj/xbox_main.o
0x0000000003a1f7d0 loadkernel
0x0000000003a1f930 cleanup
*fill* 0x0000000003a1f935 0xb
.text 0x0000000003a1f940 0x2b6 /home/cromwelldev/workspace/cromwell/obj/elf.o
0x0000000003a1f940 prepare_boot_params
0x0000000003a1fbe0 elf_start
*fill* 0x0000000003a1fbf6 0xa
.text 0x0000000003a1fc00 0x33 /home/cromwelldev/workspace/cromwell/obj/exec_elf.o
0x0000000003a1fc00 try_elf_boot
0x0000000003a1fc33 _end_low_rom = .
.iplt 0x0000000000000000 0x0
.iplt 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rel.dyn 0x0000000000000000 0x0
.rel.iplt 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rel.text 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rel.data 0x0000000000000000 0x0 /home/cromwelldev/workspace/cromwell/obj/BootStartup.o
.rodata 0x0000000003a1fc33 0x11024 load address 0x000000000001fc33
*(.rodata)
我认为问题存在于我在链接描述文件中放入的.text.unlikely
部分。我必须说我迷失在这里。我对链接器脚本不熟悉,所以我真的不知道该怎么做。
有没有办法构建项目而不将.text.unlikely
部分与.text
部分的其余部分分开?这会是解决我问题的方法吗?
我还认为-fno-reorder-functions -fno-unwind-tables -fno-asynchronous-unwind-tables
标志不是我问题的解决方案。在这样的项目中,有些元素需要在特定的内存位置,我担心这些标记会以一种糟糕的方式移动事物!
提前谢谢!
本
答案 0 :(得分:1)
根据GCC docs,如果激活了选项.text.hot
,链接器可能会选择将内容放入.text.unlikely
和-freorder-functions
部分(默认情况下为优化级别-O2, -O3,-Os)。
取决于它是否"思考"一个函数经常调用或不调用。如果您的硬件具有快速和慢速内存区域,我想这可能会给您一些优化潜力
如果不是 - 只需将这些部分添加到.text就可以了。
答案 1 :(得分:0)
您为修复有关.text.unlikely
重叠.text
的错误所采取的措施实际上是正确的 - 链接器错误是由链接器“发送”到加载地址开始.text.unlikely
部分引起的0因为链接描述文件没有指定它去的任何地方。重复.eh_frame
部分的链接器脚本更改并删除-fno-reorder-functions -fno-unwind-tables -fno-asynchronous-unwind-tables
编译器标志应更正.eh_frame
重叠.text
的错误,而不会导致下游出现进一步的问题。