I am trying to make 32 bit library on a 64 bit Ubuntu box. I am creating .so as follows
gcc - shared -Wl,-soname,libtest.so *.o
I am getting /usr/bin/ld : relocation R_X86_64_PC32 against symbol "set_bright' cann't be used when making shared object;recompile with -fPIC.
Already I tried compiling with -fPIC. It didn't work.
Please let me know if I need to use any flag while compilation .c or some flag while creating .so
thanks,
I believe you get that error if there you're calling a function declared as hidden, e.g.
int set_hidden(void) __attribute__((visibility("hidden")));
and it's not defined in the same shared object.
To solve it you have to also link the object file containing the definition of set_hidden, or remove the call to it.
Related
It seems to not be possible to build a shared lib from relocable objects with R_X86_64_PC32 references and I don't understand why.
These references are IP relative and so are position independent. So why ld tell me this is not the case and I have to use -fPIC which generate a GOT reference ?
relocation R_X86_64_PC32 against symbol `infolib' can not be used when making a shared object; recompile with -fPIC
As it is said here : Difference in position-independent code: x86 vs x86-64
IP-relative offset does not work for shared libraries, because global symbols can be overridden, so x86-64 breaks down when not built with PIC.
We have to use -fPIC to go through GOT which is updated at runtime for symbol overriding.
I am trying to compile a simple executable using CMake and Clang on Ubuntu 18. Some code coming from a third party source and compiled as a shared library libtommath ends up calling the function __udivti3 after the compiler does some code optimisations.
At link time, I have an error coming from ld saying hidden symbol "__udivti3" in /usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a(_udivdi3.o) is referenced by DSO
I did some research and thanks to this link this effectively means that __udivti3 is referenced by the shared library but It cannot be used from the libgcc.a as it is marked as hidden in this library.
My issue is whatever I try to fix it, the linkage always fails. I tried to link with libgcc_s which is located in the same directory but clang complains it cannot find it. On the other hand though, the compilation and linkage work perfectly on MacOS, with that problematic symbol still being present.
I'm trying to understand why I'm getting an undefined reference error during linking:
/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib -T/home/amirgon/projects/esp8266/esp-open-sdk/sdk/ld/eagle.app.v6.cpp.ld -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain build/app_app.a -Wl,--end-group -o build/app.out
build/app_app.a(routines.o):(.text+0x4): undefined reference to `pvPortMalloc(unsigned int, char const*, int)'
gcc complains it could not find the function pvPortMalloc.
However, I can confirm this function exists in libmain.a!
In the command line above, libmain is referenced by -lmain and library path is set to -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib.
When I dump symbols from libmain.a on that path I can find pvPortMalloc marked as T, which means that the symbol is in the text (code) section:
/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-nm -g /home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib/libmain.a | grep pvPortMalloc
U pvPortMalloc
0000014c T pvPortMalloc
U pvPortMalloc
So, did I miss something?
what could be the reason that gcc does not find the function although it exists in libmain.a?
How can I further debug this error?
Mixing of C++ and C code causes your issue.
This error:
undefined reference to `pvPortMalloc(unsigned int, char const*, int)'
Does not say that the symbol pvPortMalloc cannot be found. It says that the symbol pvPortMalloc(unsigned int, char const*, int) cannot be found,
and that is a C++ symbol.
This means that somewhere you are compiling C++ code which thinks there is a C++ pvPortMalloc function, whose symbol also includes its signature, but you only have a pvPortMalloc C function.
Likely your C++ code is including a header file that is not C++ clean, and you will need to do something like this:
extern "C" {
#include "some_header.h"
}
Where some_header.h is the header file declaring the pvPortMalloc function.
Not only order of object files and libraries on the command line is important, but also the order of object files within a library.
Anything that resolves a reference must come after the symbol is used, otherwise you might get strange linking problems.
The effect you see is a typical problem of a library that has been built with ar and the wrong object file order (some .o file using an external function that is defined in some .o file before the one that uses this symbol in the lib).
ranlib <libfile> is the tool that fixes this by creating an index for all objects in the library and should get rid of this problem.
I'm writing a simple C shared library using Eclipse CDT under Linux 64bit.
The code has one reference to the rand() function in the <stdlib.h> It compiles fine but when linking it reports the following error from the linker:
gcc -shared -o "libalg.so" ./sort.o
/usr/bin/ld: ./sort.o: relocation R_X86_64_PC32 against undefined symbol `rand##GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
sort.o is the object file compiled from the file. libalg.so is the target shared library name.
Can anyone explaining why this happen?
Thanks.
On x86_64 architecture gcc requires you to use -fPIC i.e Position Independent Code by default.
The underlying reason for the error is that the relocation type for the symbol rand is of type R_X86_64_PC32 which means that it is PC relative and should lie within 32bit offset from the following instruction.
But the current architecture is of x86_64 type which means that it can lie anywhere within the 64bit address space.
So the dynamic linker actually can not link a symbol with such a relocation type.
Either you have to use -fPIC or compile your code using the -mcmodel=large which will actually make the relocation type to R_X86_64_64.
For more details on how linking is done refer to this great blog by Eli Bendersky
I am trying to create a dynamic library which is meant to be linked and loaded into a host environment at runtime (e.g. similar to how class loading works in Java). As such, I want the dynamic library to be left with a few "dangling" references, which I expect it to pick up from its host environment when it is loaded into that environment.
My problem is that I cannot figure out how to create the dynamic library without explicitly linking it to existing symbols. I am hoping to produce a dynamic library that does not depend on a specific host executable (or host library), rather one that is able to be loaded (e.g. by dlopen) in any host as long as the host makes a couple symbols available for use.
Right now, any linking command I've tried results in a complaint of missing symbols. I'd like it to allow symbols to be missing (ideally, just particularly specified symbols).
For example, here's a transcript with the error on OS X:
$ cat frotz.c
void blort(void);
void run(void) {
blort();
}
$ cc -c -o frotz.o frotz.c
$ cc -dynamiclib -o libfrotz.dylib frotz.o
Undefined symbols for architecture x86_64:
"_blort", referenced from:
_run in frotz.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
If I do the same thing using a GNU toolchain (on Linux), it helpfully tells me:
$ gcc -shared -o libfrotz.so frotz.o
/usr/bin/ld: frotz.o: relocation R_X86_64_PC32 against undefined symbol `blort'
can not be used when making a shared object; recompile with -fPIC
and indeed, adding -fPIC to the C compile command seems to fix the problem in that environment. However, it doesn't seem to have any effect in OS X.
All the other dynamic-linking questions I could find on SO seem to be about the more usual arrangement of libraries, where a library is being built to be linked into an executable before that executable runs, rather than the other way around. The closest related question I found was this:
Can an executable be linked to a dynamic library after its built?
which unfortunately has very little info, none of it relevant to the question I'm asking here.
UPDATE: I distilled the info from the answer along with everything else I'd figured
out, and put together this example:
https://github.com/danfuzz/dl-example
As far as my knowledge goes, you want to use weak linkage:
// mark function as weakly-linked
extern void foo() __attribute__((weak));
// inform the linker about that too
clang -dynamiclib -o bar.dylib bar.o -flat_namespace -undefined dynamic_lookup
If a weak function can be resolved at runtime, it will then be resolved. If it can't, it will be NULL, instead of generating a runtime (or, obviously, link-time) error.