resolve.S 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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 $srp
  26. move.d [$sp+6*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+6*4]
  38. pop $srp
  39. pop $r9
  40. pop $r10
  41. pop $r11
  42. pop $r12
  43. pop $r13
  44. jump [$sp+]
  45. .size _dl_linux_resolve, . - _dl_linux_resolve