We can convince the linker to produce a shared library in which all the symbols will be relocated at load-time, eg.: $ gcc -shared foo.o -o libfoo.so produces a libfoo.so in which all the symbols will be dynamically relocated. Check it with $ objdump --dymamic-reloc libfoo.os to get the dynamic relocations, $ objdump --dymamic-syms libfoo.os to get the dynamic exports, and $ objdump --disassemble libfoo.os to get the full disassembly. We don't have to produce position-independent code, but we do get the penalty of full load-time linking which touches pages all over the shared library image, and so the library doesn't end up shared at all. PROBLEM ------- We can't convince the linker to construct the program this way. When making a binary, the linker attempts to put all the relocations together, using tricks: - relocatable function references turn into a jump table. Jumps from the code point to the jump table, the jump table gets its entries relocated at load-time. - relocatable data is allocated statically in the bss section. The contents are *copied* in from the shared library at load-time, and references from the shared library are relocated to point to the location in the bss. The .type and .size directives in the assembly file supply the information that the linker needs to perform the above shenannigans. This is all bad for us, because our functions are not C-type functions, so the jump table doesn't work properly. Furthermore, our data runs backwards from the pointer sometimes, so the linker's copying semantics for data won't work. We really need the linker to just do ordinary linking at load-time on the binary.