I'm trying to invoke sys_write
via the syscall
instruction under Linux environment on an x86_64 machine with inline assembly in C files. To achieve this, I wrote the following code:
[tjm@ArchPad poc]$ cat poc.c
const char S[] = "abcd\n";
int main() {
__asm __volatile(" \
movq $1, %%rax; \
movq $1, %%rdi; \
movq %0, %%rsi; \
movq $5, %%rdx; \
syscall;"
:
: "i"(S)
);
return 0;
}
While my compiling it with GCC, the following error promoted:
[tjm@ArchPad poc]$ gcc -O0 poc.c -o poc
/usr/bin/ld: /tmp/ccWYxmSb.o: relocation R_X86_64_32S against symbol `S' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status
Then I added -fPIE
to the compiler command. Unfortunately, nothing changed:
[tjm@ArchPad poc]$ gcc -fPIE -O0 poc.c -o poc
/usr/bin/ld: /tmp/ccdK36lx.o: relocation R_X86_64_32S against symbol `S' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status
This is so weird that it made me curious to compile and link it manually:
[tjm@ArchPad poc]$ gcc -fPIE -O0 poc.c -S
[tjm@ArchPad poc]$ as -O0 poc.s -o poc.o
[tjm@ArchPad poc]$ ld -O0 -melf_x86_64 --dynamic-linker /usr/lib/ld-linux-x86-64.so.2 /usr/lib/crt{1,i,n}.o -lc poc.o -o poc
Surprisingly, no error occurred during the attempt above. I then tested the executable's functionality, which seems working:
[tjm@ArchPad poc]$ ./poc
abcd
Any ideas of why this happens and how to prevent GCC from promoting the error above?