resolve.S 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Stolen from glibc-2.2.2 by Eddie C. Dost <ecd@atecom.com>
  3. */
  4. .text
  5. .globl _dl_linux_resolver
  6. .globl _dl_linux_resolve
  7. .type _dl_linux_resolve, @function
  8. .balign 16
  9. _dl_linux_resolve:
  10. mov.l r2, @-r15 ! see Note2 below
  11. mov.l r3, @-r15
  12. mov.l r4, @-r15
  13. mov.l r5, @-r15
  14. mov.l r6, @-r15
  15. mov.l r7, @-r15
  16. mov.l r12, @-r15
  17. movt r3 ! Save T flag
  18. mov.l r3, @-r15
  19. #ifdef HAVE_FPU
  20. sts.l fpscr, @-r15
  21. mov #8,r3
  22. swap.w r3, r3
  23. lds r3, fpscr
  24. fmov.s fr11, @-r15
  25. fmov.s fr10, @-r15
  26. fmov.s fr9, @-r15
  27. fmov.s fr8, @-r15
  28. fmov.s fr7, @-r15
  29. fmov.s fr6, @-r15
  30. fmov.s fr5, @-r15
  31. fmov.s fr4, @-r15
  32. #endif
  33. sts.l pr, @-r15
  34. /* Note - The PLT entries have been "optimised" not to use r2. r2 is used by
  35. GCC to return the address of large structures, so it should not be
  36. corrupted here. This does mean however, that those PLTs does not conform
  37. to the SH PIC ABI. That spec says that r0 contains the type of the PLT
  38. and r2 contains the GOT id. The GNU Plt version stores the GOT id in r0 and
  39. ignores the type. We can easily detect this difference however,
  40. since the type will always be 0 or 8, and the GOT ids will always be
  41. greater than or equal to 12.
  42. Found in binutils/bfd/elf32-sh.c by Stefan Allius <allius@atecom.com>
  43. Note2 - we also have to preserve r2 on the stack as the call into
  44. C code (_dl_linux_resolver) will use r2 as a scratch register and we
  45. need it for the address for returning structures,
  46. David McCullough <davidm@snapgear.com>.
  47. */
  48. mov #8 ,r5
  49. cmp/gt r5, r0
  50. bt 1f
  51. mov r2, r0 ! link map address in r2 (SH PIC ABI)
  52. 1:
  53. mov r0, r4 ! link map address in r0 (GNUs PLT)
  54. mova .LG, r0
  55. mov.l .LG, r5
  56. add r5, r0
  57. mov.l 3f, r5
  58. mov.l @(r0, r5),r5
  59. jsr @r5
  60. mov r1, r5 ! Reloc offset
  61. lds.l @r15+, pr ! Get register content back
  62. #ifdef HAVE_FPU
  63. fmov.s @r15+, fr4
  64. fmov.s @r15+, fr5
  65. fmov.s @r15+, fr6
  66. fmov.s @r15+, fr7
  67. fmov.s @r15+, fr8
  68. fmov.s @r15+, fr9
  69. fmov.s @r15+, fr10
  70. fmov.s @r15+, fr11
  71. lds.l @r15+, fpscr
  72. #endif
  73. mov.l @r15+, r3
  74. shal r3 ! Load T flag
  75. mov.l @r15+, r12
  76. mov.l @r15+, r7
  77. mov.l @r15+, r6
  78. mov.l @r15+, r5
  79. mov.l @r15+, r4
  80. mov.l @r15+, r3
  81. jmp @r0 ! Jump to function address
  82. mov.l @r15+, r2 ! see Note2 above
  83. .balign 4
  84. 3:
  85. .long _dl_linux_resolver@GOT
  86. .LG:
  87. .long _GLOBAL_OFFSET_TABLE_
  88. .size _dl_linux_resolve, . - _dl_linux_resolve