resolve.S 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. * This function is _not_ called directly. It is jumped to (so no return
  3. * address is on the stack) when attempting to use a symbol that has not yet
  4. * been resolved. The first time a jump symbol (such as a function call inside
  5. * a shared library) is used (before it gets resolved) it will jump here to
  6. * _dl_linux_resolve. When we get called the stack looks like this:
  7. * reloc_entry
  8. * tpnt
  9. *
  10. * This function saves all the registers, puts a copy of reloc_entry and tpnt
  11. * on the stack (as function arguments) then make the function call
  12. * _dl_linux_resolver(tpnt, reloc_entry). _dl_linux_resolver() figures out
  13. * where the jump symbol is _really_ supposed to have jumped to and returns
  14. * that to us. Once we have that, we overwrite tpnt with this fixed up
  15. * address. We then clean up after ourselves, put all the registers back how we
  16. * found them, then we jump to where the fixed up address, which is where the
  17. * jump symbol that got us here really wanted to jump to in the first place.
  18. * found them, then we jump to the fixed up address, which is where the jump
  19. * symbol that got us here really wanted to jump to in the first place.
  20. * -Erik Andersen
  21. */
  22. /* more info taken from glibc/sysdeps/x86_64/dl-trampoline.S */
  23. .text
  24. .global _dl_linux_resolve
  25. .type _dl_linux_resolve,%function
  26. _dl_linux_resolve:
  27. subq $56,%rsp
  28. /* Preserve registers otherwise clobbered. */
  29. movq %rax, (%rsp)
  30. movq %rcx, 8(%rsp)
  31. movq %rdx, 16(%rsp)
  32. movq %rsi, 24(%rsp)
  33. movq %rdi, 32(%rsp)
  34. movq %r8, 40(%rsp)
  35. movq %r9, 48(%rsp)
  36. movq 64(%rsp), %rsi /* Copy args pushed by PLT in register. */
  37. movq %rsi, %r11 /* Multiply by 24 */
  38. addq %r11, %rsi
  39. addq %r11, %rsi
  40. shlq $3, %rsi
  41. movq 56(%rsp), %rdi /* %rdi: link_map, %rsi: reloc_offset */
  42. call _dl_linux_resolver /* Call resolver. */
  43. movq %rax, %r11 /* Save return value */
  44. /* Get register content back. */
  45. movq 48(%rsp), %r9
  46. movq 40(%rsp), %r8
  47. movq 32(%rsp), %rdi
  48. movq 24(%rsp), %rsi
  49. movq 16(%rsp), %rdx
  50. movq 8(%rsp), %rcx
  51. movq (%rsp), %rax
  52. addq $72, %rsp /* Adjust stack(PLT did 2 pushes) */
  53. jmp *%r11 /* Jump to function address. */
  54. .size _dl_linux_resolve,.-_dl_linux_resolve