4/16/2023 0 Comments Recompile with fpic![]() ![]() We can see that in action in the disassembly of the successfully-linked libshared.so (with irrelevant bits omitted): $ objdump -disassemble libshared.soĥf0: ff 25 fa 13 00 00 jmpq *0x13fa(%rip) # 19f0 įirstly, the callq instruction in my_shared_function() has acquired a non-zero operand. shared.o gains a global object table (GOT) section and its relocation for the my_static_function() call changes from R_X86_64_PC32 to R_X86_64_PLT32 - a procedure linkage table (PLT) relocation using the GOT. ![]() The disassembly of libstatic.a remains unchanged. What happens if libstatic.a is compiled with PIC enabled? Not a whole lot changes, actually. And that’s why we get an error which talks about overflow. However, it cannot – it only has 4 bytes of operand to play with, rather than the 8 needed for a 64-bit address – so linking has to fail. This would be fine if the callq instruction could take an absolute address to call, as the linker could substitute in the absolute address of my_static_function() ( as is done on 32-bit systems). The shared library, libshared.so, must be capable of being loaded anywhere in an address space. We can see at offset 4 that the callq instruction (calling my_static_function()) leaves 4 bytes for the address of the function to call (actually, callq is instruction-pointer-relative, so the 4 bytes are for the offset of the function from the RIP register).Īs the code in libstatic.a is not PIC, it has to be loaded at a fixed offset in a process’ address space. If we look at the disassembly of the shared object: $ objdump -d shared.o usr/bin/ld: error: shared.o: requires dynamic R_X86_64_PC32 reloc against 'my_static_function' which may overflow at runtime recompile with -fPICĬollect2: error: ld returned 1 exit status So, with our example, we get the error: $ make libshared.soĬc -shared -o libshared.so shared.o libstatic.a This is all explained brilliantly by Michael Guyver on his blog. Less succinctly, it is the offset of the referenced symbol, plus a constant adjustment (the addend) minus the offset of the relocation. What does that mean? Each relocation type is essentially a mathematical function to define the address of a relocated symbol, given the information in various symbol, section and relocation tables in the dynamic object. In this case, the R_X86_64_PC32 relocation was chosen by the compiler, which is defined by the AMD64 ABI (Table 4.10). For a more in-depth account of them, see Relocations, Relocations by Michael Guyver. ![]() There are various types of relocations, defined by the platform ABI, as they are specific to the processor’s instruction set. Each relocation is effectively a note to the runtime loader instructing it to replace a symbol reference in the dynamic object being loaded, with an address calculated at load time. It is these relocations which cause the problem hinted at by the error message above. This means that dynamic objects have to have relocations performed as they’re loaded, which incurs a load-time penalty, but allows for shared libraries and symbol interpositing. What’s a dynamic object? One where symbol references can be resolved at runtime. What is a static object? It’s one where all symbol references are resolved at compile time. static.c is compiled to a static archive, libstatic.a (without position-independent code, PIC), and shared.c is compiled to a shared object, libshared.so, which links against libstatic.a. Let’s run with a minimal working example: two C files, shared.c and static.c. To understand this, we need a brief introduction to the different types of linking, and how static objects and libraries differ from shared (or dynamic) objects and libraries. You need to either link the shared library against a shared version of the static code (such as is produced automatically by libtool), or re-compile the static library with PIC enabled ( -fPIC or -fpic). Tl dr: This is caused by linking a shared library (which requires position-independent code, PIC) to a static library (which has not been compiled with PIC). I finally got a bit of time to investigate, so here we go. I recompiled everything with -fPIC, and magically the problem went away. Or, if you’re using GNU ld (the two linkers have different error messages for the same problem):Įrror: mumble.o: relocation R_X86_64_PC32 against symbol `g_strdup' can not be used when making a shared object recompile with -fPIC While merrily compiling something a little while ago, my linker threw me this gem of an error message (using GNU gold):Įrror: libmumble.a(libmumble.o): requires dynamic R_X86_64_PC32 reloc against 'g_strdup' which may overflow at runtime recompile with -fPIC ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |