PIE binary use the function __x86.get_pc_thunk
to get address dynamically defined at loading time.
i) Sometime it calls __x86.get_pc_thunk.ax
.
5ff: e8 24 00 00 00 call 628 <__x86.get_pc_thunk.ax>
604: 05 fc 19 00 00 add $0x19fc,%eax
609: 83 ec 0c sub $0xc,%esp
60c: 8d 90 b0 e6 ff ff lea -0x1950(%eax),%edx
612: 52 push %edx
613: 89 c3 mov %eax,%ebx
615: e8 36 fe ff ff call 450 <printf@plt>
ii) Sometime it calls __x86.get_pc_thunk.bx
.
634: e8 87 fe ff ff call 4c0 <__x86.get_pc_thunk.bx>
639: 81 c3 c7 19 00 00 add $0x19c7,%ebx
63f: 83 ec 0c sub $0xc,%esp
642: 8b 6c 24 20 mov 0x20(%esp),%ebp
646: 8d b3 f0 fe ff ff lea -0x110(%ebx),%esi
64c: e8 cb fd ff ff call 41c <_init>
iii) And sometimes It calls __x86.get_pc_thunk.cx
or sometimes __x86.get_pc_thunk.dx
.
I know difference between __x86.get_pc_thunk.bx
and __x86.get_pc_thunk.ax
is the register, that store return address in, .bx
to EBX
, .ax
to EAX
.
Then, my question is :
how compiler select which function to use among __x86.get_pc_thunk.ax
/__x86.get_pc_thunk.bx
/__x86.get_pc_thunk.cx
/__x86.get_pc_thunk.dx
?
Is it selected truly random at compile time?
Or is there any algorithm for select that?
The compiler selects the appropriate function for whatever register it wants to use. Which register is used is the result of the compiler's register allocation for the function it compiles and is generally not predictable.