gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > dead code elimination?

#144655 - bpoint - Mon Nov 05, 2007 12:34 pm

Hello all,

I've been working on a rather large project under Win32, and have finally ported the code over to GBA. However, I am having a bit of a problem getting my application to link properly. ld is giving me these errors (the log is not exact -- I have trimmed some things to make it more readable):

Code:
1>------ Build started: Project: sandbox, Configuration: Debug GBA ------
1>Performing Makefile project actions
1>arm-eabi-g++ -mthumb -mthumb-interwork -Wl,-Map,sandbox.elf.map -dead_strip -specs=gba_mb.specs    sandbox.o  -L../../lib/gba -lDebug-lib1 -lDebug-lib2 -lDebug-lib3 -lDebug-lib4  -o sandbox.elf
1>arm-eabi/bin/ld.exe: address 0x20ab760 of sandbox.elf section .text is not within region ewram
1>arm-eabi/bin/ld.exe: section .init [02000000 -> 02000217] overlaps section .fini [02000000 -> 0200000b]
1>arm-eabi/bin/ld.exe: section .rodata [02000010 -> 0200ddf3] overlaps section .init [02000000 -> 02000217]
1>arm-eabi/bin/ld.exe: section .text [02000218 -> 020ab75f] overlaps section .rodata [02000010 -> 0200ddf3]
1>arm-eabi/bin/ld.exe: section .ARM.extab [0200ddf4 -> 02017c77] overlaps section .text [02000218 -> 020ab75f]
1>arm-eabi/bin/ld.exe: sandbox.elf: section .init lma 0x2000000 overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .rodata lma 0x2000010 overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .text lma 0x2000218 overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .ARM.extab lma 0x200ddf4 overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .ARM.exidx lma 0x2017c78 overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .init_array lma 0x201dfe0 overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .fini_array lma 0x201e01c overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .jcr lma 0x201e020 overlaps previous sections
1>arm-eabi/bin/ld.exe: sandbox.elf: section .eh_frame lma 0x201e024 overlaps previous sections


It's obvious from the messages that the compiled code size in the .text section is larger than the ewram size (256k) of the GBA. However, this is my main() function:

Code:
int main(int argc, char *argv[], char *envp[])
{
   return 0;
}


Indeed, after looking at the .map file produced by the linker, every single function and class in every library being linked in is trying to be put inside the output .elf file. I realize I can get around the linker errors by using the gba.specs file instead of the multiboot one, but this is not a solution. I do not want any unused functions to be placed in the output .elf file. Does devkitARM not support the "-dead_strip" parameter, or am I doing something wrong here?

Any ideas would be greatly appreciated.

#144660 - wintermute - Mon Nov 05, 2007 1:32 pm

You're doing something very, very wrong somewhere.

-dead-strip is an Apple extenson as far as I'm aware - I can't find it in the FSF documentation anyway.

http://sourceware.org/binutils/docs-2.18/ld/Options.html#Options

If you don't want "unused" functions in your output file the best way is to not reference them or put them in files containing functions that *are* used.

gcc does provide a means to attempt to eliminate dead code but I'm not particularly sure how well it works. Add -ffunction-sections -fdata-sections to CFLAGS and --gc-sections to LDFLAGS. I'm not sure how well these work, I've never used them.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#144665 - tepples - Mon Nov 05, 2007 1:58 pm

Wintermute is right. In my mini-rant "The plus stands for bloat" about my experience with space inefficiency of static GNU libstdc++, I tell how -Wl,-gc-sections helped a little bit for me.

But you might run into classes where one member from one part of the standard library brings in another big chunk of the standard library. In cases like std::ostream of <iostream> bringing in some date, time, and money formatting objects from the locale library, it might take some surgery on the libraries themselves to slim them down. As I understand it, the linker can sometimes eliminate uncalled functions but not unused data members.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#144668 - bpoint - Mon Nov 05, 2007 3:54 pm

Sorry, I probably should have made it clear that all of the code that I'm linking in through libraries is all engine code that our team has written. We don't use RTTI or exceptions, and we don't use anything in the C++ standard library. We can even practically avoid linking to libc entirely (although there are a few functions left we still need to bind to).

I did some more searching on Google about "-dead_strip" -- apparently it is a Darwin-only option. My apologies.

wintermute wrote:
If you don't want "unused" functions in your output file the best way is to not reference them or put them in files containing functions that *are* used.


I'm not exactly sure what you mean by not referencing them. If I have an empty main(), how am I referencing any functions at all?

I will give the -Wl,-gc-sections option a try though. Thank you!

#144683 - bpoint - Mon Nov 05, 2007 7:05 pm

Adding -ffunction-sections -fdata-sections to CFLAGS, and -Wl,--gc-sections to LDFLAGS seemed to do the trick, for the most part. The compiled size now fits well within ewram, although I'm still seeing certain classes and their functions being put into the .text section even with my empty main().

After browsing the .map file in more detail, it's possible these remaining classes are statically allocated local to a given source file, and referenced through functions in that source file. Microsoft's compiler is smart enough to recognize that if those unused functions are not called, then the data (and code) being referenced by them is not necessary either. I guess gcc hasn't made it that far yet, but I will admit this is something that could be done better on our end anyway.

I am now trying to deal with a last few "undefined reference" errors. In order to avoid going off-topic, I'll make a new post.

Thanks again for the help!