C/C++ linker CALL16 reloc at xxxxx not against global symbol - c++

I'm getting these errors while linking, both messages have to do with the same object file.
CALL16 reloc at 0x5f8 not against global symbol
and
could not read symbols: Bad value
The 2nd message seems to be the reason I'm getting the CALL16 error, but the file compiles just fine.
Any tips on fixing this?
FYI, I'm cross compiling for a MIPS target and using gcc 4.1.2
EDIT: No luck so far:
Here are my flags used:
-fPIC,-Wl,-rpath,-Wl,-O1
I've also tried the following without success:
-mno-explicit-relocs
-mexplicit-relocs
-mlong-calls
-mno-long-calls
-mxgot
-mno-xgot
Meanwhile, I'll go back to the source at this point and investigate more.

Aha!
Thanks to a colleague of mine, we found the issue.
Here was the issue:
There was a forward declaration/prototype of a function.
void FooBarIsBest(void);
Later on in the file the function was defined.
static void FooBarIsBest(void)
{
// do the best
}
The issue here was that in the prototype the keyword static was left out. So it was like a whole new function was being defined.
The CALL16 reference is used by gcc for relocatable code. The assembly code of the file showed that CALL16 was being used on this function... Which is wrong, as this function is local.
Interestingly, this code used to compile & link just fine with an older version of gcc (3.2.2).
Another lessoned learned. :)

Try -mlong-calls flag to the compiler.
Also see the manual for more specific MIPS options.

Related

Mingw64 Linker error when trying to include -lhid [duplicate]

