table.S.tpl 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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 8
  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) daddiu $$sp, $$sp, -8; .cfi_adjust_cfa_offset 8; sd reg, 0($$sp); .cfi_rel_offset reg, 0
  33. #define POP_REG(reg) ld reg, 0($$sp); .cfi_restore reg; daddiu $$sp, $$sp, 8; .cfi_adjust_cfa_offset -8
  34. // dwarf_num = 32 + reg_num
  35. #define PUSH_FREG(reg, dwarf_num) daddiu $$sp, $$sp, -8; .cfi_adjust_cfa_offset 8; sdc1 reg, 0($$sp); .cfi_rel_offset dwarf_num, 0
  36. #define POP_FREG(reg, dwarf_num) ldc1 reg, 0($$sp); .cfi_restore dwarf_num; daddiu $$sp, $$sp, 8; .cfi_adjust_cfa_offset -8
  37. PUSH_REG($$ra)
  38. PUSH_REG($$gp)
  39. PUSH_REG($$a0)
  40. PUSH_REG($$a1)
  41. PUSH_REG($$a2)
  42. PUSH_REG($$a3)
  43. PUSH_FREG($$f12, 44)
  44. PUSH_FREG($$f13, 45)
  45. PUSH_FREG($$f14, 46)
  46. PUSH_FREG($$f15, 47)
  47. lui $$gp, %hi(%neg(%gp_rel(_${lib_suffix}_save_regs_and_resolve)))
  48. daddu $$gp, $$gp, $$25
  49. daddiu $$gp, $$gp, %lo(%neg(%gp_rel(_${lib_suffix}_save_regs_and_resolve)))
  50. move $$a0, $$AT
  51. ld $$25, %call16(_${lib_suffix}_tramp_resolve)($$gp)
  52. .reloc 1f, R_MIPS_JALR, _${lib_suffix}_tramp_resolve
  53. 1: jalr $$25
  54. nop
  55. POP_FREG($$f15, 47)
  56. POP_FREG($$f14, 46)
  57. POP_FREG($$f13, 45)
  58. POP_FREG($$f12, 44)
  59. POP_REG($$a3)
  60. POP_REG($$a2)
  61. POP_REG($$a1)
  62. POP_REG($$a0)
  63. POP_REG($$gp)
  64. POP_REG($$ra)
  65. jr $$ra
  66. nop
  67. .set macro
  68. .set reorder
  69. .cfi_endproc