I have this program:
static int aux() {
return 1;
}
int _start(){
int a = aux();
return a;
}
When I compile it using GCC with flags -nostdlib -m32 -fpie and generate an ELF binary, I get the following assembly code:
00001000 <aux>:
1000: f3 0f 1e fb endbr32
1004: 55 push %ebp
1005: 89 e5 mov %esp,%ebp
1007: e8 2d 00 00 00 call 1039 <__x86.get_pc_thunk.ax>
100c: 05 e8 2f 00 00 add $0x2fe8,%eax
1011: b8 01 00 00 00 mov $0x1,%eax
1016: 5d pop %ebp
1017: c3 ret
00001018 <_start>:
1018: f3 0f 1e fb endbr32
101c: 55 push %ebp
101d: 89 e5 mov %esp,%ebp
101f: 83 ec 10 sub $0x10,%esp
1022: e8 12 00 00 00 call 1039 <__x86.get_pc_thunk.ax>
1027: 05 cd 2f 00 00 add $0x2fcd,%eax
102c: e8 cf ff ff ff call 1000 <aux>
1031: 89 45 fc mov %eax,-0x4(%ebp)
1034: 8b 45 fc mov -0x4(%ebp),%eax
1037: c9 leave
1038: c3 ret
00001039 <__x86.get_pc_thunk.ax>:
1039: 8b 04 24 mov (%esp),%eax
103c: c3 ret
I know that the get_pc_thunk function is used to implement position-independent code in x86, but in this case I can't understand why it is being used. My questions are:
- The function is returning the address of the next instruction in the
eaxregister and, in both usages, anaddinstruction is being used to makeeaxpoint to the GOT. Normally, (at least when accessing global variables), thiseaxregister would be immediately used to access a global variable in the table. In this case, however, theeaxis being completely ignored. What is going on? - I also don't understand why the
get_pc_thunkis even present in the code, since bothcallinstructions are using relative addresses. Since the addresses are relative, shouldn't they already be position-independent out of the box?
Thanks!