9

I try to make functions in assembly language and put them in a dynamic library so I create .o with .S with this command:
nasm -f elf64 hello.S -o hello.o
but when I want to create the lib with gcc:
gcc -fPIC -shared hello.o -o libasm.so
and it displays me this error:
/usr/bin/ld: hello.o: relocation R_X86_64_PC32 against undefined symbol printf@@GLIBC_2.2.5 can not be used when making a shared object; recompile with -fPIC

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
killmat
  • 113
  • 1
  • 4
  • 2
    See http://www.nasm.us/xdoc/2.10rc8/html/nasmdoc9.html#section-9.2.5 (_Calling procedures outside the library_) – Michael Mar 15 '16 at 11:32

1 Answers1

13

From http://www.nasm.us/xdoc/2.10rc8/html/nasmdoc9.html#section-9.2.5:

To call an external routine, you must use another special PIC relocation type, WRT ..plt. This is much easier than the GOT-based ones: you simply replace calls such as CALL printf with the PLT-relative version CALL printf WRT ..plt.

so instead of

; ...
call     printf

use

; ...
call     printf WRT ..plt

and compile and link as normal.

BTW, "WRT" means "With Respect To ...", i.e, "in the context of ..."

cat
  • 3,888
  • 5
  • 32
  • 61
  • 2
    Or better, `call [rel printf wrt ..got]` like `gcc -fno-plt` uses. Full details in [Can't call C standard library function on 64-bit Linux from assembly (yasm) code](https://stackoverflow.com/q/52126328) – Peter Cordes Apr 08 '21 at 20:06
  • maybe this should be closed as duplicate of that if the justification for `..got` appears there? – cat Apr 09 '21 at 12:32
  • I already did close it as a duplicate, right after updating my answer on the linked question to include a TL:DR at the top :P And yes, my answer there describes the fact that using the GOT pointer directly removes the layer of indirection through the PLT. – Peter Cordes Apr 09 '21 at 19:52
  • ah, way ahead of me – cat Apr 09 '21 at 21:37