resolve.S 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /*
  2. * This function is _not_ called directly. It is jumped to from PLT when
  3. * attempting to use a symbol that has not yet been resolved. The first time a
  4. * jump symbol (such as a function call inside a shared library) is used
  5. * (before it gets resolved) it will jump here. When we get called the stack
  6. * contains reloc_offset and tpnt is in MOF.
  7. *
  8. * We save all the registers, setup R10 and R11 with the right arguments then
  9. * call _dl_linux_resolver(tpnt, reloc_offset). _dl_linux_resolver() figures
  10. * out where the jump symbol is _really_ supposed to have jumped to and returns
  11. * that to us. Once we have that, we overwrite tpnt with this fixed up
  12. * address. We then clean up after ourselves, put all the registers back how we
  13. * found them, then we jump to where the fixed up address, which is where the
  14. * jump symbol that got us here really wanted to jump to in the first place.
  15. */
  16. .globl _dl_linux_resolve
  17. .type _dl_linux_resolve,@function
  18. _dl_linux_resolve:
  19. push $r13
  20. push $r12
  21. push $r11
  22. push $r10
  23. push $r9
  24. push $r0
  25. push $srp
  26. move.d [$sp+7*4],$r11
  27. move $mof,$r10
  28. #ifdef __PIC__
  29. move.d $pc,$r0
  30. sub.d .:GOTOFF,$r0
  31. move.d _dl_linux_resolver:PLTG,$r9
  32. add.d $r0,$r9
  33. jsr $r9
  34. #else
  35. jsr _dl_linux_resolver
  36. #endif
  37. move.d $r10,[$sp+7*4]
  38. pop $srp
  39. pop $r0
  40. pop $r9
  41. pop $r10
  42. pop $r11
  43. pop $r12
  44. pop $r13
  45. jump [$sp+]
  46. .size _dl_linux_resolve, . - _dl_linux_resolve