* 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.
This commit is contained in:
Mark Mitchell
1999-07-07 17:50:56 +00:00
parent 9846de1bb5
commit c7ac6ff835
8 changed files with 277 additions and 42 deletions

View File

@ -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> 1999-07-07 Ian Lance Taylor <ian@zembu.com>
* elflink.h (elf_bfd_final_link): Assert that section reloc_count * elflink.h (elf_bfd_final_link): Assert that section reloc_count

View File

@ -803,6 +803,20 @@ bfd_make_readable PARAMS ((bfd *abfd));
#define bfd_get_signed_64(abfd, ptr) \ #define bfd_get_signed_64(abfd, ptr) \
BFD_SEND(abfd, bfd_getx_signed_64, (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. */ /* Byte swapping macros for file header data. */

View File

@ -236,6 +236,13 @@ struct elf_size_info {
unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr; unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr;
unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note; 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 arch_size, file_align;
unsigned char elfclass, ev_current; unsigned char elfclass, ev_current;
int (*write_out_phdrs) PARAMS ((bfd *, const Elf_Internal_Phdr *, int)); int (*write_out_phdrs) PARAMS ((bfd *, const Elf_Internal_Phdr *, int));
@ -246,6 +253,32 @@ struct elf_size_info {
PARAMS ((bfd *, asection *, asymbol **, boolean)); PARAMS ((bfd *, asection *, asymbol **, boolean));
long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean)); long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean));
void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); 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) \ #define elf_symbol_from(ABFD,S) \
@ -1024,7 +1057,7 @@ extern void bfd_elf32_swap_phdr_out
extern void bfd_elf32_swap_dyn_in extern void bfd_elf32_swap_dyn_in
PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
extern void bfd_elf32_swap_dyn_out 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 extern long bfd_elf32_slurp_symbol_table
PARAMS ((bfd *, asymbol **, boolean)); PARAMS ((bfd *, asymbol **, boolean));
extern boolean bfd_elf32_write_shdrs_and_ehdr PARAMS ((bfd *)); 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 extern void bfd_elf64_swap_dyn_in
PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
extern void bfd_elf64_swap_dyn_out 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 extern long bfd_elf64_slurp_symbol_table
PARAMS ((bfd *, asymbol **, boolean)); PARAMS ((bfd *, asymbol **, boolean));
extern boolean bfd_elf64_write_shdrs_and_ehdr PARAMS ((bfd *)); extern boolean bfd_elf64_write_shdrs_and_ehdr PARAMS ((bfd *));

View File

@ -1532,7 +1532,7 @@ elf_fake_sections (abfd, asect, failedptrarg)
else if (strcmp (asect->name, ".hash") == 0) else if (strcmp (asect->name, ".hash") == 0)
{ {
this_hdr->sh_type = SHT_HASH; 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) else if (strcmp (asect->name, ".dynsym") == 0)
{ {

View File

@ -52,14 +52,20 @@ static void mips_elf64_swap_reloc_in
static void mips_elf64_swap_reloca_in static void mips_elf64_swap_reloca_in
PARAMS ((bfd *, const Elf64_Mips_External_Rela *, PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
Elf64_Mips_Internal_Rela *)); Elf64_Mips_Internal_Rela *));
#if 0
static void mips_elf64_swap_reloc_out static void mips_elf64_swap_reloc_out
PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *, PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *,
Elf64_Mips_External_Rel *)); Elf64_Mips_External_Rel *));
#endif
static void mips_elf64_swap_reloca_out static void mips_elf64_swap_reloca_out
PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *, PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
Elf64_Mips_External_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 static reloc_howto_type *mips_elf64_reloc_type_lookup
PARAMS ((bfd *, bfd_reloc_code_real_type)); PARAMS ((bfd *, bfd_reloc_code_real_type));
static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *)); 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); 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. */ /* Swap out a MIPS 64-bit Rel reloc. */
static void 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); bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
} }
#endif /* 0 */
/* Swap out a MIPS 64-bit Rela reloc. */ /* Swap out a MIPS 64-bit Rela reloc. */
static void 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); 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. */ /* A mapping from BFD reloc types to MIPS ELF reloc types. */
struct elf_reloc_map struct elf_reloc_map
@ -2099,6 +2189,8 @@ const struct elf_size_info mips_elf64_size_info =
sizeof (Elf64_External_Sym), sizeof (Elf64_External_Sym),
sizeof (Elf64_External_Dyn), sizeof (Elf64_External_Dyn),
sizeof (Elf_External_Note), sizeof (Elf_External_Note),
4, /* hash-table entry size */
3, /* internal relocations per external relocations */
64, /* arch_size */ 64, /* arch_size */
8, /* file_align */ 8, /* file_align */
ELFCLASS64, ELFCLASS64,
@ -2109,7 +2201,12 @@ const struct elf_size_info mips_elf64_size_info =
bfd_elf64_swap_symbol_out, bfd_elf64_swap_symbol_out,
mips_elf64_slurp_reloc_table, mips_elf64_slurp_reloc_table,
bfd_elf64_slurp_symbol_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 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec

