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
Shell Programming: Executing Two Applications at The Same Time
How Connect Variable with a String in Bash
How to Take Screenshot of Obscured Window in C++ on Linux
How to Set Umask Default for an User
Find Is Returning "Find: .: Permission Denied", But I Am Not Searching In
Kernel Oops Page Fault Error Codes for Arm
Downgrade R Version and R Package Bioconductor
Tomcat 6 Log4J - Linux - Safely Remove Catalina.Out
Is There Any General Interfaces on Linux to Simulate Mouse Movements and Click
Windows .Crl to .Pem for Nginx
Linux - Run Android Emulator on Nouveau Driver
Jmp Unexpected Behavior in Shellcode When Next(Skipped) Instruction Is a Variable Definition
How to Use Sed to Replace a String in a File with a Shell Variable
Warning: The Use of 'Tmpnam' Is Dangerous, Better Use 'Mkstemp'
Running Linux Container on Docker Windows
How to Dynamic Load The Library with Same Name But in Different Directory in Linux