Update buildroot to 2021.02.4 (#1522)

Signed-off-by: Stefan Agner <stefan@agner.ch>
This commit is contained in:
Stefan Agner
2021-09-03 00:20:44 +02:00
committed by GitHub
parent 382a3cc7be
commit 82764e7822
334 changed files with 7541 additions and 1389 deletions

View File

@@ -1,35 +0,0 @@
From 1659226a96b1daecfd08c057d0d5c39309d207ee Mon Sep 17 00:00:00 2001
From: Giulio Benetti <giulio.benetti@benettiengineering.com>
Date: Mon, 22 Mar 2021 13:30:07 +0100
Subject: [PATCH] bfd/elf32-or1k: fix ld assert
Fixes https://sourceware.org/bugzilla/show_bug.cgi?id=27624
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
---
bfd/elf32-or1k.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 65938e5137..41908f8938 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -2566,11 +2566,10 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
if (h->type == STT_FUNC
|| h->needs_plt)
{
- if (! bfd_link_pic (info)
- && !h->def_dynamic
- && !h->ref_dynamic
- && h->root.type != bfd_link_hash_undefweak
- && h->root.type != bfd_link_hash_undefined)
+ if (h->plt.refcount <= 0
+ || (SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak)))
{
/* This case can occur if we saw a PLT reloc in an input
file, but the symbol was never referred to by a dynamic
--
2.25.1

View File

@@ -0,0 +1,59 @@
From 651c3617a04a1d1f78e89623b81be7ba32ff59a5 Mon Sep 17 00:00:00 2001
From: Stafford Horne <shorne@gmail.com>
Date: Sun, 2 May 2021 06:02:14 +0900
Subject: [PATCH] or1k: Fix issue with plt link failure for local calls
When building protobuf we were seeing the assert failure:
/home/giuliobenetti/git/upstream/or1k-binutils-2.36.1/host/lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld:
BFD (GNU Binutils) 2.36.1 assertion fail elf32-or1k.c:2377
/home/giuliobenetti/git/upstream/or1k-binutils-2.36.1/host/lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld:
BFD (GNU Binutils) 2.36.1 assertion fail elf32-or1k.c:2377
/home/giuliobenetti/git/upstream/or1k-binutils-2.36.1/host/lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld:
BFD (GNU Binutils) 2.36.1 assertion fail elf32-or1k.c:2377
collect2: error: ld returned 1 exit status
This failure happens while writing out PLT entries, there is a check
"BFD_ASSERT (h->dynindx != -1)" to confirm all plt entries have dynamic
symbol attributes. This was failing for symbols that were
"forced_local" in previous linking code.
The fix adds logic to or1k_elf_adjust_dynamic_symbol to identify
"forced_local" symbols and exclude them from the the PLT.
bfd/ChangeLog:
PR 27624
* elf32-or1k.c (or1k_elf_adjust_dynamic_symbol): Change
condition used to cleanup plt entries to cleanup forced local
entries.
Cc: Giulio Benetti <giulio.benetti@benettiengineering.com>
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
---
bfd/elf32-or1k.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 31ef758a926..58246875546 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -2535,11 +2535,10 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
if (h->type == STT_FUNC
|| h->needs_plt)
{
- if (! bfd_link_pic (info)
- && !h->def_dynamic
- && !h->ref_dynamic
- && h->root.type != bfd_link_hash_undefweak
- && h->root.type != bfd_link_hash_undefined)
+ if (h->plt.refcount <= 0
+ || (SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak)))
{
/* This case can occur if we saw a PLT reloc in an input
file, but the symbol was never referred to by a dynamic
--
2.25.1

View File

@@ -0,0 +1,256 @@
From 5fb945116ba058eb8f032f94ab2e0c71024388ec Mon Sep 17 00:00:00 2001
From: Stafford Horne <shorne@gmail.com>
Date: Sun, 2 May 2021 06:02:15 +0900
Subject: [PATCH] or1k: Implement relocation R_OR1K_GOT_AHI16 for gotha()
The gotha() relocation mnemonic will be outputted by OpenRISC GCC when
using the -mcmodel=large option. This relocation is used along with
got() to generate 32-bit GOT offsets. This increases the previous GOT
offset limit from the previous 16-bit (64K) limit.
This is needed on large binaries where the GOT grows larger than 64k.
bfd/ChangeLog:
PR 21464
* bfd-in2.h: Add BFD_RELOC_OR1K_GOT_AHI16 relocation.
* elf32-or1k.c (or1k_elf_howto_table, or1k_reloc_map): Likewise.
(or1k_final_link_relocate, or1k_elf_relocate_section,
or1k_elf_check_relocs): Likewise.
* libbfd.h (bfd_reloc_code_real_names): Likewise.
* reloc.c: Likewise.
cpu/ChangeLog:
PR 21464
* or1k.opc (or1k_imm16_relocs, parse_reloc): Define parse logic
for gotha() relocation.
include/ChangeLog:
PR 21464
* elf/or1k.h (elf_or1k_reloc_type): Define R_OR1K_GOT_AHI16 number.
opcodes/ChangeLog:
PR 21464
* or1k-asm.c: Regenerate.
gas/ChangeLog:
PR 21464
* testsuite/gas/or1k/reloc-1.s: Add test for new relocation.
* testsuite/gas/or1k/reloc-1.d: Add test result for new
relocation.
Cc: Giulio Benetti <giulio.benetti@benettiengineering.com>
fixup reloc, add tests
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
---
bfd/bfd-in2.h | 1 +
bfd/elf32-or1k.c | 21 ++++++++++++++++++++-
bfd/libbfd.h | 1 +
bfd/reloc.c | 2 ++
cpu/or1k.opc | 7 ++++++-
gas/testsuite/gas/or1k/reloc-1.d | 4 +++-
gas/testsuite/gas/or1k/reloc-1.s | 4 ++++
include/elf/or1k.h | 1 +
opcodes/or1k-asm.c | 7 ++++++-
9 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 7c13bc8c91a..ae1082a67c2 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5017,6 +5017,7 @@ then it may be truncated to 8 bits. */
BFD_RELOC_OR1K_TLS_TPOFF,
BFD_RELOC_OR1K_TLS_DTPOFF,
BFD_RELOC_OR1K_TLS_DTPMOD,
+ BFD_RELOC_OR1K_GOT_AHI16,
/* H8 elf Relocations. */
BFD_RELOC_H8_DIR16A8,
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 58246875546..1273fbacb3c 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -808,6 +808,20 @@ static reloc_howto_type or1k_elf_howto_table[] =
0, /* Source Mask. */
0x03ffffff, /* Dest Mask. */
TRUE), /* PC relative offset? */
+
+ HOWTO (R_OR1K_GOT_AHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_GOT_AHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
};
/* Map BFD reloc types to Or1k ELF reloc types. */
@@ -871,6 +885,7 @@ static const struct or1k_reloc_map or1k_reloc_map[] =
{ BFD_RELOC_OR1K_TLS_IE_LO13, R_OR1K_TLS_IE_LO13 },
{ BFD_RELOC_OR1K_SLO13, R_OR1K_SLO13 },
{ BFD_RELOC_OR1K_PLTA26, R_OR1K_PLTA26 },
+ { BFD_RELOC_OR1K_GOT_AHI16, R_OR1K_GOT_AHI16 },
};
#define TLS_UNKNOWN 0
@@ -1080,6 +1095,7 @@ or1k_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
switch (howto->type)
{
case R_OR1K_AHI16:
+ case R_OR1K_GOT_AHI16:
case R_OR1K_GOTOFF_AHI16:
case R_OR1K_TLS_IE_AHI16:
case R_OR1K_TLS_LE_AHI16:
@@ -1344,6 +1360,7 @@ or1k_elf_relocate_section (bfd *output_bfd,
}
break;
+ case R_OR1K_GOT_AHI16:
case R_OR1K_GOT16:
case R_OR1K_GOT_PG21:
case R_OR1K_GOT_LO13:
@@ -1435,7 +1452,8 @@ or1k_elf_relocate_section (bfd *output_bfd,
/* The GOT_PG21 and GOT_LO13 relocs are pc-relative,
while the GOT16 reloc is GOT relative. */
relocation = got_base + off;
- if (r_type == R_OR1K_GOT16)
+ if (r_type == R_OR1K_GOT16
+ || r_type == R_OR1K_GOT_AHI16)
relocation -= got_sym_value;
/* Addend should be zero. */
@@ -1943,6 +1961,7 @@ or1k_elf_check_relocs (bfd *abfd,
}
break;
+ case R_OR1K_GOT_AHI16:
case R_OR1K_GOT16:
case R_OR1K_GOT_PG21:
case R_OR1K_GOT_LO13:
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index d97d4e57a77..9edc71e0558 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2704,6 +2704,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_OR1K_TLS_TPOFF",
"BFD_RELOC_OR1K_TLS_DTPOFF",
"BFD_RELOC_OR1K_TLS_DTPMOD",
+ "BFD_RELOC_OR1K_GOT_AHI16",
"BFD_RELOC_H8_DIR16A8",
"BFD_RELOC_H8_DIR16R8",
"BFD_RELOC_H8_DIR24A8",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 33cd67150cf..f57ad14a501 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -6175,6 +6175,8 @@ ENUMX
BFD_RELOC_OR1K_GOTPC_HI16
ENUMX
BFD_RELOC_OR1K_GOTPC_LO16
+ENUMX
+ BFD_RELOC_OR1K_GOT_AHI16
ENUMX
BFD_RELOC_OR1K_GOT16
ENUMX
diff --git a/cpu/or1k.opc b/cpu/or1k.opc
index f0adcbb00a5..5d20a1f33a7 100644
--- a/cpu/or1k.opc
+++ b/cpu/or1k.opc
@@ -193,7 +193,7 @@ static const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = {
BFD_RELOC_OR1K_GOT_LO13,
BFD_RELOC_UNUSED,
BFD_RELOC_UNUSED,
- BFD_RELOC_UNUSED },
+ BFD_RELOC_OR1K_GOT_AHI16 },
{ BFD_RELOC_OR1K_GOTPC_LO16,
BFD_RELOC_UNUSED,
BFD_RELOC_UNUSED,
@@ -296,6 +296,11 @@ parse_reloc (const char **strp)
str += 5;
cls = RCLASS_TPOFF;
}
+ else if (strncasecmp (str, "got", 3) == 0)
+ {
+ str += 3;
+ cls = RCLASS_GOT;
+ }
if (strncasecmp (str, "hi(", 3) == 0)
{
diff --git a/gas/testsuite/gas/or1k/reloc-1.d b/gas/testsuite/gas/or1k/reloc-1.d
index d1bcf5608bb..3a001c4ed99 100644
--- a/gas/testsuite/gas/or1k/reloc-1.d
+++ b/gas/testsuite/gas/or1k/reloc-1.d
@@ -68,5 +68,7 @@ OFFSET TYPE VALUE
000000ec R_OR1K_LO13 x
000000f0 R_OR1K_GOT_LO13 x
000000f4 R_OR1K_SLO13 x
-
+000000f8 R_OR1K_GOT_AHI16 x
+000000fc R_OR1K_GOT_AHI16 x
+00000100 R_OR1K_GOT_AHI16 x
diff --git a/gas/testsuite/gas/or1k/reloc-1.s b/gas/testsuite/gas/or1k/reloc-1.s
index e76abef6532..562609aa869 100644
--- a/gas/testsuite/gas/or1k/reloc-1.s
+++ b/gas/testsuite/gas/or1k/reloc-1.s
@@ -74,3 +74,7 @@
l.lbz r5,po(x)(r3)
l.lbz r5,gotpo(x)(r3)
l.sb po(x)(r3),r6
+
+ l.movhi r4,gotha(x)
+ l.ori r3,r4,gotha(x)
+ l.addi r3,r4,gotha(x)
diff --git a/include/elf/or1k.h b/include/elf/or1k.h
index a215ef5c17e..dff37d875f2 100644
--- a/include/elf/or1k.h
+++ b/include/elf/or1k.h
@@ -77,6 +77,7 @@ START_RELOC_NUMBERS (elf_or1k_reloc_type)
RELOC_NUMBER (R_OR1K_TLS_IE_LO13, 51)
RELOC_NUMBER (R_OR1K_SLO13, 52)
RELOC_NUMBER (R_OR1K_PLTA26, 53)
+ RELOC_NUMBER (R_OR1K_GOT_AHI16, 54)
END_RELOC_NUMBERS (R_OR1K_max)
#define EF_OR1K_NODELAY (1UL << 0)
diff --git a/opcodes/or1k-asm.c b/opcodes/or1k-asm.c
index 4715c4f2826..a72a4e85363 100644
--- a/opcodes/or1k-asm.c
+++ b/opcodes/or1k-asm.c
@@ -177,7 +177,7 @@ static const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = {
BFD_RELOC_OR1K_GOT_LO13,
BFD_RELOC_UNUSED,
BFD_RELOC_UNUSED,
- BFD_RELOC_UNUSED },
+ BFD_RELOC_OR1K_GOT_AHI16 },
{ BFD_RELOC_OR1K_GOTPC_LO16,
BFD_RELOC_UNUSED,
BFD_RELOC_UNUSED,
@@ -280,6 +280,11 @@ parse_reloc (const char **strp)
str += 5;
cls = RCLASS_TPOFF;
}
+ else if (strncasecmp (str, "got", 3) == 0)
+ {
+ str += 3;
+ cls = RCLASS_GOT;
+ }
if (strncasecmp (str, "hi(", 3) == 0)
{
--
2.25.1

View File

@@ -0,0 +1,61 @@
From d92116c7df340ff40063c5c97d202e7e87400027 Mon Sep 17 00:00:00 2001
From: Stafford Horne <shorne@gmail.com>
Date: Sun, 2 May 2021 06:02:16 +0900
Subject: [PATCH] or1k: Avoid R_OR1K_GOT16 overflow failures in presence of
R_OR1K_GOT_AHI16
Now that we support R_OR1K_GOT_AHI16 we can relax the R_OR1K_GOT16
overflow validation check if the section has R_OR1K_GOT_AHI16.
We cannot simple disable R_OR1K_GOT16 overflow validation as there will
still be binaries that will have only R_OR1K_GOT16. The
R_OR1K_GOT_AHI16 relocation will only be added by GCC when building with
the option -mcmodel=large.
This assumes that R_OR1K_GOT_AHI16 will come before R_OR1K_GOT16, which
is the code pattern that will be emitted by GCC.
bfd/ChangeLog:
PR 21464
* elf32-or1k.c (or1k_elf_relocate_section): Relax R_OR1K_GOT16
overflow check if we have R_OR1K_GOT_AHI16 followed by
R_OR1K_GOT16.
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
---
bfd/elf32-or1k.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 1273fbacb3c..ce2c4fdb3bd 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -1248,6 +1248,7 @@ or1k_elf_relocate_section (bfd *output_bfd,
asection *sgot, *splt;
bfd_vma plt_base, got_base, got_sym_value;
bfd_boolean ret_val = TRUE;
+ bfd_boolean saw_gotha = FALSE;
if (htab == NULL)
return FALSE;
@@ -1456,6 +1457,16 @@ or1k_elf_relocate_section (bfd *output_bfd,
|| r_type == R_OR1K_GOT_AHI16)
relocation -= got_sym_value;
+ if (r_type == R_OR1K_GOT_AHI16)
+ saw_gotha = TRUE;
+
+ /* If we have a R_OR1K_GOT16 followed by a R_OR1K_GOT_AHI16
+ relocation we assume the code is doing the right thing to avoid
+ overflows. Here we mask the lower 16-bit of the relocation to
+ avoid overflow validation failures. */
+ if (r_type == R_OR1K_GOT16 && saw_gotha)
+ relocation &= 0xffff;
+
/* Addend should be zero. */
if (rel->r_addend != 0)
{
--
2.25.1

View File

@@ -0,0 +1,500 @@
From cba29e387040eaa401c52eb20e7cab5a4401185c 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 ce2c4fdb3bd..8b021b79d92 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
@@ -903,6 +907,8 @@ struct elf_or1k_link_hash_entry
/* Track dynamic relocs copied for this symbol. */
struct elf_dyn_relocs *dyn_relocs;
+ /* For calculating PLT size. */
+ bfd_vma plt_index;
/* Track type of TLS access. */
unsigned char tls_type;
};
@@ -930,9 +936,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)) \
@@ -2173,33 +2190,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. */
@@ -2266,7 +2296,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
@@ -2277,27 +2308,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;
}
@@ -2340,7 +2371,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;
@@ -2352,6 +2384,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. */
@@ -2369,10 +2402,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. */
@@ -2384,27 +2420,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
@@ -2699,11 +2765,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
{
asection *s = 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 (s->size == 0)
- s->size = PLT_ENTRY_SIZE;
+ s->size = elf_or1k_plt_entry_size (plt_index);
h->plt.offset = s->size;
@@ -2720,7 +2791,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
}
/* Make room for this entry. */
- s->size += PLT_ENTRY_SIZE;
+ s->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

