dl-trampoline.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /* PLT trampolines. Alpha version.
  2. Copyright (C) 2005-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library. If not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <sysdep.h>
  16. .set noat
  17. .macro savei regno, offset
  18. stq $\regno, \offset($30)
  19. cfi_rel_offset(\regno, \offset)
  20. .endm
  21. .macro savef regno, offset
  22. stt $f\regno, \offset($30)
  23. cfi_rel_offset(\regno+32, \offset)
  24. .endm
  25. .align 4
  26. .globl _dl_runtime_resolve_new
  27. .ent _dl_runtime_resolve_new
  28. #undef FRAMESIZE
  29. #define FRAMESIZE 14*8
  30. _dl_runtime_resolve_new:
  31. .frame $30, FRAMESIZE, $26, 0
  32. .mask 0x4000000, 0
  33. ldah $29, 0($27) !gpdisp!1
  34. lda $30, -FRAMESIZE($30)
  35. stq $26, 0*8($30)
  36. stq $16, 2*8($30)
  37. stq $17, 3*8($30)
  38. lda $29, 0($29) !gpdisp!1
  39. stq $18, 4*8($30)
  40. mov $28, $16 /* link_map from .got.plt */
  41. stq $19, 5*8($30)
  42. mov $25, $17 /* offset of reloc entry */
  43. stq $20, 6*8($30)
  44. mov $26, $18 /* return address */
  45. stq $21, 7*8($30)
  46. stt $f16, 8*8($30)
  47. stt $f17, 9*8($30)
  48. stt $f18, 10*8($30)
  49. stt $f19, 11*8($30)
  50. stt $f20, 12*8($30)
  51. stt $f21, 13*8($30)
  52. .prologue 2
  53. bsr $26, _dl_fixup !samegp
  54. mov $0, $27
  55. ldq $26, 0*8($30)
  56. ldq $16, 2*8($30)
  57. ldq $17, 3*8($30)
  58. ldq $18, 4*8($30)
  59. ldq $19, 5*8($30)
  60. ldq $20, 6*8($30)
  61. ldq $21, 7*8($30)
  62. ldt $f16, 8*8($30)
  63. ldt $f17, 9*8($30)
  64. ldt $f18, 10*8($30)
  65. ldt $f19, 11*8($30)
  66. ldt $f20, 12*8($30)
  67. ldt $f21, 13*8($30)
  68. lda $30, FRAMESIZE($30)
  69. jmp $31, ($27), 0
  70. .end _dl_runtime_resolve_new
  71. .globl _dl_runtime_profile_new
  72. .type _dl_runtime_profile_new, @function
  73. #ifdef SHARED
  74. #undef FRAMESIZE
  75. #define FRAMESIZE 20*8
  76. /* We save the registers in a different order than desired by
  77. .mask/.fmask, so we have to use explicit cfi directives. */
  78. cfi_startproc
  79. _dl_runtime_profile_new:
  80. ldah $29, 0($27) !gpdisp!2
  81. lda $30, -FRAMESIZE($30)
  82. savei 26, 0*8
  83. stq $16, 2*8($30)
  84. stq $17, 3*8($30)
  85. lda $29, 0($29) !gpdisp!2
  86. stq $18, 4*8($30)
  87. lda $1, FRAMESIZE($30) /* incoming sp value */
  88. stq $1, 1*8($30)
  89. stq $19, 5*8($30)
  90. stq $20, 6*8($30)
  91. mov $28, $16 /* link_map from .got.plt */
  92. stq $21, 7*8($30)
  93. mov $25, $17 /* offset of reloc entry */
  94. stt $f16, 8*8($30)
  95. mov $26, $18 /* return address */
  96. stt $f17, 9*8($30)
  97. mov $30, $19 /* La_alpha_regs address */
  98. stt $f18, 10*8($30)
  99. lda $20, 14*8($30) /* framesize address */
  100. stt $f19, 11*8($30)
  101. stt $f20, 12*8($30)
  102. stt $f21, 13*8($30)
  103. stq $28, 16*8($30)
  104. stq $25, 17*8($30)
  105. bsr $26, _dl_profile_fixup !samegp
  106. mov $0, $27
  107. /* Discover if we're wrapping this call. */
  108. ldq $18, 14*8($30)
  109. bge $18, 1f
  110. ldq $26, 0*8($30)
  111. ldq $16, 2*8($30)
  112. ldq $17, 3*8($30)
  113. ldq $18, 4*8($30)
  114. ldq $19, 5*8($30)
  115. ldq $20, 6*8($30)
  116. ldq $21, 7*8($30)
  117. ldt $f16, 8*8($30)
  118. ldt $f17, 9*8($30)
  119. ldt $f18, 10*8($30)
  120. ldt $f19, 11*8($30)
  121. ldt $f20, 12*8($30)
  122. ldt $f21, 13*8($30)
  123. lda $30, FRAMESIZE($30)
  124. jmp $31, ($27), 0
  125. 1:
  126. /* Create a frame pointer and allocate a new argument frame. */
  127. savei 15, 15*8
  128. mov $30, $15
  129. cfi_def_cfa_register (15)
  130. addq $18, 15, $18
  131. bic $18, 15, $18
  132. subq $30, $18, $30
  133. /* Save the call destination around memcpy. */
  134. stq $0, 14*8($30)
  135. /* Copy the stack arguments into place. */
  136. lda $16, 0($30)
  137. lda $17, FRAMESIZE($15)
  138. jsr $26, memcpy
  139. ldgp $29, 0($26)
  140. /* Reload the argument registers. */
  141. ldq $27, 14*8($30)
  142. ldq $16, 2*8($15)
  143. ldq $17, 3*8($15)
  144. ldq $18, 4*8($15)
  145. ldq $19, 5*8($15)
  146. ldq $20, 6*8($15)
  147. ldq $21, 7*8($15)
  148. ldt $f16, 8*8($15)
  149. ldt $f17, 9*8($15)
  150. ldt $f18, 10*8($15)
  151. ldt $f19, 11*8($15)
  152. ldt $f20, 12*8($15)
  153. ldt $f21, 13*8($15)
  154. jsr $26, ($27), 0
  155. ldgp $29, 0($26)
  156. /* Set up for call to _dl_audit_pltexit. */
  157. ldq $16, 16*8($15)
  158. ldq $17, 17*8($15)
  159. stq $0, 16*8($15)
  160. lda $18, 0($15)
  161. stq $1, 17*8($15)
  162. lda $19, 16*8($15)
  163. stt $f0, 18*8($15)
  164. stt $f1, 19*8($15)
  165. bsr $26, _dl_audit_pltexit !samegp
  166. mov $15, $30
  167. cfi_def_cfa_register (30)
  168. ldq $26, 0($30)
  169. ldq $15, 15*8($30)
  170. lda $30, FRAMESIZE($30)
  171. ret
  172. cfi_endproc
  173. .size _dl_runtime_profile_new, .-_dl_runtime_profile_new
  174. #endif /* SHARED */
  175. .align 4
  176. .globl _dl_runtime_resolve_old
  177. .ent _dl_runtime_resolve_old
  178. #undef FRAMESIZE
  179. #define FRAMESIZE 44*8
  180. _dl_runtime_resolve_old:
  181. lda $30, -FRAMESIZE($30)
  182. .frame $30, FRAMESIZE, $26
  183. /* Preserve all registers that C normally doesn't. */
  184. stq $26, 0*8($30)
  185. stq $0, 1*8($30)
  186. stq $1, 2*8($30)
  187. stq $2, 3*8($30)
  188. stq $3, 4*8($30)
  189. stq $4, 5*8($30)
  190. stq $5, 6*8($30)
  191. stq $6, 7*8($30)
  192. stq $7, 8*8($30)
  193. stq $8, 9*8($30)
  194. stq $16, 10*8($30)
  195. stq $17, 11*8($30)
  196. stq $18, 12*8($30)
  197. stq $19, 13*8($30)
  198. stq $20, 14*8($30)
  199. stq $21, 15*8($30)
  200. stq $22, 16*8($30)
  201. stq $23, 17*8($30)
  202. stq $24, 18*8($30)
  203. stq $25, 19*8($30)
  204. stq $29, 20*8($30)
  205. stt $f0, 21*8($30)
  206. stt $f1, 22*8($30)
  207. stt $f10, 23*8($30)
  208. stt $f11, 24*8($30)
  209. stt $f12, 25*8($30)
  210. stt $f13, 26*8($30)
  211. stt $f14, 27*8($30)
  212. stt $f15, 28*8($30)
  213. stt $f16, 29*8($30)
  214. stt $f17, 30*8($30)
  215. stt $f18, 31*8($30)
  216. stt $f19, 32*8($30)
  217. stt $f20, 33*8($30)
  218. stt $f21, 34*8($30)
  219. stt $f22, 35*8($30)
  220. stt $f23, 36*8($30)
  221. stt $f24, 37*8($30)
  222. stt $f25, 38*8($30)
  223. stt $f26, 39*8($30)
  224. stt $f27, 40*8($30)
  225. stt $f28, 41*8($30)
  226. stt $f29, 42*8($30)
  227. stt $f30, 43*8($30)
  228. .mask 0x27ff01ff, -FRAMESIZE
  229. .fmask 0xfffffc03, -FRAMESIZE+21*8
  230. /* Set up our GP. */
  231. br $29, .+4
  232. ldgp $29, 0($29)
  233. .prologue 0
  234. /* Set up the arguments for _dl_fixup:
  235. $16 = link_map out of plt0
  236. $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
  237. $18 = return address
  238. */
  239. subq $28, $27, $17
  240. ldq $16, 8($27)
  241. subq $17, 20, $17
  242. mov $26, $18
  243. addq $17, $17, $17
  244. bsr $26, _dl_fixup !samegp
  245. /* Move the destination address into position. */
  246. mov $0, $27
  247. /* Restore program registers. */
  248. ldq $26, 0*8($30)
  249. ldq $0, 1*8($30)
  250. ldq $1, 2*8($30)
  251. ldq $2, 3*8($30)
  252. ldq $3, 4*8($30)
  253. ldq $4, 5*8($30)
  254. ldq $5, 6*8($30)
  255. ldq $6, 7*8($30)
  256. ldq $7, 8*8($30)
  257. ldq $8, 9*8($30)
  258. ldq $16, 10*8($30)
  259. ldq $17, 11*8($30)
  260. ldq $18, 12*8($30)
  261. ldq $19, 13*8($30)
  262. ldq $20, 14*8($30)
  263. ldq $21, 15*8($30)
  264. ldq $22, 16*8($30)
  265. ldq $23, 17*8($30)
  266. ldq $24, 18*8($30)
  267. ldq $25, 19*8($30)
  268. ldq $29, 20*8($30)
  269. ldt $f0, 21*8($30)
  270. ldt $f1, 22*8($30)
  271. ldt $f10, 23*8($30)
  272. ldt $f11, 24*8($30)
  273. ldt $f12, 25*8($30)
  274. ldt $f13, 26*8($30)
  275. ldt $f14, 27*8($30)
  276. ldt $f15, 28*8($30)
  277. ldt $f16, 29*8($30)
  278. ldt $f17, 30*8($30)
  279. ldt $f18, 31*8($30)
  280. ldt $f19, 32*8($30)
  281. ldt $f20, 33*8($30)
  282. ldt $f21, 34*8($30)
  283. ldt $f22, 35*8($30)
  284. ldt $f23, 36*8($30)
  285. ldt $f24, 37*8($30)
  286. ldt $f25, 38*8($30)
  287. ldt $f26, 39*8($30)
  288. ldt $f27, 40*8($30)
  289. ldt $f28, 41*8($30)
  290. ldt $f29, 42*8($30)
  291. ldt $f30, 43*8($30)
  292. /* Flush the Icache after having modified the .plt code. */
  293. imb
  294. /* Clean up and turn control to the destination */
  295. lda $30, FRAMESIZE($30)
  296. jmp $31, ($27)
  297. .end _dl_runtime_resolve_old
  298. .globl _dl_runtime_profile_old
  299. .usepv _dl_runtime_profile_old, no
  300. .type _dl_runtime_profile_old, @function
  301. #ifdef SHARED
  302. /* We save the registers in a different order than desired by
  303. .mask/.fmask, so we have to use explicit cfi directives. */
  304. cfi_startproc
  305. #undef FRAMESIZE
  306. #define FRAMESIZE 50*8
  307. .align 4
  308. _dl_runtime_profile_old:
  309. lda $30, -FRAMESIZE($30)
  310. cfi_adjust_cfa_offset (FRAMESIZE)
  311. /* Preserve all argument registers. This also constructs the
  312. La_alpha_regs structure. */
  313. savei 26, 0*8
  314. savei 16, 2*8
  315. savei 17, 3*8
  316. savei 18, 4*8
  317. savei 19, 5*8
  318. savei 20, 6*8
  319. savei 21, 7*8
  320. lda $16, FRAMESIZE($30)
  321. savef 16, 8*8
  322. savef 17, 9*8
  323. savef 18, 10*8
  324. savef 19, 11*8
  325. savef 20, 12*8
  326. savef 21, 13*8
  327. stq $16, 1*8($30)
  328. /* Preserve all registers that C normally doesn't. */
  329. savei 0, 14*8
  330. savei 1, 15*8
  331. savei 2, 16*8
  332. savei 3, 17*8
  333. savei 4, 18*8
  334. savei 5, 19*8
  335. savei 6, 20*8
  336. savei 7, 21*8
  337. savei 8, 22*8
  338. savei 22, 23*8
  339. savei 23, 24*8
  340. savei 24, 25*8
  341. savei 25, 26*8
  342. savei 29, 27*8
  343. savef 0, 28*8
  344. savef 1, 29*8
  345. savef 10, 30*8
  346. savef 11, 31*8
  347. savef 12, 32*8
  348. savef 13, 33*8
  349. savef 14, 34*8
  350. savef 15, 35*8
  351. savef 22, 36*8
  352. savef 23, 37*8
  353. savef 24, 38*8
  354. savef 25, 39*8
  355. savef 26, 40*8
  356. savef 27, 41*8
  357. savef 28, 42*8
  358. savef 29, 43*8
  359. savef 30, 44*8
  360. /* Set up our GP. */
  361. br $29, .+4
  362. ldgp $29, 0($29)
  363. /* Set up the arguments for _dl_profile_fixup:
  364. $16 = link_map out of plt0
  365. $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
  366. $18 = return address
  367. $19 = La_alpha_regs address
  368. $20 = framesize address
  369. */
  370. subq $28, $27, $17
  371. ldq $16, 8($27)
  372. subq $17, 20, $17
  373. mov $26, $18
  374. addq $17, $17, $17
  375. lda $19, 0($30)
  376. lda $20, 45*8($30)
  377. stq $16, 48*8($30)
  378. stq $17, 49*8($30)
  379. bsr $26, _dl_profile_fixup !samegp
  380. /* Discover if we're wrapping this call. */
  381. ldq $18, 45*8($30)
  382. bge $18, 1f
  383. /* Move the destination address into position. */
  384. mov $0, $27
  385. /* Restore program registers. */
  386. ldq $26, 0*8($30)
  387. ldq $16, 2*8($30)
  388. ldq $17, 3*8($30)
  389. ldq $18, 4*8($30)
  390. ldq $19, 5*8($30)
  391. ldq $20, 6*8($30)
  392. ldq $21, 7*8($30)
  393. ldt $f16, 8*8($30)
  394. ldt $f17, 9*8($30)
  395. ldt $f18, 10*8($30)
  396. ldt $f19, 11*8($30)
  397. ldt $f20, 12*8($30)
  398. ldt $f21, 13*8($30)
  399. ldq $0, 14*8($30)
  400. ldq $1, 15*8($30)
  401. ldq $2, 16*8($30)
  402. ldq $3, 17*8($30)
  403. ldq $4, 18*8($30)
  404. ldq $5, 19*8($30)
  405. ldq $6, 20*8($30)
  406. ldq $7, 21*8($30)
  407. ldq $8, 22*8($30)
  408. ldq $22, 23*8($30)
  409. ldq $23, 24*8($30)
  410. ldq $24, 25*8($30)
  411. ldq $25, 26*8($30)
  412. ldq $29, 27*8($30)
  413. ldt $f0, 28*8($30)
  414. ldt $f1, 29*8($30)
  415. ldt $f10, 30*8($30)
  416. ldt $f11, 31*8($30)
  417. ldt $f12, 32*8($30)
  418. ldt $f13, 33*8($30)
  419. ldt $f14, 34*8($30)
  420. ldt $f15, 35*8($30)
  421. ldt $f22, 36*8($30)
  422. ldt $f23, 37*8($30)
  423. ldt $f24, 38*8($30)
  424. ldt $f25, 39*8($30)
  425. ldt $f26, 40*8($30)
  426. ldt $f27, 41*8($30)
  427. ldt $f28, 42*8($30)
  428. ldt $f29, 43*8($30)
  429. ldt $f30, 44*8($30)
  430. /* Clean up and turn control to the destination. */
  431. lda $30, FRAMESIZE($30)
  432. jmp $31, ($27)
  433. 1:
  434. /* Create a frame pointer and allocate a new argument frame. */
  435. savei 15, 45*8
  436. mov $30, $15
  437. cfi_def_cfa_register (15)
  438. addq $18, 15, $18
  439. bic $18, 15, $18
  440. subq $30, $18, $30
  441. /* Save the call destination around memcpy. */
  442. stq $0, 46*8($30)
  443. /* Copy the stack arguments into place. */
  444. lda $16, 0($30)
  445. lda $17, FRAMESIZE($15)
  446. jsr $26, memcpy
  447. ldgp $29, 0($26)
  448. /* Reload the argument registers. */
  449. ldq $27, 46*8($30)
  450. ldq $16, 2*8($15)
  451. ldq $17, 3*8($15)
  452. ldq $18, 4*8($15)
  453. ldq $19, 5*8($15)
  454. ldq $20, 6*8($15)
  455. ldq $21, 7*8($15)
  456. ldt $f16, 8*8($15)
  457. ldt $f17, 9*8($15)
  458. ldt $f18, 10*8($15)
  459. ldt $f19, 11*8($15)
  460. ldt $f20, 12*8($15)
  461. ldt $f21, 13*8($15)
  462. jsr $26, ($27), 0
  463. ldgp $29, 0($26)
  464. /* Set up for call to _dl_audit_pltexit. */
  465. ldq $16, 48*8($15)
  466. ldq $17, 49*8($15)
  467. stq $0, 46*8($15)
  468. lda $18, 0($15)
  469. stq $1, 47*8($15)
  470. lda $19, 46*8($15)
  471. stt $f0, 48*8($15)
  472. stt $f1, 49*8($15)
  473. bsr $26, _dl_audit_pltexit !samegp
  474. mov $15, $30
  475. cfi_def_cfa_register (30)
  476. ldq $26, 0($30)
  477. ldq $15, 45*8($30)
  478. lda $30, FRAMESIZE($30)
  479. ret
  480. cfi_endproc
  481. .size _dl_runtime_profile_old, .-_dl_runtime_profile_old
  482. #endif /* SHARED */