gcc-4.1 - > gcc-4.8链接器错误。新的" .text.unlikely"部分重叠" .text"部分

时间:2015-05-15 13:36:00

标签: gcc makefile linker linker-errors linker-scripts

我正在尝试使用更新版本的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-protectorCFLAGS中添加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标志不是我问题的解决方案。在这样的项目中,有些元素需要在特定的内存位置,我担心这些标记会以一种糟糕的方式移动事物!

提前谢谢!

2 个答案:

答案 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的错误,而不会导致下游出现进一步的问题。