Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

relocation R_X86_64_32 against `.data' can not be used when making a shared object;

Tags:

c

assembly

ld

I write the below assembler code, and it can build pass by as and ld directly.

as cpuid.s -o cpuid.o
ld cpuid.o -o cpuid

But when I used gcc to do the whole procedure. I meet the below error.

$ gcc cpuid.s -o cpuid
/tmp/cctNMsIU.o: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o:(.text+0x0): first defined here
/usr/bin/ld: /tmp/cctNMsIU.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/usr/bin/ld: final link failed: Invalid operation
collect2: error: ld returned 1 exit status

Then I modify _start to main, and also add -fPIC to gcc parameter. But it doesn't fix my ld error. the error msg is changed to below.

$ gcc cpuid.s -o cpuid
/usr/bin/ld: /tmp/ccYCG80T.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

I don't understand the meaning for that due to I don't make a shared object. I just want to make an executable binary.

    .section .data
output:

    .ascii "The processor Vendor ID is 'xxxxxxxxxxxx'\n"

    .section .text

    .global _start

_start:

    movl $0, %eax

    cpuid

    movl $output, %edi
    movl %ebx, 28(%edi)
    movl %edx, 32(%edi)
    movl %ecx, 36(%edi)

    movl $4, %eax
    movl $1, %ebx
    movl $output, %ecx
    movl $42, %edx
    int $0x80

    movl $1, %eax
    movl $0, %ebx
    int $0x80

If i modify the above code to below, whether it is correct or having some side effect on 64bit asm programming ?

         .section .data
 output:
         .ascii "The processor Vendor ID is 'xxxxxxxxxxxx'\n"

         .section .text

         .global main
 main:
         movq $0, %rax
         cpuid

         lea output(%rip), %rdi
         movl %ebx, 28(%rdi)
         movl %edx, 32(%rdi)
         movl %ecx, 36(%rdi)
         movq %rdi, %r10

         movq $1, %rax
         movq $1, %rdi
         movq %r10, %rsi
         movq $42, %rdx
         syscall
like image 813
Miracle Huang Avatar asked Mar 22 '18 17:03

Miracle Huang


2 Answers

As comments have noted, you could work around this by linking your program as non-PIE, but it would be better to fix your asm to be position-independent. If it's 32-bit x86 code that's a bit ugly. This instruction:

    movl $output, %edi

would become:

    call 1f
1:  pop %edi
    add $output-1b, %edi

for 64-bit it's much cleaner. Instead of:

    movq $output, %rdi

you'd write:

    lea output(%rip), %rdi
like image 61
R.. GitHub STOP HELPING ICE Avatar answered Nov 16 '22 00:11

R.. GitHub STOP HELPING ICE


With NASM I fixed this by putting the line "DEFAULT REL" in the source file (check nasmdoc.pdf p.76).

like image 38
Michael Avatar answered Nov 16 '22 00:11

Michael