394c62b21b
Add upstream backported patches that allows using -mcmodel=large gcc option that in order allows fixing build failure due to binutils bug 21464: https://sourceware.org/bugzilla/show_bug.cgi?id=21464 Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be> [Arnout: remove the PATCH M/N parts - cfr. check-package]
501 lines
16 KiB
Diff
501 lines
16 KiB
Diff
From c87692eb894b4b86eced7b7ba205f9bf27c2c213 Mon Sep 17 00:00:00 2001
|
|
From: Stafford Horne <shorne@gmail.com>
|
|
Date: Sun, 2 May 2021 06:02:17 +0900
|
|
Subject: [PATCH] or1k: Support large plt_relocs when generating plt
|
|
entries
|
|
|
|
The current PLT generation code will generate invalid code when the PLT
|
|
relocation offset exceeds 64k. This fixes the issue by detecting large
|
|
plt_reloc offsets and generare code sequences to create larger plt
|
|
relocations.
|
|
|
|
The "large" plt code needs 2 extra instructions to create 32-bit offsets.
|
|
|
|
bfd/ChangeLog:
|
|
|
|
PR 27746
|
|
* elf32-or1k.c (PLT_ENTRY_SIZE_LARGE, PLT_MAX_INSN_COUNT,
|
|
OR1K_ADD, OR1K_ORI): New macros to help with plt creation.
|
|
(elf_or1k_link_hash_table): New field plt_count.
|
|
(elf_or1k_link_hash_entry): New field plt_index.
|
|
(elf_or1k_plt_entry_size): New function.
|
|
(or1k_write_plt_entry): Update to support variable size PLTs.
|
|
(or1k_elf_finish_dynamic_sections): Use new or1k_write_plt_entry
|
|
API.
|
|
(or1k_elf_finish_dynamic_symbol): Update to write large PLTs
|
|
when needed.
|
|
(allocate_dynrelocs): Use elf_or1k_plt_entry_size to account for
|
|
PLT size.
|
|
|
|
ld/ChangeLog:
|
|
|
|
PR 27746
|
|
testsuite/ld-or1k/or1k.exp (or1kplttests): Add tests for linking
|
|
along with gotha() relocations.
|
|
testsuite/ld-or1k/gotha1.dd: New file.
|
|
testsuite/ld-or1k/gotha1.s: New file.
|
|
testsuite/ld-or1k/gotha2.dd: New file.
|
|
testsuite/ld-or1k/gotha2.s: New file
|
|
testsuite/ld-or1k/pltlib.s (x): Define size to avoid link
|
|
failure.
|
|
|
|
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
|
|
---
|
|
bfd/elf32-or1k.c | 149 ++++++++++++++++++++++++---------
|
|
ld/testsuite/ld-or1k/gotha1.dd | 34 ++++++++
|
|
ld/testsuite/ld-or1k/gotha1.s | 24 ++++++
|
|
ld/testsuite/ld-or1k/gotha2.dd | 21 +++++
|
|
ld/testsuite/ld-or1k/gotha2.s | 22 +++++
|
|
ld/testsuite/ld-or1k/or1k.exp | 8 ++
|
|
ld/testsuite/ld-or1k/pltlib.s | 1 +
|
|
7 files changed, 220 insertions(+), 39 deletions(-)
|
|
create mode 100644 ld/testsuite/ld-or1k/gotha1.dd
|
|
create mode 100644 ld/testsuite/ld-or1k/gotha1.s
|
|
create mode 100644 ld/testsuite/ld-or1k/gotha2.dd
|
|
create mode 100644 ld/testsuite/ld-or1k/gotha2.s
|
|
|
|
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
|
|
index 9f315bfda99..7a14eaa3a46 100644
|
|
--- a/bfd/elf32-or1k.c
|
|
+++ b/bfd/elf32-or1k.c
|
|
@@ -30,10 +30,14 @@
|
|
#define N_ONES(X) (((bfd_vma)2 << (X)) - 1)
|
|
|
|
#define PLT_ENTRY_SIZE 16
|
|
+#define PLT_ENTRY_SIZE_LARGE (6*4)
|
|
+#define PLT_MAX_INSN_COUNT 6
|
|
|
|
#define OR1K_MOVHI(D) (0x18000000 | (D << 21))
|
|
#define OR1K_ADRP(D) (0x08000000 | (D << 21))
|
|
#define OR1K_LWZ(D,A) (0x84000000 | (D << 21) | (A << 16))
|
|
+#define OR1K_ADD(D,A,B) (0xE0000000 | (D << 21) | (A << 16) | (B << 11))
|
|
+#define OR1K_ORI(D,A) (0xA8000000 | (D << 21) | (A << 16))
|
|
#define OR1K_ORI0(D) (0xA8000000 | (D << 21))
|
|
#define OR1K_JR(B) (0x44000000 | (B << 11))
|
|
#define OR1K_NOP 0x15000000
|
|
@@ -907,6 +911,8 @@ struct elf_or1k_link_hash_entry
|
|
{
|
|
struct elf_link_hash_entry root;
|
|
|
|
+ /* For calculating PLT size. */
|
|
+ bfd_vma plt_index;
|
|
/* Track type of TLS access. */
|
|
unsigned char tls_type;
|
|
};
|
|
@@ -934,9 +940,20 @@ struct elf_or1k_link_hash_table
|
|
/* Small local sym to section mapping cache. */
|
|
struct sym_cache sym_sec;
|
|
|
|
+ bfd_vma plt_count;
|
|
bfd_boolean saw_plta;
|
|
};
|
|
|
|
+static size_t
|
|
+elf_or1k_plt_entry_size (bfd_vma plt_index)
|
|
+{
|
|
+ bfd_vma plt_reloc;
|
|
+
|
|
+ plt_reloc = plt_index * sizeof (Elf32_External_Rela);
|
|
+
|
|
+ return (plt_reloc > 0xffff) ? PLT_ENTRY_SIZE_LARGE : PLT_ENTRY_SIZE;
|
|
+}
|
|
+
|
|
/* Get the ELF linker hash table from a link_info structure. */
|
|
#define or1k_elf_hash_table(p) \
|
|
(elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
|
|
@@ -2224,33 +2241,46 @@ or1k_elf_check_relocs (bfd *abfd,
|
|
}
|
|
|
|
static void
|
|
-or1k_write_plt_entry (bfd *output_bfd, bfd_byte *contents, unsigned insn1,
|
|
- unsigned insn2, unsigned insn3, unsigned insnj)
|
|
+or1k_write_plt_entry (bfd *output_bfd, bfd_byte *contents, unsigned insnj,
|
|
+ unsigned insns[], size_t insn_count)
|
|
{
|
|
unsigned nodelay = elf_elfheader (output_bfd)->e_flags & EF_OR1K_NODELAY;
|
|
- unsigned insn4;
|
|
+ unsigned output_insns[PLT_MAX_INSN_COUNT];
|
|
+
|
|
+ /* Copy instructions into the output buffer. */
|
|
+ for (size_t i = 0; i < insn_count; i++)
|
|
+ output_insns[i] = insns[i];
|
|
|
|
/* Honor the no-delay-slot setting. */
|
|
- if (insn3 == OR1K_NOP)
|
|
+ if (insns[insn_count-1] == OR1K_NOP)
|
|
{
|
|
- insn4 = insn3;
|
|
+ unsigned slot1, slot2;
|
|
+
|
|
if (nodelay)
|
|
- insn3 = insnj;
|
|
+ slot1 = insns[insn_count-2], slot2 = insnj;
|
|
else
|
|
- insn3 = insn2, insn2 = insnj;
|
|
+ slot1 = insnj, slot2 = insns[insn_count-2];
|
|
+
|
|
+ output_insns[insn_count-2] = slot1;
|
|
+ output_insns[insn_count-1] = slot2;
|
|
+ output_insns[insn_count] = OR1K_NOP;
|
|
}
|
|
else
|
|
{
|
|
+ unsigned slot1, slot2;
|
|
+
|
|
if (nodelay)
|
|
- insn4 = insnj;
|
|
+ slot1 = insns[insn_count-1], slot2 = insnj;
|
|
else
|
|
- insn4 = insn3, insn3 = insnj;
|
|
+ slot1 = insnj, slot2 = insns[insn_count-1];
|
|
+
|
|
+ output_insns[insn_count-1] = slot1;
|
|
+ output_insns[insn_count] = slot2;
|
|
}
|
|
|
|
- bfd_put_32 (output_bfd, insn1, contents);
|
|
- bfd_put_32 (output_bfd, insn2, contents + 4);
|
|
- bfd_put_32 (output_bfd, insn3, contents + 8);
|
|
- bfd_put_32 (output_bfd, insn4, contents + 12);
|
|
+ /* Write out the output buffer. */
|
|
+ for (size_t i = 0; i < (insn_count+1); i++)
|
|
+ bfd_put_32 (output_bfd, output_insns[i], contents + (i*4));
|
|
}
|
|
|
|
/* Finish up the dynamic sections. */
|
|
@@ -2317,7 +2347,8 @@ or1k_elf_finish_dynamic_sections (bfd *output_bfd,
|
|
splt = htab->root.splt;
|
|
if (splt && splt->size > 0)
|
|
{
|
|
- unsigned plt0, plt1, plt2;
|
|
+ unsigned plt[PLT_MAX_INSN_COUNT];
|
|
+ size_t plt_insn_count = 3;
|
|
bfd_vma got_addr = sgot->output_section->vma + sgot->output_offset;
|
|
|
|
/* Note we force 16 byte alignment on the .got, so that
|
|
@@ -2328,27 +2359,27 @@ or1k_elf_finish_dynamic_sections (bfd *output_bfd,
|
|
bfd_vma pc = splt->output_section->vma + splt->output_offset;
|
|
unsigned pa = ((got_addr >> 13) - (pc >> 13)) & 0x1fffff;
|
|
unsigned po = got_addr & 0x1fff;
|
|
- plt0 = OR1K_ADRP(12) | pa;
|
|
- plt1 = OR1K_LWZ(15,12) | (po + 8);
|
|
- plt2 = OR1K_LWZ(12,12) | (po + 4);
|
|
+ plt[0] = OR1K_ADRP(12) | pa;
|
|
+ plt[1] = OR1K_LWZ(15,12) | (po + 8);
|
|
+ plt[2] = OR1K_LWZ(12,12) | (po + 4);
|
|
}
|
|
else if (bfd_link_pic (info))
|
|
{
|
|
- plt0 = OR1K_LWZ(15, 16) | 8; /* .got+8 */
|
|
- plt1 = OR1K_LWZ(12, 16) | 4; /* .got+4 */
|
|
- plt2 = OR1K_NOP;
|
|
+ plt[0] = OR1K_LWZ(15, 16) | 8; /* .got+8 */
|
|
+ plt[1] = OR1K_LWZ(12, 16) | 4; /* .got+4 */
|
|
+ plt[2] = OR1K_NOP;
|
|
}
|
|
else
|
|
{
|
|
unsigned ha = ((got_addr + 0x8000) >> 16) & 0xffff;
|
|
unsigned lo = got_addr & 0xffff;
|
|
- plt0 = OR1K_MOVHI(12) | ha;
|
|
- plt1 = OR1K_LWZ(15,12) | (lo + 8);
|
|
- plt2 = OR1K_LWZ(12,12) | (lo + 4);
|
|
+ plt[0] = OR1K_MOVHI(12) | ha;
|
|
+ plt[1] = OR1K_LWZ(15,12) | (lo + 8);
|
|
+ plt[2] = OR1K_LWZ(12,12) | (lo + 4);
|
|
}
|
|
|
|
- or1k_write_plt_entry (output_bfd, splt->contents,
|
|
- plt0, plt1, plt2, OR1K_JR(15));
|
|
+ or1k_write_plt_entry (output_bfd, splt->contents, OR1K_JR(15),
|
|
+ plt, plt_insn_count);
|
|
|
|
elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
|
|
}
|
|
@@ -2391,7 +2422,8 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|
|
|
if (h->plt.offset != (bfd_vma) -1)
|
|
{
|
|
- unsigned int plt0, plt1, plt2;
|
|
+ unsigned int plt[PLT_MAX_INSN_COUNT];
|
|
+ size_t plt_insn_count = 3;
|
|
asection *splt;
|
|
asection *sgot;
|
|
asection *srela;
|
|
@@ -2403,6 +2435,7 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|
bfd_vma got_offset;
|
|
bfd_vma got_addr;
|
|
Elf_Internal_Rela rela;
|
|
+ bfd_boolean large_plt_entry;
|
|
|
|
/* This symbol has an entry in the procedure linkage table. Set
|
|
it up. */
|
|
@@ -2420,10 +2453,13 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|
corresponds to this symbol. This is the index of this symbol
|
|
in all the symbols for which we are making plt entries. The
|
|
first entry in the procedure linkage table is reserved. */
|
|
- plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
|
|
+ plt_index = ((struct elf_or1k_link_hash_entry *) h)->plt_index;
|
|
plt_addr = plt_base_addr + h->plt.offset;
|
|
plt_reloc = plt_index * sizeof (Elf32_External_Rela);
|
|
|
|
+ large_plt_entry = (elf_or1k_plt_entry_size (plt_index)
|
|
+ == PLT_ENTRY_SIZE_LARGE);
|
|
+
|
|
/* Get the offset into the .got table of the entry that
|
|
corresponds to this function. Each .got entry is 4 bytes.
|
|
The first three are reserved. */
|
|
@@ -2435,27 +2471,57 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|
{
|
|
unsigned pa = ((got_addr >> 13) - (plt_addr >> 13)) & 0x1fffff;
|
|
unsigned po = (got_addr & 0x1fff);
|
|
- plt0 = OR1K_ADRP(12) | pa;
|
|
- plt1 = OR1K_LWZ(12,12) | po;
|
|
- plt2 = OR1K_ORI0(11) | plt_reloc;
|
|
+ plt[0] = OR1K_ADRP(12) | pa;
|
|
+ plt[1] = OR1K_LWZ(12,12) | po;
|
|
+ plt[2] = OR1K_ORI0(11) | plt_reloc;
|
|
}
|
|
else if (bfd_link_pic (info))
|
|
{
|
|
- plt0 = OR1K_LWZ(12,16) | got_offset;
|
|
- plt1 = OR1K_ORI0(11) | plt_reloc;
|
|
- plt2 = OR1K_NOP;
|
|
+ if (large_plt_entry)
|
|
+ {
|
|
+ unsigned gotha = ((got_offset + 0x8000) >> 16) & 0xffff;
|
|
+ unsigned got = got_offset & 0xffff;
|
|
+ unsigned pltrelhi = (plt_reloc >> 16) & 0xffff;
|
|
+ unsigned pltrello = plt_reloc & 0xffff;
|
|
+
|
|
+ plt[0] = OR1K_MOVHI(12) | gotha;
|
|
+ plt[1] = OR1K_ADD(12,12,16);
|
|
+ plt[2] = OR1K_LWZ(12,12) | got;
|
|
+ plt[3] = OR1K_MOVHI(11) | pltrelhi;
|
|
+ plt[4] = OR1K_ORI(11,11) | pltrello;
|
|
+ plt_insn_count = 5;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ plt[0] = OR1K_LWZ(12,16) | got_offset;
|
|
+ plt[1] = OR1K_ORI0(11) | plt_reloc;
|
|
+ plt[2] = OR1K_NOP;
|
|
+ }
|
|
}
|
|
else
|
|
{
|
|
unsigned ha = ((got_addr + 0x8000) >> 16) & 0xffff;
|
|
unsigned lo = got_addr & 0xffff;
|
|
- plt0 = OR1K_MOVHI(12) | ha;
|
|
- plt1 = OR1K_LWZ(12,12) | lo;
|
|
- plt2 = OR1K_ORI0(11) | plt_reloc;
|
|
+ plt[0] = OR1K_MOVHI(12) | ha;
|
|
+ plt[1] = OR1K_LWZ(12,12) | lo;
|
|
+ plt[2] = OR1K_ORI0(11) | plt_reloc;
|
|
+ }
|
|
+
|
|
+ /* For large code model we fixup the non-PIC PLT relocation instructions
|
|
+ here. */
|
|
+ if (large_plt_entry && !bfd_link_pic (info))
|
|
+ {
|
|
+ unsigned pltrelhi = (plt_reloc >> 16) & 0xffff;
|
|
+ unsigned pltrello = plt_reloc & 0xffff;
|
|
+
|
|
+ plt[2] = OR1K_MOVHI(11) | pltrelhi;
|
|
+ plt[3] = OR1K_ORI(11,11) | pltrello;
|
|
+ plt[4] = OR1K_NOP;
|
|
+ plt_insn_count = 5;
|
|
}
|
|
|
|
or1k_write_plt_entry (output_bfd, splt->contents + h->plt.offset,
|
|
- plt0, plt1, plt2, OR1K_JR(12));
|
|
+ OR1K_JR(12), plt, plt_insn_count);
|
|
|
|
/* Fill in the entry in the global offset table. We initialize it to
|
|
point to the top of the plt. This is done to lazy lookup the actual
|
|
@@ -2779,11 +2845,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
|
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
|
|
{
|
|
asection *splt = htab->root.splt;
|
|
+ bfd_vma plt_index;
|
|
+
|
|
+ /* Track the index of our plt entry for use in calculating size. */
|
|
+ plt_index = htab->plt_count++;
|
|
+ ((struct elf_or1k_link_hash_entry *) h)->plt_index = plt_index;
|
|
|
|
/* If this is the first .plt entry, make room for the special
|
|
first entry. */
|
|
if (splt->size == 0)
|
|
- splt->size = PLT_ENTRY_SIZE;
|
|
+ splt->size = elf_or1k_plt_entry_size (plt_index);
|
|
|
|
h->plt.offset = splt->size;
|
|
|
|
@@ -2800,7 +2871,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
|
}
|
|
|
|
/* Make room for this entry. */
|
|
- splt->size += PLT_ENTRY_SIZE;
|
|
+ splt->size += elf_or1k_plt_entry_size (plt_index);
|
|
|
|
/* We also need to make an entry in the .got.plt section, which
|
|
will be placed in the .got section by the linker script. */
|
|
diff --git a/ld/testsuite/ld-or1k/gotha1.dd b/ld/testsuite/ld-or1k/gotha1.dd
|
|
new file mode 100644
|
|
index 00000000000..0ad1f8f5399
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-or1k/gotha1.dd
|
|
@@ -0,0 +1,34 @@
|
|
+
|
|
+.*\.x: file format elf32-or1k
|
|
+
|
|
+
|
|
+Disassembly of section \.plt:
|
|
+
|
|
+[0-9a-f]+ <\.plt>:
|
|
+ +[0-9a-f]+: 19 80 00 00 l\.movhi r12,0x0
|
|
+ +[0-9a-f]+: 85 ec [0-9a-f]+ [0-9a-f]+ l\.lwz r15,[0-9]+\(r12\)
|
|
+ +[0-9a-f]+: 44 00 78 00 l\.jr r15
|
|
+ +[0-9a-f]+: 85 8c [0-9a-f]+ [0-9a-f]+ l\.lwz r12,[0-9]+\(r12\)
|
|
+ +[0-9a-f]+: 19 80 00 00 l\.movhi r12,0x0
|
|
+ +[0-9a-f]+: 85 8c [0-9a-f]+ [0-9a-f]+ l\.lwz r12,[0-9]+\(r12\)
|
|
+ +[0-9a-f]+: 44 00 60 00 l\.jr r12
|
|
+ +[0-9a-f]+: a9 60 00 00 l\.ori r11,r0,0x0
|
|
+
|
|
+Disassembly of section \.text:
|
|
+
|
|
+[0-9a-f]+ <_start>:
|
|
+ +[0-9a-f]+: 9c 21 ff fc l\.addi r1,r1,-4
|
|
+ +[0-9a-f]+: d4 01 48 00 l\.sw 0\(r1\),r9
|
|
+ +[0-9a-f]+: 04 00 00 02 l\.jal [0-9a-f]+ <_start\+0x10>
|
|
+ +[0-9a-f]+: 1a 60 00 00 l\.movhi r19,0x0
|
|
+ +[0-9a-f]+: aa 73 [0-9a-f]+ [0-9a-f]+ l\.ori r19,r19,0x[0-9a-f]+
|
|
+ +[0-9a-f]+: e2 73 48 00 l\.add r19,r19,r9
|
|
+ +[0-9a-f]+: 1a 20 00 00 l\.movhi r17,0x0
|
|
+ +[0-9a-f]+: e2 31 98 00 l\.add r17,r17,r19
|
|
+ +[0-9a-f]+: 86 31 00 10 l\.lwz r17,16\(r17\)
|
|
+ +[0-9a-f]+: 84 71 00 00 l\.lwz r3,0\(r17\)
|
|
+ +[0-9a-f]+: 07 ff ff f2 l\.jal [0-9a-f]+ <\.plt\+0x10>
|
|
+ +[0-9a-f]+: 15 00 00 00 l\.nop 0x0
|
|
+ +[0-9a-f]+: 85 21 00 00 l\.lwz r9,0\(r1\)
|
|
+ +[0-9a-f]+: 44 00 48 00 l\.jr r9
|
|
+ +[0-9a-f]+: 9c 21 00 04 l\.addi r1,r1,4
|
|
diff --git a/ld/testsuite/ld-or1k/gotha1.s b/ld/testsuite/ld-or1k/gotha1.s
|
|
new file mode 100644
|
|
index 00000000000..42b16db425c
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-or1k/gotha1.s
|
|
@@ -0,0 +1,24 @@
|
|
+ .data
|
|
+ .p2align 16
|
|
+
|
|
+ .text
|
|
+ .globl _start
|
|
+_start:
|
|
+ l.addi r1, r1, -4
|
|
+ l.sw 0(r1), r9
|
|
+
|
|
+ l.jal 8
|
|
+ l.movhi r19, gotpchi(_GLOBAL_OFFSET_TABLE_-4)
|
|
+ l.ori r19, r19, gotpclo(_GLOBAL_OFFSET_TABLE_+0)
|
|
+ l.add r19, r19, r9
|
|
+
|
|
+ l.movhi r17, gotha(x)
|
|
+ l.add r17, r17, r19
|
|
+ l.lwz r17, got(x)(r17)
|
|
+ l.lwz r3, 0(r17)
|
|
+
|
|
+ l.jal plt(func)
|
|
+ l.nop
|
|
+ l.lwz r9, 0(r1)
|
|
+ l.jr r9
|
|
+ l.addi r1, r1, 4
|
|
diff --git a/ld/testsuite/ld-or1k/gotha2.dd b/ld/testsuite/ld-or1k/gotha2.dd
|
|
new file mode 100644
|
|
index 00000000000..fe09da5466b
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-or1k/gotha2.dd
|
|
@@ -0,0 +1,21 @@
|
|
+
|
|
+.*\.x: file format elf32-or1k
|
|
+
|
|
+
|
|
+Disassembly of section \.text:
|
|
+
|
|
+[0-9a-f]+ <test>:
|
|
+ +[0-9a-f]+: 9c 21 ff f8 l\.addi r1,r1,-8
|
|
+ +[0-9a-f]+: d4 01 80 00 l\.sw 0\(r1\),r16
|
|
+ +[0-9a-f]+: d4 01 48 04 l\.sw 4\(r1\),r9
|
|
+ +[0-9a-f]+: 04 00 [0-9a-f]+ [0-9a-f]+ l\.jal [0-9a-f]+ <test\+0x14>
|
|
+ +[0-9a-f]+: 1a 00 00 00 l\.movhi r16,0x0
|
|
+ +[0-9a-f]+: aa 10 [0-9a-f]+ [0-9a-f]+ l\.ori r16,r16,0x[0-9a-f]+
|
|
+ +[0-9a-f]+: e2 10 48 00 l\.add r16,r16,r9
|
|
+ +[0-9a-f]+: 1a 20 00 00 l\.movhi r17,0x0
|
|
+ +[0-9a-f]+: e2 31 80 00 l\.add r17,r17,r16
|
|
+ +[0-9a-f]+: 86 31 00 0c l\.lwz r17,12\(r17\)
|
|
+ +[0-9a-f]+: 85 21 00 04 l\.lwz r9,4\(r1\)
|
|
+ +[0-9a-f]+: 86 01 00 00 l\.lwz r16,0\(r1\)
|
|
+ +[0-9a-f]+: 44 00 48 00 l\.jr r9
|
|
+ +[0-9a-f]+: 9c 21 00 08 l\.addi r1,r1,8
|
|
diff --git a/ld/testsuite/ld-or1k/gotha2.s b/ld/testsuite/ld-or1k/gotha2.s
|
|
new file mode 100644
|
|
index 00000000000..164b282f2dd
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-or1k/gotha2.s
|
|
@@ -0,0 +1,22 @@
|
|
+ .section .text
|
|
+ .align 4
|
|
+ .global test
|
|
+ .type test, @function
|
|
+test:
|
|
+ l.addi r1, r1, -8
|
|
+ l.sw 0(r1), r16
|
|
+ l.sw 4(r1), r9
|
|
+
|
|
+ l.jal 8
|
|
+ l.movhi r16, gotpchi(_GLOBAL_OFFSET_TABLE_-4)
|
|
+ l.ori r16, r16, gotpclo(_GLOBAL_OFFSET_TABLE_+0)
|
|
+ l.add r16, r16, r9
|
|
+
|
|
+ l.movhi r17, gotha(i)
|
|
+ l.add r17, r17, r16
|
|
+ l.lwz r17, got(i)(r17)
|
|
+
|
|
+ l.lwz r9, 4(r1)
|
|
+ l.lwz r16, 0(r1)
|
|
+ l.jr r9
|
|
+ l.addi r1, r1, 8
|
|
diff --git a/ld/testsuite/ld-or1k/or1k.exp b/ld/testsuite/ld-or1k/or1k.exp
|
|
index 7592e8307c1..8e19ec6c31a 100644
|
|
--- a/ld/testsuite/ld-or1k/or1k.exp
|
|
+++ b/ld/testsuite/ld-or1k/or1k.exp
|
|
@@ -53,6 +53,14 @@ set or1kplttests {
|
|
"" {plt1.s}
|
|
{{objdump -dr plt1.x.dd}}
|
|
"plt1.x"}
|
|
+ {"gotha exec plt" "tmpdir/libpltlib.so" ""
|
|
+ "" {gotha1.s}
|
|
+ {{objdump -dr gotha1.dd}}
|
|
+ "gotha1.x"}
|
|
+ {"gotha -fpic -shared" "-fpic -shared" ""
|
|
+ "" {gotha2.s}
|
|
+ {{objdump -dr gotha2.dd}}
|
|
+ "gotha2.x"}
|
|
}
|
|
|
|
# Not implemented yet
|
|
diff --git a/ld/testsuite/ld-or1k/pltlib.s b/ld/testsuite/ld-or1k/pltlib.s
|
|
index baf76ca1af7..8b4d7ba48fd 100644
|
|
--- a/ld/testsuite/ld-or1k/pltlib.s
|
|
+++ b/ld/testsuite/ld-or1k/pltlib.s
|
|
@@ -1,5 +1,6 @@
|
|
.section .data
|
|
.globl x, y
|
|
+ .size x, 4
|
|
x: .long 33
|
|
y: .long 44
|
|
|
|
--
|
|
2.25.1
|
|
|