cronburg
cronburg

Reputation: 891

Why "Multiple definitions linker error" when nm only sees one definition

When linking some object files together I get a bunch of errors like:

obj-ia32/ShadowRoutine.o: In function `InitializeMap(unsigned int*)':
ShadowRoutine.cpp:(.text+0x0): multiple definition of `InitializeMap(unsigned int*)'
obj-ia32/ShadowRoutine.o:ShadowRoutine.cpp:(.text+0x0): first defined here

with compilation and linking commands of:

g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
    -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX  -I../../../source/include/pin \
    -I../../../source/include/pin/gen -I../../../extras/components/include \
    -I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
    -fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
    -Wno-unused-function -I. -Ishadow-memory -m32 -c \
    -o obj-ia32/ShadowRoutine.o ShadowRoutine.cpp
g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
    -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX  -I../../../source/include/pin \
    -I../../../source/include/pin/gen -I../../../extras/components/include \
    -I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
    -fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
    -Wno-unused-function -I. -Ishadow-memory -m32 -c \
    -o obj-ia32/Jikes.o Jikes.cpp
g++ -shared -Wl,--hash-style=sysv -Wl,-Bsymbolic \
    -Wl,--version-script=../../../source/include/pin/pintool.ver \
    -m32 -o obj-ia32/Jikes.so obj-ia32/ClientReq.o obj-ia32/Server.o \
    obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
    obj-ia32/Jikes.o obj-ia32/ClientReq.o obj-ia32/Server.o \
    obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
    -L../../../ia32/lib -L../../../ia32/lib-ext -L../../../ia32/runtime/glibc \
    -L../../../extras/xed-ia32/lib \
    -L/home/karl/r/git/pin/source/tools/Jikes/zmq/inst/lib \
    -lpin -lxed -lpindwarf -ldl -lzmq

The only two object files with InitializeMap are Jikes.o and ShadowRoutine.o:

$ nm obj-ia32/Jikes.o  | grep InitializeMap
         U _Z13InitializeMapPj
$ nm obj-ia32/ShadowRoutine.o | grep InitializeMap
00000000 T _Z13InitializeMapPj
$ nm obj-ia32/* | grep InitializeMap
         U _Z13InitializeMapPj
00000000 T _Z13InitializeMapPj

So why am I getting "multiple definitions of InitializeMap" if it's only "defined" in one object file and "undefined" in the only other object file that required it using extern?

This is what the declarations, definitions, and uses look like:

$ grep -r InitializeMap *
Jikes.cpp:  if (rtn_name == "sysInitializeMap") {       RTN_INSERT_1(InitializeMap);
Binary file obj-ia32/Jikes.o matches
Binary file obj-ia32/ShadowRoutine.o matches
ShadowRoutine.cpp:VOID InitializeMap(ADDRINT *smID) { init_map(*(int*)smID); }
ShadowRoutine.hpp:VOID InitializeMap(ADDRINT *smID);

where both the cpp files #include "ShadowRoutine.hpp".

EDIT: My question is why does the linker command (the third g++ command in the second code snippet above) not work even though nm says that the function is only defined in the text of ShadowRoutine.o and undefined in Jikes.o?

Upvotes: 0

Views: 331

Answers (1)

aschepler
aschepler

Reputation: 72356

You have the file obj-ia32/ShadowRoutine.o listed twice in your link command.

Upvotes: 4

Related Questions