diff --git a/packages/binutils/2.37/0009-arc-Fix-potential-invalid-pointer-access-when-fixing.patch b/packages/binutils/2.37/0009-arc-Fix-potential-invalid-pointer-access-when-fixing.patch new file mode 100644 index 00000000..ade3180b --- /dev/null +++ b/packages/binutils/2.37/0009-arc-Fix-potential-invalid-pointer-access-when-fixing.patch @@ -0,0 +1,217 @@ +From 29d31b4ed96fcbc774740fac91ef77cb3d62a714 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +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 + Claudiu Zissulescu + + * 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 + + * 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 +[Added links to the origins] +Signed-off-by: Alexey Brodkin +--- + 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]