Page 1 of 2
Linker is adding extra crap (Unreferenced library code)
Posted: Fri Sep 30, 2011 8:33 am
by Dwedit
I'm having problems with unnecessary code getting linked into my project. I can't figure out where these symbols are coming from:
abort
_Unwind_decode_target2
__aeabi_unwind_cpp_pr0
restore_core_regs
__gnu_unwind_execute
__libc_init_array
After I disassemble my .elf file with objdump, I can't find any jumps, calls, or references to any of these symbols. I also tried disassembling all the .o files from my source code, and saw no references to them there either.
Of these symbols, "abort" is particularly bad, because linking in "abort" brings malloc into a program that does not use it. Linking in malloc eats up some IWRAM, and it's enough to make me run out.
When I was investigating some of the symbols, I noticed that "abort" is called by some of the multiplcation and division code in libgcc (why?!), but I could not find any calls to abort anywhere in my disassembled code.
I managed to exclude any "linker junk" by making a bunch of blank functions:
Code: Select all
void abort(){}
void __libc_init_array(){}
void _Unwind_VRS_Get(){}
void _Unwind_VRS_Set(){}
void __aeabi_unwind_cpp_pr2(){}
void __aeabi_unwind_cpp_pr1(){}
void __aeabi_unwind_cpp_pr0(){}
void _Unwind_VRS_Pop(){}
void _Unwind_GetCFA(){}
void __gnu_Unwind_RaiseException(){}
void __gnu_Unwind_ForcedUnwind(){}
void __gnu_Unwind_Resume(){}
void __gnu_Unwind_Resume_or_Rethrow(){}
void _Unwind_Complete(){}
void _Unwind_DeleteException(){}
void __gnu_Unwind_Backtrace(){}
void __restore_core_regs(){}
void restore_core_regs(){}
void __gnu_Unwind_Restore_VFP(){}
void __gnu_Unwind_Save_VFP(){}
void __gnu_Unwind_Restore_VFP_D(){}
void __gnu_Unwind_Save_VFP_D(){}
void __gnu_Unwind_Restore_VFP_D_16_to_31(){}
void __gnu_Unwind_Save_VFP_D_16_to_31(){}
void __gnu_Unwind_Restore_WMMXD(){}
void __gnu_Unwind_Save_WMMXD(){}
void __gnu_Unwind_Restore_WMMXC(){}
void __gnu_Unwind_Save_WMMXC(){}
void ___Unwind_RaiseException(){}
void _Unwind_RaiseException(){}
void _Unwind_Resume(){}
void ___Unwind_Resume(){}
void _Unwind_Resume_or_Rethrow(){}
void ___Unwind_Resume_or_Rethrow(){}
void _Unwind_ForcedUnwind(){}
void ___Unwind_ForcedUnwind(){}
void ___Unwind_Backtrace(){}
void _Unwind_Backtrace(){}
When I include these blank functions, I get no extraneous library functions thrown in during linking.
After including these blank functions, I checked the disassembly of my code, and saw
absolutely no references or calls to any of these functions.
What is going on here? Why are unreferenced functions getting linked in and bloating up the program?
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Sat Oct 01, 2011 1:22 pm
by WinterMute
None of your questions are going to be answered until you learn to phrase them with a lot more respect. I have yet to see a post from you that isn't really quite offensive.
Re: Linker is adding extra unreferenced library code
Posted: Sat Oct 01, 2011 10:14 pm
by Dwedit
I'm sorry, it's just that these posts usually come immediately after I've been trying for about 4 hours to frantically figure out what's going on, and I'm really frustrated at the time I'm posting them.
I just really don't understand how code that isn't referenced anywhere ends up in the program. What steps would I need to do to see what code is attempting to import the library code in question? It is very mysterious, since there are no references to this stuff anywhere in the disassemblies. Right now, the only method I have to "fight" against this problem is to make dummy functions.
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Sun Oct 02, 2011 12:39 am
by vuurrobin
my knowledge of gcc is limited, but AFAIK if your program uses 1 part of an object file, it includes the entire object file, causing the linker to include unused functions.
according to this post (
http://devkitpro.org/viewtopic.php?f=14&t=1665), you can remove unused code with "-Wl,--gc-sections":
link option: add -Wl,--gc-sections => garbage collect unreferenced sections => removes all your unused code, but also compiler generated code & data which is finally unused. It means that even if all of your routines are used, it still saves ROM.
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Sun Oct 02, 2011 2:08 am
by Dwedit
I have now tried that, but it didn't work.
My makefile line now looks like
LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $@).map,--gc-sections
EDIT:
When I look through "libgcc.a", I see this odd symbol table stuff in "bpabi.o".
There are references to "aeabi_unwind_cpp_pr0", but they do not appear in the disassembled code, and seem to only appear in the *UND* section. So why does that symbol get linked in?
Code: Select all
bpabi.o: file format elf32-littlearm
bpabi.o
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000074 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 000000a8 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 000000a8 2**0
ALLOC
3 .ARM.extab 00000000 00000000 00000000 000000a8 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .ARM.exidx 00000010 00000000 00000000 000000a8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
5 .comment 00000023 00000000 00000000 000000b8 2**0
CONTENTS, READONLY
6 .ARM.attributes 00000032 00000000 00000000 000000db 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .ARM.extab 00000000 .ARM.extab
00000000 l d .ARM.exidx 00000000 .ARM.exidx
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 *UND* 00000000 __aeabi_lmul
00000000 g F .text 0000003a __gnu_ldivmod_helper
00000000 *UND* 00000000 __divdi3
00000000 *UND* 00000000 __aeabi_unwind_cpp_pr0
0000003c g F .text 00000036 __gnu_uldivmod_helper
00000000 *UND* 00000000 __udivdi3
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000c R_ARM_THM_CALL __divdi3
0000001c R_ARM_THM_CALL __aeabi_lmul
00000048 R_ARM_THM_CALL __udivdi3
00000054 R_ARM_THM_CALL __aeabi_lmul
RELOCATION RECORDS FOR [.ARM.exidx]:
OFFSET TYPE VALUE
00000000 R_ARM_PREL31 .text
00000000 R_ARM_NONE __aeabi_unwind_cpp_pr0
00000008 R_ARM_PREL31 .text
I see a few other *UND* section references as well:
Code: Select all
_divdi3.o.headers.txt(37): 00000000 *UND* 00000000 __aeabi_unwind_cpp_pr1
_divdi3.o.headers.txt(67): 00000000 R_ARM_NONE __aeabi_unwind_cpp_pr1
_moddi3.o.headers.txt(37): 00000000 *UND* 00000000 __aeabi_unwind_cpp_pr1
_moddi3.o.headers.txt(67): 00000000 R_ARM_NONE __aeabi_unwind_cpp_pr1
_udiv_w_sdiv.o.headers.txt(34): 00000000 *UND* 00000000 __aeabi_unwind_cpp_pr0
_udiv_w_sdiv.o.headers.txt(40): 00000000 R_ARM_NONE __aeabi_unwind_cpp_pr0
_udivdi3.o.headers.txt(37): 00000000 *UND* 00000000 __aeabi_unwind_cpp_pr1
_udivdi3.o.headers.txt(67): 00000000 R_ARM_NONE __aeabi_unwind_cpp_pr1
_udivmoddi4.o.headers.txt(37): 00000000 *UND* 00000000 __aeabi_unwind_cpp_pr1
_udivmoddi4.o.headers.txt(67): 00000000 R_ARM_NONE __aeabi_unwind_cpp_pr1
_umoddi3.o.headers.txt(37): 00000000 *UND* 00000000 __aeabi_unwind_cpp_pr1
_umoddi3.o.headers.txt(67): 00000000 R_ARM_NONE __aeabi_unwind_cpp_pr1
bpabi.o.headers.txt(36): 00000000 *UND* 00000000 __aeabi_unwind_cpp_pr0
bpabi.o.headers.txt(52): 00000000 R_ARM_NONE __aeabi_unwind_cpp_pr0
None of these symbols appears anywhere in the disassembled code.
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Mon Oct 03, 2011 2:35 pm
by WinterMute
This stuff is part of the aeabi standard for some reason that escapes me - some parts of libgcc are built with exception handling code and pull in some extras that most people don't expect to see in their code. I've actually been looking into this over the last few weeks to see what will break if I do some tweaks to remove the extra dependencies.
devkitARM is intended to be a lot more generic than just a compiler that targets GBA/NDS so I need to be pretty careful about making changes for one particular use case.
Making a bunch of blank functions to avoid pulling in extra library code you don't really need isn't an ideal solution so hopefully I can manage to get rid of this stuff without causing problems elsewhere.
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Mon Oct 03, 2011 6:40 pm
by tueidj
The *divdi3 functions are used for 64-bit division/modulus, they will only get linked in (along with the *divmod_helper functions) if you use a (u)int64 in a divide or mod operation. Probably *lmul serves a similar purpose (long multiplication?) but I'm not positive about that. For this reason it's best to avoid using div/mod/mul on 64-bit types if at all possible. If they're still getting linked in, check the .map file to find out what function is calling them.
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Tue Oct 04, 2011 2:04 am
by Dwedit
Here, I'm doing a 64-bit unsigned division. This is a call to the function __aeabi_uldivmod.
So it depends on these functions:
__aeabi_uldivmod from _aeabi_uldivmod.o
__aeabi_ldiv0 from _dvmd_tls.o (this appears to be a blank function, the only content is "bx lr", it's probably the division by 0 handler)
__gnu_uldivmod_helper from bpabi.o
> __divdi3 from _divdi3.o
> __aeabi_lmul from _muldi3.o
> __udivdi3 from _udivdi3.o
>> __aeabi_uidiv from _udivsi3.o
>> __aeabi_uidivmod from _udivsi3.o
>> __clzsi2 from _clzsi2.o
So far, so good. No problems here.
Except then it proceeds to bring in "__aeabi_unwind_cpp_pr0", even though none of these functions call that function.
"bpabi.o" contains a reference to that function in the symbol table, but it does not exist anywhere in the code. It is tagged as *UND*.
You can see this yourself, use "arm-eabi-ar -x libgcc.a" to get the *.o files out of the library, and "arm-eabi-objdump -d bpabi.o > bpabi.s" to get a disassembly. No code anywhere calls __aeabi_unwind_cpp_pr0.
But if you do "arm-eabi-objdump -t bpabi.o > bpabi.sym" to get the symbol table, there's an external reference symbol for that function anyway.
"__aeabi_unwind_cpp_pr0" brings in a lot more code, including "abort", which brings in "malloc".
So if the code doesn't use it, why does it make a reference to it?
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Tue Oct 04, 2011 5:22 am
by zeromus
youll also see sections .ARM.extab and .ARM.exidx in the bpapi.o ; exception handling junk that isnt in dwedit.o. its not too surprising that gcc also emit an extern reference to the exception handling code into that file when it emit the exception handling data..maybe to make sure that the exception handling system got linked in, even if there was no code that raised any exceptions?
I was unable to find my way through the maze of gcc to find out where the exceptions related to divs get raised from, but maybe if someone could find that point then wintermute could add a patch with one weak symbol to raise the exception instead of doing it at the spot of the exception, so that it could be overridden cleanly with one function. Thats the nicest way i can think of to reconcile the two use cases.. but I dont know much about this kind of stuff.
Re: Linker is adding extra crap (Unreferenced library code)
Posted: Tue Oct 04, 2011 9:08 am
by tueidj
I say leave it as is. If I want an exception when I divide by zero then I should get one. If someone else doesn't, they can write their own long division function.