0

I'm trying to add a global data label to 64-bit assembly code which i'd like to assemble to a shared library. Part of code is as followed.

# 64bit out.s
.section .text
...

.globl export_func
.type   export_func, @function
export_func:
pushq %rbp
movq %rsp,%rbp
pushq %rax
movzbl export_func_input_0,%eax
movsbl %al,%eax
mov %eax,%edi
callq S_0x400607
mov %al, export_func_output
add $0,%rsp
popq %rax
popq %rbp
ret

...

.section .data
.globl export_func_input_0
.type export_func_input_0, @object
export_func_input_0:
.byte 0x41

...

I'm trying to workThen i got error like this

$ gcc -fPIC -shared out.s -o libout.so
/usr/bin/ld: /tmp/ccqrtdKg.o: relocation R_X86_64_32S against symbol `export_func_input_0' 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

But for assembly codes with the same function of 32bit, No errors like this occured.

# 32bit out.s
.section .text
...

.globl export_func
.type   export_func, @function
export_func:
pushl %ebp
movl %esp,%ebp
pushl %eax
pushl %edx
movzbl export_func_input_0,%eax
movsbl %al,%eax
push %eax
call S_0x8048506
mov %al, export_func_output
add $4,%esp
popl %edx
popl %eax
popl %ebp
ret

...
.section .data
.globl export_func_input_0
.type export_func_input_0, @object
export_func_input_0:
.byte 0x41

...

Apology if i've asked a very simple question. I'm totally new in this region.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
S1mple
  • 35
  • 6
  • I can't reproduce that `R_X86_64_8` relocation error from your asm after editing out the `...` parts to make a [mcve]; I get the expected `R_X86_64_32S` relocation error from trying to use `export_func_input_0` as an absolute address instead of `export_func_input_0(%rip)`. [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427). I'd only expect R_X86_64_8 if you did something like `mov $export_func_input_0, %al` to try to put an absolute address into an 8-bit register, or with a `.byte`. – Peter Cordes May 22 '22 at 03:53
  • I'm trying to guess how you got this inefficient asm that doesn't use RIP-relative addressing for globals. It looks like `gcc -O0` compiler output given the hilariously inefficient pattern of zero-extending load into EAX, then sign-extending AL into EAX, then copying to EDI, instead of a `movsbl` load into EDI. I'd assume no human would write that. Or possibly `clang -O0` or maybe recent GCC since it's using `push %rax` to align the stack before a call, instead of `sub $8, %rsp`. So maybe you had compiler output for something else, and manually modified the addressing mode? – Peter Cordes May 22 '22 at 03:58
  • @PeterCordes Sorry, It's `R_X86_64_32S`. I got wrong – S1mple May 22 '22 at 04:43
  • Eh... The assembly codes are automatically generated by a reassemble tool. i just wanna fix the code and add global data label for passing arguments and return values. I think it is easier to automate.(Though it is inefficient.) It's more important to make automatically-generated executables run without faults than make them more efficient, isn't it? – S1mple May 22 '22 at 04:53
  • Reassemble? Do you mean it's from a disassembler intended to create asm that can be reassembled? Seems it's not doing that, e.g. messing up RIP-relative addressing. There's no way compiler-generated code looked like this. Anyway, it's not as easy as just changing to `export_func_input_0(%rip)` for a shared library (as opposed to a PIE executable), since the definition is `.globl`, rather than ELF type `.hidden` or the default of totally private to this file. So you need indirection through the GOT in case the main executable defines its version of that symbol. – Peter Cordes May 22 '22 at 04:59
  • Through the "symbolization" of arguments and return values, The position to call the interfaces generated by reassembly tools will be independent. Then it just like to "evaluate" an value to a variable in advanced programing language. We just need to "mov" values into "argument labels" and "mov" return values from "return value labels". It makes the problem easier and feasible to automate. – S1mple May 22 '22 at 05:01
  • The part of code which passes argument are merged from other code generated by reassembly tool. – S1mple May 22 '22 at 05:03
  • 1
    A normal function that takes args in registers and returns in AL/AX/EAX/RAX can also be called by calling its absolute address, or a wrapper for it (or PLT stub). If you have some tool that's adding wrappers that use global variables, that makes it *less* convenient to call as part of a shared library, especially if you don't fix it to emit `mov export_func_output@gotpcrel(%rip), %rcx` ; `mov %al, (%rcx)` - accessing global variables in PIC code needs to load a pointer from the GOT, unless you have a separate non-global label on the same storage to bypass symbol interposition. – Peter Cordes May 22 '22 at 05:06

0 Answers0