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