GCC-Assemby Error: Relocation R_X86_64_32S against

2019-09-01 09:33发布

问题:

Situation


  1. Enviroment

    Arch Linux x86-64 (4.2.3-1-ARCH)

  2. GCC

    gcc (GCC) 5.2.0

  3. Command

    gcc -Wall -g -o asm_printf asm_printf.s 
    
  4. Error

    /usr/bin/ld: /tmp/cct4fa.o: Relocation R_X86_64_32S against '.data' can not be used when making a shared object; recompile with -fPIC
    /tmp/cct4fa.o:err adding symbols: Bad value
    collect2: error: ld returned 1 exit status
    
  5. Code

    .section .data
    msg:
        .asciz "Printf In Assembly!!\n"
    
    .section .text
    .globl main
    main:
        pushq $msg
        call printf
        addq $8 %esp
    
        pushq $0
        call exit
    

Question


I tried to use gcc to compile the program in the above Code section using the command in the above Command section and ended up with a error in the Error Section.

Note that I am not compiling a shared library.

  1. What is this error?
  2. How do i fix this?

回答1:

The specific error is due to the push instruction only supporting 32 bit immediates and you tried to use that for a 64 bit address.

However, the whole code is wrong. It's unclear whether you want 32 or 64 bit code. Most of the code seems to be 32 bit, except for the pushq so I assume you really wanted 32 bit code. For that, change all those to push (which is a good idea anyway) and compile using gcc -m32. Also, you only need to remove 4 bytes from the stack, so use addl $4, %esp. (Thanks to @Employed Russian for pointing this out.)

The 64 bit calling convention is different from 32 bit, so to create a 64 bit version you must make more changes. Since I assume you really wanted 32 bit, here it is for illustration only:

.section .data
msg:
    .asciz "Printf In Assembly!!\n"

.section .text
.globl main
main:
    subq $8, %rsp
    leaq msg(%rip), %rdi
    xor %al, %al
    call printf

    xor %edi, %edi
    call exit