Hi everyone, I'm a little confused by the assembly gcc generating for a program built in -fpie mode. Consider the following: $ cat tester.c __attribute__((always_inline)) void inline func(char *arg) { arg[0] = 0; } void main(void) { char *foo; foo = "this is a string"; func(foo); } I can compile and link it: $ gcc -c -fpie -Wa,--noexecstack -fno-jump-tables -nostdlib tester.c -o tester.o $ ld -r tester.o -o tester.bin and when I disassemble it I get: $ objdump -D tester.bin tester.bin: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <main>: 0: 55 push rbp 1: 48 89 e5 mov rbp,rsp 4: 48 8d 05 00 00 00 00 lea rax,[rip+0x0] # b <main+0xb> b: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax f: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8] 13: 48 89 45 f0 mov QWORD PTR [rbp-0x10],rax 17: 48 8b 45 f0 mov rax,QWORD PTR [rbp-0x10] 1b: c6 00 00 mov BYTE PTR [rax],0x0 1e: 90 nop 1f: 5d pop rbp 20: c3 ret Disassembly of section .rodata: 0000000000000000 <.rodata>: 0: 74 68 je 6a <main+0x6a> 2: 69 73 20 69 73 20 61 imul esi,DWORD PTR [rbx+0x20],0x61207369 9: 20 73 74 and BYTE PTR [rbx+0x74],dh c: 72 69 jb 77 <main+0x77> e: 6e outs dx,BYTE PTR ds:[rsi] f: 67 addr32 ... So now I'm confused. .rodata is clearly my string (using a cheap hack by doing objdump -D to display it), but the code at 0x4 in .text has me confused, 4: 48 8d 05 00 00 00 00 lea rax,[rip+0x0] # b <main+0xb> This doesn't load my string; in fact it doesn't really do anything useful. I suspect that this is something that is rewritten at load time, but I don't really know. I also haven't had much luck looking for information about what's going on here :( What I'm really interested in is compiling something from C that's entirely shellcode, and doesn't have any of this load time rewriting; I could use a linker script to stuff .rodata into .text, but it doesn't seem to help anything (other than make the offset easily computable from rip, but gcc doesn't actually emit assembly that does it). Is there a way to do this? Thanks, Tycho