resolve.S 1.4 KB

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