summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-07-07 17:50:56 +0000
committerMark Mitchell <mark@codesourcery.com>1999-07-07 17:50:56 +0000
commit1afe515ca62a65f9631acce446de613002575447 (patch)
tree75d5d5417f82655dbfb3e1622fdfc154b63c4181
parentfde9fcb594ca52233ddbe06ad667f1ccaaeb7862 (diff)
downloadgdb-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/ChangeLog33
-rw-r--r--bfd/bfd-in2.h14
-rw-r--r--bfd/elf-bfd.h37
-rw-r--r--bfd/elf.c2
-rw-r--r--bfd/elf64-mips.c115
-rw-r--r--bfd/elfcode.h16
-rw-r--r--bfd/elflink.h88
-rw-r--r--bfd/libbfd.c14
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))
+.
*/
/*