View File

@ -423,11 +423,13 @@ elf_swap_dyn_in (abfd, p, dst)
} }
INLINE void INLINE void
elf_swap_dyn_out (abfd, src, dst) elf_swap_dyn_out (abfd, src, p)
bfd *abfd; bfd *abfd;
const Elf_Internal_Dyn *src; 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_tag, dst->d_tag);
put_word (abfd, src->d_un.d_val, dst->d_un.d_val); 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_Sym),
sizeof (Elf_External_Dyn), sizeof (Elf_External_Dyn),
sizeof (Elf_External_Note), sizeof (Elf_External_Note),
ARCH_SIZE / 8,
1,
ARCH_SIZE, FILE_ALIGN, ARCH_SIZE, FILE_ALIGN,
ELFCLASS, EV_CURRENT, ELFCLASS, EV_CURRENT,
elf_write_out_phdrs, elf_write_out_phdrs,
@ -1509,5 +1512,10 @@ const struct elf_size_info NAME(_bfd_elf,size_info) = {
elf_swap_symbol_out, elf_swap_symbol_out,
elf_slurp_reloc_table, elf_slurp_reloc_table,
elf_slurp_symbol_table, elf_slurp_symbol_table,
elf_swap_dyn_in elf_swap_dyn_in,
elf_swap_dyn_out,
NULL,
NULL,
NULL,
NULL
}; };

View File

