From: Ian Lance Taylor Date: Wed, 29 May 1996 20:33:00 +0000 (+0000) Subject: 64-bit MIPS ELF ABI objdump support: X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d1bf45aa9433f77547b091015145da0109f17917;p=binutils-gdb.git 64-bit MIPS ELF ABI objdump support: * elf64-mips.c: New file. * Makefile.in: Rebuild dependencies. (BFD64_BACKENDS): Add elf64-mips.o. (BFD64_BACKENDS_CFILES): Add elf64-mips.c. * config.bfd (mips*el-*-elf*) Add bfd_elf64_bigmips_vec and bfd_elf64_littlemips_vec to targ_selvecs. (mips*-*-elf*): Likewise. * confingure.in: Add bfd_elf64_bigmips_vec and bfd_elf64_littlemips_vec to vector switch. * configure: Rebuild. * elf32-mips.c (_bfd_mips_elf_section_from_shdr): New function, broken out of mips_elf_section_from_shdr. (mips_elf32_section_from_shdr): Rename from mips_elf_section_from_shdr. Call new function. (elf_backend_section_from_shdr): Update name of renamed function. * elf-bfd.h (struct elf_size_info): Change second parameter of write_out_phdrs to be const. Likewise for second parameter of swap_symbol_out. (struct bfd_elf_section_data): Add rel_hdr2 field. (bfd_elf32_swap_symbol_in): Change second parameter to be const. (bfd_elf32_swap_symbol_out): Likewise. (bfd_elf32_swap_reloc_in): Likewise. (bfd_elf32_swap_reloc_out): Likewise. (bfd_elf32_swap_reloca_in): Likewise. (bfd_elf32_swap_reloca_out): Likewise. (bfd_elf32_swap_phdr_in): Likewise. (bfd_elf32_swap_phdr_out): Likewise. (bfd_elf32_swap_dyn_in): Likewise. (bfd_elf32_swap_dyn_out): Likewise. (bfd_elf32_slurp_symbol_table): Declare. (bfd_elf32_write_shdrs_and_ehdr): Declare. (bfd_elf32_write_out_phdrs): Declare. (bfd_elf64_swap_symbol_in): Change second parameter to be const. (bfd_elf64_swap_symbol_out): Likewise. (bfd_elf64_swap_reloc_in): Likewise. (bfd_elf64_swap_reloc_out): Likewise. (bfd_elf64_swap_reloca_in): Likewise. (bfd_elf64_swap_reloca_out): Likewise. (bfd_elf64_swap_phdr_in): Likewise. (bfd_elf64_swap_phdr_out): Likewise. (bfd_elf64_swap_dyn_in): Likewise. (bfd_elf64_swap_dyn_out): Likewise. (bfd_elf64_slurp_symbol_table): Declare. (bfd_elf64_write_shdrs_and_ehdr): Declare. (bfd_elf64_write_out_phdrs): Declare. (_bfd_mips_elf_section_from_shdr): Declare. * elf.c (bfd_section_from_shdr): Remove assertion requiring SHT_REL/SHT_RELA to match use_rela_p. If there is already a reloc section for the section, add the new one to rel_hdr2. Increment reloc_count rather than setting it. * elfcode.h (elf_slurp_symbol_table): Define name as macro. Remove static declaration. (elf_write_shdrs_and_ehdr): Define name as macro. (elf_write_out_phdrs): Likewise. (elf_swap_ehdr_in, elf_swap_ehdr_out): Declare. (elf_swap_shdr_in, elf_swap_shdr_out): Declare. (elf_swap_symbol_in): Change second parameter to be const. (elf_swap_symbol_out): Likewise. (elf_swap_ehdr_in, elf_swap_ehdr_out): Likewise. (elf_swap_shdr_in, elf_swap_shdr_out): Likewise. (elf_swap_phdr_in, elf_swap_phdr_out): Likewise. (elf_swap_reloc_in, elf_swap_reloc_out): Likewise. (elf_swap_reloca_in, elf_swap_reloca_out): Likewise. (elf_write_out_phdrs): Rename from write_out_phdrs. Change second parameter to be const. Make non-static. (elf_write_shdrs_and_ehdr): Rename from write_shdrs_and_ehdr. Make non-static. (elf_slurp_symbol_table): Make non-static. (NAME(_bfd_elf,size_info)): Update names of renamed functions. * elfxx-target.h (elf_info_to_howto): Define if not defined. (elf_backend_size_info): Likewise. (elfNN_bed): Use elf_backend_size_info. * targets.c (bfd_elf64_bigmips_vec): Declare. (bfd_elf64_littlemips_vec): Declare. (bfd_target_vector): Add bfd_elf64_bigmips_vec and bfd_elf64_littlemips_vec if BFD64 is defined. --- diff --git a/bfd/.Sanitize b/bfd/.Sanitize index 4e9e373e86c..583ab699245 100644 --- a/bfd/.Sanitize +++ b/bfd/.Sanitize @@ -147,6 +147,7 @@ elf32-ppc.c elf32-sparc.c elf32.c elf64-gen.c +elf64-mips.c elf64-sparc.c elf64.c elfxx-target.h diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ce7eabcded2..26c512b1e4b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,85 @@ +Wed May 29 16:15:29 1996 Ian Lance Taylor + + 64-bit MIPS ELF ABI objdump support: + * elf64-mips.c: New file. + * Makefile.in: Rebuild dependencies. + (BFD64_BACKENDS): Add elf64-mips.o. + (BFD64_BACKENDS_CFILES): Add elf64-mips.c. + * config.bfd (mips*el-*-elf*) Add bfd_elf64_bigmips_vec and + bfd_elf64_littlemips_vec to targ_selvecs. + (mips*-*-elf*): Likewise. + * confingure.in: Add bfd_elf64_bigmips_vec and + bfd_elf64_littlemips_vec to vector switch. + * configure: Rebuild. + * elf32-mips.c (_bfd_mips_elf_section_from_shdr): New function, + broken out of mips_elf_section_from_shdr. + (mips_elf32_section_from_shdr): Rename from + mips_elf_section_from_shdr. Call new function. + (elf_backend_section_from_shdr): Update name of renamed function. + * elf-bfd.h (struct elf_size_info): Change second parameter of + write_out_phdrs to be const. Likewise for second parameter of + swap_symbol_out. + (struct bfd_elf_section_data): Add rel_hdr2 field. + (bfd_elf32_swap_symbol_in): Change second parameter to be const. + (bfd_elf32_swap_symbol_out): Likewise. + (bfd_elf32_swap_reloc_in): Likewise. + (bfd_elf32_swap_reloc_out): Likewise. + (bfd_elf32_swap_reloca_in): Likewise. + (bfd_elf32_swap_reloca_out): Likewise. + (bfd_elf32_swap_phdr_in): Likewise. + (bfd_elf32_swap_phdr_out): Likewise. + (bfd_elf32_swap_dyn_in): Likewise. + (bfd_elf32_swap_dyn_out): Likewise. + (bfd_elf32_slurp_symbol_table): Declare. + (bfd_elf32_write_shdrs_and_ehdr): Declare. + (bfd_elf32_write_out_phdrs): Declare. + (bfd_elf64_swap_symbol_in): Change second parameter to be const. + (bfd_elf64_swap_symbol_out): Likewise. + (bfd_elf64_swap_reloc_in): Likewise. + (bfd_elf64_swap_reloc_out): Likewise. + (bfd_elf64_swap_reloca_in): Likewise. + (bfd_elf64_swap_reloca_out): Likewise. + (bfd_elf64_swap_phdr_in): Likewise. + (bfd_elf64_swap_phdr_out): Likewise. + (bfd_elf64_swap_dyn_in): Likewise. + (bfd_elf64_swap_dyn_out): Likewise. + (bfd_elf64_slurp_symbol_table): Declare. + (bfd_elf64_write_shdrs_and_ehdr): Declare. + (bfd_elf64_write_out_phdrs): Declare. + (_bfd_mips_elf_section_from_shdr): Declare. + * elf.c (bfd_section_from_shdr): Remove assertion requiring + SHT_REL/SHT_RELA to match use_rela_p. If there is already a reloc + section for the section, add the new one to rel_hdr2. Increment + reloc_count rather than setting it. + * elfcode.h (elf_slurp_symbol_table): Define name as macro. + Remove static declaration. + (elf_write_shdrs_and_ehdr): Define name as macro. + (elf_write_out_phdrs): Likewise. + (elf_swap_ehdr_in, elf_swap_ehdr_out): Declare. + (elf_swap_shdr_in, elf_swap_shdr_out): Declare. + (elf_swap_symbol_in): Change second parameter to be const. + (elf_swap_symbol_out): Likewise. + (elf_swap_ehdr_in, elf_swap_ehdr_out): Likewise. + (elf_swap_shdr_in, elf_swap_shdr_out): Likewise. + (elf_swap_phdr_in, elf_swap_phdr_out): Likewise. + (elf_swap_reloc_in, elf_swap_reloc_out): Likewise. + (elf_swap_reloca_in, elf_swap_reloca_out): Likewise. + (elf_write_out_phdrs): Rename from write_out_phdrs. Change second + parameter to be const. Make non-static. + (elf_write_shdrs_and_ehdr): Rename from write_shdrs_and_ehdr. + Make non-static. + (elf_slurp_symbol_table): Make non-static. + (NAME(_bfd_elf,size_info)): Update names of renamed functions. + * elfxx-target.h (elf_info_to_howto): Define if not defined. + (elf_backend_size_info): Likewise. + (elfNN_bed): Use elf_backend_size_info. + * targets.c (bfd_elf64_bigmips_vec): Declare. + (bfd_elf64_littlemips_vec): Declare. + (bfd_target_vector): Add bfd_elf64_bigmips_vec and + bfd_elf64_littlemips_vec if BFD64 is defined. + + * libbfd.c (bfd_get_file_window): Add cast to fprintf argument. + Tue May 28 11:42:08 1996 Ian Lance Taylor * coff-sh.c (sh_relax_delete_bytes): Insert nop instructions, not diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 11d337c1d03..7245d7ac696 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -99,13 +99,13 @@ BFD_LIBS = \ archive.o archures.o bfd.o cache.o coffgen.o corefile.o \ format.o init.o libbfd.o opncls.o reloc.o \ section.o syms.o targets.o hash.o linker.o \ - elf.o srec.o binary.o tekhex.o ihex.o stab-syms.o + elf.o srec.o binary.o tekhex.o ihex.o stabs.o stab-syms.o BFD_LIBS_CFILES = \ archive.c archures.c bfd.c cache.c coffgen.c corefile.c \ format.c init.c libbfd.c opncls.c reloc.c \ section.c syms.c targets.c hash.c linker.c \ - elf.c srec.c binary.c tekhex.c ihex.c stab-syms.c + elf.c srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c # This list is alphabetized to make it easier to keep in sync # with the decls and initializer in archures.c. @@ -345,6 +345,7 @@ BFD64_BACKENDS = \ coff-alpha.o \ demo64.o \ elf64-gen.o \ + elf64-mips.o \ elf64-sparc.o \ elf64.o \ nlm32-alpha.o \ @@ -355,6 +356,7 @@ BFD64_BACKENDS_CFILES = \ coff-alpha.c \ demo64.c \ elf64-gen.c \ + elf64-mips.c \ elf64-sparc.c \ elf64.c \ nlm32-alpha.c \ @@ -825,6 +827,7 @@ srec.o: srec.c $(INCDIR)/libiberty.h binary.o: binary.c tekhex.o: tekhex.c $(INCDIR)/libiberty.h ihex.o: ihex.c $(INCDIR)/libiberty.h +stabs.o: stabs.c $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def stab-syms.o: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def cpu-a29k.o: cpu-a29k.c @@ -1079,6 +1082,9 @@ demo64.o: demo64.c aoutf1.h $(INCDIR)/aout/sun4.h libaout.h \ elf64-gen.o: elf64-gen.c elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \ elf64-target.h +elf64-mips.o: elf64-mips.c $(INCDIR)/bfdlink.h genlink.h \ + elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ + $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h elf64-target.h elf64-sparc.o: elf64-sparc.c elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \ $(INCDIR)/elf/sparc.h elf64-target.h diff --git a/bfd/configure b/bfd/configure index e4168c937bc..3b325a3031f 100755 --- a/bfd/configure +++ b/bfd/configure @@ -1766,11 +1766,15 @@ do # end-sanitize-arc bfd_elf32_big_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; bfd_elf32_bigmips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; + bfd_elf64_bigmips_vec) tb="$tb elf64-mips.o elf64.o elf32-mips.o elf32.o $elf ecofflink.o" + target64=true ;; bfd_elf32_hppa_vec) tb="$tb elf32-hppa.o elf32.o $elf" ;; bfd_elf32_i386_vec) tb="$tb elf32-i386.o elf32.o $elf" ;; bfd_elf32_i860_vec) tb="$tb elf32-i860.o elf32.o $elf" ;; bfd_elf32_little_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; bfd_elf32_littlemips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; + bfd_elf64_littlemips_vec) tb="$tb elf64-mips.o elf64.o elf32-mips.o elf32.o $elf ecofflink.o" + target64=true ;; bfd_elf32_m68k_vec) tb="$tb elf32-m68k.o elf32.o $elf" ;; bfd_elf32_m88k_vec) tb="$tb elf32-m88k.o elf32.o $elf" ;; bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.o elf32.o $elf" ;; @@ -1928,7 +1932,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1982,7 +1986,7 @@ else ac_cv_func_mmap=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:2059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_func_mmap=yes else @@ -2076,7 +2080,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff --git a/bfd/configure.in b/bfd/configure.in index 7c27e1d4d77..b04ca1ac014 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -23,7 +23,8 @@ AC_ARG_ENABLE(shared, [case "${enableval}" in yes) shared=true ;; no) shared=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for BFD shared option]) ;; + *bfd*) shared=true ;; + *) shared=false ;; esac])dnl AC_ARG_ENABLE(commonbfdlib, [ --enable-commonbfdlib build shared BFD/opcodes/libiberty library], @@ -418,11 +419,15 @@ do # end-sanitize-arc bfd_elf32_big_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; bfd_elf32_bigmips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; + bfd_elf64_bigmips_vec) tb="$tb elf64-mips.o elf64.o elf32-mips.o elf32.o $elf ecofflink.o" + target64=true ;; bfd_elf32_hppa_vec) tb="$tb elf32-hppa.o elf32.o $elf" ;; bfd_elf32_i386_vec) tb="$tb elf32-i386.o elf32.o $elf" ;; bfd_elf32_i860_vec) tb="$tb elf32-i860.o elf32.o $elf" ;; bfd_elf32_little_generic_vec) tb="$tb elf32-gen.o elf32.o $elf" ;; bfd_elf32_littlemips_vec) tb="$tb elf32-mips.o elf32.o $elf ecofflink.o" ;; + bfd_elf64_littlemips_vec) tb="$tb elf64-mips.o elf64.o elf32-mips.o elf32.o $elf ecofflink.o" + target64=true ;; bfd_elf32_m68k_vec) tb="$tb elf32-m68k.o elf32.o $elf" ;; bfd_elf32_m88k_vec) tb="$tb elf32-m88k.o elf32.o $elf" ;; bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.o elf32.o $elf" ;; @@ -488,6 +493,7 @@ do bfd_powerpcle_pe_vec) tb="$tb pe-ppc.o cofflink.o" ;; bfd_powerpc_pei_vec) tb="$tb pei-ppc.o cofflink.o" ;; bfd_powerpcle_pei_vec) tb="$tb pei-ppc.o cofflink.o" ;; + ppcboot_vec) tb="$tb ppcboot.o" ;; shcoff_vec) tb="$tb coff-sh.o cofflink.o" ;; # start-sanitize-rce rce_aout_vec) tb="$tb aout-rce.o aout32.o" ;; diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 987425ea7eb..7b9b2432214 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -158,6 +158,8 @@ struct elf_link_hash_table struct bfd_link_needed_list *needed; /* The _GLOBAL_OFFSET_TABLE_ symbol. */ struct elf_link_hash_entry *hgot; + /* A pointer to information used to link stabs in sections. */ + PTR stab_info; }; /* Look up an entry in an ELF linker hash table. */ @@ -187,10 +189,10 @@ struct elf_size_info { unsigned char arch_size, file_align; unsigned char elfclass, ev_current; - int (*write_out_phdrs) PARAMS ((bfd *, Elf_Internal_Phdr *, int)); + int (*write_out_phdrs) PARAMS ((bfd *, const Elf_Internal_Phdr *, int)); boolean (*write_shdrs_and_ehdr) PARAMS ((bfd *)); void (*write_relocs) PARAMS ((bfd *, asection *, PTR)); - void (*swap_symbol_out) PARAMS ((bfd *, Elf_Internal_Sym *, PTR)); + void (*swap_symbol_out) PARAMS ((bfd *, const Elf_Internal_Sym *, PTR)); boolean (*slurp_reloc_table) PARAMS ((bfd *, asection *, asymbol **)); long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean)); void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); @@ -464,6 +466,9 @@ struct bfd_elf_section_data /* The ELF header for the reloc section associated with this section, if any. */ Elf_Internal_Shdr rel_hdr; + /* If there is a second reloc section associated with this section, + as can happen on Irix 6, this field points to the header. */ + Elf_Internal_Shdr *rel_hdr2; /* The ELF section number of this section. Only used for an output file. */ int this_idx; @@ -481,6 +486,8 @@ struct bfd_elf_section_data record the dynamic symbol index for a section symbol corresponding to this section. */ long dynindx; + /* A pointer used for .stab linking optimizations. */ + PTR stab_info; /* A pointer available for the processor specific ELF backend. */ PTR tdata; }; @@ -794,25 +801,30 @@ extern boolean bfd_elf32_bfd_final_link PARAMS ((bfd *, struct bfd_link_info *)); extern void bfd_elf32_swap_symbol_in - PARAMS ((bfd *, Elf32_External_Sym *, Elf_Internal_Sym *)); + PARAMS ((bfd *, const Elf32_External_Sym *, Elf_Internal_Sym *)); extern void bfd_elf32_swap_symbol_out - PARAMS ((bfd *, Elf_Internal_Sym *, PTR)); + PARAMS ((bfd *, const Elf_Internal_Sym *, PTR)); extern void bfd_elf32_swap_reloc_in - PARAMS ((bfd *, Elf32_External_Rel *, Elf_Internal_Rel *)); + PARAMS ((bfd *, const Elf32_External_Rel *, Elf_Internal_Rel *)); extern void bfd_elf32_swap_reloc_out - PARAMS ((bfd *, Elf_Internal_Rel *, Elf32_External_Rel *)); + PARAMS ((bfd *, const Elf_Internal_Rel *, Elf32_External_Rel *)); extern void bfd_elf32_swap_reloca_in - PARAMS ((bfd *, Elf32_External_Rela *, Elf_Internal_Rela *)); + PARAMS ((bfd *, const Elf32_External_Rela *, Elf_Internal_Rela *)); extern void bfd_elf32_swap_reloca_out - PARAMS ((bfd *, Elf_Internal_Rela *, Elf32_External_Rela *)); + PARAMS ((bfd *, const Elf_Internal_Rela *, Elf32_External_Rela *)); extern void bfd_elf32_swap_phdr_in - PARAMS ((bfd *, Elf32_External_Phdr *, Elf_Internal_Phdr *)); + PARAMS ((bfd *, const Elf32_External_Phdr *, Elf_Internal_Phdr *)); extern void bfd_elf32_swap_phdr_out - PARAMS ((bfd *, Elf_Internal_Phdr *, Elf32_External_Phdr *)); + PARAMS ((bfd *, const Elf_Internal_Phdr *, Elf32_External_Phdr *)); extern void bfd_elf32_swap_dyn_in PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); extern void bfd_elf32_swap_dyn_out PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf32_External_Dyn *)); +extern long bfd_elf32_slurp_symbol_table + PARAMS ((bfd *, asymbol **, boolean)); +extern boolean bfd_elf32_write_shdrs_and_ehdr PARAMS ((bfd *)); +extern int bfd_elf32_write_out_phdrs + PARAMS ((bfd *, const Elf_Internal_Phdr *, int)); extern boolean bfd_elf32_add_dynamic_entry PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma)); extern boolean bfd_elf32_link_create_dynamic_sections @@ -830,25 +842,30 @@ extern boolean bfd_elf64_bfd_final_link PARAMS ((bfd *, struct bfd_link_info *)); extern void bfd_elf64_swap_symbol_in - PARAMS ((bfd *, Elf64_External_Sym *, Elf_Internal_Sym *)); + PARAMS ((bfd *, const Elf64_External_Sym *, Elf_Internal_Sym *)); extern void bfd_elf64_swap_symbol_out - PARAMS ((bfd *, Elf_Internal_Sym *, PTR)); + PARAMS ((bfd *, const Elf_Internal_Sym *, PTR)); extern void bfd_elf64_swap_reloc_in - PARAMS ((bfd *, Elf64_External_Rel *, Elf_Internal_Rel *)); + PARAMS ((bfd *, const Elf64_External_Rel *, Elf_Internal_Rel *)); extern void bfd_elf64_swap_reloc_out - PARAMS ((bfd *, Elf_Internal_Rel *, Elf64_External_Rel *)); + PARAMS ((bfd *, const Elf_Internal_Rel *, Elf64_External_Rel *)); extern void bfd_elf64_swap_reloca_in - PARAMS ((bfd *, Elf64_External_Rela *, Elf_Internal_Rela *)); + PARAMS ((bfd *, const Elf64_External_Rela *, Elf_Internal_Rela *)); extern void bfd_elf64_swap_reloca_out - PARAMS ((bfd *, Elf_Internal_Rela *, Elf64_External_Rela *)); + PARAMS ((bfd *, const Elf_Internal_Rela *, Elf64_External_Rela *)); extern void bfd_elf64_swap_phdr_in - PARAMS ((bfd *, Elf64_External_Phdr *, Elf_Internal_Phdr *)); + PARAMS ((bfd *, const Elf64_External_Phdr *, Elf_Internal_Phdr *)); extern void bfd_elf64_swap_phdr_out - PARAMS ((bfd *, Elf_Internal_Phdr *, Elf64_External_Phdr *)); + PARAMS ((bfd *, const Elf_Internal_Phdr *, Elf64_External_Phdr *)); extern void bfd_elf64_swap_dyn_in PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); extern void bfd_elf64_swap_dyn_out PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf64_External_Dyn *)); +extern long bfd_elf64_slurp_symbol_table + PARAMS ((bfd *, asymbol **, boolean)); +extern boolean bfd_elf64_write_shdrs_and_ehdr PARAMS ((bfd *)); +extern int bfd_elf64_write_out_phdrs + PARAMS ((bfd *, const Elf_Internal_Phdr *, int)); extern boolean bfd_elf64_add_dynamic_entry PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma)); extern boolean bfd_elf64_link_create_dynamic_sections @@ -857,4 +874,9 @@ extern boolean bfd_elf64_link_create_dynamic_sections #define bfd_elf32_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol #define bfd_elf64_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol +/* MIPS ELF specific routines. */ + +extern boolean _bfd_mips_elf_section_from_shdr + PARAMS ((bfd *, Elf_Internal_Shdr *, const char *)); + #endif /* _LIBELF_H_ */ diff --git a/bfd/elf.c b/bfd/elf.c index 6ede06aec84..599706794b3 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -584,6 +584,7 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc) table->bucketcount = 0; table->needed = NULL; table->hgot = NULL; + table->stab_info = NULL; return _bfd_link_hash_table_init (&table->root, abfd, newfunc); } @@ -800,7 +801,6 @@ bfd_section_from_shdr (abfd, shindex) { asection *target_sect; Elf_Internal_Shdr *hdr2; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; /* For some incomprehensible reason Oracle distributes libraries for Solaris in which some of the objects have @@ -845,30 +845,24 @@ bfd_section_from_shdr (abfd, shindex) if (hdr->sh_link != elf_onesymtab (abfd)) return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - /* Don't allow REL relocations on a machine that uses RELA and - vice versa. */ - /* @@ Actually, the generic ABI does suggest that both might be - used in one file. But the four ABI Processor Supplements I - have access to right now all specify that only one is used on - each of those architectures. It's conceivable that, e.g., a - bunch of absolute 32-bit relocs might be more compact in REL - form even on a RELA machine... */ - BFD_ASSERT (use_rela_p - ? (hdr->sh_type == SHT_RELA - && hdr->sh_entsize == bed->s->sizeof_rela) - : (hdr->sh_type == SHT_REL - && hdr->sh_entsize == bed->s->sizeof_rel)); - if (! bfd_section_from_shdr (abfd, hdr->sh_info)) return false; target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info); if (target_sect == NULL) return false; - hdr2 = &elf_section_data (target_sect)->rel_hdr; + if ((target_sect->flags & SEC_RELOC) == 0 + || target_sect->reloc_count == 0) + hdr2 = &elf_section_data (target_sect)->rel_hdr; + else + { + BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL); + hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2)); + elf_section_data (target_sect)->rel_hdr2 = hdr2; + } *hdr2 = *hdr; elf_elfsections (abfd)[shindex] = hdr2; - target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize; + target_sect->reloc_count += hdr->sh_size / hdr->sh_entsize; target_sect->flags |= SEC_RELOC; target_sect->relocation = NULL; target_sect->rel_filepos = hdr->sh_offset; diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index f049ef4a657..88be8529d77 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -96,7 +96,7 @@ static void mips_elf_final_write_processing static boolean mips_elf_set_private_flags PARAMS ((bfd *, flagword)); static boolean mips_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *)); static boolean mips_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean mips_elf_section_from_shdr +static boolean mips_elf32_section_from_shdr PARAMS ((bfd *, Elf32_Internal_Shdr *, char *)); static boolean mips_elf_fake_sections PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *)); @@ -1564,6 +1564,7 @@ mips_elf_copy_private_bfd_data (ibfd, obfd) || (elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags)); + elf_gp (obfd) = elf_gp (ibfd); elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; elf_flags_init (obfd) = true; return true; @@ -1647,17 +1648,17 @@ mips_elf_merge_private_bfd_data (ibfd, obfd) /* Handle a MIPS specific section when reading an object file. This is called when elfcode.h finds a section with an unknown type. + This routine supports both the 32-bit and 64-bit ELF ABI. + FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure how to. */ -static boolean -mips_elf_section_from_shdr (abfd, hdr, name) +boolean +_bfd_mips_elf_section_from_shdr (abfd, hdr, name) bfd *abfd; - Elf32_Internal_Shdr *hdr; - char *name; + Elf_Internal_Shdr *hdr; + const char *name; { - asection *newsect; - /* There ought to be a place to keep ELF backend specific flags, but at the moment there isn't one. We just keep track of the sections by their name, instead. Fortunately, the ABI gives @@ -1712,27 +1713,42 @@ mips_elf_section_from_shdr (abfd, hdr, name) if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) return false; - newsect = hdr->bfd_section; if (hdr->sh_type == SHT_MIPS_DEBUG) { - if (! bfd_set_section_flags (abfd, newsect, - (bfd_get_section_flags (abfd, newsect) + if (! bfd_set_section_flags (abfd, hdr->bfd_section, + (bfd_get_section_flags (abfd, + hdr->bfd_section) | SEC_DEBUGGING))) return false; } + return true; +} + +/* Handle a 32-bit MIPS ELF specific section. */ + +static boolean +mips_elf32_section_from_shdr (abfd, hdr, name) + bfd *abfd; + Elf_Internal_Shdr *hdr; + char *name; +{ + if (! _bfd_mips_elf_section_from_shdr (abfd, hdr, name)) + return false; + /* FIXME: We should record sh_info for a .gptab section. */ /* For a .reginfo section, set the gp value in the tdata information from the contents of this section. We need the gp value while - processing relocs, so we just get it now. */ + processing relocs, so we just get it now. The .reginfo section + is not used in the 64-bit MIPS ELF ABI. */ if (hdr->sh_type == SHT_MIPS_REGINFO) { Elf32_External_RegInfo ext; Elf32_RegInfo s; - if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext, + if (! bfd_get_section_contents (abfd, hdr->bfd_section, (PTR) &ext, (file_ptr) 0, sizeof ext)) return false; bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s); @@ -5923,7 +5939,7 @@ static const struct ecoff_debug_swap mips_elf_ecoff_debug_swap = #define elf_info_to_howto_rel mips_info_to_howto_rel #define elf_backend_sym_is_global mips_elf_sym_is_global #define elf_backend_object_p mips_elf_object_p -#define elf_backend_section_from_shdr mips_elf_section_from_shdr +#define elf_backend_section_from_shdr mips_elf32_section_from_shdr #define elf_backend_fake_sections mips_elf_fake_sections #define elf_backend_section_from_bfd_section \ mips_elf_section_from_bfd_section diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c new file mode 100644 index 00000000000..ae444aa36b8 --- /dev/null +++ b/bfd/elf64-mips.c @@ -0,0 +1,1554 @@ +/* MIPS-specific support for 64-bit ELF + Copyright 1996 Free Software Foundation, Inc. + Ian Lance Taylor, Cygnus Support + +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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" +#include "bfdlink.h" +#include "genlink.h" +#include "elf-bfd.h" +#include "elf/mips.h" + +/* This file supports the 64-bit MIPS ELF ABI. + + The MIPS 64-bit ELF ABI uses an unusual reloc format. This file + overrides the usual ELF reloc handling, and handles reading and + writing the relocations here. */ + +static void mips_elf64_swap_reloc_in + PARAMS ((bfd *, const Elf64_Mips_External_Rel *, + Elf64_Mips_Internal_Rel *)); +static void mips_elf64_swap_reloca_in + PARAMS ((bfd *, const Elf64_Mips_External_Rela *, + Elf64_Mips_Internal_Rela *)); +static void mips_elf64_swap_reloc_out + PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *, + Elf64_Mips_External_Rel *)); +static void mips_elf64_swap_reloca_out + PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *, + Elf64_Mips_External_Rela *)); +static reloc_howto_type *mips_elf64_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); +static boolean mips_elf64_slurp_one_reloc_table + PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *)); +static boolean mips_elf64_slurp_reloc_table + PARAMS ((bfd *, asection *, asymbol **)); +static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR)); +static boolean mips_elf64_section_from_shdr + PARAMS ((bfd *, Elf_Internal_Shdr *, char *)); + +/* The relocation types. */ + +enum mips_elf64_reloc_type +{ + R_MIPS_NONE = 0, + R_MIPS_16 = 1, + R_MIPS_32 = 2, + R_MIPS_ADD = 2, + R_MIPS_REL32 = 3, + R_MIPS_REL = 3, + R_MIPS_26 = 4, + R_MIPS_HI16 = 5, + R_MIPS_LO16 = 6, + R_MIPS_GPREL16 = 7, + R_MIPS_GPREL = 7, + R_MIPS_LITERAL = 8, + R_MIPS_GOT16 = 9, + R_MIPS_GOT = 9, + R_MIPS_PC16 = 10, + R_MIPS_CALL16 = 11, + R_MIPS_CALL = 11, + R_MIPS_GPREL32 = 12, + R_MIPS_SHIFT5 = 16, + R_MIPS_SHIFT6 = 17, + R_MIPS_64 = 18, + R_MIPS_GOT_DISP = 19, + R_MIPS_GOT_PAGE = 20, + R_MIPS_GOT_OFST = 21, + R_MIPS_GOT_HI16 = 22, + R_MIPS_GOT_LO16 = 23, + R_MIPS_SUB = 24, + R_MIPS_INSERT_A = 25, + R_MIPS_INSERT_B = 26, + R_MIPS_DELETE = 27, + R_MIPS_HIGHER = 28, + R_MIPS_HIGHEST = 29, + R_MIPS_CALL_HI16 = 30, + R_MIPS_CALL_LO16 = 31, + R_MIPS_SCN_DISP = 32, + R_MIPS_REL16 = 33, + R_MIPS_ADD_IMMEDIATE = 34 +}; + +/* In case we're on a 32-bit machine, construct a 64-bit "-1" value + from smaller values. Start with zero, widen, *then* decrement. */ +#define MINUS_ONE (((bfd_vma)0) - 1) + +/* FIXME: These need to be rewritten, or we need to use the versions + in elf32-mips.c. */ +#define mips_elf_hi16_reloc bfd_elf_generic_reloc +#define mips_elf_lo16_reloc bfd_elf_generic_reloc +#define mips_elf_gprel16_reloc bfd_elf_generic_reloc +#define mips_elf_got16_reloc bfd_elf_generic_reloc +#define mips_elf_gprel32_reloc bfd_elf_generic_reloc + +/* The relocation table used for SHT_REL sections. */ + +static reloc_howto_type mips_elf64_howto_table_rel[] = +{ + /* No relocation. */ + HOWTO (R_MIPS_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit relocation. */ + HOWTO (R_MIPS_16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_16", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit relocation. */ + HOWTO (R_MIPS_32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_32", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit symbol relative relocation. */ + HOWTO (R_MIPS_REL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_REL32", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 26 bit branch address. */ + HOWTO (R_MIPS_26, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_26", /* name */ + true, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of symbol value. */ + HOWTO (R_MIPS_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + mips_elf_hi16_reloc, /* special_function */ + "R_MIPS_HI16", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of symbol value. */ + HOWTO (R_MIPS_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + mips_elf_lo16_reloc, /* special_function */ + "R_MIPS_LO16", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_MIPS_GPREL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips_elf_gprel16_reloc, /* special_function */ + "R_MIPS_GPREL16", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to literal section. */ + HOWTO (R_MIPS_LITERAL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips_elf_gprel16_reloc, /* special_function */ + "R_MIPS_LITERAL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to global offset table. */ + HOWTO (R_MIPS_GOT16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips_elf_got16_reloc, /* special_function */ + "R_MIPS_GOT16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit PC relative reference. */ + HOWTO (R_MIPS_PC16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_PC16", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit call through global offset table. */ + /* FIXME: This is not handled correctly. */ + HOWTO (R_MIPS_CALL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit GP relative reference. */ + HOWTO (R_MIPS_GPREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + mips_elf_gprel32_reloc, /* special_function */ + "R_MIPS_GPREL32", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + { 13 }, + { 14 }, + { 15 }, + + /* A 5 bit shift field. */ + HOWTO (R_MIPS_SHIFT5, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 5, /* bitsize */ + false, /* pc_relative */ + 6, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SHIFT5", /* name */ + true, /* partial_inplace */ + 0x000007c0, /* src_mask */ + 0x000007c0, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 6 bit shift field. */ + /* FIXME: This is not handled correctly; a special function is + needed to put the most significant bit in the right place. */ + HOWTO (R_MIPS_SHIFT6, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 6, /* bitsize */ + false, /* pc_relative */ + 6, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SHIFT6", /* name */ + true, /* partial_inplace */ + 0x000007c4, /* src_mask */ + 0x000007c4, /* dst_mask */ + false), /* pcrel_offset */ + + /* 64 bit relocation. */ + HOWTO (R_MIPS_64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_64", /* name */ + true, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement in the global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_DISP, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_DISP", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement to page pointer in the global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_PAGE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_PAGE", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Offset from page pointer in the global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_OFST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_OFST", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_HI16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_LO16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 64 bit substraction. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_SUB, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SUB", /* name */ + true, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Insert the addend as an instruction. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_INSERT_A, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_INSERT_A", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Insert the addend as an instruction, and change all relocations + to refer to the old instruction at the address. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_INSERT_B, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_INSERT_B", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Delete a 32 bit instruction. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_DELETE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_DELETE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Get the higher value of a 64 bit addend. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_HIGHER, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_HIGHER", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Get the highest value of a 64 bit addend. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_HIGHEST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_HIGHEST", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_CALL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL_HI16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_CALL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL_LO16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* I'm not sure what the remaining relocs are, but they are defined + on Irix 6. */ + + HOWTO (R_MIPS_SCN_DISP, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SCN_DISP", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_MIPS_REL16, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_REL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_MIPS_ADD_IMMEDIATE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_ADD_IMMEDIATE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false) /* pcrel_offset */ +}; + +/* The relocation table used for SHT_RELA sections. */ + +static reloc_howto_type mips_elf64_howto_table_rela[] = +{ + /* No relocation. */ + HOWTO (R_MIPS_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit relocation. */ + HOWTO (R_MIPS_16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit relocation. */ + HOWTO (R_MIPS_32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_32", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit symbol relative relocation. */ + HOWTO (R_MIPS_REL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_REL32", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 26 bit branch address. */ + HOWTO (R_MIPS_26, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_26", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x3ffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of symbol value. */ + HOWTO (R_MIPS_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_HI16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of symbol value. */ + HOWTO (R_MIPS_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_LO16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_MIPS_GPREL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips_elf_gprel16_reloc, /* special_function */ + "R_MIPS_GPREL16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to literal section. */ + HOWTO (R_MIPS_LITERAL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips_elf_gprel16_reloc, /* special_function */ + "R_MIPS_LITERAL", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to global offset table. */ + HOWTO (R_MIPS_GOT16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips_elf_got16_reloc, /* special_function */ + "R_MIPS_GOT16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit PC relative reference. */ + HOWTO (R_MIPS_PC16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_PC16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit call through global offset table. */ + /* FIXME: This is not handled correctly. */ + HOWTO (R_MIPS_CALL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit GP relative reference. */ + HOWTO (R_MIPS_GPREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + mips_elf_gprel32_reloc, /* special_function */ + "R_MIPS_GPREL32", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + { 13 }, + { 14 }, + { 15 }, + + /* A 5 bit shift field. */ + HOWTO (R_MIPS_SHIFT5, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 5, /* bitsize */ + false, /* pc_relative */ + 6, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SHIFT5", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x000007c0, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 6 bit shift field. */ + /* FIXME: This is not handled correctly; a special function is + needed to put the most significant bit in the right place. */ + HOWTO (R_MIPS_SHIFT6, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 6, /* bitsize */ + false, /* pc_relative */ + 6, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SHIFT6", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x000007c4, /* dst_mask */ + false), /* pcrel_offset */ + + /* 64 bit relocation. */ + HOWTO (R_MIPS_64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_64", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement in the global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_DISP, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_DISP", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement to page pointer in the global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_PAGE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_PAGE", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Offset from page pointer in the global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_OFST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_OFST", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_HI16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_GOT_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_LO16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 64 bit substraction. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_SUB, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SUB", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Insert the addend as an instruction. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_INSERT_A, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_INSERT_A", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Insert the addend as an instruction, and change all relocations + to refer to the old instruction at the address. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_INSERT_B, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_INSERT_B", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Delete a 32 bit instruction. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_DELETE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_DELETE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Get the higher value of a 64 bit addend. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_HIGHER, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_HIGHER", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Get the highest value of a 64 bit addend. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_HIGHEST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_HIGHEST", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_CALL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL_HI16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + /* FIXME: Not handled correctly. */ + HOWTO (R_MIPS_CALL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL_LO16", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* I'm not sure what the remaining relocs are, but they are defined + on Irix 6. */ + + HOWTO (R_MIPS_SCN_DISP, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_SCN_DISP", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_MIPS_REL16, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_REL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_MIPS_ADD_IMMEDIATE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_ADD_IMMEDIATE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false) /* pcrel_offset */ +}; + +/* Swap in a MIPS 64-bit Rel reloc. */ + +static void +mips_elf64_swap_reloc_in (abfd, src, dst) + bfd *abfd; + const Elf64_Mips_External_Rel *src; + Elf64_Mips_Internal_Rel *dst; +{ + dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset); + dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym); + dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym); + dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3); + dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2); + dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type); +} + +/* Swap in a MIPS 64-bit Rela reloc. */ + +static void +mips_elf64_swap_reloca_in (abfd, src, dst) + bfd *abfd; + const Elf64_Mips_External_Rela *src; + Elf64_Mips_Internal_Rela *dst; +{ + dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset); + dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym); + dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym); + dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3); + dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2); + dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type); + dst->r_addend = bfd_h_get_64 (abfd, (bfd_byte *) src->r_addend); +} + +/* Swap out a MIPS 64-bit Rel reloc. */ + +static void +mips_elf64_swap_reloc_out (abfd, src, dst) + bfd *abfd; + const Elf64_Mips_Internal_Rel *src; + Elf64_Mips_External_Rel *dst; +{ + bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset); + bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym); + bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym); + bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3); + bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2); + bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type); +} + +/* Swap out a MIPS 64-bit Rela reloc. */ + +static void +mips_elf64_swap_reloca_out (abfd, src, dst) + bfd *abfd; + const Elf64_Mips_Internal_Rela *src; + Elf64_Mips_External_Rela *dst; +{ + bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset); + bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym); + bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym); + bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3); + bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2); + bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type); + bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset); +} + +/* A mapping from BFD reloc types to MIPS ELF reloc types. */ + +struct elf_reloc_map +{ + bfd_reloc_code_real_type bfd_reloc_val; + enum mips_elf64_reloc_type elf_reloc_val; +}; + +static CONST struct elf_reloc_map mips_reloc_map[] = +{ + { BFD_RELOC_NONE, R_MIPS_NONE, }, + { BFD_RELOC_16, R_MIPS_16 }, + { BFD_RELOC_32, R_MIPS_32 }, + { BFD_RELOC_64, R_MIPS_64 }, + { BFD_RELOC_CTOR, R_MIPS_64 }, + { BFD_RELOC_32_PCREL, R_MIPS_REL32 }, + { BFD_RELOC_MIPS_JMP, R_MIPS_26 }, + { BFD_RELOC_HI16_S, R_MIPS_HI16 }, + { BFD_RELOC_LO16, R_MIPS_LO16 }, + { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 }, + { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL }, + { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 }, + { BFD_RELOC_16_PCREL, R_MIPS_PC16 }, + { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 }, + { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 }, + { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 }, + { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 }, + { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 }, + { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 } +}; + +/* Given a BFD reloc type, return a howto structure. */ + +static reloc_howto_type * +mips_elf64_reloc_type_lookup (abfd, code) + bfd *abfd; + bfd_reloc_code_real_type code; +{ + unsigned int i; + + for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++) + { + if (mips_reloc_map[i].bfd_reloc_val == code) + { + int v; + + v = (int) mips_reloc_map[i].elf_reloc_val; + return &mips_elf64_howto_table_rel[v]; + } + } + + return NULL; +} + +/* Read the relocations from one reloc section. */ + +static boolean +mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr) + bfd *abfd; + asection *asect; + asymbol **symbols; + const Elf_Internal_Shdr *rel_hdr; +{ + PTR allocated = NULL; + bfd_byte *native_relocs; + arelent *relents; + arelent *relent; + unsigned int count; + unsigned int i; + int entsize; + reloc_howto_type *howto_table; + + allocated = (PTR) bfd_malloc (rel_hdr->sh_size); + if (allocated == NULL) + goto error_return; + + if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0 + || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)) + goto error_return; + + native_relocs = (bfd_byte *) allocated; + + relents = asect->relocation + asect->reloc_count; + + entsize = rel_hdr->sh_entsize; + BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel) + || entsize == sizeof (Elf64_Mips_External_Rela)); + + count = rel_hdr->sh_size / entsize; + + if (entsize == sizeof (Elf64_Mips_External_Rel)) + howto_table = mips_elf64_howto_table_rel; + else + howto_table = mips_elf64_howto_table_rela; + + relent = relents; + for (i = 0; i < count; i++, native_relocs += entsize) + { + Elf64_Mips_Internal_Rela rela; + boolean used_sym, used_ssym; + int ir; + + if (entsize == sizeof (Elf64_Mips_External_Rela)) + mips_elf64_swap_reloca_in (abfd, + (Elf64_Mips_External_Rela *) native_relocs, + &rela); + else + { + Elf64_Mips_Internal_Rel rel; + + mips_elf64_swap_reloc_in (abfd, + (Elf64_Mips_External_Rel *) native_relocs, + &rel); + rela.r_offset = rel.r_offset; + rela.r_sym = rel.r_sym; + rela.r_ssym = rel.r_ssym; + rela.r_type3 = rel.r_type3; + rela.r_type2 = rel.r_type2; + rela.r_type = rel.r_type; + rela.r_addend = 0; + } + + /* Each entry represents up to three actual relocations. */ + + used_sym = false; + used_ssym = false; + for (ir = 0; ir < 3; ir++) + { + enum mips_elf64_reloc_type type; + + switch (ir) + { + default: + abort (); + case 0: + type = (enum mips_elf64_reloc_type) rela.r_type; + break; + case 1: + type = (enum mips_elf64_reloc_type) rela.r_type2; + break; + case 2: + type = (enum mips_elf64_reloc_type) rela.r_type3; + break; + } + + if (type == R_MIPS_NONE) + { + /* There are no more relocations in this entry. If this + is the first entry, we need to generate a dummy + relocation so that the generic linker knows that + there has been a break in the sequence of relocations + applying to a particular address. */ + if (ir == 0) + { + relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) + relent->address = rela.r_offset; + else + relent->address = rela.r_offset - asect->vma; + relent->addend = 0; + relent->howto = &howto_table[(int) R_MIPS_NONE]; + ++relent; + } + break; + } + + /* Some types require symbols, whereas some do not. */ + switch (type) + { + case R_MIPS_NONE: + case R_MIPS_LITERAL: + case R_MIPS_INSERT_A: + case R_MIPS_INSERT_B: + case R_MIPS_DELETE: + relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + break; + + default: + if (! used_sym) + { + if (rela.r_sym == 0) + relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + else + { + asymbol **ps, *s; + + ps = symbols + rela.r_sym - 1; + s = *ps; + if ((s->flags & BSF_SECTION_SYM) == 0) + relent->sym_ptr_ptr = ps; + else + relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; + } + + used_sym = true; + } + else if (! used_ssym) + { + switch (rela.r_ssym) + { + case RSS_UNDEF: + relent->sym_ptr_ptr = + bfd_abs_section_ptr->symbol_ptr_ptr; + break; + + case RSS_GP: + case RSS_GP0: + case RSS_LOC: + /* FIXME: I think these need to be handled using + special howto structures. */ + BFD_ASSERT (0); + break; + + default: + BFD_ASSERT (0); + break; + } + + used_ssym = true; + } + else + relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + + break; + } + + /* The address of an ELF reloc is section relative for an + object file, and absolute for an executable file or + shared library. The address of a BFD reloc is always + section relative. */ + if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) + relent->address = rela.r_offset; + else + relent->address = rela.r_offset - asect->vma; + + relent->addend = rela.r_addend; + + relent->howto = &howto_table[(int) type]; + + ++relent; + } + } + + asect->reloc_count += relent - relents; + + if (allocated != NULL) + free (allocated); + + return true; + + error_return: + if (allocated != NULL) + free (allocated); + return false; +} + +/* Read the relocations. On Irix 6, there can be two reloc sections + associated with a single data section. */ + +static boolean +mips_elf64_slurp_reloc_table (abfd, asect, symbols) + bfd *abfd; + asection *asect; + asymbol **symbols; +{ + struct bfd_elf_section_data * const d = elf_section_data (asect); + + if (asect->relocation != NULL + || (asect->flags & SEC_RELOC) == 0 + || asect->reloc_count == 0) + return true; + + /* Allocate space for 3 arelent structures for each Rel structure. */ + asect->relocation = ((arelent *) + bfd_alloc (abfd, + asect->reloc_count * 3 * sizeof (arelent))); + if (asect->relocation == NULL) + return false; + + /* The slurp_one_reloc_table routine increments reloc_count. */ + asect->reloc_count = 0; + + if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr)) + return false; + if (d->rel_hdr2 != NULL) + { + if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, + d->rel_hdr2)) + return false; + } + + return true; +} + +/* Write out the relocations. */ + +static void +mips_elf64_write_relocs (abfd, sec, data) + bfd *abfd; + asection *sec; + PTR data; +{ + /* FIXME. */ + abort (); +} + +/* Handle a 64-bit MIPS ELF specific section. */ + +static boolean +mips_elf64_section_from_shdr (abfd, hdr, name) + bfd *abfd; + Elf_Internal_Shdr *hdr; + char *name; +{ + if (! _bfd_mips_elf_section_from_shdr (abfd, hdr, name)) + return false; + + return true; +} + +/* Relocations in the 64 bit MIPS ELF ABI are more complex than in + standard ELF. This structure is used to redirect the relocation + handling routines. */ + +const struct elf_size_info mips_elf64_size_info = +{ + sizeof (Elf64_External_Ehdr), + sizeof (Elf64_External_Phdr), + sizeof (Elf64_External_Shdr), + sizeof (Elf64_Mips_External_Rel), + sizeof (Elf64_Mips_External_Rela), + sizeof (Elf64_External_Sym), + sizeof (Elf64_External_Dyn), + sizeof (Elf_External_Note), + 64, /* arch_size */ + 8, /* file_align */ + ELFCLASS64, + EV_CURRENT, + bfd_elf64_write_out_phdrs, + bfd_elf64_write_shdrs_and_ehdr, + mips_elf64_write_relocs, + bfd_elf64_swap_symbol_out, + mips_elf64_slurp_reloc_table, + bfd_elf64_slurp_symbol_table, + bfd_elf64_swap_dyn_in +}; + +#define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec +#define TARGET_LITTLE_NAME "elf64-littlemips" +#define TARGET_BIG_SYM bfd_elf64_bigmips_vec +#define TARGET_BIG_NAME "elf64-bigmips" +#define ELF_ARCH bfd_arch_mips +#define ELF_MACHINE_CODE EM_MIPS +#define ELF_MAXPAGESIZE 0x1000 +#define elf_backend_size_info mips_elf64_size_info +#define elf_backend_section_from_shdr mips_elf64_section_from_shdr +#define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup + +#include "elf64-target.h" diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 85d991d3a39..405e79f6ce8 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -63,7 +63,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ it's cast in stone. */ -#include /* For strrchr and friends */ #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" @@ -100,6 +99,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out) #define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) #define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) +#define elf_slurp_symbol_table NAME(bfd_elf,slurp_symbol_table) #define elf_get_symtab NAME(bfd_elf,get_symtab) #define elf_canonicalize_dynamic_symtab \ NAME(bfd_elf,canonicalize_dynamic_symtab) @@ -115,6 +115,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_find_section NAME(bfd_elf,find_section) #define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols) #define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry) +#define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr) +#define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs) #define elf_link_create_dynamic_sections \ NAME(bfd_elf,link_create_dynamic_sections) #define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol @@ -141,6 +143,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Forward declarations of static functions */ +static void elf_swap_ehdr_in + PARAMS ((bfd *, const Elf_External_Ehdr *, Elf_Internal_Ehdr *)); +static void elf_swap_ehdr_out + PARAMS ((bfd *, const Elf_Internal_Ehdr *, Elf_External_Ehdr *)); +static void elf_swap_shdr_in + PARAMS ((bfd *, const Elf_External_Shdr *, Elf_Internal_Shdr *)); +static void elf_swap_shdr_out + PARAMS ((bfd *, const Elf_Internal_Shdr *, Elf_External_Shdr *)); + #define elf_stringtab_init _bfd_elf_stringtab_init extern struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void)); @@ -148,8 +159,6 @@ extern struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void)); extern boolean bfd_section_from_phdr PARAMS ((bfd *, Elf_Internal_Phdr *, int)); -static long elf_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean)); - static boolean elf_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **)); int _bfd_elf_symbol_from_bfd_symbol PARAMS ((bfd *, @@ -185,7 +194,7 @@ static char *elf_symbol_flags PARAMS ((flagword)); void elf_swap_symbol_in (abfd, src, dst) bfd *abfd; - Elf_External_Sym *src; + const Elf_External_Sym *src; Elf_Internal_Sym *dst; { dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name); @@ -202,7 +211,7 @@ elf_swap_symbol_in (abfd, src, dst) void elf_swap_symbol_out (abfd, src, cdst) bfd *abfd; - Elf_Internal_Sym *src; + const Elf_Internal_Sym *src; PTR cdst; { Elf_External_Sym *dst = (Elf_External_Sym *) cdst; @@ -221,7 +230,7 @@ elf_swap_symbol_out (abfd, src, cdst) static void elf_swap_ehdr_in (abfd, src, dst) bfd *abfd; - Elf_External_Ehdr *src; + const Elf_External_Ehdr *src; Elf_Internal_Ehdr *dst; { memcpy (dst->e_ident, src->e_ident, EI_NIDENT); @@ -246,7 +255,7 @@ elf_swap_ehdr_in (abfd, src, dst) static void elf_swap_ehdr_out (abfd, src, dst) bfd *abfd; - Elf_Internal_Ehdr *src; + const Elf_Internal_Ehdr *src; Elf_External_Ehdr *dst; { memcpy (dst->e_ident, src->e_ident, EI_NIDENT); @@ -273,7 +282,7 @@ elf_swap_ehdr_out (abfd, src, dst) static void elf_swap_shdr_in (abfd, src, dst) bfd *abfd; - Elf_External_Shdr *src; + const Elf_External_Shdr *src; Elf_Internal_Shdr *dst; { dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name); @@ -296,7 +305,7 @@ elf_swap_shdr_in (abfd, src, dst) static void elf_swap_shdr_out (abfd, src, dst) bfd *abfd; - Elf_Internal_Shdr *src; + const Elf_Internal_Shdr *src; Elf_External_Shdr *dst; { /* note that all elements of dst are *arrays of unsigned char* already... */ @@ -319,7 +328,7 @@ elf_swap_shdr_out (abfd, src, dst) void elf_swap_phdr_in (abfd, src, dst) bfd *abfd; - Elf_External_Phdr *src; + const Elf_External_Phdr *src; Elf_Internal_Phdr *dst; { dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type); @@ -335,7 +344,7 @@ elf_swap_phdr_in (abfd, src, dst) void elf_swap_phdr_out (abfd, src, dst) bfd *abfd; - Elf_Internal_Phdr *src; + const Elf_Internal_Phdr *src; Elf_External_Phdr *dst; { /* note that all elements of dst are *arrays of unsigned char* already... */ @@ -353,7 +362,7 @@ elf_swap_phdr_out (abfd, src, dst) INLINE void elf_swap_reloc_in (abfd, src, dst) bfd *abfd; - Elf_External_Rel *src; + const Elf_External_Rel *src; Elf_Internal_Rel *dst; { dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); @@ -363,7 +372,7 @@ elf_swap_reloc_in (abfd, src, dst) INLINE void elf_swap_reloca_in (abfd, src, dst) bfd *abfd; - Elf_External_Rela *src; + const Elf_External_Rela *src; Elf_Internal_Rela *dst; { dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); @@ -375,7 +384,7 @@ elf_swap_reloca_in (abfd, src, dst) INLINE void elf_swap_reloc_out (abfd, src, dst) bfd *abfd; - Elf_Internal_Rel *src; + const Elf_Internal_Rel *src; Elf_External_Rel *dst; { put_word (abfd, src->r_offset, dst->r_offset); @@ -385,7 +394,7 @@ elf_swap_reloc_out (abfd, src, dst) INLINE void elf_swap_reloca_out (abfd, src, dst) bfd *abfd; - Elf_Internal_Rela *src; + const Elf_Internal_Rela *src; Elf_External_Rela *dst; { put_word (abfd, src->r_offset, dst->r_offset); @@ -540,7 +549,11 @@ elf_object_p (abfd) if ((*target_ptr)->flavour != bfd_target_elf_flavour) continue; back = (struct elf_backend_data *) (*target_ptr)->backend_data; - if (back->elf_machine_code == i_ehdrp->e_machine) + if (back->elf_machine_code == i_ehdrp->e_machine + || (back->elf_machine_alt1 != 0 + && back->elf_machine_alt1 == i_ehdrp->e_machine) + || (back->elf_machine_alt2 != 0 + && back->elf_machine_alt2 == i_ehdrp->e_machine)) { /* target_ptr is an ELF backend which matches this object file, so reject the generic ELF target. */ @@ -776,7 +789,7 @@ write_relocs (abfd, sec, data) unsigned int idx; int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; asymbol *last_sym = 0; - int last_sym_idx = 9999999; /* should always be written before use */ + int last_sym_idx = 0; /* If we have already failed, don't do anything. */ if (*failedp) @@ -832,10 +845,16 @@ write_relocs (abfd, sec, data) else { last_sym = sym; - last_sym_idx = n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); + n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); + if (n < 0) + { + *failedp = true; + return; + } + last_sym_idx = n; } - if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec + if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec && ! validate_reloc (abfd, ptr)) { *failedp = true; @@ -878,10 +897,16 @@ write_relocs (abfd, sec, data) else { last_sym = sym; - last_sym_idx = n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); + n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); + if (n < 0) + { + *failedp = true; + return; + } + last_sym_idx = n; } - if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec + if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec && ! validate_reloc (abfd, ptr)) { *failedp = true; @@ -895,10 +920,12 @@ write_relocs (abfd, sec, data) } } -static int -write_out_phdrs (abfd, phdr, count) +/* Write out the program headers. */ + +int +elf_write_out_phdrs (abfd, phdr, count) bfd *abfd; - Elf_Internal_Phdr *phdr; + const Elf_Internal_Phdr *phdr; int count; { while (count--) @@ -913,8 +940,10 @@ write_out_phdrs (abfd, phdr, count) return 0; } -static boolean -write_shdrs_and_ehdr (abfd) +/* Write out the section headers and the ELF file header. */ + +boolean +elf_write_shdrs_and_ehdr (abfd) bfd *abfd; { Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ @@ -960,7 +989,7 @@ write_shdrs_and_ehdr (abfd) return true; } -static long +long elf_slurp_symbol_table (abfd, symptrs, dynamic) bfd *abfd; asymbol **symptrs; /* Buffer for generated bfd symbols */ @@ -1384,8 +1413,8 @@ const struct elf_size_info NAME(_bfd_elf,size_info) = { ARCH_SIZE, FILE_ALIGN, ELFCLASS, EV_CURRENT, - write_out_phdrs, - write_shdrs_and_ehdr, + elf_write_out_phdrs, + elf_write_shdrs_and_ehdr, write_relocs, elf_swap_symbol_out, elf_slurp_reloc_table, diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index f1573f4b0a0..b4e68ecc2be 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -1,5 +1,5 @@ /* Target definitions for NN-bit ELF - Copyright 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -69,10 +69,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_backend_want_plt_sym 0 #endif -#ifndef elf_backend_want_hdr_in_seg -#define elf_backend_want_hdr_in_seg 0 -#endif - #define bfd_elfNN_bfd_debug_info_start bfd_void #define bfd_elfNN_bfd_debug_info_end bfd_void #define bfd_elfNN_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void @@ -145,6 +141,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define bfd_elfNN_bfd_link_split_section _bfd_generic_link_split_section #endif +#ifndef elf_symbol_leading_char +#define elf_symbol_leading_char 0 +#endif + +#ifndef elf_info_to_howto +#define elf_info_to_howto 0 +#endif + #ifndef elf_info_to_howto_rel #define elf_info_to_howto_rel 0 #endif @@ -235,6 +239,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define ELF_MACHINE_ALT2 0 #endif +#ifndef elf_backend_size_info +#define elf_backend_size_info _bfd_elfNN_size_info +#endif + extern const struct elf_size_info _bfd_elfNN_size_info; static CONST struct elf_backend_data elfNN_bed = @@ -275,11 +283,10 @@ static CONST struct elf_backend_data elfNN_bed = elf_backend_ecoff_debug_swap, ELF_MACHINE_ALT1, ELF_MACHINE_ALT2, - &_bfd_elfNN_size_info, + &elf_backend_size_info, elf_backend_want_got_plt, elf_backend_plt_readonly, - elf_backend_want_plt_sym, - elf_backend_want_hdr_in_seg, + elf_backend_want_plt_sym }; #ifdef TARGET_BIG_SYM @@ -307,7 +314,7 @@ const bfd_target TARGET_BIG_SYM = /* leading_symbol_char: is the first char of a user symbol predictable, and if so what is it */ - 0, + elf_symbol_leading_char, /* ar_pad_char: pad character for filenames within an archive header FIXME: this really has nothing to do with ELF, this is a characteristic @@ -391,7 +398,7 @@ const bfd_target TARGET_LITTLE_SYM = /* leading_symbol_char: is the first char of a user symbol predictable, and if so what is it */ - 0, + elf_symbol_leading_char, /* ar_pad_char: pad character for filenames within an archive header FIXME: this really has nothing to do with ELF, this is a characteristic