table.S.tpl 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Copyright 2022-2023 Yury Gribov
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Use of this source code is governed by MIT license that can be
  7. * found in the LICENSE.txt file.
  8. */
  9. .section .note.GNU-stack,"",@progbits
  10. .data
  11. .globl _${lib_suffix}_tramp_table
  12. .hidden _${lib_suffix}_tramp_table
  13. .align 4
  14. _${lib_suffix}_tramp_table:
  15. .zero $table_size
  16. .text
  17. .globl _${lib_suffix}_tramp_resolve
  18. .hidden _${lib_suffix}_tramp_resolve
  19. .globl _${lib_suffix}_save_regs_and_resolve
  20. .hidden _${lib_suffix}_save_regs_and_resolve
  21. .type _${lib_suffix}_save_regs_and_resolve, %function
  22. _${lib_suffix}_save_regs_and_resolve:
  23. .cfi_startproc
  24. .set noreorder
  25. .cpload $$25
  26. .set nomacro
  27. .set noat
  28. // Slow path which calls dlsym, taken only on first call.
  29. // Registers are saved acc. to "Procedure Call Standard for the MIPS Architecture".
  30. // For DWARF directives, read https://www.imperialviolet.org/2017/01/18/cfi.html.
  31. // TODO: push two regs at once here and in trampoline to avoid temporarily unaligned stack
  32. #define PUSH_REG(reg) addiu $$sp, $$sp, -4; .cfi_adjust_cfa_offset 4; sw reg, 4($$sp); .cfi_rel_offset reg, 0
  33. #define POP_REG(reg) addiu $$sp, $$sp, 4; .cfi_adjust_cfa_offset -4; lw reg, 0($$sp); .cfi_restore reg
  34. // dwarf_num = 32 + reg_num
  35. #define PUSH_FREG(reg, dwarf_num) addiu $$sp, $$sp, -4; .cfi_adjust_cfa_offset 4; swc1 reg, 4($$sp); .cfi_rel_offset dwarf_num, 0
  36. #define POP_FREG(reg, dwarf_num) addiu $$sp, $$sp, 4; .cfi_adjust_cfa_offset -4; lwc1 reg, 0($$sp); .cfi_restore dwarf_num
  37. PUSH_REG($$ra)
  38. PUSH_REG($$a0)
  39. PUSH_REG($$a1)
  40. PUSH_REG($$a2)
  41. PUSH_REG($$a3)
  42. PUSH_REG($$a3) // For alignment
  43. #if 0
  44. // FIXME: GCC complains about odd FP regs without -modd-spreg
  45. PUSH_FREG($$f12, 44)
  46. PUSH_FREG($$f13, 45)
  47. PUSH_FREG($$f14, 46)
  48. PUSH_FREG($$f15, 47)
  49. #endif
  50. move $$a0, $$AT
  51. lw $$25, %call16(_${lib_suffix}_tramp_resolve)($$gp)
  52. .reloc 1f, R_MIPS_JALR, _${lib_suffix}_tramp_resolve
  53. 1: jalr $$25
  54. nop
  55. #if 0
  56. POP_FREG($$f15, 47)
  57. POP_FREG($$f14, 46)
  58. POP_FREG($$f13, 45)
  59. POP_FREG($$f12, 44)
  60. #endif
  61. POP_REG($$a3)
  62. POP_REG($$a3)
  63. POP_REG($$a2)
  64. POP_REG($$a1)
  65. POP_REG($$a0)
  66. POP_REG($$ra)
  67. jr $$ra
  68. nop
  69. .set macro
  70. .set reorder
  71. .cfi_endproc