There are few questions on StackOverflow with the similar title but this question addresses different issue.
I have created a simple fprintf program which prints a certain value in a file. I wanted to understand the execution flow of the program with respect to the library code. My analysis of the dynamic libraries is that each dynamic library is called using a stub which is stored in the plt section of the object file. Simple objdump of an object file revealed three main sections : init, plt and text. All the stubs in the plt section consist of 3/4 similar lines. Example for fprintf :
00000000004004d0 <fprintf@plt>:
4004d0: jmpq *0x200b42(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x30>
4004d6: pushq $0x3
4004db: jmpq 400490 <_init+0x18>
I used the pintool to trace the execution of the program. Apparently, the first time fprintf is called, the execution flow is 4004d0,4004d6,4004db. This means that the first instruction i.e. jump goes to the next instruction at the first time and then the next time, the same jump instruction leads to the library code(I could identify this from the ip of the next instruction).
I used the pintool to trace the execution of the program. Apparently, the first time fprintf is called, the execution flow is 4004d0,4004d6,4004db. This means that the first instruction i.e. jump goes to the next instruction at the first time and then the next time, the same jump instruction leads to the library code(I could identify this from the ip of the next instruction).
Congratulations, you have observed lazy symbol relocation in action. Read more about it here (especially "The lazy binding optimization" section).
My query is where is the
_GLOBAL_OFFSET_TABLE_
information maintained in the object file ?
It's not (as reading referenced blog post will show).