Reputation: 16441
I'm trying to systematically debug the following problem:
% gcc -fPIC -flto -o try1.o -c try1.c
% gcc -fPIC -flto -o try2.o -c try2.c
% gcc -shared -flto -fPIC -o try.so try1.o try2.o
try2.c:1:14: warning: type of 'aaaaaaaa' does not match original declaration [enabled by default]
try1.c:1:5: note: previously declared here
I this synthetic test, I know exactly what's the problem - aaaaaaaa
is defined int
here, but short
there. In my real problem, the linkage combines many objects which are the result of a complicated build process, and I don't know which two objects contain the conflicting definitions.
I want to tackle it by examining each of the linked object files, see how the symbol is defined in each, and find a pair with mismatching definitions. Then I'll track the build process to see how they're built and get to the root cause. But I don't know a way to see the way an object is defined.
I tried nm -A
and objdump -t
, but they don't show the symbol type/size:
% nm -A try1.o
try1.o:00000001 C __gnu_lto_v1
try1.o:00000000 D aaaaaaaa
% nm -A try2.o
try2.o:00000001 C __gnu_lto_v1
try2.o: U aaaaaaaa
try2.o:00000000 T foo
% objdump -t try1.o | grep aaa
00000000 g O .data 00000004 aaaaaaaa
% objdump -t try2.o | grep aaa
00000000 *UND* 00000000 aaaaaaaa
My compiler:
% gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Upvotes: 5
Views: 1961
Reputation: 8657
Use nm --print-size
. GNU nm
defaults to BSD format, which only displays the values. This doesn't show the sizes of undefined symbols, because this information isn't required for linking and isn't stored anywhere.
When compiling with -flto
, GCC adds a couple of .gnu.lto_.
sections, which among others contain the expected size of the undefined symbols. I don't know if there's any readily available tool to parse them.
You can show a hexdump with:
F=try2.o; objdump -h $F | grep -o '\.gnu.lto_\S*' | xargs -I% readelf -x % $F
Upvotes: 2