5

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.
ugoren
  • 16,023
  • 3
  • 35
  • 65

1 Answers1

2

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
a3f
  • 8,517
  • 1
  • 41
  • 46
  • This gives me the size for defined symbols only. So it doesn't help with a mismatch between a defined and undefined symbol. – ugoren Aug 11 '16 at 12:21
  • @ugoren Hmm, that I don't know either. I will revise the answer if I find something. – a3f Aug 11 '16 at 12:49
  • Thanks. But I can't find any resource to help me read the hex dump. – ugoren Aug 11 '16 at 15:03
  • The GCC source code is probably the only documentation. I hope someone experienced with GCC internals can chime in. – a3f Aug 11 '16 at 15:28