View File

@@ -0,0 +1,50 @@
From c3003947e4bad18faea4337fd2073feeb30ee078 Mon Sep 17 00:00:00 2001
From: Giulio Benetti <giulio.benetti@benettiengineering.com>
Date: Wed, 9 Jun 2021 17:28:27 +0200
Subject: [PATCH] bfd/elf32-or1k: fix building with gcc version < 5
Gcc version >= 5 has standard C mode not set to -std=gnu11, so if we use
an old compiler(i.e. gcc 4.9) build fails on:
```
elf32-or1k.c:2251:3: error: 'for' loop initial declarations are only allowed in
C99 or C11 mode
for (size_t i = 0; i < insn_count; i++)
^
```
So let's declare `size_t i` at the top of the function instead of inside
for loop.
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
---
bfd/elf32-or1k.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 4ae7f324d33..32063ab0289 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -2244,9 +2244,10 @@ or1k_write_plt_entry (bfd *output_bfd, bfd_byte *contents, unsigned insnj,
{
unsigned nodelay = elf_elfheader (output_bfd)->e_flags & EF_OR1K_NODELAY;
unsigned output_insns[PLT_MAX_INSN_COUNT];
+ size_t i;
/* Copy instructions into the output buffer. */
- for (size_t i = 0; i < insn_count; i++)
+ for (i = 0; i < insn_count; i++)
output_insns[i] = insns[i];
/* Honor the no-delay-slot setting. */
@@ -2277,7 +2278,7 @@ or1k_write_plt_entry (bfd *output_bfd, bfd_byte *contents, unsigned insnj,
}
/* Write out the output buffer. */
- for (size_t i = 0; i < (insn_count+1); i++)
+ for (i = 0; i < (insn_count+1); i++)
bfd_put_32 (output_bfd, output_insns[i], contents + (i*4));
}
--
2.25.1

View File

@@ -0,0 +1,59 @@
From 9af93e143a7fbdb75aa1ed37277f9250eb111628 Mon Sep 17 00:00:00 2001
From: Giulio Benetti <giulio.benetti@benettiengineering.com>
Date: Sat, 10 Jul 2021 17:57:34 +0200
Subject: [PATCH] or1k: fix pc-relative relocation against dynamic on PC
relative 26 bit relocation
When building openal we were seeing the assert failure:
/home/buildroot/autobuild/run/instance-0/output-1/host/opt/ext-toolchain/bin/../lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld: CMakeFiles/OpenAL.dir/al/source.cpp.o:
pc-relative relocation against dynamic symbol alSourcePausev
/home/buildroot/autobuild/run/instance-0/output-1/host/opt/ext-toolchain/bin/../lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld: CMakeFiles/OpenAL.dir/al/source.cpp.o:
pc-relative relocation against dynamic symbol alSourceStopv
/home/buildroot/autobuild/run/instance-0/output-1/host/opt/ext-toolchain/bin/../lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld: CMakeFiles/OpenAL.dir/al/source.cpp.o:
pc-relative relocation against dynamic symbol alSourceRewindv
/home/buildroot/autobuild/run/instance-0/output-1/host/opt/ext-toolchain/bin/../lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld: CMakeFiles/OpenAL.dir/al/source.cpp.o:
pc-relative relocation against dynamic symbol alSourcePlayv
collect2: error: ld returned 1 exit status
This happens because in R_OR1K_INSN_REL_26 case we can't reference local
symbol as previously done but we need to make sure that calls to actual
symbol always call the version of current object.
bfd/Changelog:
* elf32-or1k.c (or1k_elf_relocate_section): use a separate entry
in switch case R_OR1K_INSN_REL_26 where we need to check for
!SYMBOL_CALLS_LOCAL() instead of !SYMBOL_REFERENCES_LOCAL().
Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
---
bfd/elf32-or1k.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 4ae7f324d33..4f9092539f5 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -1543,6 +1543,18 @@ or1k_elf_relocate_section (bfd *output_bfd,
break;
case R_OR1K_INSN_REL_26:
+ /* For a non-shared link, these will reference plt or call the
+ version of actual object. */
+ if (bfd_link_pic (info) && !SYMBOL_CALLS_LOCAL (info, h))
+ {
+ _bfd_error_handler
+ (_("%pB: pc-relative relocation against dynamic symbol %s"),
+ input_bfd, name);
+ ret_val = FALSE;
+ bfd_set_error (bfd_error_bad_value);
+ }
+ break;
+
case R_OR1K_PCREL_PG21:
case R_OR1K_LO13:
case R_OR1K_SLO13:
--
2.25.1