@ -1997,16 +1997,18 @@ elf_link_create_dynamic_sections (abfd, info)
&& ! _bfd_elf_link_record_dynamic_symbol (info, h)) && ! _bfd_elf_link_record_dynamic_symbol (info, h))
return false; return false;
bed = get_elf_backend_data (abfd);
s = bfd_make_section (abfd, ".hash"); s = bfd_make_section (abfd, ".hash");
if (s == NULL if (s == NULL
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN))
return false; 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 /* Let the backend create the rest of the sections. This lets the
backend set the right flags. The backend will normally create backend set the right flags. The backend will normally create
the .got and .plt sections. */ the .got and .plt sections. */
bed = get_elf_backend_data (abfd);
if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
return false; return false;
@ -2068,6 +2070,8 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs,
PTR external_relocs; PTR external_relocs;
Elf_Internal_Rela *internal_relocs; Elf_Internal_Rela *internal_relocs;
{ {
struct elf_backend_data *bed;
/* If there aren't any relocations, that's OK. */ /* If there aren't any relocations, that's OK. */
if (!shdr) if (!shdr)
return true; return true;
@ -2081,24 +2085,36 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs,
!= shdr->sh_size) != shdr->sh_size)
return false; return false;
bed = get_elf_backend_data (abfd);
/* Convert the external relocations to the internal format. */ /* Convert the external relocations to the internal format. */
if (shdr->sh_entsize == sizeof (Elf_External_Rel)) if (shdr->sh_entsize == sizeof (Elf_External_Rel))
{ {
Elf_External_Rel *erel; Elf_External_Rel *erel;
Elf_External_Rel *erelend; Elf_External_Rel *erelend;
Elf_Internal_Rela *irela; Elf_Internal_Rela *irela;
Elf_Internal_Rel *irel;
erel = (Elf_External_Rel *) external_relocs; erel = (Elf_External_Rel *) external_relocs;
erelend = erel + shdr->sh_size / shdr->sh_entsize; erelend = erel + shdr->sh_size / shdr->sh_entsize;
irela = internal_relocs; 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;
elf_swap_reloc_in (abfd, erel, &irel); if (bed->s->swap_reloc_in)
irela->r_offset = irel.r_offset; (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, irel);
irela->r_info = irel.r_info; else
irela->r_addend = 0; elf_swap_reloc_in (abfd, erel, irel);
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 else
@ -2112,8 +2128,13 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs,
erela = (Elf_External_Rela *) external_relocs; erela = (Elf_External_Rela *) external_relocs;
erelaend = erela + shdr->sh_size / shdr->sh_entsize; erelaend = erela + shdr->sh_size / shdr->sh_entsize;
irela = internal_relocs; irela = internal_relocs;
for (; erela < erelaend; erela++, irela++) for (; erela < erelaend; erela++, irela += bed->s->int_rels_per_ext_rel)
elf_swap_reloca_in (abfd, erela, irela); {
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; return true;
@ -2141,6 +2162,7 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs,
Elf_Internal_Shdr *rel_hdr; Elf_Internal_Shdr *rel_hdr;
PTR alloc1 = NULL; PTR alloc1 = NULL;
Elf_Internal_Rela *alloc2 = NULL; Elf_Internal_Rela *alloc2 = NULL;
struct elf_backend_data *bed = get_elf_backend_data (abfd);
if (elf_section_data (o)->relocs != NULL) if (elf_section_data (o)->relocs != NULL)
return elf_section_data (o)->relocs; 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_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) if (keep_memory)
internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size); internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
else else
@ -2183,7 +2206,8 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs,
(abfd, (abfd,
elf_section_data (o)->rel_hdr2, elf_section_data (o)->rel_hdr2,
((bfd_byte *) external_relocs) + rel_hdr->sh_size, ((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; goto error_return;
/* Cache the results for next time, if we can. */ /* 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; asection *s;
size_t bucketcount = 0; size_t bucketcount = 0;
Elf_Internal_Sym isym; Elf_Internal_Sym isym;
size_t hash_entry_size;
/* Set up the version definition section. */ /* Set up the version definition section. */
s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); 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"); s = bfd_get_section_by_name (dynobj, ".hash");
BFD_ASSERT (s != NULL); 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); s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
if (s->contents == NULL) if (s->contents == NULL)
return false; return false;
memset (s->contents, 0, (size_t) s->_raw_size); memset (s->contents, 0, (size_t) s->_raw_size);
put_word (output_bfd, bucketcount, s->contents); bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8)); bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
s->contents + hash_entry_size);
elf_hash_table (info)->bucketcount = bucketcount; 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.external_relocs = (PTR) bfd_malloc (max_external_reloc_size);
finfo.internal_relocs = ((Elf_Internal_Rela *) finfo.internal_relocs = ((Elf_Internal_Rela *)
bfd_malloc (max_internal_reloc_count 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 *) finfo.external_syms = ((Elf_External_Sym *)
bfd_malloc (max_sym_count bfd_malloc (max_sym_count
* sizeof (Elf_External_Sym))); * sizeof (Elf_External_Sym)));
@ -4738,6 +4766,7 @@ elf_link_output_extsym (h, data)
{ {
size_t bucketcount; size_t bucketcount;
size_t bucket; size_t bucket;
size_t hash_entry_size;
bfd_byte *bucketpos; bfd_byte *bucketpos;
bfd_vma chain; bfd_vma chain;
@ -4750,13 +4779,15 @@ elf_link_output_extsym (h, data)
bucketcount = elf_hash_table (finfo->info)->bucketcount; bucketcount = elf_hash_table (finfo->info)->bucketcount;
bucket = h->elf_hash_value % 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 bucketpos = ((bfd_byte *) finfo->hash_sec->contents
+ (bucket + 2) * (ARCH_SIZE / 8)); + (bucket + 2) * hash_entry_size);
chain = get_word (finfo->output_bfd, bucketpos); chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos);
put_word (finfo->output_bfd, h->dynindx, bucketpos); bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos);
put_word (finfo->output_bfd, chain, bfd_put (8 * hash_entry_size, finfo->output_bfd, chain,
((bfd_byte *) finfo->hash_sec->contents ((bfd_byte *) finfo->hash_sec->contents
+ (bucketcount + 2 + h->dynindx) * (ARCH_SIZE / 8))); + (bucketcount + 2 + h->dynindx) * hash_entry_size));
if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL)
{ {
@ -4898,10 +4929,11 @@ elf_link_input_bfd (finfo, input_bfd)
long *pindex; long *pindex;
asection **ppsection; asection **ppsection;
asection *o; asection *o;
struct elf_backend_data *bed;
output_bfd = finfo->output_bfd; output_bfd = finfo->output_bfd;
relocate_section = bed = get_elf_backend_data (output_bfd);
get_elf_backend_data (output_bfd)->elf_backend_relocate_section; relocate_section = bed->elf_backend_relocate_section;
/* If this is a dynamic object, we don't want to do anything here: /* 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 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. */ /* Adjust the reloc addresses and symbol indices. */
irela = internal_relocs; 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 rel_hash = (elf_section_data (o->output_section)->rel_hashes
+ elf_section_data (o->output_section)->rel_count); + elf_section_data (o->output_section)->rel_count);
for (; irela < irelaend; irela++, rel_hash++) for (; irela < irelaend; irela++, rel_hash++)
@ -5748,6 +5781,7 @@ elf_gc_mark (info, sec, gc_mark_hook)
size_t extsymoff; size_t extsymoff;
Elf_External_Sym *locsyms, *freesyms = NULL; Elf_External_Sym *locsyms, *freesyms = NULL;
bfd *input_bfd = sec->owner; 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 /* GCFIXME: how to arrange so that relocs and symbols are not
reread continually? */ reread continually? */
@ -5791,7 +5825,7 @@ elf_gc_mark (info, sec, gc_mark_hook)
ret = false; ret = false;
goto out1; 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++) for (rel = relstart; rel < relend; rel++)
{ {
@ -5997,6 +6031,7 @@ elf_gc_smash_unused_vtentry_relocs (h, okp)
asection *sec; asection *sec;
bfd_vma hstart, hend; bfd_vma hstart, hend;
Elf_Internal_Rela *relstart, *relend, *rel; Elf_Internal_Rela *relstart, *relend, *rel;
struct elf_backend_data *bed;
/* Take care of both those symbols that do not describe vtables as /* Take care of both those symbols that do not describe vtables as
well as those that are not loaded. */ 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)); (sec->owner, sec, NULL, (Elf_Internal_Rela *) NULL, true));
if (!relstart) if (!relstart)
return *(boolean *)okp = false; 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) for (rel = relstart; rel < relend; ++rel)
if (rel->r_offset >= hstart && rel->r_offset < hend) if (rel->r_offset >= hstart && rel->r_offset < hend)

View File

@ -827,6 +827,20 @@ DESCRIPTION
.#define bfd_get_signed_64(abfd, ptr) \ .#define bfd_get_signed_64(abfd, ptr) \
. BFD_SEND(abfd, bfd_getx_signed_64, (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))
.
*/ */
/* /*