diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-07-07 17:50:56 +0000 |
---|---|---|
committer | Mark Mitchell <mark@codesourcery.com> | 1999-07-07 17:50:56 +0000 |
commit | 1afe515ca62a65f9631acce446de613002575447 (patch) | |
tree | 75d5d5417f82655dbfb3e1622fdfc154b63c4181 | |
parent | fde9fcb594ca52233ddbe06ad667f1ccaaeb7862 (diff) | |
download | gdb-1afe515ca62a65f9631acce446de613002575447.tar.gz |
* elflink.h (elf_link_create_dynamic_sections): Handle non-standard
hash-entry sizes.
(size_dynamic_sections): Likewise.
(elf_link_output_extsym): Likewise.
* elf.c: (elf_fake_sections): Likewise.
* libbfd.c (bfd_get): New macro.
(bfd_put): Likewise.
* bfd-in2.h: Regenerated.
* elf-bfd.h (elf_size_info): Add hash_entry_size,
int_rels_per_ext_rel, swap_dyn_out, swap_reloc_in, swap_reloc_out,
wap_reloca_in, and swap_reloca_out.
* elflink.h (elf_link_read_relocs_from_section): Adjust to handle
multiple internal relocations per external relocation.
(link_read_relocs): Likewise.
(elf_bfd_final_link): Likewise.
(elf_link_input_bfd): Likewise.
(elf_gc_mark): Likewise.
(elf_gc_smash_unused_vtentry_relocs): Likewise.
* elfcode.h (elf_swap_dyn_out): Adjust type to match
elf_swap_dyn_in.
(size_info): Add entries for new fields.
* elf64-mips.c (mips_elf64_swap_reloc_out): Enable.
(mips_elf64_be_swap_reloc_in): New function.
(mips_elf64_be_swap_reloc_out): Likewise.
(mips_elf64_be_swap_reloca_in): Likewise.
(mips_elf64_be_swap_reloca_out): Likewise.
(mips_elf64_size_info): Add entries for new fields.
-rw-r--r-- | bfd/ChangeLog | 33 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 14 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 37 | ||||
-rw-r--r-- | bfd/elf.c | 2 | ||||
-rw-r--r-- | bfd/elf64-mips.c | 115 | ||||
-rw-r--r-- | bfd/elfcode.h | 16 | ||||
-rw-r--r-- | bfd/elflink.h | 88 | ||||
-rw-r--r-- | bfd/libbfd.c | 14 |
8 files changed, 277 insertions, 42 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1babf26170f..22232e89272 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,36 @@ +1999-07-07 Mark Mitchell <mark@codesourcery.com> + + * elflink.h (elf_link_create_dynamic_sections): Handle non-standard + hash-entry sizes. + (size_dynamic_sections): Likewise. + (elf_link_output_extsym): Likewise. + * elf.c: (elf_fake_sections): Likewise. + * libbfd.c (bfd_get): New macro. + (bfd_put): Likewise. + * bfd-in2.h: Regenerated. + +1999-07-07 Mark Mitchell <mark@codesourcery.com> + + * elf-bfd.h (elf_size_info): Add hash_entry_size, + int_rels_per_ext_rel, swap_dyn_out, swap_reloc_in, swap_reloc_out, + wap_reloca_in, and swap_reloca_out. + * elflink.h (elf_link_read_relocs_from_section): Adjust to handle + multiple internal relocations per external relocation. + (link_read_relocs): Likewise. + (elf_bfd_final_link): Likewise. + (elf_link_input_bfd): Likewise. + (elf_gc_mark): Likewise. + (elf_gc_smash_unused_vtentry_relocs): Likewise. + * elfcode.h (elf_swap_dyn_out): Adjust type to match + elf_swap_dyn_in. + (size_info): Add entries for new fields. + * elf64-mips.c (mips_elf64_swap_reloc_out): Enable. + (mips_elf64_be_swap_reloc_in): New function. + (mips_elf64_be_swap_reloc_out): Likewise. + (mips_elf64_be_swap_reloca_in): Likewise. + (mips_elf64_be_swap_reloca_out): Likewise. + (mips_elf64_size_info): Add entries for new fields. + 1999-07-07 Ian Lance Taylor <ian@zembu.com> * elflink.h (elf_bfd_final_link): Assert that section reloc_count diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 78cadabc45b..aa20c0817cd 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -803,6 +803,20 @@ bfd_make_readable PARAMS ((bfd *abfd)); #define bfd_get_signed_64(abfd, ptr) \ BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) +#define bfd_get(bits, abfd, ptr) \ + ((bits) == 8 ? bfd_get_8 (abfd, ptr) \ + : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ + : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ + : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ + : (abort (), (bfd_vma) - 1)) + +#define bfd_put(bits, abfd, val, ptr) \ + ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ + : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ + : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ + : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ + : (abort (), (void) 0)) + /* Byte swapping macros for file header data. */ diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 05667bd5552..303f0a8707a 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -236,6 +236,13 @@ struct elf_size_info { unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr; unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note; + /* The size of entries in the .hash section. */ + unsigned char sizeof_hash_entry; + + /* The number of internal relocations to allocate per external + relocation entry. */ + unsigned char int_rels_per_ext_rel; + unsigned char arch_size, file_align; unsigned char elfclass, ev_current; int (*write_out_phdrs) PARAMS ((bfd *, const Elf_Internal_Phdr *, int)); @@ -246,6 +253,32 @@ struct elf_size_info { PARAMS ((bfd *, asection *, asymbol **, boolean)); long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean)); void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); + void (*swap_dyn_out) PARAMS ((bfd *, const Elf_Internal_Dyn *, PTR)); + + /* This function, if defined, is called to swap in a REL + relocation. If an external relocation corresponds to more than + one internal relocation, then all relocations are swapped in at + once. */ + void (*swap_reloc_in) + PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *)); + + /* This function, if defined, is called to swap out a REL + relocation. */ + void (*swap_reloc_out) + PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *)); + + /* This function, if defined, is called to swap in a RELA + relocation. If an external relocation corresponds to more than + one internal relocation, then all relocations are swapped in at + once. */ + void (*swap_reloca_in) + PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); + + /* This function, if defined, is called to swap out a RELA + relocation. */ + void (*swap_reloca_out) + PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); + }; #define elf_symbol_from(ABFD,S) \ @@ -1024,7 +1057,7 @@ extern void bfd_elf32_swap_phdr_out 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 *)); + PARAMS ((bfd *, const Elf_Internal_Dyn *, PTR)); extern long bfd_elf32_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean)); extern boolean bfd_elf32_write_shdrs_and_ehdr PARAMS ((bfd *)); @@ -1067,7 +1100,7 @@ extern void bfd_elf64_swap_phdr_out 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 *)); + PARAMS ((bfd *, const Elf_Internal_Dyn *, PTR)); extern long bfd_elf64_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean)); extern boolean bfd_elf64_write_shdrs_and_ehdr PARAMS ((bfd *)); diff --git a/bfd/elf.c b/bfd/elf.c index f3d23c4d0f1..4db37c46850 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1532,7 +1532,7 @@ elf_fake_sections (abfd, asect, failedptrarg) else if (strcmp (asect->name, ".hash") == 0) { this_hdr->sh_type = SHT_HASH; - this_hdr->sh_entsize = bed->s->arch_size / 8; + this_hdr->sh_entsize = bed->s->sizeof_hash_entry; } else if (strcmp (asect->name, ".dynsym") == 0) { diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 36e607508d1..79b172f5b26 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -52,14 +52,20 @@ static void mips_elf64_swap_reloc_in static void mips_elf64_swap_reloca_in PARAMS ((bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *)); -#if 0 static void mips_elf64_swap_reloc_out PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *, Elf64_Mips_External_Rel *)); -#endif static void mips_elf64_swap_reloca_out PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *)); +static void mips_elf64_be_swap_reloc_in + PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *)); +static void mips_elf64_be_swap_reloc_out + PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *)); +static void mips_elf64_be_swap_reloca_in + PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); +static void mips_elf64_be_swap_reloca_out + PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); static reloc_howto_type *mips_elf64_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type)); static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *)); @@ -1220,10 +1226,6 @@ mips_elf64_swap_reloca_in (abfd, src, dst) dst->r_addend = bfd_h_get_signed_64 (abfd, (bfd_byte *) src->r_addend); } -#if 0 - -/* This is not currently used. */ - /* Swap out a MIPS 64-bit Rel reloc. */ static void @@ -1240,8 +1242,6 @@ mips_elf64_swap_reloc_out (abfd, src, dst) bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type); } -#endif /* 0 */ - /* Swap out a MIPS 64-bit Rela reloc. */ static void @@ -1259,6 +1259,96 @@ mips_elf64_swap_reloca_out (abfd, src, dst) bfd_h_put_64 (abfd, src->r_addend, (bfd_byte *) dst->r_addend); } +/* Swap in a MIPS 64-bit Rel reloc. */ + +static void +mips_elf64_be_swap_reloc_in (abfd, src, dst) + bfd *abfd; + const bfd_byte *src; + Elf_Internal_Rel *dst; +{ + Elf64_Mips_Internal_Rel mirel; + + mips_elf64_swap_reloc_in (abfd, + (const Elf64_Mips_External_Rel *) src, + &mirel); + + dst[0].r_offset = mirel.r_offset; + dst[0].r_info = ELF32_R_INFO (mirel.r_sym, mirel.r_type); + dst[1].r_offset = mirel.r_offset; + dst[1].r_info = ELF32_R_INFO (mirel.r_ssym, mirel.r_type2); + dst[2].r_offset = mirel.r_offset; + dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirel.r_type3); +} + +/* Swap in a MIPS 64-bit Rela reloc. */ + +static void +mips_elf64_be_swap_reloca_in (abfd, src, dst) + bfd *abfd; + const bfd_byte *src; + Elf_Internal_Rela *dst; +{ + Elf64_Mips_Internal_Rela mirela; + + mips_elf64_swap_reloca_in (abfd, + (const Elf64_Mips_External_Rela *) src, + &mirela); + + dst[0].r_offset = mirela.r_offset; + dst[0].r_info = ELF32_R_INFO (mirela.r_sym, mirela.r_type); + dst[0].r_addend = mirela.r_addend; + dst[1].r_offset = mirela.r_offset; + dst[1].r_info = ELF32_R_INFO (mirela.r_ssym, mirela.r_type2); + dst[1].r_addend = 0; + dst[2].r_offset = mirela.r_offset; + dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirela.r_type3); + dst[2].r_addend = 0; +} + +/* Swap out a MIPS 64-bit Rel reloc. */ + +static void +mips_elf64_be_swap_reloc_out (abfd, src, dst) + bfd *abfd; + const Elf_Internal_Rel *src; + bfd_byte *dst; +{ + Elf64_Mips_Internal_Rel mirel; + + mirel.r_offset = src->r_offset; + mirel.r_type = ELF32_R_TYPE (src->r_info); + mirel.r_sym = ELF32_R_SYM (src->r_info); + mirel.r_type2 = R_MIPS_NONE; + mirel.r_ssym = STN_UNDEF; + mirel.r_type3 = R_MIPS_NONE; + + mips_elf64_swap_reloc_out (abfd, &mirel, + (Elf64_Mips_External_Rel *) dst); +} + +/* Swap out a MIPS 64-bit Rela reloc. */ + +static void +mips_elf64_be_swap_reloca_out (abfd, src, dst) + bfd *abfd; + const Elf_Internal_Rela *src; + bfd_byte *dst; +{ + Elf64_Mips_Internal_Rela mirela; + + mirela.r_offset = src->r_offset; + mirela.r_type = ELF32_R_TYPE (src->r_info); + mirela.r_addend = src->r_addend; + mirela.r_sym = ELF32_R_SYM (src->r_info); + mirela.r_type2 = R_MIPS_NONE; + mirela.r_ssym = STN_UNDEF; + mirela.r_type3 = R_MIPS_NONE; + + mips_elf64_swap_reloca_out (abfd, &mirela, + (Elf64_Mips_External_Rela *) dst); +} + /* A mapping from BFD reloc types to MIPS ELF reloc types. */ struct elf_reloc_map @@ -2099,6 +2189,8 @@ const struct elf_size_info mips_elf64_size_info = sizeof (Elf64_External_Sym), sizeof (Elf64_External_Dyn), sizeof (Elf_External_Note), + 4, /* hash-table entry size */ + 3, /* internal relocations per external relocations */ 64, /* arch_size */ 8, /* file_align */ ELFCLASS64, @@ -2109,7 +2201,12 @@ const struct elf_size_info mips_elf64_size_info = bfd_elf64_swap_symbol_out, mips_elf64_slurp_reloc_table, bfd_elf64_slurp_symbol_table, - bfd_elf64_swap_dyn_in + bfd_elf64_swap_dyn_in, + bfd_elf64_swap_dyn_out, + mips_elf64_be_swap_reloc_in, + mips_elf64_be_swap_reloc_out, + mips_elf64_be_swap_reloca_in, + mips_elf64_be_swap_reloca_out }; #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 29a19438386..49e156efe2c 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -423,11 +423,13 @@ elf_swap_dyn_in (abfd, p, dst) } INLINE void -elf_swap_dyn_out (abfd, src, dst) +elf_swap_dyn_out (abfd, src, p) bfd *abfd; const Elf_Internal_Dyn *src; - Elf_External_Dyn *dst; + PTR p; { + Elf_External_Dyn *dst = (Elf_External_Dyn *) p; + put_word (abfd, src->d_tag, dst->d_tag); put_word (abfd, src->d_un.d_val, dst->d_un.d_val); } @@ -1500,7 +1502,8 @@ const struct elf_size_info NAME(_bfd_elf,size_info) = { sizeof (Elf_External_Sym), sizeof (Elf_External_Dyn), sizeof (Elf_External_Note), - + ARCH_SIZE / 8, + 1, ARCH_SIZE, FILE_ALIGN, ELFCLASS, EV_CURRENT, elf_write_out_phdrs, @@ -1509,5 +1512,10 @@ const struct elf_size_info NAME(_bfd_elf,size_info) = { elf_swap_symbol_out, elf_slurp_reloc_table, elf_slurp_symbol_table, - elf_swap_dyn_in + elf_swap_dyn_in, + elf_swap_dyn_out, + NULL, + NULL, + NULL, + NULL }; diff --git a/bfd/elflink.h b/bfd/elflink.h index c2debca59e2..057dc5e92ad 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -1997,16 +1997,18 @@ elf_link_create_dynamic_sections (abfd, info) && ! _bfd_elf_link_record_dynamic_symbol (info, h)) return false; + bed = get_elf_backend_data (abfd); + s = bfd_make_section (abfd, ".hash"); if (s == NULL || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) return false; + elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry; /* Let the backend create the rest of the sections. This lets the backend set the right flags. The backend will normally create the .got and .plt sections. */ - bed = get_elf_backend_data (abfd); if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) return false; @@ -2068,6 +2070,8 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs, PTR external_relocs; Elf_Internal_Rela *internal_relocs; { + struct elf_backend_data *bed; + /* If there aren't any relocations, that's OK. */ if (!shdr) return true; @@ -2081,24 +2085,36 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs, != shdr->sh_size) return false; + bed = get_elf_backend_data (abfd); + /* Convert the external relocations to the internal format. */ if (shdr->sh_entsize == sizeof (Elf_External_Rel)) { Elf_External_Rel *erel; Elf_External_Rel *erelend; Elf_Internal_Rela *irela; + Elf_Internal_Rel *irel; erel = (Elf_External_Rel *) external_relocs; erelend = erel + shdr->sh_size / shdr->sh_entsize; irela = internal_relocs; - for (; erel < erelend; erel++, irela++) + irel = bfd_alloc (abfd, (bed->s->int_rels_per_ext_rel + * sizeof (Elf_Internal_Rel))); + for (; erel < erelend; erel++, irela += bed->s->int_rels_per_ext_rel) { - Elf_Internal_Rel irel; + int i; + + if (bed->s->swap_reloc_in) + (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, irel); + else + elf_swap_reloc_in (abfd, erel, irel); - elf_swap_reloc_in (abfd, erel, &irel); - irela->r_offset = irel.r_offset; - irela->r_info = irel.r_info; - irela->r_addend = 0; + for (i = 0; i < bed->s->int_rels_per_ext_rel; ++i) + { + irela[i].r_offset = irel[i].r_offset; + irela[i].r_info = irel[i].r_info; + irela[i].r_addend = 0; + } } } else @@ -2112,8 +2128,13 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs, erela = (Elf_External_Rela *) external_relocs; erelaend = erela + shdr->sh_size / shdr->sh_entsize; irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - elf_swap_reloca_in (abfd, erela, irela); + for (; erela < erelaend; erela++, irela += bed->s->int_rels_per_ext_rel) + { + if (bed->s->swap_reloca_in) + (*bed->s->swap_reloca_in) (abfd, (bfd_byte *) erela, irela); + else + elf_swap_reloca_in (abfd, erela, irela); + } } return true; @@ -2141,6 +2162,7 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs, Elf_Internal_Shdr *rel_hdr; PTR alloc1 = NULL; Elf_Internal_Rela *alloc2 = NULL; + struct elf_backend_data *bed = get_elf_backend_data (abfd); if (elf_section_data (o)->relocs != NULL) return elf_section_data (o)->relocs; @@ -2154,7 +2176,8 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs, { size_t size; - size = o->reloc_count * sizeof (Elf_Internal_Rela); + size = (o->reloc_count * bed->s->int_rels_per_ext_rel + * sizeof (Elf_Internal_Rela)); if (keep_memory) internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size); else @@ -2183,7 +2206,8 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs, (abfd, elf_section_data (o)->rel_hdr2, ((bfd_byte *) external_relocs) + rel_hdr->sh_size, - internal_relocs + rel_hdr->sh_size / rel_hdr->sh_entsize)) + internal_relocs + (rel_hdr->sh_size / rel_hdr->sh_entsize + * bed->s->int_rels_per_ext_rel))) goto error_return; /* Cache the results for next time, if we can. */ @@ -2699,6 +2723,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, asection *s; size_t bucketcount = 0; Elf_Internal_Sym isym; + size_t hash_entry_size; /* Set up the version definition section. */ s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); @@ -3047,14 +3072,16 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, s = bfd_get_section_by_name (dynobj, ".hash"); BFD_ASSERT (s != NULL); - s->_raw_size = (2 + bucketcount + dynsymcount) * (ARCH_SIZE / 8); + hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; + s->_raw_size = ((2 + bucketcount + dynsymcount) * hash_entry_size); s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); if (s->contents == NULL) return false; memset (s->contents, 0, (size_t) s->_raw_size); - put_word (output_bfd, bucketcount, s->contents); - put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8)); + bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents); + bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, + s->contents + hash_entry_size); elf_hash_table (info)->bucketcount = bucketcount; @@ -4043,7 +4070,8 @@ elf_bfd_final_link (abfd, info) finfo.external_relocs = (PTR) bfd_malloc (max_external_reloc_size); finfo.internal_relocs = ((Elf_Internal_Rela *) bfd_malloc (max_internal_reloc_count - * sizeof (Elf_Internal_Rela))); + * sizeof (Elf_Internal_Rela) + * bed->s->int_rels_per_ext_rel)); finfo.external_syms = ((Elf_External_Sym *) bfd_malloc (max_sym_count * sizeof (Elf_External_Sym))); @@ -4738,6 +4766,7 @@ elf_link_output_extsym (h, data) { size_t bucketcount; size_t bucket; + size_t hash_entry_size; bfd_byte *bucketpos; bfd_vma chain; @@ -4750,13 +4779,15 @@ elf_link_output_extsym (h, data) bucketcount = elf_hash_table (finfo->info)->bucketcount; bucket = h->elf_hash_value % bucketcount; + hash_entry_size + = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; bucketpos = ((bfd_byte *) finfo->hash_sec->contents - + (bucket + 2) * (ARCH_SIZE / 8)); - chain = get_word (finfo->output_bfd, bucketpos); - put_word (finfo->output_bfd, h->dynindx, bucketpos); - put_word (finfo->output_bfd, chain, - ((bfd_byte *) finfo->hash_sec->contents - + (bucketcount + 2 + h->dynindx) * (ARCH_SIZE / 8))); + + (bucket + 2) * hash_entry_size); + chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); + bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); + bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, + ((bfd_byte *) finfo->hash_sec->contents + + (bucketcount + 2 + h->dynindx) * hash_entry_size)); if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) { @@ -4898,10 +4929,11 @@ elf_link_input_bfd (finfo, input_bfd) long *pindex; asection **ppsection; asection *o; + struct elf_backend_data *bed; output_bfd = finfo->output_bfd; - relocate_section = - get_elf_backend_data (output_bfd)->elf_backend_relocate_section; + bed = get_elf_backend_data (output_bfd); + relocate_section = bed->elf_backend_relocate_section; /* If this is a dynamic object, we don't want to do anything here: we don't want the local symbols, and we don't want the section @@ -5138,7 +5170,8 @@ elf_link_input_bfd (finfo, input_bfd) /* Adjust the reloc addresses and symbol indices. */ irela = internal_relocs; - irelaend = irela + o->reloc_count; + irelaend = + irela + o->reloc_count * bed->s->int_rels_per_ext_rel; rel_hash = (elf_section_data (o->output_section)->rel_hashes + elf_section_data (o->output_section)->rel_count); for (; irela < irelaend; irela++, rel_hash++) @@ -5748,6 +5781,7 @@ elf_gc_mark (info, sec, gc_mark_hook) size_t extsymoff; Elf_External_Sym *locsyms, *freesyms = NULL; bfd *input_bfd = sec->owner; + struct elf_backend_data *bed = get_elf_backend_data (input_bfd); /* GCFIXME: how to arrange so that relocs and symbols are not reread continually? */ @@ -5791,7 +5825,7 @@ elf_gc_mark (info, sec, gc_mark_hook) ret = false; goto out1; } - relend = relstart + sec->reloc_count; + relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; for (rel = relstart; rel < relend; rel++) { @@ -5997,6 +6031,7 @@ elf_gc_smash_unused_vtentry_relocs (h, okp) asection *sec; bfd_vma hstart, hend; Elf_Internal_Rela *relstart, *relend, *rel; + struct elf_backend_data *bed; /* Take care of both those symbols that do not describe vtables as well as those that are not loaded. */ @@ -6014,7 +6049,8 @@ elf_gc_smash_unused_vtentry_relocs (h, okp) (sec->owner, sec, NULL, (Elf_Internal_Rela *) NULL, true)); if (!relstart) return *(boolean *)okp = false; - relend = relstart + sec->reloc_count; + bed = get_elf_backend_data (sec->owner); + relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; for (rel = relstart; rel < relend; ++rel) if (rel->r_offset >= hstart && rel->r_offset < hend) diff --git a/bfd/libbfd.c b/bfd/libbfd.c index 8da3de0a0e4..23a27e3257c 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -827,6 +827,20 @@ DESCRIPTION .#define bfd_get_signed_64(abfd, ptr) \ . BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) . +.#define bfd_get(bits, abfd, ptr) \ +. ((bits) == 8 ? bfd_get_8 (abfd, ptr) \ +. : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ +. : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ +. : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ +. : (abort (), (bfd_vma) - 1)) +. +.#define bfd_put(bits, abfd, val, ptr) \ +. ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ +. : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ +. : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ +. : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ +. : (abort (), (void) 0)) +. */ /* |