mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2025-01-15 09:19:59 +00:00
2160d68291
While building statically-linked executables for ARC on 32-bit platform
LD segfaulted like that:
--------------------------->8-------------------------
$ gcc test.c -static
potentially unexpected fatal signal 11.
Path: /arc_gnu_2021.03_prebuilt_glibc_le_archs_native_install/arc-snps-linux-gnu/bin/ld
CPU: 0 PID: 79 Comm: ld Not tainted 5.10.43 #8
Invalid Read @ 0x00000020 by insn @ 0x40bbe
@off 0x40bbe in [/arc_gnu_2021.03_prebuilt_glibc_le_archs_native_install/arc-snps-linux-gnu/bin/ld] VMA: 0x00010000 to 0x0010e000
ECR: 0x00050100 EFA: 0x00000020 ERET: 0x00040bbe
STAT: 0x80080082 [IE U ] BTA: 0x0003fc24
SP: 0x5fdb8dec FP: 0x00129598 BLK: 0x40b66
LPS: 0x2008c602 LPE: 0x2008c63e LPC: 0x00000001
r00: 0x008392f2 r01: 0x00000001 r02: 0x00000000
r03: 0x008392f2 r04: 0x00000058 r05: 0x00e37e88
r06: 0x00eb8ea8 r07: 0x00a837e8 r08: 0x0000003f
r09: 0x736e7520 r10: 0x2011aa74 r11: 0x001147f4
r12: 0x00a83834 r13: 0x00a837e8 r14: 0x00ce92b8
r15: 0x00112130 r16: 0x00eb8ea8 r17: 0x00000058
r18: 0x001273b8 r19: 0x00e37e88 r20: 0x00129598
r21: 0x5fdb8e74 r22: 0x00112130 r23: 0x00179bb0
r24: 0x00170684 r25: 0x20122490
collect2: fatal error: ld terminated with signal 11 [Segmentation fault]
compilation terminated.
--------------------------->8-------------------------
Originally found during native building on ARC board, but later
re-produced on other 32-bit systems like i386/i586.
For all the gory details please refer to [1].
Original fix could be found here [2].
[1] https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/issues/402
[2] 29d31b4ed9
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
218 lines
6.1 KiB
Diff
218 lines
6.1 KiB
Diff
From 29d31b4ed96fcbc774740fac91ef77cb3d62a714 Mon Sep 17 00:00:00 2001
|
|
From: Claudiu Zissulescu <claziss@synopsys.com>
|
|
Date: Tue, 17 Aug 2021 13:44:17 +0300
|
|
Subject: [PATCH] arc: Fix potential invalid pointer access when fixing got
|
|
symbols.
|
|
|
|
When statically linking, it can arrive to an undefined weak symbol of
|
|
which its value cannot be determined. However, we are having pieces of
|
|
code which doesn't take this situation into account, leading to access
|
|
a structure which may not be initialized. Fix this situation and add a
|
|
test.
|
|
|
|
bfd/
|
|
xxxx-xx-xx Cupertino Miranda <cmiranda@synopsys.com>
|
|
Claudiu Zissulescu <claziss@synopsys.com>
|
|
|
|
* arc-got.h (arc_static_sym_data): New structure.
|
|
(get_static_sym_data): New function.
|
|
(relocate_fix_got_relocs_for_got_info): Move the computation fo
|
|
symbol value and section to above introduced function, and use
|
|
this new function.
|
|
|
|
ld/testsuite/
|
|
xxxx-xx-xx Claudiu Zissulescu <claziss@synopsys.com>
|
|
|
|
* ld-arc/got-weak.d: New file.
|
|
* ld-arc/got-weak.s: Likewise.
|
|
|
|
For all the gory details please refer to [1].
|
|
Original fix could be found here [2].
|
|
|
|
[1] https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/issues/402
|
|
[2] https://github.com/foss-for-synopsys-dwc-arc-processors/binutils-gdb/commit/29d31b4ed96fcbc774740fac91ef77cb3d62a714
|
|
|
|
Signed-off-by: Claudiu Zissulescu <claziss@synopsys.com>
|
|
[Added links to the origins]
|
|
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
|
|
---
|
|
bfd/arc-got.h | 94 ++++++++++++++++++++++++-----------------
|
|
ld/testsuite/ld-arc/got-weak.d | 12 +++++
|
|
ld/testsuite/ld-arc/got-weak.s | 7 +++
|
|
3 files changed, 76 insertions(+), 37 deletions(-)
|
|
create mode 100644 ld/testsuite/ld-arc/got-weak.d
|
|
create mode 100644 ld/testsuite/ld-arc/got-weak.s
|
|
|
|
--- a/bfd/arc-got.h
|
|
+++ b/bfd/arc-got.h
|
|
@@ -262,6 +262,48 @@
|
|
return true;
|
|
}
|
|
|
|
+struct arc_static_sym_data {
|
|
+ bfd_vma sym_value;
|
|
+ const char *symbol_name;
|
|
+};
|
|
+
|
|
+static struct arc_static_sym_data
|
|
+get_static_sym_data (unsigned long r_symndx,
|
|
+ Elf_Internal_Sym *local_syms,
|
|
+ asection **local_sections,
|
|
+ struct elf_link_hash_entry *h,
|
|
+ struct arc_relocation_data *reloc_data)
|
|
+{
|
|
+ static const char local_name[] = "(local)";
|
|
+ struct arc_static_sym_data ret = { 0, NULL };
|
|
+
|
|
+ if (h != NULL)
|
|
+ {
|
|
+ BFD_ASSERT (h->root.type != bfd_link_hash_undefweak
|
|
+ && h->root.type != bfd_link_hash_undefined);
|
|
+ /* TODO: This should not be here. */
|
|
+ reloc_data->sym_value = h->root.u.def.value;
|
|
+ reloc_data->sym_section = h->root.u.def.section;
|
|
+
|
|
+ ret.sym_value = h->root.u.def.value
|
|
+ + h->root.u.def.section->output_section->vma
|
|
+ + h->root.u.def.section->output_offset;
|
|
+
|
|
+ ret.symbol_name = h->root.root.string;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ Elf_Internal_Sym *sym = local_syms + r_symndx;
|
|
+ asection *sec = local_sections[r_symndx];
|
|
+
|
|
+ ret.sym_value = sym->st_value
|
|
+ + sec->output_section->vma
|
|
+ + sec->output_offset;
|
|
+
|
|
+ ret.symbol_name = local_name;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
|
|
static bfd_vma
|
|
relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p,
|
|
@@ -290,38 +332,7 @@
|
|
&& SYMBOL_REFERENCES_LOCAL (info, h))))
|
|
{
|
|
const char ATTRIBUTE_UNUSED *symbol_name;
|
|
- static const char local_name[] = "(local)";
|
|
- asection *tls_sec = NULL;
|
|
- bfd_vma sym_value = 0;
|
|
-
|
|
- if (h != NULL)
|
|
- {
|
|
- /* TODO: This should not be here. */
|
|
- reloc_data->sym_value = h->root.u.def.value;
|
|
- reloc_data->sym_section = h->root.u.def.section;
|
|
-
|
|
- sym_value = h->root.u.def.value
|
|
- + h->root.u.def.section->output_section->vma
|
|
- + h->root.u.def.section->output_offset;
|
|
-
|
|
- tls_sec = elf_hash_table (info)->tls_sec;
|
|
-
|
|
- symbol_name = h->root.root.string;
|
|
- }
|
|
- else
|
|
- {
|
|
- Elf_Internal_Sym *sym = local_syms + r_symndx;
|
|
- asection *sec = local_sections[r_symndx];
|
|
-
|
|
- sym_value = sym->st_value
|
|
- + sec->output_section->vma
|
|
- + sec->output_offset;
|
|
-
|
|
- tls_sec = elf_hash_table (info)->tls_sec;
|
|
-
|
|
- symbol_name = local_name;
|
|
- }
|
|
-
|
|
+ asection *tls_sec = elf_hash_table (info)->tls_sec;
|
|
|
|
if (entry && !entry->processed)
|
|
{
|
|
@@ -335,8 +346,12 @@
|
|
if (h == NULL || h->forced_local
|
|
|| !elf_hash_table (info)->dynamic_sections_created)
|
|
{
|
|
+ struct arc_static_sym_data tmp =
|
|
+ get_static_sym_data (r_symndx, local_syms, local_sections,
|
|
+ h, reloc_data);
|
|
+
|
|
bfd_put_32 (output_bfd,
|
|
- sym_value - sec_vma
|
|
+ tmp.sym_value - sec_vma
|
|
+ (elf_hash_table (info)->dynamic_sections_created
|
|
? 0
|
|
: (align_power (0,
|
|
@@ -355,7 +370,7 @@
|
|
+ entry->offset
|
|
+ (entry->existing_entries == TLS_GOT_MOD_AND_OFF
|
|
? 4 : 0)),
|
|
- symbol_name);
|
|
+ tmp.symbol_name);
|
|
}
|
|
}
|
|
break;
|
|
@@ -366,8 +381,12 @@
|
|
bfd_vma ATTRIBUTE_UNUSED sec_vma
|
|
= tls_sec->output_section->vma;
|
|
|
|
+ struct arc_static_sym_data tmp =
|
|
+ get_static_sym_data (r_symndx, local_syms, local_sections,
|
|
+ h, reloc_data);
|
|
+
|
|
bfd_put_32 (output_bfd,
|
|
- sym_value - sec_vma
|
|
+ tmp.sym_value - sec_vma
|
|
+ (elf_hash_table (info)->dynamic_sections_created
|
|
? 0
|
|
: (align_power (TCB_SIZE,
|
|
@@ -386,7 +405,7 @@
|
|
+ entry->offset
|
|
+ (entry->existing_entries == TLS_GOT_MOD_AND_OFF
|
|
? 4 : 0)),
|
|
- symbol_name);
|
|
+ tmp.symbol_name);
|
|
}
|
|
break;
|
|
|
|
@@ -415,7 +434,8 @@
|
|
"@ %#08lx for sym %s in got offset %#lx\n",
|
|
(long) (reloc_data->sym_value + sec_vma),
|
|
(long) (htab->sgot->output_section->vma
|
|
- + htab->sgot->output_offset + entry->offset),
|
|
+ + htab->sgot->output_offset
|
|
+ + entry->offset),
|
|
symbol_name,
|
|
(long) entry->offset);
|
|
}
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-arc/got-weak.d
|
|
@@ -0,0 +1,12 @@
|
|
+#source: got-weak.s
|
|
+#as:
|
|
+#ld: -Bstatic
|
|
+#objdump: -d
|
|
+
|
|
+[^:]*: file format elf32-.*arc
|
|
+
|
|
+
|
|
+Disassembly of section \.text:
|
|
+
|
|
+00000100 <.*>:
|
|
+ 100: 2730 7f80 0000 2014 ld r0,\[pcl,0x2014\].*
|
|
--- /dev/null
|
|
+++ b/ld/testsuite/ld-arc/got-weak.s
|
|
@@ -0,0 +1,7 @@
|
|
+ .cpu archs
|
|
+
|
|
+ .weak symb
|
|
+ .global __start
|
|
+ .text
|
|
+__start:
|
|
+ ld r0,[pcl,@symb@gotpc]
|