0

I am making a relocatable shared library (all compiles should be with -fPIC and -DPIC) using several object files assembled from assembly code.

In my codes I have push label instructions. When I assemble my assembly code down to an object file using -fPIC -DPIC everything looks fine, however when I want to make the shared library using the object files I get the relocation R_X86_64_32S against '.text' can not be used when making a shared object; recompile with -fPIC message.

I am sure the problem is with these push label instructions as when I remove them the error vanishes.

Any idea on how can I get it assembled?

By the way my platform is Linux with Intel x86_64 architecture and the compiler is gcc with GAS syntax. I am interested in 64bit libraries.

masec
  • 584
  • 5
  • 16
  • Note that assembly is assembled, not compiled. Getting this wrong can be confusing to readers. – fuz Jul 26 '18 at 15:51
  • You should update your question with the name of the assembler you're using as `push label` has two different interpretations depending on the assembler. – Ross Ridge Jul 26 '18 at 16:14

2 Answers2

5

Assuming you're using GAS:

lea  label(%rip), %rax
push %rax

There's no push effective address instruction so you need to go through a register.

Note that isn't a lot of reason to use the push immediate instruction in 64-bit x86 code as arguments aren't normally passed on the stack, there may be better ways to rewrite your code.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
  • Well then yeah I think probably I need a register somehow. I know it is not a well written code. Actually I am hardening assembly code so it is all hacking and not a well documented assembly programming. Thanks by the way. – masec Jul 26 '18 at 15:59
4

Instead of

push label

use

lea rax,[rel label]
push rax

This avoids an absolute reference to label, replacing it with a relative reference which can be resolved in position independent code if label is defined in the same shared object. The exact syntax depends on your assembler, this syntax should work on nasm at least.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • Well thank you. Unfortunately I want the address to be pushed to the stack not a relative address. – masec Jul 26 '18 at 15:57
  • @masec The actual address is pushed on the stack. The effect of `lea rax,[rel label]` is to translate a relative address in the instruction stream into an absolute address in `rax`. – fuz Jul 26 '18 at 15:59
  • @masec: go read up on how RIP-relative addressing works. [Referencing the contents of a memory location. (x86 addressing modes)](https://stackoverflow.com/q/34058101). RIP-relative LEA is the best way to get addresses of static locations into registers in x86-64, unless you're making position-dependent executables so you can use `mov r32, imm32`. And like Ross said, are you sure you should be pushing the address? Only if you've already put 6 integer/pointer args into registers rdi..r9 does the x86-64 System V ABI pass integers on the stack. – Peter Cordes Jul 26 '18 at 16:33