From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1957) id C506C3858C2D; Mon, 25 Sep 2023 08:35:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C506C3858C2D Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Claudiu Zissulescu To: bfd-cvs@sourceware.org Subject: [binutils-gdb] arc: Add new ARCv3 ISA to BFD. X-Act-Checkin: binutils-gdb X-Git-Author: Claudiu Zissulescu X-Git-Refname: refs/heads/master X-Git-Oldrev: 6e467e9a94c1135bd11d985e9263d43204a9258b X-Git-Newrev: 06e8d9861d16c5b7e6920ad0e89889ccf45c575a Message-Id: <20230925083538.C506C3858C2D@sourceware.org> Date: Mon, 25 Sep 2023 08:35:38 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Sep 2023 08:35:39 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D06e8d9861d16= c5b7e6920ad0e89889ccf45c575a commit 06e8d9861d16c5b7e6920ad0e89889ccf45c575a Author: Claudiu Zissulescu Date: Mon Sep 25 10:55:51 2023 +0300 arc: Add new ARCv3 ISA to BFD. =20 The new Synopsys's ARCv3 ISA is capable to run either 64-bit or 32-bit ISA. The new 32-bit ISA is not compatible with the old Synopsys ARCv1/ARCv2 ISA, however, it retains a lot of common concepts. Thus, this patch is reusing the old ARC BFD backend and adds the necessary bits for the new architecture in a similar way as it is done for RISCV backend. =20 bfd/ xxxx-xx-xx Claudiu Zissulescu Cupertino Miranda =20 * bfd/Makefile.am: Add ARC64 files. * bfd/Makefile.in: Regerate. * bfd/arc-got.h (TCB_SIZE): Depends on the target architecture. (GOT_ENTRY_SIZE): New define. (write_in_got): Likewise. (read_from_got): Likewise. (align_power): Likewise. (arc_got_entry_type_for_reloc): Use RELA_SIZE and GOT_ENTRY_SIZ= E. (arc_fill_got_info_for_reloc): Update formating. (relocate_fix_got_relocs_for_got_info): Likewise. (arc_static_sym_data): Deleted structure. (get_static_sym_data): Deleted function. (relocate_fix_got_relocs_for_got_info): Use symbol static data. (create_got_dynrelocs_for_single_entry): Update formating. (create_got_dynrelocs_for_got_info): Likewise. * bfd/arc-plt.c: New file. * bfd/arc-plt.def: Add ARC64 PLT entry. * bfd/arc-plt.h: Clean it up, move functionality to arc-plt.c f= ile. * bfd/archures.c: Add ARC64 target. * bfd/config.bfd: Likewise. * bfd/configure.ac: Likewise. * bfd/bfd-in2.h: Regenerate. * bfd/configure: Likewise. * bfd/libbfd.h: Likewise. * bfd/cpu-arc.c: Clean it up. * bfd/cpu-arc64.c: New file. * bfd/elf32-arc.c: Renamed to elfnn-arc.c. * bfd/elfnn-arc.c: New file. * bfd/reloc.c: Add new ARC64 relocs. * bfd/targets.c: Add ARC64 target. =20 Signed-off-by: Claudiu Zissulescu Diff: --- bfd/Makefile.am | 23 +- bfd/Makefile.in | 27 +- bfd/arc-got.h | 251 +++---- bfd/arc-plt.c | 121 ++++ bfd/arc-plt.def | 127 +++- bfd/arc-plt.h | 93 +-- bfd/archures.c | 5 + bfd/bfd-in2.h | 25 + bfd/config.bfd | 20 +- bfd/configure | 6 +- bfd/configure.ac | 6 +- bfd/cpu-arc.c | 79 +- bfd/cpu-arc64.c | 75 ++ bfd/{elf32-arc.c =3D> elfnn-arc.c} | 1486 +++++++++++++++++++++++++-------= ------ bfd/libbfd.h | 22 + bfd/reloc.c | 44 ++ bfd/targets.c | 6 + 17 files changed, 1592 insertions(+), 824 deletions(-) diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 378c13198d6..d8b1cdfeb19 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -99,6 +99,7 @@ ALL_MACHINES =3D \ cpu-alpha.lo \ cpu-amdgcn.lo \ cpu-arc.lo \ + cpu-arc64.lo \ cpu-arm.lo \ cpu-avr.lo \ cpu-bfin.lo \ @@ -183,6 +184,7 @@ ALL_MACHINES_CFILES =3D \ cpu-alpha.c \ cpu-amdgcn.c \ cpu-arc.c \ + cpu-arc64.c \ cpu-arm.c \ cpu-avr.c \ cpu-bfin.c \ @@ -265,6 +267,7 @@ ALL_MACHINES_CFILES =3D \ # The .o files needed by all of the 32 bit vectors that are configured into # target_vector in targets.c if configured with --enable-targets=3Dall. BFD32_BACKENDS =3D \ + arc-plt.lo \ aout-cris.lo \ aout-ns32k.lo \ aout32.lo \ @@ -400,6 +403,7 @@ BFD32_BACKENDS =3D \ xtensa-modules.lo =20 BFD32_BACKENDS_CFILES =3D \ + arc-plt.c \ aout-cris.c \ aout-ns32k.c \ aout32.c \ @@ -432,7 +436,6 @@ BFD32_BACKENDS_CFILES =3D \ elf-vxworks.c \ elf.c \ elf32-am33lin.c \ - elf32-arc.c \ elf32-arm.c \ elf32-avr.c \ elf32-bfin.c \ @@ -545,6 +548,7 @@ BFD64_BACKENDS =3D \ coff-x86_64.lo \ coff64-rs6000.lo \ elf32-aarch64.lo \ + elf32-arc64.lo \ elf32-ia64.lo \ elf32-kvx.lo \ elf32-loongarch.lo \ @@ -553,6 +557,7 @@ BFD64_BACKENDS =3D \ elf32-score.lo \ elf32-score7.lo \ elf64-aarch64.lo \ + elf64-arc64.lo \ elf64-alpha.lo \ elf64-amdgcn.lo \ elf64-bpf.lo \ @@ -687,6 +692,7 @@ SOURCE_CFILES =3D \ =20 BUILD_CFILES =3D \ elf32-aarch64.c elf64-aarch64.c \ + elf32-arc.c elf64-arc64.c elf32-arc64.c\ elf32-kvx.c elf64-kvx.c \ elf32-ia64.c elf64-ia64.c \ elf32-loongarch.c elf64-loongarch.c \ @@ -849,6 +855,21 @@ elf64-aarch64.c : elfnn-aarch64.c $(AM_V_at)echo "#line 1 \"$<\"" > $@ $(AM_V_GEN)$(SED) -e s/NN/64/g < $< >> $@ =20 +elf32-arc.c : elfnn-arc.c + rm -f elf32-arc.c + $(AM_V_at)echo "#line 1 \"$(srcdir)/elfnn-arc.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/NN/32/g -e s/AA//g < $< >> $@ + +elf64-arc64.c : elfnn-arc.c + rm -f elf64-arc64.c + $(AM_V_at)echo "#line 1 \"$(srcdir)/elfnn-arc.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/NN/64/g -e s/AA/64/g < $< >> $@ + +elf32-arc64.c : elfnn-arc.c + rm -f elf32-arc64.c + $(AM_V_at)echo "#line 1 \"$(srcdir)/elfnn-arc.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/NN/32/g -e s/AA/64/g < $< >> $@ + elf32-ia64.c : elfnn-ia64.c $(AM_V_at)echo "#line 1 \"$<\"" > $@ $(AM_V_GEN)$(SED) -e s/NN/32/g < $< >> $@ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 8d09f6fa4af..4c396334a0e 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -554,6 +554,7 @@ ALL_MACHINES =3D \ cpu-alpha.lo \ cpu-amdgcn.lo \ cpu-arc.lo \ + cpu-arc64.lo \ cpu-arm.lo \ cpu-avr.lo \ cpu-bfin.lo \ @@ -638,6 +639,7 @@ ALL_MACHINES_CFILES =3D \ cpu-alpha.c \ cpu-amdgcn.c \ cpu-arc.c \ + cpu-arc64.c \ cpu-arm.c \ cpu-avr.c \ cpu-bfin.c \ @@ -721,6 +723,7 @@ ALL_MACHINES_CFILES =3D \ # The .o files needed by all of the 32 bit vectors that are configured into # target_vector in targets.c if configured with --enable-targets=3Dall. BFD32_BACKENDS =3D \ + arc-plt.lo \ aout-cris.lo \ aout-ns32k.lo \ aout32.lo \ @@ -856,6 +859,7 @@ BFD32_BACKENDS =3D \ xtensa-modules.lo =20 BFD32_BACKENDS_CFILES =3D \ + arc-plt.c \ aout-cris.c \ aout-ns32k.c \ aout32.c \ @@ -888,7 +892,6 @@ BFD32_BACKENDS_CFILES =3D \ elf-vxworks.c \ elf.c \ elf32-am33lin.c \ - elf32-arc.c \ elf32-arm.c \ elf32-avr.c \ elf32-bfin.c \ @@ -1002,6 +1005,7 @@ BFD64_BACKENDS =3D \ coff-x86_64.lo \ coff64-rs6000.lo \ elf32-aarch64.lo \ + elf32-arc64.lo \ elf32-ia64.lo \ elf32-kvx.lo \ elf32-loongarch.lo \ @@ -1010,6 +1014,7 @@ BFD64_BACKENDS =3D \ elf32-score.lo \ elf32-score7.lo \ elf64-aarch64.lo \ + elf64-arc64.lo \ elf64-alpha.lo \ elf64-amdgcn.lo \ elf64-bpf.lo \ @@ -1143,6 +1148,7 @@ SOURCE_CFILES =3D \ =20 BUILD_CFILES =3D \ elf32-aarch64.c elf64-aarch64.c \ + elf32-arc.c elf32-arc64.c elf64-arc64.c \ elf32-kvx.c elf64-kvx.c \ elf32-ia64.c elf64-ia64.c \ elf32-loongarch.c elf64-loongarch.c \ @@ -1435,6 +1441,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout-ns32k.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout64.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc-plt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archures.Plo@am__quote@ @@ -1468,6 +1475,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-alpha.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-amdgcn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-arc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-arc64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-arm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-avr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-bfin.Plo@am__quote@ @@ -1564,6 +1572,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-aarch64.Plo@am__quo= te@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-am33lin.Plo@am__quo= te@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-arc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-arc64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-arm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-avr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-bfin.Plo@am__quote@ @@ -1633,6 +1642,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-aarch64.Plo@am__quo= te@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-alpha.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-amdgcn.Plo@am__quot= e@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-arc64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-bpf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-gen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-hppa.Plo@am__quote@ @@ -2351,6 +2361,21 @@ elf64-aarch64.c : elfnn-aarch64.c $(AM_V_at)echo "#line 1 \"$<\"" > $@ $(AM_V_GEN)$(SED) -e s/NN/64/g < $< >> $@ =20 +elf32-arc.c : elfnn-arc.c + rm -f elf32-arc.c + $(AM_V_at)echo "#line 1 \"$(srcdir)/elfnn-arc.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/NN/32/g -e s/AA//g < $< >> $@ + +elf64-arc64.c : elfnn-arc.c + rm -f elf64-arc64.c + $(AM_V_at)echo "#line 1 \"$(srcdir)/elfnn-arc.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/NN/64/g -e s/AA/64/g < $< >> $@ + +elf32-arc64.c : elfnn-arc.c + rm -f elf32-arc64.c + $(AM_V_at)echo "#line 1 \"$(srcdir)/elfnn-arc.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/NN/32/g -e s/AA/64/g < $< >> $@ + elf32-ia64.c : elfnn-ia64.c $(AM_V_at)echo "#line 1 \"$<\"" > $@ $(AM_V_GEN)$(SED) -e s/NN/32/g < $< >> $@ diff --git a/bfd/arc-got.h b/bfd/arc-got.h index dfa3f5b4fe0..862b86181a9 100644 --- a/bfd/arc-got.h +++ b/bfd/arc-got.h @@ -22,9 +22,25 @@ #ifndef ARC_GOT_H #define ARC_GOT_H =20 +/* Thread Control Block (TCB) contains at offset zero a pointer to the + dynamic thread vector dtvt for the thread. */ +#if ARCH_SIZE =3D=3D 32 #define TCB_SIZE (8) - -#define align_power(addr, align) \ +#else +#define TCB_SIZE (16) +#endif + +#if ARCH_SIZE =3D=3D 32 +#define GOT_ENTRY_SIZE 4 +#define write_in_got(A, B, C) bfd_put_32 (A, B, C) +#define read_from_got(A, B) bfd_get_32 (A, B) +#else +#define GOT_ENTRY_SIZE 8 +#define write_in_got(A, B, C) bfd_put_64 (A, B, C) +#define read_from_got(A, B) bfd_get_64 (A, B) +#endif + +#define align_power(addr, align) \ (((addr) + ((bfd_vma) 1 << (align)) - 1) & (-((bfd_vma) 1 << (align)))) =20 enum tls_type_e @@ -201,7 +217,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type *howto) { \ if (COND_FOR_RELOC) \ { \ - htab->srel##SECNAME->size +=3D sizeof (Elf32_External_Rela); \ + htab->srel##SECNAME->size +=3D RELA_SIZE; \ ARC_DEBUG ("arc_info: Added reloc space in " \ #SECNAME " section at " __FILE__ \ ":%d for symbol %s\n", \ @@ -211,7 +227,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type *howto) if (H->dynindx =3D=3D -1 && !H->forced_local) \ if (! bfd_elf_link_record_dynamic_symbol (info, H)) \ return false; \ - htab->s##SECNAME->size +=3D 4; \ + htab->s##SECNAME->size +=3D GOT_ENTRY_SIZE; \ } \ =20 static bool @@ -230,13 +246,13 @@ arc_fill_got_info_for_reloc (enum tls_type_e type, case GOT_NORMAL: { bfd_vma offset - =3D ADD_SYMBOL_REF_SEC_AND_RELOC (got, bfd_link_pic (info) - || h !=3D NULL, h); + =3D ADD_SYMBOL_REF_SEC_AND_RELOC (got, + bfd_link_pic (info) || h !=3D NULL, + h); new_got_entry_to_list (list, type, offset, TLS_GOT_NONE); } break; =20 - case GOT_TLS_GD: { bfd_vma offset @@ -262,59 +278,16 @@ arc_fill_got_info_for_reloc (enum tls_type_e type, return true; } =20 -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[] =3D "(local)"; - struct arc_static_sym_data ret =3D { 0, NULL }; - - if (h !=3D NULL) - { - BFD_ASSERT (h->root.type !=3D bfd_link_hash_undefweak - && h->root.type !=3D bfd_link_hash_undefined); - /* TODO: This should not be here. */ - reloc_data->sym_value =3D h->root.u.def.value; - reloc_data->sym_section =3D h->root.u.def.section; - - ret.sym_value =3D h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset; - - ret.symbol_name =3D h->root.root.string; - } - else - { - Elf_Internal_Sym *sym =3D local_syms + r_symndx; - asection *sec =3D local_sections[r_symndx]; - - ret.sym_value =3D sym->st_value - + sec->output_section->vma - + sec->output_offset; - - ret.symbol_name =3D local_name; - } - return ret; -} - static bfd_vma -relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, - enum tls_type_e type, - struct bfd_link_info * info, - bfd * output_bfd, - unsigned long r_symndx, - Elf_Internal_Sym * local_syms, - asection ** local_sections, - struct elf_link_hash_entry * h, - struct arc_relocation_data * reloc_data) +relocate_fix_got_relocs_for_got_info (struct got_entry **list_p, + enum tls_type_e type, + struct bfd_link_info *info, + bfd *output_bfd, + unsigned long r_symndx, + Elf_Internal_Sym * local_syms, + asection **local_sections, + struct elf_link_hash_entry *h, + struct arc_relocation_data *reloc_data) { struct elf_link_hash_table *htab =3D elf_hash_table (info); struct got_entry *entry =3D NULL; @@ -332,91 +305,84 @@ relocate_fix_got_relocs_for_got_info (struct got_entr= y ** list_p, && SYMBOL_REFERENCES_LOCAL (info, h)))) { const char ATTRIBUTE_UNUSED *symbol_name; - asection *tls_sec =3D elf_hash_table (info)->tls_sec; + static const char *local_name =3D "(local)"; + bfd_vma sym_value =3D 0; + asection *sec =3D NULL; + + if (h !=3D NULL) + { + reloc_data->sym_value =3D h->root.u.def.value; + reloc_data->sym_section =3D h->root.u.def.section; + + sec =3D h->root.u.def.section; + sym_value =3D h->root.u.def.value; + symbol_name =3D h->root.root.string; + } + else + { + Elf_Internal_Sym *sym =3D local_syms + r_symndx; + + sec =3D local_sections[r_symndx]; + sym_value =3D sym->st_value; + symbol_name =3D local_name; + } =20 if (entry && !entry->processed) { + int tcb_size =3D 0; + switch (entry->type) { + case GOT_TLS_IE: + tcb_size =3D TCB_SIZE; + /* Fall through. */ case GOT_TLS_GD: { + asection *tls_sec =3D elf_hash_table (info)->tls_sec; + BFD_ASSERT (tls_sec && tls_sec->output_section); - bfd_vma sec_vma =3D tls_sec->output_section->vma; + bfd_vma tls_vma =3D tls_sec->output_section->vma; + + BFD_ASSERT (sec->output_section); + sym_value +=3D sec->output_section->vma + sec->output_offset; =20 - if (h =3D=3D NULL || h->forced_local - || !elf_hash_table (info)->dynamic_sections_created) + if (h =3D=3D NULL + || h->forced_local + || !elf_hash_table (info)->dynamic_sections_created) { - struct arc_static_sym_data tmp =3D - get_static_sym_data (r_symndx, local_syms, local_sections, - h, reloc_data); - - bfd_put_32 (output_bfd, - tmp.sym_value - sec_vma - + (elf_hash_table (info)->dynamic_sections_created - ? 0 - : (align_power (0, - tls_sec->alignment_power))), - htab->sgot->contents + entry->offset - + (entry->existing_entries =3D=3D TLS_GOT_MOD_AND_OFF - ? 4 : 0)); - - ARC_DEBUG ("arc_info: FIXED -> %s value =3D %#lx " - "@ %lx, for symbol %s\n", - (entry->type =3D=3D GOT_TLS_GD ? "GOT_TLS_GD" : - "GOT_TLS_IE"), - (long) (sym_value - sec_vma), - (long) (htab->sgot->output_section->vma - + htab->sgot->output_offset - + entry->offset - + (entry->existing_entries =3D=3D TLS_GOT_MOD_AND_OFF - ? 4 : 0)), - tmp.symbol_name); + write_in_got + (output_bfd, + /* S - TLS_REL + { round (TCB_SIZE, align), 0 } */ + sym_value - tls_vma + + (elf_hash_table (info)->dynamic_sections_created + ? 0 : (align_power (tcb_size, + tls_sec->alignment_power))), + htab->sgot->contents + entry->offset + + (entry->existing_entries =3D=3D TLS_GOT_MOD_AND_OFF + ? GOT_ENTRY_SIZE : 0)); + + ARC_DEBUG + ("arc_info: FIXED -> %s value =3D %#lx " + "@ %lx, for symbol %s\n", + (entry->type =3D=3D GOT_TLS_GD ? "GOT_TLS_GD" : + "GOT_TLS_IE"), + (long) (sym_value - tls_vma), + (long) (htab->sgot->output_section->vma + + htab->sgot->output_offset + + entry->offset + + (entry->existing_entries =3D=3D TLS_GOT_MOD_AND_OFF + ? GOT_ENTRY_SIZE : 0)), + symbol_name); } } break; =20 - case GOT_TLS_IE: - { - BFD_ASSERT (tls_sec && tls_sec->output_section); - bfd_vma ATTRIBUTE_UNUSED sec_vma - =3D tls_sec->output_section->vma; - - struct arc_static_sym_data tmp =3D - get_static_sym_data (r_symndx, local_syms, local_sections, - h, reloc_data); - - bfd_put_32 (output_bfd, - tmp.sym_value - sec_vma - + (elf_hash_table (info)->dynamic_sections_created - ? 0 - : (align_power (TCB_SIZE, - tls_sec->alignment_power))), - htab->sgot->contents + entry->offset - + (entry->existing_entries =3D=3D TLS_GOT_MOD_AND_OFF - ? 4 : 0)); - - ARC_DEBUG ("arc_info: FIXED -> %s value =3D %#lx " - "@ %p, for symbol %s\n", - (entry->type =3D=3D GOT_TLS_GD ? "GOT_TLS_GD" : - "GOT_TLS_IE"), - (long) (sym_value - sec_vma), - (long) (htab->sgot->output_section->vma - + htab->sgot->output_offset - + entry->offset - + (entry->existing_entries =3D=3D TLS_GOT_MOD_AND_OFF - ? 4 : 0)), - tmp.symbol_name); - } - break; - case GOT_NORMAL: { - bfd_vma sec_vma - =3D reloc_data->sym_section->output_section->vma - + reloc_data->sym_section->output_offset; - if (h !=3D NULL - && h->root.type =3D=3D bfd_link_hash_undefweak) + && (h->root.type =3D=3D bfd_link_hash_undefweak + /* FIXME! catch the undefined situation in a test. */ + || h->root.type =3D=3D bfd_link_hash_undefined)) ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED " "@ %#08lx for sym %s in got offset %#lx " "(is undefweak)\n", @@ -427,12 +393,16 @@ relocate_fix_got_relocs_for_got_info (struct got_entr= y ** list_p, (long) entry->offset); else { - bfd_put_32 (output_bfd, - reloc_data->sym_value + sec_vma, - htab->sgot->contents + entry->offset); + BFD_ASSERT (sec->output_section); + + sym_value +=3D sec->output_section->vma + sec->output_offset; + + write_in_got (output_bfd, + sym_value, + htab->sgot->contents + entry->offset); ARC_DEBUG ("arc_info: PATCHED: %#08lx " "@ %#08lx for sym %s in got offset %#lx\n", - (long) (reloc_data->sym_value + sec_vma), + (long) sym_value, (long) (htab->sgot->output_section->vma + htab->sgot->output_offset + entry->offset), @@ -455,7 +425,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry = ** list_p, static void create_got_dynrelocs_for_single_entry (struct got_entry *list, bfd *output_bfd, - struct bfd_link_info * info, + struct bfd_link_info *info, struct elf_link_hash_entry *h) { if (list =3D=3D NULL) @@ -474,8 +444,8 @@ create_got_dynrelocs_for_single_entry (struct got_entry= *list, ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0); } /* Do not fully understand the side effects of this condition. - The relocation space might still being reserved. Perhaps - I should clear its value. */ + The relocation space might still being reserved. Perhaps I + should clear its value. */ else if (h !=3D NULL && h->dynindx !=3D -1) { ADD_RELA (output_bfd, got, got_offset, h->dynindx, R_ARC_GLOB_DAT, 0); @@ -516,12 +486,12 @@ GOT_OFFSET =3D %#lx, GOT_VMA =3D %#lx, INDEX =3D %ld,= ADDEND =3D 0x0\n", bfd_vma addend =3D 0; if (list->type =3D=3D GOT_TLS_IE) { - addend =3D bfd_get_32 (output_bfd, - htab->sgot->contents + got_offset); + addend =3D read_from_got (output_bfd, + htab->sgot->contents + got_offset); } =20 - ADD_RELA (output_bfd, got, - got_offset + (e =3D=3D TLS_GOT_MOD_AND_OFF ? 4 : 0), + ADD_RELA (output_bfd, got, got_offset + + (e =3D=3D TLS_GOT_MOD_AND_OFF ? GOT_ENTRY_SIZE : 0), dynindx, (list->type =3D=3D GOT_TLS_IE ? R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF), @@ -542,13 +512,14 @@ GOT_OFFSET =3D %#lx, GOT_VMA =3D %#lx, INDEX =3D %ld,= ADDEND =3D %#lx\n", static void create_got_dynrelocs_for_got_info (struct got_entry **list_p, bfd *output_bfd, - struct bfd_link_info * info, + struct bfd_link_info *info, struct elf_link_hash_entry *h) { + struct got_entry *list =3D *list_p; + if (list_p =3D=3D NULL) return; =20 - struct got_entry *list =3D *list_p; /* Traverse the list of got entries for this symbol. */ while (list) { diff --git a/bfd/arc-plt.c b/bfd/arc-plt.c new file mode 100644 index 00000000000..8dd778b58d2 --- /dev/null +++ b/bfd/arc-plt.c @@ -0,0 +1,121 @@ +/* ARC-specific support for PLT relocations. + Copyright (C) 2023 Free Software Foundation, Inc. + Contributed by Cupertino Miranda (cmiranda@synopsys.com). + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "arc-plt.h" + +#define PLT_TYPE_START(NAME) \ + const insn_hword NAME##_plt_entry[] =3D { +#define PLT_TYPE_END(NAME) }; +#define PLT_ENTRY(...) __VA_ARGS__, +#define PLT_ELEM(...) +#define ENTRY_RELOC(...) +#define ELEM_RELOC(...) + +#include "arc-plt.def" + +#undef PLT_TYPE_START +#undef PLT_TYPE_END +#undef PLT_ENTRY +#undef PLT_ELEM +#undef ENTRY_RELOC +#undef ELEM_RELOC + +#define PLT_TYPE_START(NAME) \ + const struct plt_reloc NAME##_plt_entry_relocs[] =3D { +#define PLT_TYPE_END(NAME) \ + {0, 0, 0, LAST_RELOC, 0} \ + }; +#define PLT_ENTRY(...) +#define PLT_ELEM(...) +#define ENTRY_RELOC(...) { __VA_ARGS__ }, +#define ELEM_RELOC(...) + +#include "arc-plt.def" + +#undef PLT_TYPE_START +#undef PLT_TYPE_END +#undef PLT_ENTRY +#undef PLT_ELEM +#undef ENTRY_RELOC +#undef ELEM_RELOC + + +#define PLT_TYPE_START(NAME) \ + const insn_hword NAME##_plt_elem[] =3D { +#define PLT_TYPE_END(NAME) }; +#define PLT_ENTRY(...) +#define PLT_ELEM(...) __VA_ARGS__, +#define ENTRY_RELOC(...) +#define ELEM_RELOC(...) + +#include "arc-plt.def" + +#undef PLT_TYPE_START +#undef PLT_TYPE_END +#undef PLT_ENTRY +#undef PLT_ELEM +#undef ENTRY_RELOC +#undef ELEM_RELOC + +#define PLT_TYPE_START(NAME) \ + const struct plt_reloc NAME##_plt_elem_relocs[] =3D { +#define PLT_TYPE_END(NAME) \ + {0, 0, 0, LAST_RELOC, 0} \ + }; +#define PLT_ENTRY(...) +#define PLT_ELEM(...) +#define ENTRY_RELOC(...) +#define ELEM_RELOC(...) { __VA_ARGS__ }, + +#include "arc-plt.def" + +#undef PLT_TYPE_START +#undef PLT_TYPE_END +#undef PLT_ENTRY +#undef PLT_ELEM +#undef ENTRY_RELOC +#undef ELEM_RELOC + + +#define PLT_TYPE_START(NAME) \ + { \ + .entry =3D &NAME##_plt_entry, \ + .entry_size =3D sizeof (NAME##_plt_entry), \ + .elem =3D &NAME##_plt_elem, \ + .elem_size =3D sizeof (NAME##_plt_elem), \ + .entry_relocs =3D NAME##_plt_entry_relocs, \ + .elem_relocs =3D NAME##_plt_elem_relocs +#define PLT_TYPE_END(NAME) }, +#define PLT_ENTRY(...) +#define PLT_ELEM(...) +#define ENTRY_RELOC(...) +#define ELEM_RELOC(...) +struct plt_version_t plt_versions[PLT_MAX] =3D + { +#include "arc-plt.def" + }; + +#undef PLT_TYPE_START +#undef PLT_TYPE_END +#undef PLT_ENTRY +#undef PLT_ELEM +#undef ENTRY_RELOC +#undef ELEM_RELOC diff --git a/bfd/arc-plt.def b/bfd/arc-plt.def index 2b602c47639..a3b32f379f0 100644 --- a/bfd/arc-plt.def +++ b/bfd/arc-plt.def @@ -1,4 +1,4 @@ -/* Arc V2 Related PLT entries. +/* Arc V2/V3 Related PLT entries. Copyright (C) 2016-2023 Free Software Foundation, Inc. Contributed by Cupertino Miranda (cmiranda@synopsys.com). =20 @@ -19,15 +19,72 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ =20 -PLT_TYPE_START (ELF_ARCV2_PIC) - PLT_ENTRY (0x2730, 0x7f8b, 0x0000, 0x0000) /* ld %r11, [pcl,0] : 0 to be= replaced by _DYNAMIC@GOTPC+4 */ - PLT_ENTRY (0x2730, 0x7f8a, 0x0000, 0x0000) /* ld %r10, [pcl,0] : 0 to be= replaced by _DYNAMIC@GOTPC+8 */ - PLT_ENTRY (0x2020, 0x0280) /* j [%r10] */ - PLT_ENTRY (0x0,0x0,0x0,0x0,0x0,0x0) /* padding */ =20 - PLT_ELEM (0x2730, 0x7f8c, 0x0000, 0x0000) /* ld %r12, [%pc,func@got] */ - PLT_ELEM (0x2021, 0x0300) /* j.d [%r12] */ - PLT_ELEM (0x240a, 0x1fc0) /* mov %r12, %pcl */ +PLT_TYPE_START (ELF_ARCV3_PIC) +/* + -- at .got.plt + 0 should be the address of .dynamic + ldl r11, [pcl, 0] .got.plt + 8 + ldl r10, [pcl, 0] .got.plt + 16 + j [r10] + padding + + 2e: 2731 ff0b 0000 0000 ldl r11,[pcl,0@s32] ;2c + 32: R_ARC_GOTPC32 f_var + 36: 2731 ff0a 0000 0000 ldl r10,[pcl,0@s32] ;34 + 3a: R_ARC_GOTPC32 f_var + 3e: 2020 0280 j [r10] +*/ + +/* ldl %r11, [pcl,0] : 0 to be replaced by _DYNAMIC@GOTPC+4. */ + PLT_ENTRY (0x2731, 0xff0b, 0x0000, 0x0000) +/* ldl %r10, [pcl,0] : 0 to be replaced by _DYNAMIC@GOTPC+8. */ + PLT_ENTRY (0x2731, 0xff0a, 0x0000, 0x0000) +/* j [%r10]. */ + PLT_ENTRY (0x2020, 0x0280) +/* padding. */ + PLT_ENTRY (0x0, 0x0, 0x0, 0x0, 0x0,0x0) + +/* + ldl r12, [pcl, 0] -- at .got.plt + 0 should be the address of .dynamic + + 46: 2731 ff0c 0000 0000 ldl r12,[pcl,0@s32] ;44 + 4a: R_ARC_GOTPC32 f_var + 4e: 2021 0300 j.d [r12] + 52: 5c0a 1fc0 movl r12,pcl +*/ + +/* ld %r12, [%pc,func@got]. */ + PLT_ELEM (0x2731, 0xff0c, 0x0000, 0x0000) +/* j.d [%r12]. */ + PLT_ELEM (0x2021, 0x0300) +/* movl %r12, %pcl. */ + PLT_ELEM (0x5c0a, 0x1fc0) + + ENTRY_RELOC (4, 32, 0xFFFFFFFF, SGOT | RELATIVE_INSN_32 | MIDDLE_ENDIAN,= 8) + ENTRY_RELOC (12, 32, 0xFFFFFFFF, SGOT | RELATIVE_INSN_32 | MIDDLE_ENDIAN= , 16) + ENTRY_RELOC (20, 32, 0xFFFFFFFF, SGOT, 0) + + ELEM_RELOC (4, 32, 0xFFFFFFFF, SGOT | RELATIVE_INSN_32 | MIDDLE_ENDIAN, = 0) + +PLT_TYPE_END (ELF_ARCV3_PIC) + + +PLT_TYPE_START (ELF_ARCV2_PIC) +/* ld %r11, [pcl,0] : 0 to be replaced by _DYNAMIC@GOTPC+4. */ + PLT_ENTRY (0x2730, 0x7f8b, 0x0000, 0x0000) +/* ld %r10, [pcl,0] : 0 to be replaced by _DYNAMIC@GOTPC+8. */ + PLT_ENTRY (0x2730, 0x7f8a, 0x0000, 0x0000) +/* j [%r10]. */ + PLT_ENTRY (0x2020, 0x0280) +/* padding. */ + PLT_ENTRY (0x0,0x0,0x0,0x0,0x0,0x0) + + /* ld %r12, [%pc,func@got]. */ + PLT_ELEM (0x2730, 0x7f8c, 0x0000, 0x0000) +/* j.d [%r12]. */ + PLT_ELEM (0x2021, 0x0300) +/* mov %r12, %pcl. */ + PLT_ELEM (0x240a, 0x1fc0) =20 ENTRY_RELOC (4, 32, 0xFFFFFFFF, SGOT | RELATIVE_INSN_32 | MIDDLE_ENDIAN,= 4) ENTRY_RELOC (12, 32, 0xFFFFFFFF, SGOT | RELATIVE_INSN_32 | MIDDLE_ENDIAN= , 8) @@ -38,14 +95,18 @@ PLT_TYPE_START (ELF_ARCV2_PIC) PLT_TYPE_END (ELF_ARCV2_PIC) =20 PLT_TYPE_START (ELF_ARCV2_ABS) - PLT_ENTRY (0x1600,0x700b,0x0000,0x0000) /* ld %r11, [0] */ - PLT_ENTRY (0x1600,0x700a,0x0000,0x0000) /* ld %r10, [0] */ - PLT_ENTRY (0x2020,0x0280) /* j [%r10] */ - PLT_ENTRY (0x0,0x0,0x0,0x0,0x0,0x0) /* padding */ - - PLT_ELEM (0x2730, 0x7f8c, 0x0000, 0x0000) /* ld %r12, [%pcl,func@gotpc] = */ - PLT_ELEM (0x2021,0x0300) /* j.d [%r12] */ - PLT_ELEM (0x240a,0x1fc0) /* mov %r12, %pcl */ +/* ld %r11, [0]. */ + PLT_ENTRY (0x1600,0x700b,0x0000,0x0000) +/* ld %r10, [0]. */ + PLT_ENTRY (0x1600,0x700a,0x0000,0x0000) +/* j [%r10]. */ + PLT_ENTRY (0x2020,0x0280) +/* padding. */ + PLT_ENTRY (0x0,0x0,0x0,0x0,0x0,0x0) + + PLT_ELEM (0x2730, 0x7f8c, 0x0000, 0x0000) /* ld %r12, [%pcl,func@gotpc].= */ + PLT_ELEM (0x2021,0x0300) /* j.d [%r12]. */ + PLT_ELEM (0x240a,0x1fc0) /* mov %r12, %pcl. */ =20 ENTRY_RELOC (4, 32, 0xFFFFFFFF, SGOT | MIDDLE_ENDIAN, 4) ENTRY_RELOC (12, 32, 0xFFFFFFFF, SGOT | MIDDLE_ENDIAN, 8) @@ -59,14 +120,18 @@ PLT_TYPE_END (ELF_ARCV2_ABS) /* Non Arc V2 Related PLT entries. */ =20 PLT_TYPE_START (ELF_ARC_PIC) - PLT_ENTRY (0x2730,0x7f8b,0x0000,0x0000) /* ld %r11, [pcl,0] : 0 to be re= placed by _DYNAMIC@GOTPC+4 */ - PLT_ENTRY (0x2730,0x7f8a,0x0000,0x0000) /* ld %r10, [pcl,0] : 0 to be re= placed by -DYNAMIC@GOTPC+8 */ - PLT_ENTRY (0x2020,0x0280) /* j [%r10] */ - PLT_ENTRY (0x0,0x0) /* padding */ - - PLT_ELEM (0x2730,0x7f8c,0x0000,0x0000) /* ld %r12, [%pc,func@got] */ - PLT_ELEM (0x7c20) /* j_s.d [%r12] */ - PLT_ELEM (0x74ef) /* mov_s %r12, %pcl */ +/* ld %r11, [pcl,0] : 0 to be replaced by _DYNAMIC@GOTPC+4. */ + PLT_ENTRY (0x2730,0x7f8b,0x0000,0x0000) +/* ld %r10, [pcl,0] : 0 to be replaced by -DYNAMIC@GOTPC+8. */ + PLT_ENTRY (0x2730,0x7f8a,0x0000,0x0000) +/* j [%r10]. */ + PLT_ENTRY (0x2020,0x0280) +/* padding. */ + PLT_ENTRY (0x0,0x0) + + PLT_ELEM (0x2730,0x7f8c,0x0000,0x0000) /* ld %r12, [%pc,func@got]. */ + PLT_ELEM (0x7c20) /* j_s.d [%r12]. */ + PLT_ELEM (0x74ef) /* mov_s %r12, %pcl. */ =20 ENTRY_RELOC (4, 32, 0xFFFFFFFF, SGOT | RELATIVE_INSN_32 | MIDDLE_ENDIAN,= 4) ENTRY_RELOC (12, 32, 0xFFFFFFFF, SGOT | RELATIVE_INSN_32 | MIDDLE_ENDIAN= , 8) @@ -77,13 +142,13 @@ PLT_TYPE_START (ELF_ARC_PIC) PLT_TYPE_END (ELF_ARC_PIC) =20 PLT_TYPE_START (ELF_ARC_ABS) - PLT_ENTRY (0x1600,0x700b,0x0000,0x0000) /* ld %r11, [0] */ - PLT_ENTRY (0x1600,0x700a,0x0000,0x0000) /* ld %r10, [0] */ - PLT_ENTRY (0x2020,0x0280) /* j [%r10] */ - PLT_ENTRY (0x0,0x0) /* padding */ + PLT_ENTRY (0x1600,0x700b,0x0000,0x0000) /* ld %r11, [0]. */ + PLT_ENTRY (0x1600,0x700a,0x0000,0x0000) /* ld %r10, [0]. */ + PLT_ENTRY (0x2020,0x0280) /* j [%r10]. */ + PLT_ENTRY (0x0,0x0) /* padding. */ =20 - PLT_ELEM (0x2730,0x7f8c,0x0000,0x0000) /* ld %r12, [%pc,func@gotpc] */ - PLT_ELEM (0x7c20,0x74ef) /* mov_s %r12, %pcl */ + PLT_ELEM (0x2730,0x7f8c,0x0000,0x0000) /* ld %r12, [%pc,func@gotpc]. */ + PLT_ELEM (0x7c20,0x74ef) /* mov_s %r12, %pcl. */ =20 ENTRY_RELOC (4, 32, 0xFFFFFFFF, SGOT | MIDDLE_ENDIAN, 4) ENTRY_RELOC (12, 32, 0xFFFFFFFF, SGOT | MIDDLE_ENDIAN, 8) diff --git a/bfd/arc-plt.h b/bfd/arc-plt.h index e11b72eeadd..ad1b86fc9f8 100644 --- a/bfd/arc-plt.h +++ b/bfd/arc-plt.h @@ -22,6 +22,9 @@ #ifndef ARC_PLT_H #define ARC_PLT_H =20 +#include "sysdep.h" +#include "bfd.h" + /* Instructions appear in memory as a sequence of half-words (16 bit); individual half-words are represented on the target in target byte orde= r. We use 'unsigned short' on the host to represent the PLT templates, @@ -92,97 +95,20 @@ struct plt_version_t }; =20 #define PLT_TYPE_START(NAME) \ - const insn_hword NAME##_plt_entry[] =3D { -#define PLT_TYPE_END(NAME) }; -#define PLT_ENTRY(...) __VA_ARGS__, -#define PLT_ELEM(...) -#define ENTRY_RELOC(...) -#define ELEM_RELOC(...) - -#include "arc-plt.def" - -#undef PLT_TYPE_START -#undef PLT_TYPE_END -#undef PLT_ENTRY -#undef PLT_ELEM -#undef ENTRY_RELOC -#undef ELEM_RELOC - -#define PLT_TYPE_START(NAME) \ - const struct plt_reloc NAME##_plt_entry_relocs[] =3D { -#define PLT_TYPE_END(NAME) \ - {0, 0, 0, LAST_RELOC, 0} \ - }; -#define PLT_ENTRY(...) -#define PLT_ELEM(...) -#define ENTRY_RELOC(...) { __VA_ARGS__ }, -#define ELEM_RELOC(...) + extern const insn_hword NAME##_plt_entry[]; \ + extern const struct plt_reloc NAME##_plt_entry_relocs[]; \ + extern const insn_hword NAME##_plt_elem[]; \ + extern const struct plt_reloc NAME##_plt_elem_relocs[]; =20 -#include "arc-plt.def" =20 -#undef PLT_TYPE_START -#undef PLT_TYPE_END -#undef PLT_ENTRY -#undef PLT_ELEM -#undef ENTRY_RELOC -#undef ELEM_RELOC - - -#define PLT_TYPE_START(NAME) \ - const insn_hword NAME##_plt_elem[] =3D { -#define PLT_TYPE_END(NAME) }; -#define PLT_ENTRY(...) -#define PLT_ELEM(...) __VA_ARGS__, -#define ENTRY_RELOC(...) -#define ELEM_RELOC(...) - -#include "arc-plt.def" - -#undef PLT_TYPE_START -#undef PLT_TYPE_END -#undef PLT_ENTRY -#undef PLT_ELEM -#undef ENTRY_RELOC -#undef ELEM_RELOC - -#define PLT_TYPE_START(NAME) \ - const struct plt_reloc NAME##_plt_elem_relocs[] =3D { -#define PLT_TYPE_END(NAME) \ - {0, 0, 0, LAST_RELOC, 0} \ - }; -#define PLT_ENTRY(...) -#define PLT_ELEM(...) -#define ENTRY_RELOC(...) -#define ELEM_RELOC(...) { __VA_ARGS__ }, - -#include "arc-plt.def" - -#undef PLT_TYPE_START -#undef PLT_TYPE_END -#undef PLT_ENTRY -#undef PLT_ELEM -#undef ENTRY_RELOC -#undef ELEM_RELOC - - -#define PLT_TYPE_START(NAME) \ - { \ - .entry =3D &NAME##_plt_entry, \ - .entry_size =3D sizeof (NAME##_plt_entry), \ - .elem =3D &NAME##_plt_elem, \ - .elem_size =3D sizeof (NAME##_plt_elem), \ - .entry_relocs =3D NAME##_plt_entry_relocs, \ - .elem_relocs =3D NAME##_plt_elem_relocs -#define PLT_TYPE_END(NAME) }, +#define PLT_TYPE_END(NAME) #define PLT_ENTRY(...) #define PLT_ELEM(...) #define ENTRY_RELOC(...) #define ELEM_RELOC(...) -const struct plt_version_t plt_versions[PLT_MAX] =3D { =20 #include "arc-plt.def" =20 -}; #undef PLT_TYPE_START #undef PLT_TYPE_END #undef PLT_ENTRY @@ -190,5 +116,6 @@ const struct plt_version_t plt_versions[PLT_MAX] =3D { #undef ENTRY_RELOC #undef ELEM_RELOC =20 +extern struct plt_version_t plt_versions[PLT_MAX]; =20 -#endif /* ARC_PLT_H */ +#endif diff --git a/bfd/archures.c b/bfd/archures.c index b59979e60ac..b0c1e3e70bd 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -361,6 +361,9 @@ DESCRIPTION .#define bfd_mach_arc_arc601 4 .#define bfd_mach_arc_arc700 3 .#define bfd_mach_arc_arcv2 5 +. bfd_arch_arc64, {* ARCv3 32/64 Cores. *} +.#define bfd_mach_arcv3_64 1 +.#define bfd_mach_arcv3_32 2 . bfd_arch_m32c, {* Renesas M16C/M32C. *} .#define bfd_mach_m16c 0x75 .#define bfd_mach_m32c 0x78 @@ -632,6 +635,7 @@ extern const bfd_arch_info_type bfd_aarch64_arch; extern const bfd_arch_info_type bfd_alpha_arch; extern const bfd_arch_info_type bfd_amdgcn_arch; extern const bfd_arch_info_type bfd_arc_arch; +extern const bfd_arch_info_type bfd_arc64_arch; extern const bfd_arch_info_type bfd_arm_arch; extern const bfd_arch_info_type bfd_avr_arch; extern const bfd_arch_info_type bfd_bfin_arch; @@ -721,6 +725,7 @@ static const bfd_arch_info_type * const bfd_archures_li= st[] =3D &bfd_alpha_arch, &bfd_amdgcn_arch, &bfd_arc_arch, + &bfd_arc64_arch, &bfd_arm_arch, &bfd_avr_arch, &bfd_bfin_arch, diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 1c4f75ae244..991344adf5c 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1617,6 +1617,9 @@ enum bfd_architecture #define bfd_mach_arc_arc601 4 #define bfd_mach_arc_arc700 3 #define bfd_mach_arc_arcv2 5 + bfd_arch_arc64, /* ARCv3 32/64 Cores. */ +#define bfd_mach_arcv3_64 1 +#define bfd_mach_arcv3_32 2 bfd_arch_m32c, /* Renesas M16C/M32C. */ #define bfd_mach_m16c 0x75 #define bfd_mach_m32c 0x78 @@ -4383,6 +4386,7 @@ pc-relative or some form of GOT-indirect relocation. = */ BFD_RELOC_ARC_16, BFD_RELOC_ARC_24, BFD_RELOC_ARC_32, + BFD_RELOC_ARC_64, BFD_RELOC_ARC_N8, BFD_RELOC_ARC_N16, BFD_RELOC_ARC_N24, @@ -4447,6 +4451,27 @@ pc-relative or some form of GOT-indirect relocation.= */ BFD_RELOC_ARC_S21H_PCREL_PLT, BFD_RELOC_ARC_NPS_CMEM16, BFD_RELOC_ARC_JLI_SECTOFF, + BFD_RELOC_ARC_S7H_PCREL, + BFD_RELOC_ARC_S8H_PCREL, + BFD_RELOC_ARC_S9H_PCREL, + BFD_RELOC_ARC_S10H_PCREL, + BFD_RELOC_ARC_S13H_PCREL, + BFD_RELOC_ARC_ALIGN, + BFD_RELOC_ARC_ADD8, + BFD_RELOC_ARC_ADD16, + BFD_RELOC_ARC_SUB8, + BFD_RELOC_ARC_SUB16, + BFD_RELOC_ARC_SUB32, + BFD_RELOC_ARC_LO32, + BFD_RELOC_ARC_HI32, + BFD_RELOC_ARC_LO32_ME, + BFD_RELOC_ARC_HI32_ME, + BFD_RELOC_ARC_N64, + BFD_RELOC_ARC_SDA_LDST3, + BFD_RELOC_ARC_NLO32, + BFD_RELOC_ARC_NLO32_ME, + BFD_RELOC_ARC_PCLO32_ME_2, + BFD_RELOC_ARC_PLT34, =20 /* ADI Blackfin 16 bit immediate absolute reloc. */ BFD_RELOC_BFIN_16_IMM, diff --git a/bfd/config.bfd b/bfd/config.bfd index 08129e6a8cb..861a520a752 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -180,7 +180,8 @@ case "${targ_cpu}" in aarch64*) targ_archs=3D"bfd_aarch64_arch bfd_arm_arch";; alpha*) targ_archs=3Dbfd_alpha_arch ;; am33_2.0*) targ_archs=3Dbfd_mn10300_arch ;; -arc*) targ_archs=3Dbfd_arc_arch ;; +arc|arceb) targ_archs=3Dbfd_arc_arch ;; +arc64|arc32) targ_archs=3Dbfd_arc64_arch ;; arm*) targ_archs=3Dbfd_arm_arch ;; amdgcn*) targ_archs=3Dbfd_amdgcn_arch ;; bfin*) targ_archs=3Dbfd_bfin_arch ;; @@ -353,16 +354,29 @@ case "${targ}" in targ_defvec=3Dam33_elf32_linux_vec ;; =20 - arc*eb-*-elf* | arc*eb-*-linux*) + arceb-*-elf* | arceb-*-linux*) targ_defvec=3Darc_elf32_be_vec targ_selvecs=3Darc_elf32_le_vec ;; =20 - arc*-*-elf* | arc*-*-linux*) + arc-*-elf* | arc-*-linux*) targ_defvec=3Darc_elf32_le_vec targ_selvecs=3Darc_elf32_be_vec ;; =20 +#ifdef BFD64 + arc64-*-*) + targ_defvec=3Darc64_elf64_le_vec + targ_selvecs=3Darc64_elf32_le_vec + want64=3Dtrue + ;; + arc32-*-*) + targ_defvec=3Darc64_elf32_le_vec + targ_selvecs=3Darc64_elf64_le_vec + want64=3Dtrue + ;; +#endif + arm-*-darwin*) targ_defvec=3Darm_mach_o_vec targ_selvecs=3D"mach_o_le_vec mach_o_be_vec mach_o_fat_vec" diff --git a/bfd/configure b/bfd/configure index f0a07ff675f..f30ac5b25f4 100755 --- a/bfd/configure +++ b/bfd/configure @@ -13883,8 +13883,10 @@ do aout0_be_vec) tb=3D"$tb aout0.lo aout32.lo" ;; aout64_vec) tb=3D"$tb demo64.lo aout64.lo"; target_size=3D64 ;; aout_vec) tb=3D"$tb host-aout.lo aout32.lo" ;; - arc_elf32_be_vec) tb=3D"$tb elf32-arc.lo elf32.lo $elf" ;; - arc_elf32_le_vec) tb=3D"$tb elf32-arc.lo elf32.lo $elf" ;; + arc_elf32_be_vec) tb=3D"$tb arc-plt.lo elf32-arc.lo elf32.lo $elf" ;; + arc_elf32_le_vec) tb=3D"$tb arc-plt.lo elf32-arc.lo elf32.lo $elf" ;; + arc64_elf64_le_vec) tb=3D"$tb arc-plt.lo elf64-arc64.lo elf64.lo $el= f"; target_size=3D64 ;; + arc64_elf32_le_vec) tb=3D"$tb arc-plt.lo elf32-arc64.lo elf32.lo $el= f"; target_size=3D64 ;; arm_elf32_be_vec) tb=3D"$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vx= works.lo $elf" ;; arm_elf32_le_vec) tb=3D"$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vx= works.lo $elf" ;; arm_elf32_fdpic_be_vec) tb=3D"$tb elf32-arm.lo elf32.lo elf-nacl.lo e= lf-vxworks.lo $elf" ;; diff --git a/bfd/configure.ac b/bfd/configure.ac index d1e7e3a4bf3..64334743ce3 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -419,8 +419,10 @@ do aout0_be_vec) tb=3D"$tb aout0.lo aout32.lo" ;; aout64_vec) tb=3D"$tb demo64.lo aout64.lo"; target_size=3D64 ;; aout_vec) tb=3D"$tb host-aout.lo aout32.lo" ;; - arc_elf32_be_vec) tb=3D"$tb elf32-arc.lo elf32.lo $elf" ;; - arc_elf32_le_vec) tb=3D"$tb elf32-arc.lo elf32.lo $elf" ;; + arc_elf32_be_vec) tb=3D"$tb arc-plt.lo elf32-arc.lo elf32.lo $elf" ;; + arc_elf32_le_vec) tb=3D"$tb arc-plt.lo elf32-arc.lo elf32.lo $elf" ;; + arc64_elf64_le_vec) tb=3D"$tb arc-plt.lo elf64-arc64.lo elf64.lo $el= f"; target_size=3D64 ;; + arc64_elf32_le_vec) tb=3D"$tb arc-plt.lo elf32-arc64.lo elf32.lo $el= f"; target_size=3D64 ;; arm_elf32_be_vec) tb=3D"$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vx= works.lo $elf" ;; arm_elf32_le_vec) tb=3D"$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vx= works.lo $elf" ;; arm_elf32_fdpic_be_vec) tb=3D"$tb elf32-arm.lo elf32.lo elf-nacl.lo e= lf-vxworks.lo $elf" ;; diff --git a/bfd/cpu-arc.c b/bfd/cpu-arc.c index 390a69dc2a7..a5e0f80a0cc 100644 --- a/bfd/cpu-arc.c +++ b/bfd/cpu-arc.c @@ -26,51 +26,53 @@ static const bfd_arch_info_type * arc_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b); =20 -#define ARC(mach, print_name, default_p, next) \ - { \ - 32, /* Bits in a word. */ \ - 32, /* Bits in an address. */ \ - 8, /* Bits in a byte. */ \ - bfd_arch_arc, \ - mach, \ - "arc", \ - print_name, \ - 4, /* Section alignment power. */ \ - default_p, \ - arc_compatible, \ - bfd_default_scan, \ - bfd_arch_default_fill, \ - next, \ - 0 /* Maximum offset of a reloc from the start of an insn. */ \ - } +#define ARC(BITS_WORD, BITS_ADDR, MACH, PRINT_NAME, DEFAULT_P, NEXT) \ +{ \ + BITS_WORD, /* 32 bits in a word. */ \ + BITS_ADDR, /* 32 bits in an address. */ \ + 8, /* 8 bits in a byte. */ \ + bfd_arch_arc, \ + MACH, \ + "arc", \ + PRINT_NAME, \ + 4, /* section alignment power. */ \ + DEFAULT_P, \ + arc_compatible, \ + bfd_default_scan, \ + bfd_arch_default_fill, \ + NEXT, \ + 0 /* Maximum offset of a reloc from the start of an insn. */ \ +} =20 static const bfd_arch_info_type arch_info_struct[] =3D { - ARC (bfd_mach_arc_arc600, "A6" , false, &arch_info_struct[1]), - ARC (bfd_mach_arc_arc601, "ARC601", false, &arch_info_struct[2]), - ARC (bfd_mach_arc_arc700, "ARC700", false, &arch_info_struct[3]), - ARC (bfd_mach_arc_arc700, "A7", false, &arch_info_struct[4]), - ARC (bfd_mach_arc_arcv2, "ARCv2", false, &arch_info_struct[5]), - ARC (bfd_mach_arc_arcv2, "EM", false, &arch_info_struct[6]), - ARC (bfd_mach_arc_arcv2, "HS", false, NULL), + ARC (32, 32, bfd_mach_arc_arc600, "A6" , false, &arch_info_struct[1]), + ARC (32, 32, bfd_mach_arc_arc601, "ARC601", false, &arch_info_struct[2]), + ARC (32, 32, bfd_mach_arc_arc700, "ARC700", false, &arch_info_struct[3]), + ARC (32, 32, bfd_mach_arc_arc700, "A7", false, &arch_info_struct[4]), + ARC (32, 32, bfd_mach_arc_arcv2, "ARCv2", false, &arch_info_struct[5]), + ARC (32, 32, bfd_mach_arc_arcv2, "EM", false, &arch_info_struct[6]), + ARC (32, 32, bfd_mach_arc_arcv2, "HS", false, NULL), }; =20 const bfd_arch_info_type bfd_arc_arch =3D - ARC (bfd_mach_arc_arc600, "ARC600", true, &arch_info_struct[0]); - -/* ARC-specific "compatible" function. The general rule is that if A and = B are - compatible, then this function should return architecture that is more - "feature-rich", that is, can run both A and B. ARCv2, EM and HS all has - same mach number, so bfd_default_compatible assumes they are the same, = and - returns an A. That causes issues with GDB, because GDB assumes that if - machines are compatible, then "compatible ()" always returns same machi= ne - regardless of argument order. As a result GDB gets confused because, f= or - example, compatible (ARCv2, EM) returns ARCv2, but compatible (EM, ARCv= 2) - returns EM, hence GDB is not sure if they are compatible and prints a - warning. */ + ARC (32, 32, bfd_mach_arc_arc600, "ARC600", true, &arch_info_struct[0]); + +/* ARC-specific "compatible" function. The general rule is that if A + and B are compatible, then this function should return architecture + that is more "feature-rich", that is, can run both A and B. ARCv2, + EM and HS all has same mach number, so bfd_default_compatible + assumes they are the same, and returns an A. That causes issues + with GDB, because GDB assumes that if machines are compatible, then + "compatible ()" always returns same machine regardless of argument + order. As a result GDB gets confused because, for example, + compatible (ARCv2, EM) returns ARCv2, but compatible (EM, ARCv2) + returns EM, hence GDB is not sure if they are compatible and prints + a warning. */ =20 static const bfd_arch_info_type * -arc_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b) +arc_compatible (const bfd_arch_info_type *a ATTRIBUTE_UNUSED, + const bfd_arch_info_type *b ATTRIBUTE_UNUSED) { const bfd_arch_info_type * const em =3D &arch_info_struct[5]; const bfd_arch_info_type * const hs =3D &arch_info_struct[6]; @@ -84,9 +86,6 @@ arc_compatible (const bfd_arch_info_type *a, const bfd_ar= ch_info_type *b) if (a->arch !=3D b->arch) return NULL; =20 - if (a->bits_per_word !=3D b->bits_per_word) - return NULL; - /* ARCv2|EM and EM. */ if ((a->mach =3D=3D bfd_mach_arc_arcv2 && b =3D=3D em) || (b->mach =3D=3D bfd_mach_arc_arcv2 && a =3D=3D em)) diff --git a/bfd/cpu-arc64.c b/bfd/cpu-arc64.c new file mode 100644 index 00000000000..a1c3a2e23b9 --- /dev/null +++ b/bfd/cpu-arc64.c @@ -0,0 +1,75 @@ +/* BFD support for the ARC64 processor + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" + +/* ARC64-specific "compatible" function. The general rule is that if + A and B are compatible, then this function should return + architecture that is more "feature-rich", that is, can run both A + and B. */ + +static const bfd_arch_info_type * +compatible (const bfd_arch_info_type *a ATTRIBUTE_UNUSED, + const bfd_arch_info_type *b ATTRIBUTE_UNUSED) +{ + /* If a & b are for different architecture we can do nothing. */ + if (a->arch !=3D b->arch) + return NULL; + + /* If a & b are for the same machine then all is well. */ + if (a->mach =3D=3D b->mach) + return a; + + /* Otherwise if either a or b is the 'default' machine + then it can be polymorphed into the other. */ + if (a->the_default) + return b; + + if (b->the_default) + return a; + + return NULL; +} + +#define ARC64(WORDSIZE, MACH, PRINT_NAME, DEFAULT_P, NEXT) \ + { \ + WORDSIZE, /* 64/32 bits in a word. */ \ + WORDSIZE, /* 64/32 bits in an address. */ \ + 8, /* 8 bits in a byte. */ \ + bfd_arch_arc64, \ + MACH, \ + "arc64", \ + PRINT_NAME, \ + 4, /* section alignment power. */ \ + DEFAULT_P, \ + compatible, \ + bfd_default_scan, \ + bfd_arch_default_fill, \ + NEXT, \ + 0 /* Maximum offset of a reloc from the start of an insn. */ \ + } + +static const bfd_arch_info_type bfd_arc64_arch_32 =3D + ARC64 (32, bfd_mach_arcv3_32, "arc64:32", false, NULL); + +const bfd_arch_info_type bfd_arc64_arch =3D + ARC64 (64, bfd_mach_arcv3_64, "arc64:64", true, &bfd_arc64_arch_32); diff --git a/bfd/elf32-arc.c b/bfd/elfnn-arc.c similarity index 68% rename from bfd/elf32-arc.c rename to bfd/elfnn-arc.c index ac9970545c3..04fce7eb6e0 100644 --- a/bfd/elf32-arc.c +++ b/bfd/elfnn-arc.c @@ -27,13 +27,43 @@ #include "libiberty.h" #include "opcode/arc-func.h" #include "opcode/arc.h" + +#define RELA_SIZE sizeof(ElfNN_External_Rela) + #include "arc-plt.h" =20 -#define FEATURE_LIST_NAME bfd_feature_list -#define CONFLICT_LIST bfd_conflict_list +#define FEATURE_LIST_NAME bfdNN_feature_list +#define CONFLICT_LIST bfdNN_conflict_list #include "opcode/arc-attrs.h" =20 -/* #define ARC_ENABLE_DEBUG 1 */ +/* Possible ARC architectures. */ +#define ARC 0 +#define ARC32 1 +#define ARC64 2 + +/* Arc's architecture size. */ +#define ARCH_SIZE NN + +/* Arc's architecture type. */ +#define ARCH_TYPE ARCAA + +/* Arc's BFD backend. There are two different backends, one for + ARCv1/v2 and the second for the ARCv3/64/32. They are + incompatible. */ +#define ARC_BFD_ARCH bfd_arch_arcAA + +/* The name of the dynamic interpreter. This is put in the .interp + section. */ + +#define ELF64_DYNAMIC_INTERPRETER "/lib/ld.so.1" +#define ELF32_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so" + +#define LOG_FILE_ALIGN (ARCH_SIZE =3D=3D 32 ? 2 : 3) + +/* Do not enable this unless you know what you are doing. + Code under this macro is not safe for production. + #define ARC_ENABLE_DEBUG 1 */ + #ifdef ARC_ENABLE_DEBUG static const char * name_for_global_symbol (struct elf_link_hash_entry *h) @@ -48,26 +78,27 @@ name_for_global_symbol (struct elf_link_hash_entry *h) #define ARC_DEBUG(...) #endif =20 - #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \ { \ struct elf_link_hash_table *_htab =3D elf_hash_table (info); \ Elf_Internal_Rela _rel; \ bfd_byte * _loc; \ + const struct elf_backend_data *bed; \ + bed =3D get_elf_backend_data (BFD); \ \ if (_htab->dynamic_sections_created) \ { \ BFD_ASSERT (_htab->srel##SECTION &&_htab->srel##SECTION->contents); \ _loc =3D _htab->srel##SECTION->contents \ + ((_htab->srel##SECTION->reloc_count) \ - * sizeof (Elf32_External_Rela)); \ + * sizeof (ElfNN_External_Rela)); \ _htab->srel##SECTION->reloc_count++; \ _rel.r_addend =3D ADDEND; \ _rel.r_offset =3D (_htab->s##SECTION)->output_section->vma \ + (_htab->s##SECTION)->output_offset + OFFSET; \ BFD_ASSERT ((long) SYM_IDX !=3D -1); \ - _rel.r_info =3D ELF32_R_INFO (SYM_IDX, TYPE); \ - bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \ + _rel.r_info =3D ELFNN_R_INFO (SYM_IDX, TYPE); \ + bed->s->swap_reloca_out (BFD, &_rel, _loc); \ } \ } =20 @@ -195,9 +226,11 @@ struct elf_arc_link_hash_entry #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B) #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B) #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B) +#define arc_bfd_get_64(A,B,C) bfd_get_64(A,B) #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C) #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C) #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C) +#define arc_bfd_put_64(A,B,C,D) bfd_put_64(A,B,C) =20 =20 static bfd_reloc_status_type @@ -230,10 +263,10 @@ arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, TYPE =3D VALUE, =20 enum howto_list -{ + { #include "elf/arc-reloc.def" - HOWTO_LIST_LAST -}; + HOWTO_LIST_LAST + }; =20 #undef ARC_RELOC_HOWTO =20 @@ -243,7 +276,7 @@ enum howto_list "R_" #TYPE, false, 0, 0, false), =20 static struct reloc_howto_struct elf_arc_howto_table[] =3D -{ + { #include "elf/arc-reloc.def" /* Example of what is generated by the preprocessor. Currently kept as an example. @@ -282,17 +315,6 @@ arc_elf_howto_init (void) } #undef ARC_RELOC_HOWTO =20 - -#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFL= OW, FORMULA) \ - [TYPE] =3D VALUE, - -const int howto_table_lookup[] =3D -{ -#include "elf/arc-reloc.def" -}; - -#undef ARC_RELOC_HOWTO - static reloc_howto_type * arc_elf_howto (unsigned int r_type) { @@ -327,7 +349,7 @@ elf_arc_link_hash_newfunc (struct bfd_hash_entry *entry, subclass. */ if (ret =3D=3D NULL) ret =3D (struct elf_arc_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct elf_arc_link_hash_entry)); + bfd_hash_allocate (table, sizeof (struct elf_arc_link_hash_entry)); if (ret =3D=3D NULL) return (struct bfd_hash_entry *) ret; =20 @@ -356,8 +378,9 @@ static struct bfd_link_hash_table * arc_elf_link_hash_table_create (bfd *abfd) { struct elf_arc_link_hash_table *ret; + bfd_size_type amt =3D sizeof (struct elf_arc_link_hash_table); =20 - ret =3D (struct elf_arc_link_hash_table *) bfd_zmalloc (sizeof (*ret)); + ret =3D (struct elf_arc_link_hash_table *) bfd_zmalloc (amt); if (ret =3D=3D NULL) return NULL; =20 @@ -379,24 +402,27 @@ arc_elf_link_hash_table_create (bfd *abfd) { BFD_RELOC_##TYPE, R_##TYPE }, =20 static const struct arc_reloc_map arc_reloc_map[] =3D -{ + { #include "elf/arc-reloc.def" =20 - {BFD_RELOC_NONE, R_ARC_NONE}, - {BFD_RELOC_8, R_ARC_8}, - {BFD_RELOC_16, R_ARC_16}, - {BFD_RELOC_24, R_ARC_24}, - {BFD_RELOC_32, R_ARC_32}, -}; + {BFD_RELOC_NONE, R_ARC_NONE}, + {BFD_RELOC_8, R_ARC_8}, + {BFD_RELOC_16, R_ARC_16}, + {BFD_RELOC_24, R_ARC_24}, + {BFD_RELOC_32, R_ARC_32}, + {BFD_RELOC_64, R_ARC_64}, + }; =20 #undef ARC_RELOC_HOWTO =20 -typedef ATTRIBUTE_UNUSED unsigned (*replace_func) (unsigned, int ATTRIBUTE= _UNUSED); +typedef ATTRIBUTE_UNUSED +bfd_vma (*replace_func) (bfd_vma, bfd_vma ATTRIBUTE_UNUSED); =20 -#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFL= OW, FORMULA) \ - case TYPE: \ - func =3D RELOC_FUNCTION; \ - break; +#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, \ + RELOC_FUNCTION, OVERFLOW, FORMULA) \ + case TYPE: \ + func =3D (void *) RELOC_FUNCTION; \ + break; =20 static replace_func get_replace_function (bfd *abfd, unsigned int r_type) @@ -405,7 +431,7 @@ get_replace_function (bfd *abfd, unsigned int r_type) =20 switch (r_type) { - #include "elf/arc-reloc.def" +#include "elf/arc-reloc.def" } =20 if (func =3D=3D replace_bits24 && bfd_big_endian (abfd)) @@ -416,7 +442,7 @@ get_replace_function (bfd *abfd, unsigned int r_type) #undef ARC_RELOC_HOWTO =20 static reloc_howto_type * -arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, +arc_elfNN_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) { unsigned int i; @@ -503,7 +529,7 @@ arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) } =20 static reloc_howto_type * -bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, +bfd_elfNN_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char *r_name) { unsigned int i; @@ -525,7 +551,7 @@ arc_info_to_howto_rel (bfd * abfd, { unsigned int r_type; =20 - r_type =3D ELF32_R_TYPE (dst->r_info); + r_type =3D ELFNN_R_TYPE (dst->r_info); if (r_type >=3D (unsigned int) R_ARC_max) { /* xgettext:c-format */ @@ -536,7 +562,7 @@ arc_info_to_howto_rel (bfd * abfd, } =20 cache_ptr->howto =3D arc_elf_howto (r_type); - return true; + return cache_ptr->howto !=3D NULL; } =20 /* Extract CPU features from an NTBS. */ @@ -549,14 +575,14 @@ arc_extract_features (const char *p) if (!p) return 0; =20 - for (i =3D 0; i < ARRAY_SIZE (bfd_feature_list); i++) + for (i =3D 0; i < ARRAY_SIZE (FEATURE_LIST_NAME); i++) { - char *t =3D strstr (p, bfd_feature_list[i].attr); - unsigned l =3D strlen (bfd_feature_list[i].attr); + char *t =3D strstr (p, FEATURE_LIST_NAME[i].attr); + unsigned l =3D strlen (FEATURE_LIST_NAME[i].attr); if ((t !=3D NULL) && (t[l] =3D=3D ',' || t[l] =3D=3D '\0')) - r |=3D bfd_feature_list[i].feature; + r |=3D FEATURE_LIST_NAME[i].feature; } =20 return r; @@ -629,20 +655,21 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_= info *info) case Tag_ARC_PCS_config: if (out_attr[i].i =3D=3D 0) out_attr[i].i =3D in_attr[i].i; - else if (in_attr[i].i !=3D 0 && out_attr[i].i !=3D in_attr[i].i) + else if ((in_attr[i].i & 0xff) !=3D 0 + && ((out_attr[i].i & 0xff) !=3D (in_attr[i].i & 0xff))) { const char *tagval[] =3D { "Absent", "Bare-metal/mwdt", - "Bare-metal/newlib", "Linux/uclibc", - "Linux/glibc" }; - BFD_ASSERT (in_attr[i].i < 5); - BFD_ASSERT (out_attr[i].i < 5); + "Bare-metal/newlib", "Linux/uclibc", + "Linux/glibc" }; + BFD_ASSERT ((in_attr[i].i & 0xff) < 5); + BFD_ASSERT ((out_attr[i].i & 0xff) < 5); /* It's sometimes ok to mix different configs, so this is only a warning. */ _bfd_error_handler (_("warning: %pB: conflicting platform configuration " "%s with %s"), ibfd, - tagval[in_attr[i].i], - tagval[out_attr[i].i]); + tagval[in_attr[i].i & 0xff], + tagval[out_attr[i].i & 0xff]); } break; =20 @@ -653,7 +680,7 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_in= fo *info) && ((out_attr[i].i + in_attr[i].i) < 6)) { const char *tagval[] =3D { "Absent", "ARC6xx", "ARC7xx", - "ARCEM", "ARCHS" }; + "ARCEM", "ARCHS" }; BFD_ASSERT (in_attr[i].i < 5); BFD_ASSERT (out_attr[i].i < 5); /* We cannot mix code for different CPUs. */ @@ -690,33 +717,33 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_= info *info) =20 /* First, check if a feature is compatible with the output object chosen CPU. */ - for (j =3D 0; j < ARRAY_SIZE (bfd_feature_list); j++) - if (((in_feature | out_feature) & bfd_feature_list[j].feature) - && (!(cpu_out & bfd_feature_list[j].cpus))) + for (j =3D 0; j < ARRAY_SIZE (FEATURE_LIST_NAME); j++) + if (((in_feature | out_feature) & FEATURE_LIST_NAME[j].feature) + && (!(cpu_out & FEATURE_LIST_NAME[j].cpus))) { _bfd_error_handler (_("error: %pB: unable to merge ISA extension attributes " "%s"), - obfd, bfd_feature_list[j].name); + obfd, FEATURE_LIST_NAME[j].name); result =3D false; break; } /* Second, if we have compatible features with the chosen CPU, check if they are compatible among them. */ - for (j =3D 0; j < ARRAY_SIZE (bfd_conflict_list); j++) - if (((in_feature | out_feature) & bfd_conflict_list[j]) - =3D=3D bfd_conflict_list[j]) + for (j =3D 0; j < ARRAY_SIZE (CONFLICT_LIST); j++) + if (((in_feature | out_feature) & CONFLICT_LIST[j]) + =3D=3D CONFLICT_LIST[j]) { unsigned k; - for (k =3D 0; k < ARRAY_SIZE (bfd_feature_list); k++) + for (k =3D 0; k < ARRAY_SIZE (FEATURE_LIST_NAME); k++) { - if (in_feature & bfd_feature_list[k].feature - & bfd_conflict_list[j]) - p1 =3D (char *) bfd_feature_list[k].name; - if (out_feature & bfd_feature_list[k].feature - & bfd_conflict_list[j]) - p2 =3D (char *) bfd_feature_list[k].name; + if (in_feature & FEATURE_LIST_NAME[k].feature + & CONFLICT_LIST[j]) + p1 =3D (char *) FEATURE_LIST_NAME[k].name; + if (out_feature & FEATURE_LIST_NAME[k].feature + & CONFLICT_LIST[j]) + p2 =3D (char *) FEATURE_LIST_NAME[k].name; } _bfd_error_handler (_("error: %pB: conflicting ISA extension attributes " @@ -728,9 +755,9 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_in= fo *info) /* Everithing is alright. */ out_feature |=3D in_feature; p1 =3D NULL; - for (j =3D 0; j < ARRAY_SIZE (bfd_feature_list); j++) - if (out_feature & bfd_feature_list[j].feature) - p1 =3D arc_stralloc (p1, bfd_feature_list[j].attr); + for (j =3D 0; j < ARRAY_SIZE (FEATURE_LIST_NAME); j++) + if (out_feature & FEATURE_LIST_NAME[j].feature) + p1 =3D arc_stralloc (p1, FEATURE_LIST_NAME[j].attr); if (p1) out_attr[Tag_ARC_ISA_config].s =3D _bfd_elf_attr_strdup (obfd, p1); @@ -784,7 +811,7 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_in= fo *info) if (out_attr[i].i =3D=3D 0) out_attr[i].i =3D in_attr[i].i; else if (out_attr[i].i !=3D 0 && in_attr[i].i !=3D 0 - && out_attr[i].i !=3D in_attr[i].i) + && out_attr[i].i !=3D in_attr[i].i) { _bfd_error_handler (_("error: %pB: conflicting attributes %s: %s with %s"), @@ -811,7 +838,7 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_in= fo *info) if (out_attr[i].i =3D=3D 0) out_attr[i].i =3D in_attr[i].i; else if (out_attr[i].i !=3D 0 && in_attr[i].i !=3D 0 - && out_attr[i].i !=3D in_attr[i].i) + && out_attr[i].i !=3D in_attr[i].i) { _bfd_error_handler (_("error: %pB: conflicting attributes %s"), @@ -865,10 +892,19 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd= _link_info *info) flagword in_flags; asection *sec; =20 - /* Check if we have the same endianess. */ + /* Check if we have the same endianess. */ if (! _bfd_generic_verify_endian_match (ibfd, info)) return false; =20 + if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) !=3D 0) + { + _bfd_error_handler + (_("%pB: ABI is incompatible with the selected emulation:\n" + " target emulation '%s' does not match '%s'"), + ibfd, bfd_get_target (ibfd), bfd_get_target (obfd)); + return false; + } + if (bfd_get_flavour (ibfd) !=3D bfd_target_elf_flavour || bfd_get_flavour (obfd) !=3D bfd_target_elf_flavour) return true; @@ -956,7 +992,7 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_l= ink_info *info) =20 if (bfd_get_mach (obfd) < bfd_get_mach (ibfd)) { - return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd)); + return bfd_set_arch_mach (obfd, ARC_BFD_ARCH, bfd_get_mach (ibfd)); } =20 return true; @@ -964,7 +1000,7 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_= link_info *info) =20 /* Return a best guess for the machine number based on the attributes. */ =20 -static unsigned int +static ATTRIBUTE_UNUSED unsigned int bfd_arc_get_mach_from_attributes (bfd * abfd) { int arch =3D bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ARC_CPU_= base); @@ -986,19 +1022,24 @@ bfd_arc_get_mach_from_attributes (bfd * abfd) ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2; } =20 -/* Set the right machine number for an ARC ELF file. */ +/* Set the right machine number for an ARC ELF file. Make sure this + is initialised, or you'll have the potential of passing + garbage---or misleading values---into the call to + bfd_default_set_arch_mach (). */ + static bool arc_elf_object_p (bfd * abfd) { - /* Make sure this is initialised, or you'll have the potential of passing - garbage---or misleading values---into the call to - bfd_default_set_arch_mach (). */ - unsigned int mach =3D bfd_mach_arc_arc700; - unsigned long arch =3D elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK; - unsigned e_machine =3D elf_elfheader (abfd)->e_machine; + unsigned int mach; + unsigned long ATTRIBUTE_UNUSED arch =3D elf_elfheader (abfd)->e_flags + & EF_ARC_MACH_MSK; + unsigned e_machine =3D elf_elfheader (abfd)->e_machine; =20 - if (e_machine =3D=3D EM_ARC_COMPACT || e_machine =3D=3D EM_ARC_COMPACT2) + switch (e_machine) { +#if (ARCH_TYPE =3D=3D ARC) && (ARCH_SIZE =3D=3D 32) + case EM_ARC_COMPACT: + case EM_ARC_COMPACT2: switch (arch) { case E_ARC_MACH_ARC600: @@ -1018,24 +1059,29 @@ arc_elf_object_p (bfd * abfd) mach =3D bfd_arc_get_mach_from_attributes (abfd); break; } - } - else - { - if (e_machine =3D=3D EM_ARC) - { - _bfd_error_handler - (_("error: the ARC4 architecture is no longer supported")); - return false; - } - else - { - _bfd_error_handler - (_("warning: unset or old architecture flags; " - "use default machine")); - } + break; + + case EM_ARC: + _bfd_error_handler + (_("error: the ARC4 architecture is no longer supported")); + return false; + +#else /* New ARCv3 arches. */ + case EM_ARC_COMPACT3_64: + mach =3D bfd_mach_arcv3_64; + break; + + case EM_ARC_COMPACT3: + mach =3D bfd_mach_arcv3_32; + break; +#endif + + default: + _bfd_error_handler (_("error: unset or old architecture flags.")); + return false; } =20 - return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach); + return bfd_default_set_arch_mach (abfd, ARC_BFD_ARCH, mach); } =20 /* The final processing done just before writing out an ARC ELF object fil= e. @@ -1049,6 +1095,7 @@ arc_elf_final_write_processing (bfd *abfd) Tag_ARC_ABI_osver); flagword e_flags =3D elf_elfheader (abfd)->e_flags & ~EF_ARC_OSABI_MSK; =20 +#if (ARCH_TYPE =3D=3D ARC) && (ARCH_SIZE =3D=3D 32) switch (bfd_get_mach (abfd)) { case bfd_mach_arc_arcv2: @@ -1058,7 +1105,21 @@ arc_elf_final_write_processing (bfd *abfd) emf =3D EM_ARC_COMPACT; break; } - +#else + switch (bfd_get_mach (abfd)) + { + case bfd_mach_arcv3_64: + emf =3D EM_ARC_COMPACT3_64; + break; + case bfd_mach_arcv3_32: + emf =3D EM_ARC_COMPACT3; + break; + default: + _bfd_error_handler (_("Unknown ARC architecture")); + bfd_set_error (bfd_error_sorry); + return false; + } +#endif elf_elfheader (abfd)->e_machine =3D emf; =20 /* Record whatever is the current syscall ABI version. */ @@ -1108,7 +1169,8 @@ debug_arc_reloc (struct arc_relocation_data reloc_dat= a) ARC_DEBUG (" Input_section:\n"); if (reloc_data.input_section !=3D NULL) { - ARC_DEBUG (" section name =3D %s, output_offset 0x%08x, output_sect= ion->vma =3D 0x%08x\n", + ARC_DEBUG (" section name =3D %s, output_offset 0x%08x, " \ + "output_section->vma =3D 0x%08x\n", reloc_data.input_section->name, (unsigned int) reloc_data.input_section->output_offset, (unsigned int) reloc_data.input_section->output_section->vma); @@ -1120,7 +1182,7 @@ debug_arc_reloc (struct arc_relocation_data reloc_dat= a) } else { - ARC_DEBUG (" input section is NULL\n"); + ARC_DEBUG ("\tinput section is NULL\n"); } } #else @@ -1134,14 +1196,14 @@ middle_endian_convert (bfd_vma insn, bool do_it) { insn =3D ((insn & 0xffff0000) >> 16) - | ((insn & 0xffff) << 16); + | ((insn & 0xffff) << 16); } return insn; } =20 -/* This function is called for relocations that are otherwise marked as NOT - requiring overflow checks. In here we perform non-standard checks of - the relocation value. */ +/* This function is called for relocations that are otherwise marked + as NOT requiring overflow checks. In here we perform non-standard + checks of the relocation value. */ =20 static inline bfd_reloc_status_type arc_special_overflow_checks (const struct arc_relocation_data reloc_data, @@ -1189,17 +1251,19 @@ arc_special_overflow_checks (const struct arc_reloc= ation_data reloc_data, =20 #define ME(reloc) (reloc) =20 -#define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") !=3D NULL) \ +#define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") !=3D NULL) \ && (!bfd_big_endian (BFD))) =20 -#define S ((bfd_signed_vma) (reloc_data.sym_value \ - + (reloc_data.sym_section->output_section !=3D NULL ? \ - (reloc_data.sym_section->output_offset \ - + reloc_data.sym_section->output_section->vma) : 0))) -#define L ((bfd_signed_vma) (reloc_data.sym_value \ - + (reloc_data.sym_section->output_section !=3D NULL ? \ - (reloc_data.sym_section->output_offset \ - + reloc_data.sym_section->output_section->vma) : 0))) +#define S \ + ((bfd_signed_vma) (reloc_data.sym_value \ + + (reloc_data.sym_section->output_section !=3D NULL ? \ + (reloc_data.sym_section->output_offset \ + + reloc_data.sym_section->output_section->vma) : 0))) +#define L \ + ((bfd_signed_vma) (reloc_data.sym_value \ + + (reloc_data.sym_section->output_section !=3D NULL ? \ + (reloc_data.sym_section->output_offset \ + + reloc_data.sym_section->output_section->vma) : 0))) #define A (reloc_data.reloc_addend) #define B (0) #define G (reloc_data.got_offset_value) @@ -1207,27 +1271,30 @@ arc_special_overflow_checks (const struct arc_reloc= ation_data reloc_data, #define GOT_BEGIN (htab->sgot->output_section->vma) =20 #define MES (0) - /* P: relative offset to PCL The offset should be to the - current location aligned to 32 bits. */ -#define P ((bfd_signed_vma) ( \ - ( \ - (reloc_data.input_section->output_section !=3D NULL ? \ - reloc_data.input_section->output_section->vma : 0) \ - + reloc_data.input_section->output_offset \ - + (reloc_data.reloc_offset - (bitsize >=3D 32 ? 4 : 0))) \ - & ~0x3)) -#define PDATA ((bfd_signed_vma) ( \ - (reloc_data.input_section->output_section->vma \ - + reloc_data.input_section->output_offset \ - + (reloc_data.reloc_offset)))) -#define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section= ->vma \ - + reloc_data.sym_section->output_offset) -#define FINAL_SECTSTART \ +/* P: relative offset to PCL The offset should be to the + current location aligned to 32 bits. */ +#define P ((bfd_signed_vma) \ + (((reloc_data.input_section->output_section !=3D NULL ? \ + reloc_data.input_section->output_section->vma : 0) \ + + reloc_data.input_section->output_offset \ + + (reloc_data.reloc_offset - (bitsize =3D=3D 32 ? 4 : \ + (bitsize =3D=3D 34 ? 2 : 0)))) \ + & ~0x3)) +#define PDATA \ + ((bfd_signed_vma) ((reloc_data.input_section->output_section->vma \ + + reloc_data.input_section->output_offset \ + + (reloc_data.reloc_offset)))) +#define SECTSTART \ + (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \ + + reloc_data.sym_section->output_offset) +#define FINAL_SECTSTART \ (bfd_signed_vma) (reloc_data.sym_section->output_section->vma) #define JLI (bfd_signed_vma) (reloc_data.sym_section->output_section->vma) #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma) #define TLS_REL (bfd_signed_vma)(tls_sec->output_section->vma) #define TLS_TBSS (align_power (TCB_SIZE, tls_sec->alignment_power)) +#define ICARRY insn +#define DEREFP (insn) =20 #define none (0) =20 @@ -1279,20 +1346,21 @@ arc_special_overflow_checks (const struct arc_reloc= ation_data reloc_data, #define PRINT_DEBUG_RELOC_INFO_BEFORE(...) #define PRINT_DEBUG_RELOC_INFO_AFTER =20 -#endif /* ARC_ENABLE_DEBUG */ +#endif /* ARC_ENABLE_DEBUG. */ =20 -#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFL= OW, FORMULA) \ +#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, \ + RELOC_FUNCTION, OVERFLOW, FORMULA) \ case R_##TYPE: \ - { \ - bfd_signed_vma bitsize ATTRIBUTE_UNUSED =3D BITSIZE; \ - relocation =3D FORMULA ; \ - PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \ - insn =3D middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \ - insn =3D (* get_replace_function (abfd, TYPE)) (insn, relocation); \ - insn =3D middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \ - PRINT_DEBUG_RELOC_INFO_AFTER; \ - } \ - break; + { \ + bfd_signed_vma bitsize ATTRIBUTE_UNUSED =3D BITSIZE; \ + relocation =3D FORMULA ; \ + PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \ + insn =3D middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \ + insn =3D (* get_replace_function (abfd, TYPE)) (insn, relocation); \ + insn =3D middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \ + PRINT_DEBUG_RELOC_INFO_AFTER; \ + } \ + break; =20 static bfd_reloc_status_type arc_do_relocation (bfd_byte * contents, @@ -1312,6 +1380,11 @@ arc_do_relocation (bfd_byte * contents, =20 switch (bfd_get_reloc_size (reloc_data.howto)) { + case 8: + insn =3D arc_bfd_get_64 (abfd, + contents + reloc_data.reloc_offset, + reloc_data.input_section); + break; case 4: insn =3D arc_bfd_get_32 (abfd, contents + reloc_data.reloc_offset, @@ -1374,7 +1447,7 @@ arc_do_relocation (bfd_byte * contents, DEBUG_ARC_RELOC (reloc_data); ARC_DEBUG ("Relocation value =3D signed -> %d, unsigned -> %u" ", hex -> (0x%08x)\n", - (int) relocation, (unsigned) relocation, (int) relocation); + (int) relocation, (unsigned) relocation, (int) relocation); =20 return flag; } @@ -1382,6 +1455,11 @@ arc_do_relocation (bfd_byte * contents, /* Write updated instruction back to memory. */ switch (bfd_get_reloc_size (reloc_data.howto)) { + case 8: + arc_bfd_put_64 (abfd, insn, + contents + reloc_data.reloc_offset, + reloc_data.input_section); + break; case 4: arc_bfd_put_32 (abfd, insn, contents + reloc_data.reloc_offset, @@ -1417,6 +1495,7 @@ arc_do_relocation (bfd_byte * contents, #undef SECTSTART #undef JLI #undef _SDA_BASE_ +#undef ICARRY #undef none =20 #undef ARC_RELOC_HOWTO @@ -1437,14 +1516,14 @@ arc_do_relocation (bfd_byte * contents, corresponding to the st_shndx field of each local symbol. */ static int -elf_arc_relocate_section (bfd * output_bfd, - struct bfd_link_info * info, - bfd * input_bfd, - asection * input_section, - bfd_byte * contents, - Elf_Internal_Rela * relocs, - Elf_Internal_Sym * local_syms, - asection ** local_sections) +elf_arc_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr * symtab_hdr; struct elf_link_hash_entry ** sym_hashes; @@ -1452,7 +1531,9 @@ elf_arc_relocate_section (bfd * output_bfd, Elf_Internal_Rela * wrel; Elf_Internal_Rela * relend; struct elf_link_hash_table * htab =3D elf_hash_table (info); + const struct elf_backend_data *bed; =20 + bed =3D get_elf_backend_data (output_bfd); symtab_hdr =3D &((elf_tdata (input_bfd))->symtab_hdr); sym_hashes =3D elf_sym_hashes (input_bfd); =20 @@ -1460,32 +1541,33 @@ elf_arc_relocate_section (bfd * output_bfd, relend =3D relocs + input_section->reloc_count; for (; rel < relend; wrel++, rel++) { - enum elf_arc_reloc_type r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - struct elf_link_hash_entry *h2; - const char *msg; - bool unresolved_reloc =3D false; + enum elf_arc_reloc_type r_type; + reloc_howto_type * howto; + unsigned long r_symndx; + struct elf_link_hash_entry * h; + Elf_Internal_Sym * sym; + asection * sec; + struct elf_link_hash_entry * h2; + const char * msg; + bool unresolved_reloc =3D false; + bool resolved_to_zero; =20 struct arc_relocation_data reloc_data =3D - { - .reloc_offset =3D 0, - .reloc_addend =3D 0, - .got_offset_value =3D 0, - .sym_value =3D 0, - .sym_section =3D NULL, - .howto =3D NULL, - .input_section =3D NULL, - .sdata_begin_symbol_vma =3D 0, - .sdata_begin_symbol_vma_set =3D false, - .got_symbol_vma =3D 0, - .should_relocate =3D false - }; - - r_type =3D ELF32_R_TYPE (rel->r_info); + { + .reloc_offset =3D 0, + .reloc_addend =3D 0, + .got_offset_value =3D 0, + .sym_value =3D 0, + .sym_section =3D NULL, + .howto =3D NULL, + .input_section =3D NULL, + .sdata_begin_symbol_vma =3D 0, + .sdata_begin_symbol_vma_set =3D false, + .got_symbol_vma =3D 0, + .should_relocate =3D false + }; + + r_type =3D ELFNN_R_TYPE (rel->r_info); =20 if (r_type >=3D (int) R_ARC_max) { @@ -1494,7 +1576,7 @@ elf_arc_relocate_section (bfd * output_bfd, } howto =3D arc_elf_howto (r_type); =20 - r_symndx =3D ELF32_R_SYM (rel->r_info); + r_symndx =3D ELFNN_R_SYM (rel->r_info); =20 /* If we are generating another .o file and the symbol in not local, skip this relocation. */ @@ -1596,9 +1678,9 @@ elf_arc_relocate_section (bfd * output_bfd, /* For ld -r, remove relocations in debug sections against sections defined in discarded sections. Not done for eh_frame editing code expects to be present. */ - if (bfd_link_relocatable (info) - && (input_section->flags & SEC_DEBUGGING)) - wrel--; + if (bfd_link_relocatable (info) + && (input_section->flags & SEC_DEBUGGING)) + wrel--; =20 continue; } @@ -1610,6 +1692,8 @@ elf_arc_relocate_section (bfd * output_bfd, continue; } =20 + resolved_to_zero =3D (h !=3D NULL && UNDEFWEAK_NO_DYNAMIC_RELOC (inf= o, h)); + if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */ { reloc_data.sym_value =3D sym->st_value; @@ -1638,7 +1722,7 @@ elf_arc_relocate_section (bfd * output_bfd, BFD_ASSERT (htab->sgot !=3D NULL || !is_reloc_for_GOT (howto)); if (htab->sgot !=3D NULL) reloc_data.got_symbol_vma =3D htab->sgot->output_section->vma - + htab->sgot->output_offset; + + htab->sgot->output_offset; =20 reloc_data.should_relocate =3D true; } @@ -1652,19 +1736,18 @@ elf_arc_relocate_section (bfd * output_bfd, =20 while (h->root.type =3D=3D bfd_link_hash_indirect || h->root.type =3D=3D bfd_link_hash_warning) - { - struct elf_arc_link_hash_entry *ah_old =3D - (struct elf_arc_link_hash_entry *) h; - h =3D (struct elf_link_hash_entry *) h->root.u.i.link; - struct elf_arc_link_hash_entry *ah =3D - (struct elf_arc_link_hash_entry *) h; - - if (ah->got_ents =3D=3D 0 && ah_old->got_ents !=3D ah->got_ents) - ah->got_ents =3D ah_old->got_ents; - } + { + struct elf_arc_link_hash_entry *ah_old + =3D (struct elf_arc_link_hash_entry *) h; + h =3D (struct elf_link_hash_entry *) h->root.u.i.link; + struct elf_arc_link_hash_entry *ah + =3D (struct elf_arc_link_hash_entry *) h; + + if (ah->got_ents =3D=3D 0 && ah_old->got_ents !=3D ah->got_ents) + ah->got_ents =3D ah_old->got_ents; + } =20 /* TODO: Need to validate what was the intention. */ - /* BFD_ASSERT ((h->dynindx =3D=3D -1) || (h->forced_local !=3D 0)); */ reloc_data.symbol_name =3D h->root.root.string; =20 /* If we have encountered a definition for this symbol. */ @@ -1681,13 +1764,13 @@ elf_arc_relocate_section (bfd * output_bfd, struct elf_arc_link_hash_entry *ah =3D (struct elf_arc_link_hash_entry *) h; /* TODO: Change it to use arc_do_relocation with - ARC_32 reloc. Try to use ADD_RELA macro. */ + ARC_32 reloc. Try to use ADD_RELA macro. */ bfd_vma relocation =3D reloc_data.sym_value + reloc_data.reloc_addend + (reloc_data.sym_section->output_section !=3D NULL ? - (reloc_data.sym_section->output_offset - + reloc_data.sym_section->output_section->vma) - : 0); + (reloc_data.sym_section->output_offset + + reloc_data.sym_section->output_section->vma) + : 0); =20 BFD_ASSERT (ah->got_ents); bfd_vma got_offset =3D ah->got_ents->offset; @@ -1718,7 +1801,8 @@ elf_arc_relocate_section (bfd * output_bfd, reloc_data.sym_section =3D htab->splt; reloc_data.should_relocate =3D true; } - else + /* See pr22269. */ + else if (!resolved_to_zero) continue; } else @@ -1752,11 +1836,12 @@ elf_arc_relocate_section (bfd * output_bfd, BFD_ASSERT (htab->sgot !=3D NULL || !is_reloc_for_GOT (howto)); if (htab->sgot !=3D NULL) reloc_data.got_symbol_vma =3D htab->sgot->output_section->vma - + htab->sgot->output_offset; + + htab->sgot->output_offset; } =20 - if ((is_reloc_for_GOT (howto) - || is_reloc_for_TLS (howto))) + if (is_reloc_for_GOT (howto) + || (is_reloc_for_TLS (howto) + && !resolved_to_zero)) { reloc_data.should_relocate =3D true; =20 @@ -1776,106 +1861,109 @@ elf_arc_relocate_section (bfd * output_bfd, =20 if (h =3D=3D NULL) { - create_got_dynrelocs_for_single_entry ( - got_entry_for_type (list, - arc_got_entry_type_for_reloc (howto)), - output_bfd, info, NULL); + create_got_dynrelocs_for_single_entry + (got_entry_for_type (list, + arc_got_entry_type_for_reloc (howto)), + output_bfd, info, NULL); } } =20 =20 -#define IS_ARC_PCREL_TYPE(TYPE) \ - ( (TYPE =3D=3D R_ARC_PC32) \ - || (TYPE =3D=3D R_ARC_32_PCREL)) +#define IS_ARC_PCREL_TYPE(TYPE) \ + ((TYPE =3D=3D R_ARC_PC32) \ + || (TYPE =3D=3D R_ARC_32_PCREL)) =20 switch (r_type) { - case R_ARC_32: - case R_ARC_32_ME: - case R_ARC_PC32: - case R_ARC_32_PCREL: - if (bfd_link_pic (info) - && (input_section->flags & SEC_ALLOC) !=3D 0 - && (!IS_ARC_PCREL_TYPE (r_type) - || (h !=3D NULL - && h->dynindx !=3D -1 - && !h->def_regular - && (!info->symbolic || !h->def_regular)))) - { - Elf_Internal_Rela outrel; - bfd_byte *loc; - bool skip =3D false; - bool relocate =3D false; - asection *sreloc =3D _bfd_elf_get_dynamic_reloc_section - (input_bfd, input_section, - /*RELA*/ true); + case R_ARC_64: + case R_ARC_32: + case R_ARC_32_ME: + case R_ARC_PC32: + case R_ARC_32_PCREL: + case R_ARC_HI32_ME: + case R_ARC_LO32_ME: + if (bfd_link_pic (info) + && !resolved_to_zero + && (input_section->flags & SEC_ALLOC) !=3D 0 + && (!IS_ARC_PCREL_TYPE (r_type) + || (h !=3D NULL + && h->dynindx !=3D -1 + && (!SYMBOL_REFERENCES_LOCAL (info, h))))) + { + Elf_Internal_Rela outrel; + bfd_byte *loc; + bool skip =3D false; + bool relocate =3D false; + asection *sreloc =3D _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, + /*RELA*/ true); =20 - BFD_ASSERT (sreloc !=3D NULL); + BFD_ASSERT (sreloc !=3D NULL); =20 - outrel.r_offset =3D _bfd_elf_section_offset (output_bfd, - info, - input_section, - rel->r_offset); + outrel.r_offset =3D _bfd_elf_section_offset (output_bfd, + info, + input_section, + rel->r_offset); =20 if (outrel.r_offset =3D=3D (bfd_vma) -1) skip =3D true; =20 - outrel.r_addend =3D rel->r_addend; - outrel.r_offset +=3D (input_section->output_section->vma - + input_section->output_offset); + outrel.r_addend =3D rel->r_addend; + outrel.r_offset +=3D (input_section->output_section->vma + + input_section->output_offset); =20 - if (skip) - { - memset (&outrel, 0, sizeof outrel); + if (skip) + { + memset (&outrel, 0, sizeof outrel); + relocate =3D false; + } + else if (h !=3D NULL + && h->dynindx !=3D -1 + && (IS_ARC_PCREL_TYPE (r_type) + || !(bfd_link_executable (info) + || SYMBOLIC_BIND (info, h)) + || ! h->def_regular)) + { + BFD_ASSERT (h !=3D NULL); + if ((input_section->flags & SEC_ALLOC) !=3D 0) relocate =3D false; - } - else if (h !=3D NULL - && h->dynindx !=3D -1 - && (IS_ARC_PCREL_TYPE (r_type) - || !(bfd_link_executable (info) - || SYMBOLIC_BIND (info, h)) - || ! h->def_regular)) - { - BFD_ASSERT (h !=3D NULL); - if ((input_section->flags & SEC_ALLOC) !=3D 0) - relocate =3D false; - else - relocate =3D true; - - BFD_ASSERT (h->dynindx !=3D -1); - outrel.r_info =3D ELF32_R_INFO (h->dynindx, r_type); - } - else - { - /* Handle local symbols, they either do not have a - global hash table entry (h =3D=3D NULL), or are - forced local due to a version script - (h->forced_local), or the third condition is - legacy, it appears to say something like, for - links where we are pre-binding the symbols, or - there's not an entry for this symbol in the - dynamic symbol table, and it's a regular symbol - not defined in a shared object, then treat the - symbol as local, resolve it now. */ + else relocate =3D true; - /* outrel.r_addend =3D 0; */ - outrel.r_info =3D ELF32_R_INFO (0, R_ARC_RELATIVE); - } =20 - BFD_ASSERT (sreloc->contents !=3D 0); + BFD_ASSERT (h->dynindx !=3D -1); + outrel.r_info =3D ELFNN_R_INFO (h->dynindx, r_type); + } + else + { + /* Handle local symbols, they either do not have a + global hash table entry (h =3D=3D NULL), or are + forced local due to a version script + (h->forced_local), or the third condition is + legacy, it appears to say something like, for + links where we are pre-binding the symbols, or + there's not an entry for this symbol in the + dynamic symbol table, and it's a regular symbol + not defined in a shared object, then treat the + symbol as local, resolve it now. */ + relocate =3D true; + /* outrel.r_addend =3D 0; */ + outrel.r_info =3D ELFNN_R_INFO (0, R_ARC_RELATIVE); + } =20 - loc =3D sreloc->contents; - loc +=3D sreloc->reloc_count * sizeof (Elf32_External_Rela); - sreloc->reloc_count +=3D 1; + BFD_ASSERT (sreloc->contents !=3D 0); =20 - bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); + loc =3D sreloc->contents; + loc +=3D sreloc->reloc_count * sizeof (ElfNN_External_Rela); + sreloc->reloc_count +=3D 1; =20 - if (!relocate) - continue; - } - break; - default: - break; + bed->s->swap_reloca_out (output_bfd, &outrel, loc); + + if (!relocate) + continue; + } + break; + default: + break; } =20 if (is_reloc_SDA_relative (howto) @@ -1892,10 +1980,12 @@ elf_arc_relocate_section (bfd * output_bfd, /* Make sure we have with a dynamic linker. In case of GOT and PLT the sym_section should point to .got or .plt respectively. */ if ((is_reloc_for_GOT (howto) || is_reloc_for_PLT (howto)) - && reloc_data.sym_section =3D=3D NULL) + && reloc_data.sym_section =3D=3D NULL + && !resolved_to_zero) { _bfd_error_handler - (_("GOT and PLT relocations cannot be fixed with a non dynamic linker= ")); + (_("GOT and PLT relocations cannot be fixed with a non dynamic" \ + " linker")); bfd_set_error (bfd_error_bad_value); return false; } @@ -1908,18 +1998,20 @@ elf_arc_relocate_section (bfd * output_bfd, =20 case bfd_reloc_overflow: (*info->callbacks->reloc_overflow) - (info, (h ? &h->root : NULL), reloc_data.symbol_name, howto->name, (b= fd_vma) 0, - input_bfd, input_section, rel->r_offset); + (info, (h ? &h->root : NULL), reloc_data.symbol_name, howto->name, + (bfd_vma) 0, input_bfd, input_section, rel->r_offset); break; =20 case bfd_reloc_undefined: (*info->callbacks->undefined_symbol) - (info, reloc_data.symbol_name, input_bfd, input_section, rel->r_offse= t, true); + (info, reloc_data.symbol_name, input_bfd, input_section, + rel->r_offset, true); break; =20 case bfd_reloc_other: /* xgettext:c-format */ - msg =3D _("%pB(%pA): warning: unaligned access to symbol '%s' in the sm= all data area"); + msg =3D _("%pB(%pA): warning: unaligned access to symbol '%s' in the" \ + " small data area"); break; =20 case bfd_reloc_outofrange: @@ -1944,7 +2036,8 @@ elf_arc_relocate_section (bfd * output_bfd, } =20 if (msg) - _bfd_error_handler (msg, input_bfd, input_section, reloc_data.symbol_name= ); + _bfd_error_handler (msg, input_bfd, input_section, + reloc_data.symbol_name); return false; } =20 @@ -1988,7 +2081,7 @@ elf_arc_check_relocs (bfd * abfd, unsigned long r_symndx; struct elf_link_hash_entry *h; =20 - r_type =3D ELF32_R_TYPE (rel->r_info); + r_type =3D ELFNN_R_TYPE (rel->r_info); =20 if (r_type >=3D (int) R_ARC_max) { @@ -1998,7 +2091,7 @@ elf_arc_check_relocs (bfd * abfd, howto =3D arc_elf_howto (r_type); =20 /* Load symbol information. */ - r_symndx =3D ELF32_R_SYM (rel->r_info); + r_symndx =3D ELFNN_R_SYM (rel->r_info); if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */ h =3D NULL; else /* Global one. */ @@ -2012,8 +2105,13 @@ elf_arc_check_relocs (bfd * abfd, =20 switch (r_type) { + case R_ARC_8: + case R_ARC_16: case R_ARC_32: + case R_ARC_64: case R_ARC_32_ME: + case R_ARC_HI32_ME: + case R_ARC_LO32_ME: /* During shared library creation, these relocs should not appear in a shared library (as memory will be read only and the dynamic linker can not resolve these. However @@ -2042,39 +2140,52 @@ elf_arc_check_relocs (bfd * abfd, return false; } =20 - /* In some cases we are not setting the 'non_got_ref' - flag, even though the relocations don't require a GOT - access. We should extend the testing in this area to - ensure that no significant cases are being missed. */ - if (h) - h->non_got_ref =3D 1; - /* FALLTHROUGH */ - case R_ARC_PC32: - case R_ARC_32_PCREL: - if ((bfd_link_pic (info)) - && ((r_type !=3D R_ARC_PC32 && r_type !=3D R_ARC_32_PCREL) - || (h !=3D NULL - && (!info->symbolic || !h->def_regular)))) - { - if (sreloc =3D=3D NULL) - { - if (info->dynamic - && ! htab->dynamic_sections_created - && ! _bfd_elf_link_create_dynamic_sections (abfd, info)) - return false; - sreloc =3D _bfd_elf_make_dynamic_reloc_section (sec, dynobj, - 2, abfd, - /*rela*/ - true); - - if (sreloc =3D=3D NULL) - return false; - } - sreloc->size +=3D sizeof (Elf32_External_Rela); + /* In some cases we are not setting the 'non_got_ref' flag, + even though the relocations don't require a GOT access. + We should extend the testing in this area to ensure that + no significant cases are being missed. */ + if (h) + h->non_got_ref =3D 1; =20 - } - default: + /* We don't need to handle relocs into sections not going + into the "real" output. */ + if ((sec->flags & SEC_ALLOC) =3D=3D 0) break; + + /* No need to do anything if we're not creating a shared + object. */ + if (!bfd_link_pic (info) + || (h !=3D NULL + && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))) + break; + + /* fall through */ + case R_ARC_PC32: + case R_ARC_32_PCREL: + if (!bfd_link_pic (info)) + break; + + if (((r_type !=3D R_ARC_PC32 && r_type !=3D R_ARC_32_PCREL) + || (!SYMBOL_REFERENCES_LOCAL (info, h)))) + { + if (sreloc =3D=3D NULL) + { + if (info->dynamic + && ! htab->dynamic_sections_created + && ! _bfd_elf_link_create_dynamic_sections (abfd, info)) + return false; + sreloc =3D _bfd_elf_make_dynamic_reloc_section (sec, dynobj, + 2, abfd, + /* rela */ + true); + + if (sreloc =3D=3D NULL) + return false; + } + sreloc->size +=3D sizeof (ElfNN_External_Rela); + } + default: + break; } =20 if (is_reloc_for_PLT (howto)) @@ -2112,20 +2223,18 @@ elf_arc_check_relocs (bfd * abfd, if (! _bfd_elf_create_got_section (dynobj, info)) return false; =20 - arc_fill_got_info_for_reloc ( - arc_got_entry_type_for_reloc (howto), - get_got_entry_list_for_symbol (abfd, r_symndx, h), - info, - h); + arc_fill_got_info_for_reloc + (arc_got_entry_type_for_reloc (howto), + get_got_entry_list_for_symbol (abfd, r_symndx, h), + info, + h); } } =20 return true; } =20 -#define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so" - -static const struct plt_version_t * +static struct plt_version_t * arc_get_plt_version (struct bfd_link_info *info) { int i; @@ -2137,7 +2246,12 @@ arc_get_plt_version (struct bfd_link_info *info) (int) plt_versions[i].elem_size); } =20 - if (bfd_get_mach (info->output_bfd) =3D=3D bfd_mach_arc_arcv2) + if (bfd_get_mach (info->output_bfd) =3D=3D bfd_mach_arcv3_64) + { + return &(plt_versions[ELF_ARCV3_PIC]); + } + else if (bfd_get_mach (info->output_bfd) =3D=3D bfd_mach_arc_arcv2 + || bfd_get_mach (info->output_bfd) =3D=3D bfd_mach_arcv3_32) { if (bfd_link_pic (info)) return &(plt_versions[ELF_ARCV2_PIC]); @@ -2151,6 +2265,8 @@ arc_get_plt_version (struct bfd_link_info *info) else return &(plt_versions[ELF_ARC_ABS]); } + BFD_ASSERT (0); + return NULL; } =20 static bfd_vma @@ -2171,9 +2287,8 @@ add_symbol_to_plt (struct bfd_link_info *info) htab->splt->size +=3D plt_data->elem_size; ARC_DEBUG ("PLT_SIZE =3D %d\n", (int) htab->splt->size); =20 - htab->sgotplt->size +=3D 4; - htab->srelplt->size +=3D sizeof (Elf32_External_Rela); - + htab->sgotplt->size +=3D GOT_ENTRY_SIZE; + htab->srelplt->size +=3D sizeof (ElfNN_External_Rela); return ret; } =20 @@ -2193,11 +2308,11 @@ plt_do_relocs_for_symbol (bfd *abfd, =20 switch (SYM_ONLY (reloc->symbol)) { - case SGOT: - relocation - =3D htab->sgotplt->output_section->vma - + htab->sgotplt->output_offset + symbol_got_offset; - break; + case SGOT: + relocation + =3D htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + symbol_got_offset; + break; } relocation +=3D reloc->addend; =20 @@ -2208,26 +2323,26 @@ plt_do_relocs_for_symbol (bfd *abfd, reloc_offset -=3D (IS_INSN_24 (reloc->symbol)) ? 2 : 0; =20 relocation -=3D htab->splt->output_section->vma - + htab->splt->output_offset - + plt_offset + reloc_offset; + + htab->splt->output_offset + + plt_offset + reloc_offset; } =20 /* TODO: being ME is not a property of the relocation but of the - section of which is applying the relocation. */ + section of which is applying the relocation. */ if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd)) { relocation =3D ((relocation & 0xffff0000) >> 16) - | ((relocation & 0xffff) << 16); + | ((relocation & 0xffff) << 16); } =20 switch (reloc->size) { - case 32: - bfd_put_32 (htab->splt->output_section->owner, - relocation, - htab->splt->contents + plt_offset + reloc->offset); - break; + case 32: + bfd_put_32 (htab->splt->output_section->owner, + relocation, + htab->splt->contents + plt_offset + reloc->offset); + break; } =20 reloc =3D &(reloc[1]); /* Jump to next relocation. */ @@ -2241,10 +2356,12 @@ relocate_plt_for_symbol (bfd *output_bfd, { const struct plt_version_t *plt_data =3D arc_get_plt_version (info); struct elf_link_hash_table *htab =3D elf_hash_table (info); + const struct elf_backend_data *bed; =20 bfd_vma plt_index =3D (h->plt.offset - plt_data->entry_size) - / plt_data->elem_size; - bfd_vma got_offset =3D (plt_index + 3) * 4; + / plt_data->elem_size; + bfd_vma got_offset =3D (plt_index + 3) * GOT_ENTRY_SIZE; + bed =3D get_elf_backend_data (output_bfd); =20 ARC_DEBUG ("arc_info: PLT_OFFSET =3D %#lx, PLT_ENTRY_VMA =3D %#lx, \ GOT_ENTRY_OFFSET =3D %#lx, GOT_ENTRY_VMA =3D %#lx, for symbol %s\n", @@ -2293,32 +2410,30 @@ GOT_ENTRY_OFFSET =3D %#lx, GOT_ENTRY_VMA =3D %#lx, = for symbol %s\n", rel.r_addend =3D 0; =20 BFD_ASSERT (h->dynindx !=3D -1); - rel.r_info =3D ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT); + rel.r_info =3D ELFNN_R_INFO (h->dynindx, R_ARC_JMP_SLOT); =20 loc =3D htab->srelplt->contents; - loc +=3D plt_index * sizeof (Elf32_External_Rela); /* relA */ - bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); + loc +=3D plt_index * sizeof (ElfNN_External_Rela); /* relA */ + bed->s->swap_reloca_out (output_bfd, &rel, loc); } } =20 +/* Initialize the PLT with ARC specific PLT header. See arc-plt.def. + Use middle-endian to fill in the data as it is executable code. */ + static void relocate_plt_for_entry (bfd *abfd, struct bfd_link_info *info) { const struct plt_version_t *plt_data =3D arc_get_plt_version (info); struct elf_link_hash_table *htab =3D elf_hash_table (info); + bfd_vma i =3D 0; + uint16_t *ptr =3D (uint16_t *) plt_data->entry; =20 - { - bfd_vma i =3D 0; - uint16_t *ptr =3D (uint16_t *) plt_data->entry; - for (i =3D 0; i < plt_data->entry_size/2; i++) - { - uint16_t data =3D ptr[i]; - bfd_put_16 (abfd, - (bfd_vma) data, - htab->splt->contents + (i*2)); - } - } + for (i =3D 0; i < plt_data->entry_size/2; i++) + { + bfd_put_16 (abfd, (bfd_vma) ptr[i], htab->splt->contents + (i*2)); + } PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs); } =20 @@ -2330,7 +2445,7 @@ relocate_plt_for_entry (bfd *abfd, =20 static bool elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h) + struct elf_link_hash_entry *h) { asection *s; bfd *dynobj =3D (elf_hash_table (info))->dynobj; @@ -2432,7 +2547,7 @@ elf_arc_adjust_dynamic_symbol (struct bfd_link_info *= info, struct elf_arc_link_hash_table *arc_htab =3D elf_arc_hash_table (inf= o); =20 BFD_ASSERT (arc_htab->elf.srelbss !=3D NULL); - arc_htab->elf.srelbss->size +=3D sizeof (Elf32_External_Rela); + arc_htab->elf.srelbss->size +=3D sizeof (ElfNN_External_Rela); h->needs_copy =3D 1; } =20 @@ -2445,7 +2560,7 @@ elf_arc_adjust_dynamic_symbol (struct bfd_link_info *= info, =20 /* Function : elf_arc_finish_dynamic_symbol Brief : Finish up dynamic symbol handling. We set the - contents of various dynamic sections here. + contents of various dynamic sections here. Args : output_bfd : info : h : @@ -2458,6 +2573,10 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd, struct elf_link_hash_entry *h, Elf_Internal_Sym * sym) { + const struct elf_backend_data *bed; + + bed =3D get_elf_backend_data (output_bfd); + if (h->plt.offset !=3D (bfd_vma) -1) { relocate_plt_for_symbol (output_bfd, info, h); @@ -2475,12 +2594,8 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd, create respective dynamic relocs. */ /* TODO: Make function to get list and not access the list directly. */ /* TODO: Move function to relocate_section create this relocs eagerly. = */ - struct elf_arc_link_hash_entry *ah =3D - (struct elf_arc_link_hash_entry *) h; - create_got_dynrelocs_for_got_info (&ah->got_ents, - output_bfd, - info, - h); + struct elf_arc_link_hash_entry *ah =3D (struct elf_arc_link_hash_entry *= ) h; + create_got_dynrelocs_for_got_info (&ah->got_ents, output_bfd, info, h); =20 if (h->needs_copy) { @@ -2500,7 +2615,7 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd, + h->root.u.def.section->output_offset); =20 bfd_byte * loc =3D arc_htab->elf.srelbss->contents - + (arc_htab->elf.srelbss->reloc_count * sizeof (Elf32_External_Rela)); + + (arc_htab->elf.srelbss->reloc_count * sizeof (ElfNN_External_Rela)); arc_htab->elf.srelbss->reloc_count++; =20 Elf_Internal_Rela rel; @@ -2508,9 +2623,9 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd, rel.r_offset =3D rel_offset; =20 BFD_ASSERT (h->dynindx !=3D -1); - rel.r_info =3D ELF32_R_INFO (h->dynindx, R_ARC_COPY); + rel.r_info =3D ELFNN_R_INFO (h->dynindx, R_ARC_COPY); =20 - bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); + bed->s->swap_reloca_out (output_bfd, &rel, loc); } =20 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ @@ -2554,8 +2669,7 @@ arc_create_forced_local_got_entries_for_tls (struct b= fd_hash_entry *bh, while (list !=3D NULL) { create_got_dynrelocs_for_single_entry (list, tmp->output_bfd, - tmp->info, - (struct elf_link_hash_entry *) h); + tmp->info, (struct elf_link_hash_entry *) h); list =3D list->next; } } @@ -2579,14 +2693,17 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd, struct elf_link_hash_table *htab =3D elf_hash_table (info); bfd *dynobj =3D (elf_hash_table (info))->dynobj; asection *sdyn =3D bfd_get_linker_section (dynobj, ".dynamic"); + const struct elf_backend_data *bed =3D get_elf_backend_data (output_bfd); =20 + /* TODO: instead of checking for sdyn, we can use elf_hash_table + (info)->dynamic_sections_created to see if we have dynamic + sections creared. */ if (sdyn) { - Elf32_External_Dyn *dyncon, *dynconend; + ElfNN_External_Dyn *dyncon, *dynconend; =20 - dyncon =3D (Elf32_External_Dyn *) sdyn->contents; - dynconend - =3D (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); + dyncon =3D (ElfNN_External_Dyn *) sdyn->contents; + dynconend =3D (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size); for (; dyncon < dynconend; dyncon++) { Elf_Internal_Dyn internal_dyn; @@ -2595,20 +2712,20 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd, struct elf_link_hash_entry *h =3D NULL; asection *s =3D NULL; =20 - bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn); + bed->s->swap_dyn_in (dynobj, dyncon, &internal_dyn); =20 switch (internal_dyn.d_tag) { GET_SYMBOL_OR_SECTION (DT_INIT, info->init_function, NULL) - GET_SYMBOL_OR_SECTION (DT_FINI, info->fini_function, NULL) - GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt") - GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt") - GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt") - GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version") - GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d") - GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r") - default: - break; + GET_SYMBOL_OR_SECTION (DT_FINI, info->fini_function, NULL) + GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt") + GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt") + GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt") + GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version") + GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d") + GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r") + default: + break; } =20 /* In case the dynamic symbols should be updated with a symbol. */ @@ -2659,9 +2776,10 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd, } =20 if (do_it) - bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon); + bed->s->swap_dyn_out (output_bfd, &internal_dyn, dyncon); } =20 + /* Fill in the first entry in the procedure linkage table. */ if (htab->splt->size > 0) { relocate_plt_for_entry (output_bfd, info); @@ -2670,30 +2788,40 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd, /* TODO: Validate this. */ if (htab->srelplt->output_section !=3D bfd_abs_section_ptr) elf_section_data[...] [diff truncated at 100000 bytes]