"Relocation R_X86_64_32S Against '.Bss' Can Not Be Used When Making a Shared Object"

relocation R_X86_64_32S against linking Error

Assuming you are generating a shared library, most probably what happens is that the variant of liblog4cplus.a you are using wasn't compiled with -fPIC. In linux, you can confirm this by extracting the object files from the static library and checking their relocations:

ar -x liblog4cplus.a  
readelf --relocs fileappender.o | egrep '(GOT|PLT|JU?MP_SLOT)'

If the output is empty, then the static library is not position-independent and cannot be used to generate a shared object.

Since the static library contains object code which was already compiled, providing the -fPIC flag won't help.

You need to get ahold of a version of liblog4cplus.a compiled with -fPIC and use that one instead.

relocation R_X86_64_32S against `.data' can not be used when making a shared object; recompile with -fPIC with gcc

It seems that your distro enables -pie by default (check gcc -v output) but your assembly is not position-independent. Try compiling a sample .c file under -fPIC and see how it generates calls. In your case it should be

call    printf@PLT

or you can try compiling with gcc -no-pie.

GCC promotes weird relocation R_X86_64_32S error but not in manually linking

The immediate move instruction movq $S, %rsi, despite taking a 64-bit register, takes only a 32-bit signed immediate. When building a position-independent executable which is to run with ASLR, as is the default on most Linux systems, your program is typically not located in the low or high 31 bits of virtual memory, so the address of a global or static object like S won't fit in a signed 32-bit immediate.

One fix is to use movabs instead, which does take a full 64-bit immediate. Replacing movq %0, %%rsi with movabs %0, %%rsi lets the code build. However, the better approach is to use RIP-relative addressing lea S(%rip), %rsi, which is a shorter instruction and avoids the need for a relocation at load time. This is a little awkward to do inside inline asm, so you can let the compiler load the address into the register for you, with an input operand like "S" (S) (confusingly the constraint for the rsi register is S, which happens to coincide with the name you chose for your array variable).

When you linked manually, you built a non-position-independent executable, which meant that treating the address as a constant worked. You can get the same effect by passing -no-pie to gcc.

There is another serious problem with your code, in that it doesn't declare the registers it clobbers - not only those which you explicitly mov into, but also rcx and r11 which syscall modifies implicitly. You should take a look at How to invoke a system call via syscall or sysenter in inline assembly? which has a correct example. It would be wise to study those examples carefully - GCC inline asm is powerful, but also very easy to get wrong in subtle ways that the compiler will not help you detect, and which may appear to work in a simple program but fail unpredictably in a more complex one.

Compilation fails with relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object

Do what the compiler tells you to do, i.e. recompile with -fPIC. To learn what does this flag do and why you need it in this case, see Code Generation Options of the GCC manual.

In brief, the term position independent code (PIC) refers to the generated machine code which is memory address agnostic, i.e. does not make any assumptions about where it was loaded into RAM. Only position independent code is supposed to be included into shared objects (SO) as they should have an ability to dynamically change their location in RAM.

Finally, you can read about it on Wikipedia too.

Relocation R_X86_64_32S against .data cannot be used when making a shared object (64 bit NASM + gcc)

rbp is a callee-saved register hence you need to preserve it. You are not changing it so you don't have to push/pop it here. However you need to preserve 16 byte stack alignment, and a push is a simple way to do that. You could have used any other register, or even sub rsp, 8.

mov rdi, hi should be lea rdi, [rel hi].

Functions are called through the PLT not the GOT, and not through a pointer. Just do call puts ..wrt plt.

As such, the following should work:

global main
extern puts

section .data
hi db 'hello', 0

section .text
main:
push rbp
lea rdi, [rel hi]
call puts wrt ..plt
pop rbp
ret


Related Topics



Leave a reply



Submit