Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging linkage warning "type of symbol does not match original declaration"

Tags:

c

gcc

linkage

lto

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.
like image 551
ugoren Avatar asked Oct 29 '22 22:10

ugoren


1 Answers

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
like image 169
a3f Avatar answered Nov 16 '22 08:11

a3f