resolve.S 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. #ifdef __arch_v32
  19. _dl_linux_resolve:
  20. subq 4,$sp
  21. move.d $r0,[$sp]
  22. subq 4,$sp
  23. move.d $r13,[$sp]
  24. subq 4,$sp
  25. move.d $r12,[$sp]
  26. subq 4,$sp
  27. move.d $r11,[$sp]
  28. subq 4,$sp
  29. addoq 5*4,$sp,$acr
  30. move.d $r10,[$sp]
  31. subq 4,$sp
  32. move $mof,$r10
  33. move.d $r9,[$sp]
  34. subq 4,$sp
  35. move.d [$acr],$r11
  36. move $srp,[$sp]
  37. lapc _GLOBAL_OFFSET_TABLE_,$r0
  38. move.d _dl_linux_resolver:PLTG,$r9
  39. add.d $r0,$r9
  40. jsr $r9
  41. nop
  42. move.d $r10,$acr
  43. move [$sp+],$srp
  44. move.d [$sp+],$r9
  45. move.d [$sp+],$r10
  46. move.d [$sp+],$r11
  47. move.d [$sp+],$r12
  48. move.d [$sp+],$r13
  49. move.d [$sp+],$r0
  50. jump $acr
  51. addq 4,$sp
  52. #else
  53. _dl_linux_resolve:
  54. push $r13
  55. push $r12
  56. push $r11
  57. push $r10
  58. push $r9
  59. push $r0
  60. push $srp
  61. move.d [$sp+7*4],$r11
  62. move $mof,$r10
  63. #ifdef __PIC__
  64. move.d $pc,$r0
  65. sub.d .:GOTOFF,$r0
  66. move.d _dl_linux_resolver:PLTG,$r9
  67. add.d $r0,$r9
  68. jsr $r9
  69. #else
  70. jsr _dl_linux_resolver
  71. #endif
  72. move.d $r10,[$sp+7*4]
  73. pop $srp
  74. pop $r0
  75. pop $r9
  76. pop $r10
  77. pop $r11
  78. pop $r12
  79. pop $r13
  80. jump [$sp+]
  81. #endif /* __arch_v32 */
  82. .size _dl_linux_resolve, . - _dl_linux_resolve