0

Trying to compile this code:

global main

extern printf

[section .data]
    fmtStr: db "Input string", 0xA, 0

[section .text]
    main:
        push rbp
        push fmtStr
        call printf
        pop rbp
        ret

First step goes well:

nasm -f elf64 printf.asm -o printf64.o

But gcc fails:

gcc printf64.o -o printf64

/bin/ld: printf64.o: relocation R_X86_64_32S against `.data' can not be used when making a shared object; recompile with -fPIC

/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status

I have

Linux 4.14.8-1-ARCH x86_64

gcc (GCC) 7.2.1 20171128

GNU ld (GNU Binutils) 2.29.1

Yarick
  • 304
  • 3
  • 14
  • 1
    https://codereview.stackexchange.com/a/181964/110284 ... or use `-no-pie` for gcc. (but that will compile the code as non-relocatable, which is not modern linux default, so you may want to go that extra challenge and learn about PIC/PIE code) – Ped7g Feb 07 '18 at 17:10
  • It's not working, gcc -fpic ... returns the same error. – Yarick Feb 07 '18 at 17:18
  • 1
    yes, you need opposite. You must read and comprehend first... also with all the errata I did on that review. If I had 1 line solution, I would posted an answer, not just hint how you can get to the solution over time. Either way, you will still need to fully understand your problem, sooner or later, and decide whether you want to write PIC code or not. On that depends whether you can just add `-no-pie` to `gcc`, or you need to fix your source code. BTW your title is a bit misleading, there's no NASM problem in your question, it compiles fines. You can't link it. – Ped7g Feb 07 '18 at 17:25
  • 3
    Not related to your program not linking, but your call to printf is incorrect. On x86_64, functions are called with parameters in `rdi`, `rsi`, `rdx`, `rcx`, `r8`, and `r9`, and the remaining parameters are pushed on the stack. For variadic functions, you also put the number of varargs in `rax`. See https://stackoverflow.com/a/38335743/6141656 for more details – C_Elegans Feb 07 '18 at 18:05
  • You can write it as relocatable code with all the changes suggest above and keeps the 16 byte alignment required by the ABI for this case `global main` `extern printf` `default rel` `[section .data]` `fmtStr: db "Input string", 0xA, 0` `[section .text]` `main:` `push rbp` `lea rdi, [fmtStr]` `xor eax, eax` `call printf wrt ..plt` `pop rbp` `ret` – Michael Petch Feb 07 '18 at 18:21
  • @C_Elegans : Actually AL is the number of vector arguments, not the number of total arguments. In this case AL should be 0 – Michael Petch Feb 07 '18 at 18:26
  • Isn't that what I said? "number of varargs in `rax`"? – C_Elegans Feb 07 '18 at 18:27
  • @C_Elegans No, `varargs` would imply the number of variable arguments`. It is not that.It is the number of arguments that are passed in the vector registers (like floats and doubles etc). Vector registers that are used to pass vector data are XMM0 to XMM7 per the 64-bit System V ABI. If you used a format string to print out 5 integers AL would still be 0. – Michael Petch Feb 07 '18 at 18:32
  • Oh interesting, will have to remember that – C_Elegans Feb 07 '18 at 20:13

0 Answers0