0006-or1k-Support-large-plt_relocs-when-generating-plt-en.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. From cba29e387040eaa401c52eb20e7cab5a4401185c Mon Sep 17 00:00:00 2001
  2. From: Stafford Horne <shorne@gmail.com>
  3. Date: Sun, 2 May 2021 06:02:17 +0900
  4. Subject: [PATCH] or1k: Support large plt_relocs when generating plt
  5. entries
  6. The current PLT generation code will generate invalid code when the PLT
  7. relocation offset exceeds 64k. This fixes the issue by detecting large
  8. plt_reloc offsets and generare code sequences to create larger plt
  9. relocations.
  10. The "large" plt code needs 2 extra instructions to create 32-bit offsets.
  11. bfd/ChangeLog:
  12. PR 27746
  13. * elf32-or1k.c (PLT_ENTRY_SIZE_LARGE, PLT_MAX_INSN_COUNT,
  14. OR1K_ADD, OR1K_ORI): New macros to help with plt creation.
  15. (elf_or1k_link_hash_table): New field plt_count.
  16. (elf_or1k_link_hash_entry): New field plt_index.
  17. (elf_or1k_plt_entry_size): New function.
  18. (or1k_write_plt_entry): Update to support variable size PLTs.
  19. (or1k_elf_finish_dynamic_sections): Use new or1k_write_plt_entry
  20. API.
  21. (or1k_elf_finish_dynamic_symbol): Update to write large PLTs
  22. when needed.
  23. (allocate_dynrelocs): Use elf_or1k_plt_entry_size to account for
  24. PLT size.
  25. ld/ChangeLog:
  26. PR 27746
  27. testsuite/ld-or1k/or1k.exp (or1kplttests): Add tests for linking
  28. along with gotha() relocations.
  29. testsuite/ld-or1k/gotha1.dd: New file.
  30. testsuite/ld-or1k/gotha1.s: New file.
  31. testsuite/ld-or1k/gotha2.dd: New file.
  32. testsuite/ld-or1k/gotha2.s: New file
  33. testsuite/ld-or1k/pltlib.s (x): Define size to avoid link
  34. failure.
  35. Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
  36. ---
  37. bfd/elf32-or1k.c | 149 ++++++++++++++++++++++++---------
  38. ld/testsuite/ld-or1k/gotha1.dd | 34 ++++++++
  39. ld/testsuite/ld-or1k/gotha1.s | 24 ++++++
  40. ld/testsuite/ld-or1k/gotha2.dd | 21 +++++
  41. ld/testsuite/ld-or1k/gotha2.s | 22 +++++
  42. ld/testsuite/ld-or1k/or1k.exp | 8 ++
  43. ld/testsuite/ld-or1k/pltlib.s | 1 +
  44. 7 files changed, 220 insertions(+), 39 deletions(-)
  45. create mode 100644 ld/testsuite/ld-or1k/gotha1.dd
  46. create mode 100644 ld/testsuite/ld-or1k/gotha1.s
  47. create mode 100644 ld/testsuite/ld-or1k/gotha2.dd
  48. create mode 100644 ld/testsuite/ld-or1k/gotha2.s
  49. diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
  50. index ce2c4fdb3bd..8b021b79d92 100644
  51. --- a/bfd/elf32-or1k.c
  52. +++ b/bfd/elf32-or1k.c
  53. @@ -30,10 +30,14 @@
  54. #define N_ONES(X) (((bfd_vma)2 << (X)) - 1)
  55. #define PLT_ENTRY_SIZE 16
  56. +#define PLT_ENTRY_SIZE_LARGE (6*4)
  57. +#define PLT_MAX_INSN_COUNT 6
  58. #define OR1K_MOVHI(D) (0x18000000 | (D << 21))
  59. #define OR1K_ADRP(D) (0x08000000 | (D << 21))
  60. #define OR1K_LWZ(D,A) (0x84000000 | (D << 21) | (A << 16))
  61. +#define OR1K_ADD(D,A,B) (0xE0000000 | (D << 21) | (A << 16) | (B << 11))
  62. +#define OR1K_ORI(D,A) (0xA8000000 | (D << 21) | (A << 16))
  63. #define OR1K_ORI0(D) (0xA8000000 | (D << 21))
  64. #define OR1K_JR(B) (0x44000000 | (B << 11))
  65. #define OR1K_NOP 0x15000000
  66. @@ -903,6 +907,8 @@ struct elf_or1k_link_hash_entry
  67. /* Track dynamic relocs copied for this symbol. */
  68. struct elf_dyn_relocs *dyn_relocs;
  69. + /* For calculating PLT size. */
  70. + bfd_vma plt_index;
  71. /* Track type of TLS access. */
  72. unsigned char tls_type;
  73. };
  74. @@ -930,9 +936,20 @@ struct elf_or1k_link_hash_table
  75. /* Small local sym to section mapping cache. */
  76. struct sym_cache sym_sec;
  77. + bfd_vma plt_count;
  78. bfd_boolean saw_plta;
  79. };
  80. +static size_t
  81. +elf_or1k_plt_entry_size (bfd_vma plt_index)
  82. +{
  83. + bfd_vma plt_reloc;
  84. +
  85. + plt_reloc = plt_index * sizeof (Elf32_External_Rela);
  86. +
  87. + return (plt_reloc > 0xffff) ? PLT_ENTRY_SIZE_LARGE : PLT_ENTRY_SIZE;
  88. +}
  89. +
  90. /* Get the ELF linker hash table from a link_info structure. */
  91. #define or1k_elf_hash_table(p) \
  92. (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
  93. @@ -2173,33 +2190,46 @@ or1k_elf_check_relocs (bfd *abfd,
  94. }
  95. static void
  96. -or1k_write_plt_entry (bfd *output_bfd, bfd_byte *contents, unsigned insn1,
  97. - unsigned insn2, unsigned insn3, unsigned insnj)
  98. +or1k_write_plt_entry (bfd *output_bfd, bfd_byte *contents, unsigned insnj,
  99. + unsigned insns[], size_t insn_count)
  100. {
  101. unsigned nodelay = elf_elfheader (output_bfd)->e_flags & EF_OR1K_NODELAY;
  102. - unsigned insn4;
  103. + unsigned output_insns[PLT_MAX_INSN_COUNT];
  104. +
  105. + /* Copy instructions into the output buffer. */
  106. + for (size_t i = 0; i < insn_count; i++)
  107. + output_insns[i] = insns[i];
  108. /* Honor the no-delay-slot setting. */
  109. - if (insn3 == OR1K_NOP)
  110. + if (insns[insn_count-1] == OR1K_NOP)
  111. {
  112. - insn4 = insn3;
  113. + unsigned slot1, slot2;
  114. +
  115. if (nodelay)
  116. - insn3 = insnj;
  117. + slot1 = insns[insn_count-2], slot2 = insnj;
  118. else
  119. - insn3 = insn2, insn2 = insnj;
  120. + slot1 = insnj, slot2 = insns[insn_count-2];
  121. +
  122. + output_insns[insn_count-2] = slot1;
  123. + output_insns[insn_count-1] = slot2;
  124. + output_insns[insn_count] = OR1K_NOP;
  125. }
  126. else
  127. {
  128. + unsigned slot1, slot2;
  129. +
  130. if (nodelay)
  131. - insn4 = insnj;
  132. + slot1 = insns[insn_count-1], slot2 = insnj;
  133. else
  134. - insn4 = insn3, insn3 = insnj;
  135. + slot1 = insnj, slot2 = insns[insn_count-1];
  136. +
  137. + output_insns[insn_count-1] = slot1;
  138. + output_insns[insn_count] = slot2;
  139. }
  140. - bfd_put_32 (output_bfd, insn1, contents);
  141. - bfd_put_32 (output_bfd, insn2, contents + 4);
  142. - bfd_put_32 (output_bfd, insn3, contents + 8);
  143. - bfd_put_32 (output_bfd, insn4, contents + 12);
  144. + /* Write out the output buffer. */
  145. + for (size_t i = 0; i < (insn_count+1); i++)
  146. + bfd_put_32 (output_bfd, output_insns[i], contents + (i*4));
  147. }
  148. /* Finish up the dynamic sections. */
  149. @@ -2266,7 +2296,8 @@ or1k_elf_finish_dynamic_sections (bfd *output_bfd,
  150. splt = htab->root.splt;
  151. if (splt && splt->size > 0)
  152. {
  153. - unsigned plt0, plt1, plt2;
  154. + unsigned plt[PLT_MAX_INSN_COUNT];
  155. + size_t plt_insn_count = 3;
  156. bfd_vma got_addr = sgot->output_section->vma + sgot->output_offset;
  157. /* Note we force 16 byte alignment on the .got, so that
  158. @@ -2277,27 +2308,27 @@ or1k_elf_finish_dynamic_sections (bfd *output_bfd,
  159. bfd_vma pc = splt->output_section->vma + splt->output_offset;
  160. unsigned pa = ((got_addr >> 13) - (pc >> 13)) & 0x1fffff;
  161. unsigned po = got_addr & 0x1fff;
  162. - plt0 = OR1K_ADRP(12) | pa;
  163. - plt1 = OR1K_LWZ(15,12) | (po + 8);
  164. - plt2 = OR1K_LWZ(12,12) | (po + 4);
  165. + plt[0] = OR1K_ADRP(12) | pa;
  166. + plt[1] = OR1K_LWZ(15,12) | (po + 8);
  167. + plt[2] = OR1K_LWZ(12,12) | (po + 4);
  168. }
  169. else if (bfd_link_pic (info))
  170. {
  171. - plt0 = OR1K_LWZ(15, 16) | 8; /* .got+8 */
  172. - plt1 = OR1K_LWZ(12, 16) | 4; /* .got+4 */
  173. - plt2 = OR1K_NOP;
  174. + plt[0] = OR1K_LWZ(15, 16) | 8; /* .got+8 */
  175. + plt[1] = OR1K_LWZ(12, 16) | 4; /* .got+4 */
  176. + plt[2] = OR1K_NOP;
  177. }
  178. else
  179. {
  180. unsigned ha = ((got_addr + 0x8000) >> 16) & 0xffff;
  181. unsigned lo = got_addr & 0xffff;
  182. - plt0 = OR1K_MOVHI(12) | ha;
  183. - plt1 = OR1K_LWZ(15,12) | (lo + 8);
  184. - plt2 = OR1K_LWZ(12,12) | (lo + 4);
  185. + plt[0] = OR1K_MOVHI(12) | ha;
  186. + plt[1] = OR1K_LWZ(15,12) | (lo + 8);
  187. + plt[2] = OR1K_LWZ(12,12) | (lo + 4);
  188. }
  189. - or1k_write_plt_entry (output_bfd, splt->contents,
  190. - plt0, plt1, plt2, OR1K_JR(15));
  191. + or1k_write_plt_entry (output_bfd, splt->contents, OR1K_JR(15),
  192. + plt, plt_insn_count);
  193. elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
  194. }
  195. @@ -2340,7 +2371,8 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
  196. if (h->plt.offset != (bfd_vma) -1)
  197. {
  198. - unsigned int plt0, plt1, plt2;
  199. + unsigned int plt[PLT_MAX_INSN_COUNT];
  200. + size_t plt_insn_count = 3;
  201. asection *splt;
  202. asection *sgot;
  203. asection *srela;
  204. @@ -2352,6 +2384,7 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
  205. bfd_vma got_offset;
  206. bfd_vma got_addr;
  207. Elf_Internal_Rela rela;
  208. + bfd_boolean large_plt_entry;
  209. /* This symbol has an entry in the procedure linkage table. Set
  210. it up. */
  211. @@ -2369,10 +2402,13 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
  212. corresponds to this symbol. This is the index of this symbol
  213. in all the symbols for which we are making plt entries. The
  214. first entry in the procedure linkage table is reserved. */
  215. - plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
  216. + plt_index = ((struct elf_or1k_link_hash_entry *) h)->plt_index;
  217. plt_addr = plt_base_addr + h->plt.offset;
  218. plt_reloc = plt_index * sizeof (Elf32_External_Rela);
  219. + large_plt_entry = (elf_or1k_plt_entry_size (plt_index)
  220. + == PLT_ENTRY_SIZE_LARGE);
  221. +
  222. /* Get the offset into the .got table of the entry that
  223. corresponds to this function. Each .got entry is 4 bytes.
  224. The first three are reserved. */
  225. @@ -2384,27 +2420,57 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
  226. {
  227. unsigned pa = ((got_addr >> 13) - (plt_addr >> 13)) & 0x1fffff;
  228. unsigned po = (got_addr & 0x1fff);
  229. - plt0 = OR1K_ADRP(12) | pa;
  230. - plt1 = OR1K_LWZ(12,12) | po;
  231. - plt2 = OR1K_ORI0(11) | plt_reloc;
  232. + plt[0] = OR1K_ADRP(12) | pa;
  233. + plt[1] = OR1K_LWZ(12,12) | po;
  234. + plt[2] = OR1K_ORI0(11) | plt_reloc;
  235. }
  236. else if (bfd_link_pic (info))
  237. {
  238. - plt0 = OR1K_LWZ(12,16) | got_offset;
  239. - plt1 = OR1K_ORI0(11) | plt_reloc;
  240. - plt2 = OR1K_NOP;
  241. + if (large_plt_entry)
  242. + {
  243. + unsigned gotha = ((got_offset + 0x8000) >> 16) & 0xffff;
  244. + unsigned got = got_offset & 0xffff;
  245. + unsigned pltrelhi = (plt_reloc >> 16) & 0xffff;
  246. + unsigned pltrello = plt_reloc & 0xffff;
  247. +
  248. + plt[0] = OR1K_MOVHI(12) | gotha;
  249. + plt[1] = OR1K_ADD(12,12,16);
  250. + plt[2] = OR1K_LWZ(12,12) | got;
  251. + plt[3] = OR1K_MOVHI(11) | pltrelhi;
  252. + plt[4] = OR1K_ORI(11,11) | pltrello;
  253. + plt_insn_count = 5;
  254. + }
  255. + else
  256. + {
  257. + plt[0] = OR1K_LWZ(12,16) | got_offset;
  258. + plt[1] = OR1K_ORI0(11) | plt_reloc;
  259. + plt[2] = OR1K_NOP;
  260. + }
  261. }
  262. else
  263. {
  264. unsigned ha = ((got_addr + 0x8000) >> 16) & 0xffff;
  265. unsigned lo = got_addr & 0xffff;
  266. - plt0 = OR1K_MOVHI(12) | ha;
  267. - plt1 = OR1K_LWZ(12,12) | lo;
  268. - plt2 = OR1K_ORI0(11) | plt_reloc;
  269. + plt[0] = OR1K_MOVHI(12) | ha;
  270. + plt[1] = OR1K_LWZ(12,12) | lo;
  271. + plt[2] = OR1K_ORI0(11) | plt_reloc;
  272. + }
  273. +
  274. + /* For large code model we fixup the non-PIC PLT relocation instructions
  275. + here. */
  276. + if (large_plt_entry && !bfd_link_pic (info))
  277. + {
  278. + unsigned pltrelhi = (plt_reloc >> 16) & 0xffff;
  279. + unsigned pltrello = plt_reloc & 0xffff;
  280. +
  281. + plt[2] = OR1K_MOVHI(11) | pltrelhi;
  282. + plt[3] = OR1K_ORI(11,11) | pltrello;
  283. + plt[4] = OR1K_NOP;
  284. + plt_insn_count = 5;
  285. }
  286. or1k_write_plt_entry (output_bfd, splt->contents + h->plt.offset,
  287. - plt0, plt1, plt2, OR1K_JR(12));
  288. + OR1K_JR(12), plt, plt_insn_count);
  289. /* Fill in the entry in the global offset table. We initialize it to
  290. point to the top of the plt. This is done to lazy lookup the actual
  291. @@ -2699,11 +2765,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
  292. if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
  293. {
  294. asection *s = htab->root.splt;
  295. + bfd_vma plt_index;
  296. +
  297. + /* Track the index of our plt entry for use in calculating size. */
  298. + plt_index = htab->plt_count++;
  299. + ((struct elf_or1k_link_hash_entry *) h)->plt_index = plt_index;
  300. /* If this is the first .plt entry, make room for the special
  301. first entry. */
  302. if (s->size == 0)
  303. - s->size = PLT_ENTRY_SIZE;
  304. + s->size = elf_or1k_plt_entry_size (plt_index);
  305. h->plt.offset = s->size;
  306. @@ -2720,7 +2791,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
  307. }
  308. /* Make room for this entry. */
  309. - s->size += PLT_ENTRY_SIZE;
  310. + s->size += elf_or1k_plt_entry_size (plt_index);
  311. /* We also need to make an entry in the .got.plt section, which
  312. will be placed in the .got section by the linker script. */
  313. diff --git a/ld/testsuite/ld-or1k/gotha1.dd b/ld/testsuite/ld-or1k/gotha1.dd
  314. new file mode 100644
  315. index 00000000000..0ad1f8f5399
  316. --- /dev/null
  317. +++ b/ld/testsuite/ld-or1k/gotha1.dd
  318. @@ -0,0 +1,34 @@
  319. +
  320. +.*\.x: file format elf32-or1k
  321. +
  322. +
  323. +Disassembly of section \.plt:
  324. +
  325. +[0-9a-f]+ <\.plt>:
  326. + +[0-9a-f]+: 19 80 00 00 l\.movhi r12,0x0
  327. + +[0-9a-f]+: 85 ec [0-9a-f]+ [0-9a-f]+ l\.lwz r15,[0-9]+\(r12\)
  328. + +[0-9a-f]+: 44 00 78 00 l\.jr r15
  329. + +[0-9a-f]+: 85 8c [0-9a-f]+ [0-9a-f]+ l\.lwz r12,[0-9]+\(r12\)
  330. + +[0-9a-f]+: 19 80 00 00 l\.movhi r12,0x0
  331. + +[0-9a-f]+: 85 8c [0-9a-f]+ [0-9a-f]+ l\.lwz r12,[0-9]+\(r12\)
  332. + +[0-9a-f]+: 44 00 60 00 l\.jr r12
  333. + +[0-9a-f]+: a9 60 00 00 l\.ori r11,r0,0x0
  334. +
  335. +Disassembly of section \.text:
  336. +
  337. +[0-9a-f]+ <_start>:
  338. + +[0-9a-f]+: 9c 21 ff fc l\.addi r1,r1,-4
  339. + +[0-9a-f]+: d4 01 48 00 l\.sw 0\(r1\),r9
  340. + +[0-9a-f]+: 04 00 00 02 l\.jal [0-9a-f]+ <_start\+0x10>
  341. + +[0-9a-f]+: 1a 60 00 00 l\.movhi r19,0x0
  342. + +[0-9a-f]+: aa 73 [0-9a-f]+ [0-9a-f]+ l\.ori r19,r19,0x[0-9a-f]+
  343. + +[0-9a-f]+: e2 73 48 00 l\.add r19,r19,r9
  344. + +[0-9a-f]+: 1a 20 00 00 l\.movhi r17,0x0
  345. + +[0-9a-f]+: e2 31 98 00 l\.add r17,r17,r19
  346. + +[0-9a-f]+: 86 31 00 10 l\.lwz r17,16\(r17\)
  347. + +[0-9a-f]+: 84 71 00 00 l\.lwz r3,0\(r17\)
  348. + +[0-9a-f]+: 07 ff ff f2 l\.jal [0-9a-f]+ <\.plt\+0x10>
  349. + +[0-9a-f]+: 15 00 00 00 l\.nop 0x0
  350. + +[0-9a-f]+: 85 21 00 00 l\.lwz r9,0\(r1\)
  351. + +[0-9a-f]+: 44 00 48 00 l\.jr r9
  352. + +[0-9a-f]+: 9c 21 00 04 l\.addi r1,r1,4
  353. diff --git a/ld/testsuite/ld-or1k/gotha1.s b/ld/testsuite/ld-or1k/gotha1.s
  354. new file mode 100644
  355. index 00000000000..42b16db425c
  356. --- /dev/null
  357. +++ b/ld/testsuite/ld-or1k/gotha1.s
  358. @@ -0,0 +1,24 @@
  359. + .data
  360. + .p2align 16
  361. +
  362. + .text
  363. + .globl _start
  364. +_start:
  365. + l.addi r1, r1, -4
  366. + l.sw 0(r1), r9
  367. +
  368. + l.jal 8
  369. + l.movhi r19, gotpchi(_GLOBAL_OFFSET_TABLE_-4)
  370. + l.ori r19, r19, gotpclo(_GLOBAL_OFFSET_TABLE_+0)
  371. + l.add r19, r19, r9
  372. +
  373. + l.movhi r17, gotha(x)
  374. + l.add r17, r17, r19
  375. + l.lwz r17, got(x)(r17)
  376. + l.lwz r3, 0(r17)
  377. +
  378. + l.jal plt(func)
  379. + l.nop
  380. + l.lwz r9, 0(r1)
  381. + l.jr r9
  382. + l.addi r1, r1, 4
  383. diff --git a/ld/testsuite/ld-or1k/gotha2.dd b/ld/testsuite/ld-or1k/gotha2.dd
  384. new file mode 100644
  385. index 00000000000..fe09da5466b
  386. --- /dev/null
  387. +++ b/ld/testsuite/ld-or1k/gotha2.dd
  388. @@ -0,0 +1,21 @@
  389. +
  390. +.*\.x: file format elf32-or1k
  391. +
  392. +
  393. +Disassembly of section \.text:
  394. +
  395. +[0-9a-f]+ <test>:
  396. + +[0-9a-f]+: 9c 21 ff f8 l\.addi r1,r1,-8
  397. + +[0-9a-f]+: d4 01 80 00 l\.sw 0\(r1\),r16
  398. + +[0-9a-f]+: d4 01 48 04 l\.sw 4\(r1\),r9
  399. + +[0-9a-f]+: 04 00 [0-9a-f]+ [0-9a-f]+ l\.jal [0-9a-f]+ <test\+0x14>
  400. + +[0-9a-f]+: 1a 00 00 00 l\.movhi r16,0x0
  401. + +[0-9a-f]+: aa 10 [0-9a-f]+ [0-9a-f]+ l\.ori r16,r16,0x[0-9a-f]+
  402. + +[0-9a-f]+: e2 10 48 00 l\.add r16,r16,r9
  403. + +[0-9a-f]+: 1a 20 00 00 l\.movhi r17,0x0
  404. + +[0-9a-f]+: e2 31 80 00 l\.add r17,r17,r16
  405. + +[0-9a-f]+: 86 31 00 0c l\.lwz r17,12\(r17\)
  406. + +[0-9a-f]+: 85 21 00 04 l\.lwz r9,4\(r1\)
  407. + +[0-9a-f]+: 86 01 00 00 l\.lwz r16,0\(r1\)
  408. + +[0-9a-f]+: 44 00 48 00 l\.jr r9
  409. + +[0-9a-f]+: 9c 21 00 08 l\.addi r1,r1,8
  410. diff --git a/ld/testsuite/ld-or1k/gotha2.s b/ld/testsuite/ld-or1k/gotha2.s
  411. new file mode 100644
  412. index 00000000000..164b282f2dd
  413. --- /dev/null
  414. +++ b/ld/testsuite/ld-or1k/gotha2.s
  415. @@ -0,0 +1,22 @@
  416. + .section .text
  417. + .align 4
  418. + .global test
  419. + .type test, @function
  420. +test:
  421. + l.addi r1, r1, -8
  422. + l.sw 0(r1), r16
  423. + l.sw 4(r1), r9
  424. +
  425. + l.jal 8
  426. + l.movhi r16, gotpchi(_GLOBAL_OFFSET_TABLE_-4)
  427. + l.ori r16, r16, gotpclo(_GLOBAL_OFFSET_TABLE_+0)
  428. + l.add r16, r16, r9
  429. +
  430. + l.movhi r17, gotha(i)
  431. + l.add r17, r17, r16
  432. + l.lwz r17, got(i)(r17)
  433. +
  434. + l.lwz r9, 4(r1)
  435. + l.lwz r16, 0(r1)
  436. + l.jr r9
  437. + l.addi r1, r1, 8
  438. diff --git a/ld/testsuite/ld-or1k/or1k.exp b/ld/testsuite/ld-or1k/or1k.exp
  439. index 7592e8307c1..8e19ec6c31a 100644
  440. --- a/ld/testsuite/ld-or1k/or1k.exp
  441. +++ b/ld/testsuite/ld-or1k/or1k.exp
  442. @@ -53,6 +53,14 @@ set or1kplttests {
  443. "" {plt1.s}
  444. {{objdump -dr plt1.x.dd}}
  445. "plt1.x"}
  446. + {"gotha exec plt" "tmpdir/libpltlib.so" ""
  447. + "" {gotha1.s}
  448. + {{objdump -dr gotha1.dd}}
  449. + "gotha1.x"}
  450. + {"gotha -fpic -shared" "-fpic -shared" ""
  451. + "" {gotha2.s}
  452. + {{objdump -dr gotha2.dd}}
  453. + "gotha2.x"}
  454. }
  455. # Not implemented yet
  456. diff --git a/ld/testsuite/ld-or1k/pltlib.s b/ld/testsuite/ld-or1k/pltlib.s
  457. index baf76ca1af7..8b4d7ba48fd 100644
  458. --- a/ld/testsuite/ld-or1k/pltlib.s
  459. +++ b/ld/testsuite/ld-or1k/pltlib.s
  460. @@ -1,5 +1,6 @@
  461. .section .data
  462. .globl x, y
  463. + .size x, 4
  464. x: .long 33
  465. y: .long 44
  466. --
  467. 2.25.1