Context: I'm using Qt 5.9.3 on Windows, building for MinGW 32-bit. The Qt part is a side issue though - the problem seems to be with MinGW. The version of MinGW is 4.3.0, supplied prebuilt as part of the Qt installation.
I'm building a library which talks to a USB device over HID. Everything compiles fine, but it fails at the link stage with
./..\..\object\debug\usb_hid_device.o: In function `ZN8MyApp3USB5Win3213getDevicePathB5cxx11Ell':
<MYPATH>/../../source/win32/usb_hid_device.cpp:99: undefined reference to `HidD_GetAttributes(void*, _HIDD_ATTRIBUTES*)#8'
./..\..\object\debug\usb_hid_device.o: In function `ZN8MyApp3USB5Win3214CHIDDeviceImplC2EllRNS_15LogPerComponentE':
<MYPATH>/../../source/win32/usb_hid_device.cpp:200: undefined reference to `HidD_FlushQueue(void*)#4'
The linker command is
g++ -shared -mthreads -Wl,-subsystem,windows -Wl,--out-implib,<MYPATH>\bin\debug\libusb_hid_comms.a -o <MYPATH>\bin\debug\usb_hid_comms.dll object_script.usb_hid_comms.Debug -lhid -lsetupapi -LC:\Qt\Qt5.9.3\5.9.3\mingw53_32\lib C:\Qt\Qt5.9.3\5.9.3\mingw53_32\lib\libQt5Guid.a C:\Qt\Qt5.9.3\5.9.3\mingw53_32\lib\libQt5Cored.a
If I omit -lhid I get the same errors. I also get the same errors if I remove -lhid and explicitly set the path and filename to libhid.a. If I deliberately mistype the path and filename, it comes up with an error, so I know the command-line is getting parsed correctly. But for whatever reason, MinGW appears to not be linking with one of its own library files.
I've also tried removing -lsetupapi and I get the linker errors I'd expect for the functions defined in there. Likewise the Qt library files. But it seems that specifically for libhid.a, MinGW can see the library file but just isn't going to link with it.
Has anyone else seen this? Or can anyone else with the same (or similar) version of MinGW confirm or deny that they can link with libhid.a? Or is there something obviously wrong with what I'm doing?
I've just found the answer. I'm posting an answer myself so that other people know in future, because I think this is still a valid question which people might want to know about.
The problem is the include file hidsdi.h. The majority of other header files which pull in Win32 API calls have extern "C" around the function declarations. However this one doesn't! The result is that we end up with C++ name mangling for linker symbols, instead of the C-style "_" in front of the linker symbols.
The solution is to use
extern "C"
{
#include <hidsdi.h>
}
and then everything works fine.
The version of hidsdi.h with the older version of MinGW (which I'm porting from) did have that protection around the function declarations. However it looks like it's gone in the newer version.

Symbol lookup error when using -Wl,--defsym GCC option

I've got a question regarding using one of the GCC linker options: -Wl,--defsym.
Some time ago I decided to rewrite one of my projects in C++ but without using its standard library and without even linking to it (I compile .cpp source files to object files using C++ compiler but I link them using C compiler).
For that I used following compiler flags:
-fno-exceptions -fno-rtti -nostdlib -nodefaultlibs
And following linker options:
-Wl,--defsym -Wl,__cxa_pure_virtual=0
Using those flags I got my shared library compiling and linking fine.
But after I try to use my shared library in some simple program (also compiled and linked using above flags) I get following error while running it:
examples/bin/blink: symbol lookup error: examples/bin/libblink.so: undefined symbol: __cxa_pure_virtual
where blink is the name of the executable and libblink.so is the name of my shared library.
I tried to fix it and it looks like replacing --Wl,--defsym linker flag (for both executable and library) with this function:
extern "C" void __cxa_pure_virtual
{
while (true);
}
does the job. Why is the --Wl,--defsym not working in this case?
I'd also like to mention that I tested this under Windows and it works fine there.
I think that I've found an answer to my question.
Changing the symbol address from 0 to any other value fixes my issue.
So instead of having:
--Wl,--defsym --Wl,__cxa_pure_virtual=0
I have:
--Wl,--defsym --Wl,__cxa_pure_virtual=1
This way runtime linker does not look for a symbol (which I think is the case when the address is set to 0).

Undefined reference to operator new

I'm trying to build a simple unit test executable, using cpputest. I've built the cpputest framework into a static library, and am now trying to link that into an executable. However, I'm tied into a fairly complicated Makefile setup, because of the related code.
This is my command line:
/usr/bin/qcc -V4.2.4,gcc_ntoarmle_acpp-ne -lang-c++ -O2 -g -g -o Application/UnitTests/Tests/symbols/UnitTestExe -Wl,--start-group Application/UnitTests/Tests/../.objs/main.o Application/UnitTests/lib/libcpputest.a -Wl,--end-group -lm
I'm getting many errors like the following:
Application/UnitTests/lib/libcpputest.a(CommandLineTestRunner.o): In function `CommandLineTestRunner::parseArguments(TestPlugin*)':
Application/UnitTests/cpputest/src/CppUTest/.objs/../CommandLineTestRunner.cpp:114: undefined reference to `operator new(unsigned int, char const*, int)'
I can't figure out what's causing this. Don't I get operator new for free with C++?
You probably need to link with the C++ support runtime library. This happens automatically when you invoke g++. On Linux, this is achieved by adding the -lstdc++ flag to the linker. You have to figure out how to do the same on your platform.
Maybe you're calling gcc, the C compiler instead of g++, which is the C++ compiler.
There's very little information in your question to work from, but it looks like some code uses some form of placement new, and while that special operator new is declared (the compiler finds it and compiles the code using it), the linker can't find its definition.
(Since this old answer of mine seems to still get attention: See here for an extensive discussion on declaration vs. definition.)
You need to rebuild your code from scratch, including the library. I got this error because I inadvertently copied object files compiled on another machine (with the rest of the source) to my machine. Most likely this disturbs the linking step since there are now two types of object files, native (for modified source files) and non-native (all others). I am guessing here, but the operator 'new' means slightly different things on different architectures and that's why you are getting this error.
p.s. I know this is way too late for a useful answer but I'm still posting this for the record.
For QNX 6.5.0 I have specified flag -lang-c++ for qcc (gcc) to avoid the error.
Like the original post, in my case this error happened while trying to link a software using CppUTest framework.
In my case, the source of the problem seems to be related to the fact I disabled the MEMORY_LEAK_DETECTION compile option of CppUTest. I enabled it again, which solved the problem.
Sometimes adding -lstdc++ is not enough. You should add it to the right place. For example I had list like this, not working:
target_link_libraries(cfr2 pthread m stdc++ "${CMAKE_SOURCE_DIR}/compressor/libcompressor.a" )
But this one works fine:
target_link_libraries(cfr2 pthread m "${CMAKE_SOURCE_DIR}/compressor/libcompressor.a" stdc++)
It'd be great if someone explained it in the comment section.

How can I find the calling routine for a symbol in case of a linker error "undefined reference"?

I have a problem linking an application for an embedded target. I'm developing on a windows box using Min-GW for an ARM9 target that runs under Linux.
Actually I'm switching from static linking to dynamic linking with .so-libraries to save memory space.
I get the error message
libT3Printer.so: undefined reference to `__ASSERT'
I checked all the sources for the lib and I have no idea where this function could be called. Is there any possibility to find out, who (which source file or function) could be the caller of the missing function?
The reference is probably being hidden by a macro. If you run the compiler with the -E option to generate predecessor output you might have a better chance of tracking it down.
Try to add definition NDEBUG.
In C, compiling with NDEBUG defined:
gcc -DNDEBUG foo.c
disables all calls to assert(), and this behavior is identical in C++:
g++ -DNDEBUG foo.cpp

Suppressing Linking Errors in G++ 3.4.6

Don't ask why, but is there any way to suppress a failed linking error?
Such as:
undefined reference to BLANK
This is in GCC 3.4.6
No, because they are errors and not warnings. By definition this means that the function was referenced someplace but not defined... that's not something you can just ignore.
The only way of supressing the link errors would be not linking (or not having errors in the first place). As mentioned by SoapBox, errors cannot be silently ignored.
If you post some code you could get to a solution to the problem that is better than trying to close your eyes and wait for the problem to go away (they don't usually).
It's not the compiler, but the linker. The best way to "suppress" this would be to pass in the library name with the compile command:
gcc try.cc -lstdc++
or
g++ try.cc -lfltk
for instance.