4

I'm trying to build cromwell (Original Xbox legal firmware replacement) using a more recent version of gcc but after altering the project compilation setup slightly, ld throws the following error:

ld: section .text.unlikely loaded at [0000000000000000,0000000000000669] overlaps section .text loaded at [0000000000000000,0000000000021515]

You can clone the project from here if you want to have a look: https://github.com/not404/cromwell

First and foremost, I want to mention I was able to successfully build and run this project(on my Xbox) using gcc-3.3 on a x32 linux VM and gcc-4.1 on cygwin x86 (built gcc for target i686-linux-gnu). I had to remove -Werror cflag in the main Makefile to successfully build it in gcc-3.3. Trying to build it using gcc-4.8.2 on a x32 VM after modifying the makefile result in the error mentionned above.

In order to get to there, I modified the CFLAGS in the Makefile in root of the project. I still had -Werror removed from CLAGS. I had to add -fno-stack-protector flags in CFLAGS and ETH_CFLAGS to get past the undefined reference to '__stack_chk_fail' error. I think this workaround is quite harmless. Older gcc versions didn't support such stack smashing protection mechanism so disabling it should not pose a problem.

After the modifications made to the Makefile, I am presented with the linker error about section overlapping. I read that the .text.unlikely section was added around gcc 4.6 so obviously it was not considered when the cromwell project was actively developped!

So, in order to get past this error, I tried to explicitely define the .text.unlikely section in the "ldscript-crom.ld" linker script. Originally, script contained the following:

.text LOW_ROM : AT ( 0 ){
    _start_low_rom = . ;
    *(.text);
    _end_low_rom = . ;
}

I changed it to:

    .text LOW_ROM : AT ( 0 ){
    _start_low_rom = . ;
    *(.text);
    *(.text.unlikely);
    _end_low_rom = . ;
}

After this change, I get yet another error:

ld: section .eh_frame loaded at [0000000000000000,00000000000062b3] overlaps section .text loaded at [0000000000000000,0000000000021b7f]

From what I read on the internet, the .eh_frame section is only related to exception handling and targeted to C++ to catch exceptions.

I was able to fix this by adding the following flags to CFLAGS and EHT_CFLAGS in the main Makefile:

-fno-reorder-functions -fno-unwind-tables -fno-asynchronous-unwind-tables 

After all that, I finally get an output file. Unfortunately, there are error in execution. It seems to start well but I get no video and execution seem to crash at some point.

I tried to print the map of the linked file but I don't see anything relevant. I won't post the 2 maps(with gcc-3.3 and with gcc-4.8, same ld) here as they are very big. Here is the part of the map containing the .text.unlikely section definition(from 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 

Here's the same section from 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)

I think the problem reside in the .text.unlikely section I put in the linker script. I must say I'm at lost here. I'm not familiar with linker scripts so much so I really don't know what to do.

Is there a way to build the project without separating the .text.unlikely section from the rest of the .text section? Would that be a way to solve my problem?

I also think -fno-reorder-functions -fno-unwind-tables -fno-asynchronous-unwind-tables flags are not a solution to my problem. In such project, there are elements that need to be at specific memory locations and I fear these flags do move things around in a bad way!

Thank you in advance!

Ben

2 Answers2

1

According to GCC docs the linker might choose to put stuff into the sections .text.hot and .text.unlikely if option -freorder-functions is activated (which is default at optimization levels -O2, -O3, -Os).
Depending on whether it "thinks" that a function is called very often or not. I guess this might give you some optimization potential if your hardware has something like fast and slow memory areas.
If not - just adding these sections to the .text should be fine.

Roman
  • 707
  • 8
  • 16
0

What you did to fix the error about .text.unlikely overlapping .text is actually correct -- the linker error is caused by the linker "punting" to beginning the .text.unlikely section at load address 0 because the linker script does not specify anywhere for it to go. Repeating the linker script change for the .eh_frame section and removing the -fno-reorder-functions -fno-unwind-tables -fno-asynchronous-unwind-tables compiler flags should correct the error about .eh_frame overlapping .text without causing further trouble downstream.

LThode
  • 1,843
  • 1
  • 17
  • 28