* elf-bfd.h (struct elf_reloc_cookie): Add r_sym_shift field.
* elflink.h: Replace all occurrences of sizeof (Elf_External_*) where Elf_External_* is different for 64 and 32 bit, with corresponding elf_size_info field. (struct elf_final_link_info): Use "bfd_byte *" instead of "Elf_External_Sym *" for external_syms and symbuf. (elf_link_adjust_relocs): Set up r_type_mask and r_sym_shift local vars and use instead of ELF_R_INFO and ELF_R_TYPE macros. (struct elf_link_sort_rela): Add "sym_mask" alias for "offset". (elf_link_sort_cmp1): Use sym_mask field instead of ELF_R_SYM. (elf_link_sort_cmp2): Adjust. (elf_link_sort_relocs): Set up r_sym_mask local var instead of using ELF_R_SYM macro. Set u.sym_mask. (elf_bfd_final_link): Call _bfd_elf_stringtab_init instead of macro version, elf_stringtab_init. Ditto for bfd_section_from_elf_index vs. section_from_elf_index. Adjust Elf_External_Sym pointer arithmetic. Pass bed to elf_link_flush_output_syms. Adjust Elf_External_Dyn pointer arithmentic. Use bed swap_dyn_in and swap_syn_out functions. Rearrange dyn swap in/out switch. (elf_link_output_sym): Adjust Elf_External_Sym pointer arithmentic. Pass bed to elf_link_flush_output_syms. Use bed swap_symbol_out. (elf_link_flush_output_syms): Add elf_backend_data arg. (elf_link_check_versioned_symbol): Likewise. (elf_link_output_extsym): Pass bed to elf_link_check_versioned_symbol. Adjust Elf_External_Sym pointer arithmetic. Use bed swap_symbol_out. (elf_link_input_bfd): Use bfd_section_from_elf_index. Set up r_type_mask and r_sym_shift local vars and use instead of ELF_R_SYM, ELF_R_TYPE and ELF_R_INFO macros. (elf_reloc_link_order): Select ELF32_R_INFO or ELF64_R_INFO invocation based on size rather than using ELF_R_INFO. (elf_gc_mark): Set up r_sym_shift local var and use instead of ELF_R_SYM macro. (struct alloc_got_off_arg): New. (elf_gc_common_finalize_got_offsets): Use elf_size_info instead of ARCH_SIZE. Pass get entry size down to elf_gc_allocate_got_offsets. (elf_gc_allocate_got_offsets): Adjust. (elf_reloc_symbol_deleted_p): Usee cookie.r_sym_shift instead of ELF_R_SYM. Use bfd_section_from_elf_index. (elf_bfd_discard_info): Set cookie.r_sym_shift. * elfcode.h (elf_stringtab_init, section_from_elf_index): Delete. (elf_slurp_symbol_table): Use bfd_section_from_elf_index.
This commit is contained in:
parent
14bde3788a
commit
140f6c8e6d
@ -1,3 +1,47 @@
|
|||||||
|
2004-03-27 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf-bfd.h (struct elf_reloc_cookie): Add r_sym_shift field.
|
||||||
|
* elflink.h: Replace all occurrences of sizeof (Elf_External_*)
|
||||||
|
where Elf_External_* is different for 64 and 32 bit, with
|
||||||
|
corresponding elf_size_info field.
|
||||||
|
(struct elf_final_link_info): Use "bfd_byte *" instead
|
||||||
|
of "Elf_External_Sym *" for external_syms and symbuf.
|
||||||
|
(elf_link_adjust_relocs): Set up r_type_mask and r_sym_shift local
|
||||||
|
vars and use instead of ELF_R_INFO and ELF_R_TYPE macros.
|
||||||
|
(struct elf_link_sort_rela): Add "sym_mask" alias for "offset".
|
||||||
|
(elf_link_sort_cmp1): Use sym_mask field instead of ELF_R_SYM.
|
||||||
|
(elf_link_sort_cmp2): Adjust.
|
||||||
|
(elf_link_sort_relocs): Set up r_sym_mask local var instead of
|
||||||
|
using ELF_R_SYM macro. Set u.sym_mask.
|
||||||
|
(elf_bfd_final_link): Call _bfd_elf_stringtab_init instead of macro
|
||||||
|
version, elf_stringtab_init. Ditto for bfd_section_from_elf_index
|
||||||
|
vs. section_from_elf_index. Adjust Elf_External_Sym pointer
|
||||||
|
arithmetic. Pass bed to elf_link_flush_output_syms. Adjust
|
||||||
|
Elf_External_Dyn pointer arithmentic. Use bed swap_dyn_in and
|
||||||
|
swap_syn_out functions. Rearrange dyn swap in/out switch.
|
||||||
|
(elf_link_output_sym): Adjust Elf_External_Sym pointer arithmentic.
|
||||||
|
Pass bed to elf_link_flush_output_syms. Use bed swap_symbol_out.
|
||||||
|
(elf_link_flush_output_syms): Add elf_backend_data arg.
|
||||||
|
(elf_link_check_versioned_symbol): Likewise.
|
||||||
|
(elf_link_output_extsym): Pass bed to elf_link_check_versioned_symbol.
|
||||||
|
Adjust Elf_External_Sym pointer arithmetic. Use bed swap_symbol_out.
|
||||||
|
(elf_link_input_bfd): Use bfd_section_from_elf_index. Set up
|
||||||
|
r_type_mask and r_sym_shift local vars and use instead of ELF_R_SYM,
|
||||||
|
ELF_R_TYPE and ELF_R_INFO macros.
|
||||||
|
(elf_reloc_link_order): Select ELF32_R_INFO or ELF64_R_INFO invocation
|
||||||
|
based on size rather than using ELF_R_INFO.
|
||||||
|
(elf_gc_mark): Set up r_sym_shift local var and use instead of
|
||||||
|
ELF_R_SYM macro.
|
||||||
|
(struct alloc_got_off_arg): New.
|
||||||
|
(elf_gc_common_finalize_got_offsets): Use elf_size_info instead of
|
||||||
|
ARCH_SIZE. Pass get entry size down to elf_gc_allocate_got_offsets.
|
||||||
|
(elf_gc_allocate_got_offsets): Adjust.
|
||||||
|
(elf_reloc_symbol_deleted_p): Usee cookie.r_sym_shift instead of
|
||||||
|
ELF_R_SYM. Use bfd_section_from_elf_index.
|
||||||
|
(elf_bfd_discard_info): Set cookie.r_sym_shift.
|
||||||
|
* elfcode.h (elf_stringtab_init, section_from_elf_index): Delete.
|
||||||
|
(elf_slurp_symbol_table): Use bfd_section_from_elf_index.
|
||||||
|
|
||||||
2004-03-26 Stan Shebs <shebs@apple.com>
|
2004-03-26 Stan Shebs <shebs@apple.com>
|
||||||
|
|
||||||
Remove MPW support, no longer used.
|
Remove MPW support, no longer used.
|
||||||
|
@ -492,6 +492,7 @@ struct elf_reloc_cookie
|
|||||||
size_t locsymcount;
|
size_t locsymcount;
|
||||||
size_t extsymoff;
|
size_t extsymoff;
|
||||||
struct elf_link_hash_entry **sym_hashes;
|
struct elf_link_hash_entry **sym_hashes;
|
||||||
|
int r_sym_shift;
|
||||||
bfd_boolean bad_symtab;
|
bfd_boolean bad_symtab;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,10 +149,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||||||
#define LOG_FILE_ALIGN 2
|
#define LOG_FILE_ALIGN 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define elf_stringtab_init _bfd_elf_stringtab_init
|
|
||||||
|
|
||||||
#define section_from_elf_index bfd_section_from_elf_index
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void elf_debug_section (int, Elf_Internal_Shdr *);
|
static void elf_debug_section (int, Elf_Internal_Shdr *);
|
||||||
static void elf_debug_file (Elf_Internal_Ehdr *);
|
static void elf_debug_file (Elf_Internal_Ehdr *);
|
||||||
@ -1109,8 +1105,8 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
|
|||||||
else if (isym->st_shndx < SHN_LORESERVE
|
else if (isym->st_shndx < SHN_LORESERVE
|
||||||
|| isym->st_shndx > SHN_HIRESERVE)
|
|| isym->st_shndx > SHN_HIRESERVE)
|
||||||
{
|
{
|
||||||
sym->symbol.section = section_from_elf_index (abfd,
|
sym->symbol.section = bfd_section_from_elf_index (abfd,
|
||||||
isym->st_shndx);
|
isym->st_shndx);
|
||||||
if (sym->symbol.section == NULL)
|
if (sym->symbol.section == NULL)
|
||||||
{
|
{
|
||||||
/* This symbol is in a section for which we did not
|
/* This symbol is in a section for which we did not
|
||||||
|
257
bfd/elflink.h
257
bfd/elflink.h
@ -48,7 +48,7 @@ struct elf_final_link_info
|
|||||||
Elf_Internal_Rela *internal_relocs;
|
Elf_Internal_Rela *internal_relocs;
|
||||||
/* Buffer large enough to hold external local symbols of any input
|
/* Buffer large enough to hold external local symbols of any input
|
||||||
BFD. */
|
BFD. */
|
||||||
Elf_External_Sym *external_syms;
|
bfd_byte *external_syms;
|
||||||
/* And a buffer for symbol section indices. */
|
/* And a buffer for symbol section indices. */
|
||||||
Elf_External_Sym_Shndx *locsym_shndx;
|
Elf_External_Sym_Shndx *locsym_shndx;
|
||||||
/* Buffer large enough to hold internal local symbols of any input
|
/* Buffer large enough to hold internal local symbols of any input
|
||||||
@ -61,7 +61,7 @@ struct elf_final_link_info
|
|||||||
symbol of any input BFD. */
|
symbol of any input BFD. */
|
||||||
asection **sections;
|
asection **sections;
|
||||||
/* Buffer to hold swapped out symbols. */
|
/* Buffer to hold swapped out symbols. */
|
||||||
Elf_External_Sym *symbuf;
|
bfd_byte *symbuf;
|
||||||
/* And one for symbol section indices. */
|
/* And one for symbol section indices. */
|
||||||
Elf_External_Sym_Shndx *symshndxbuf;
|
Elf_External_Sym_Shndx *symshndxbuf;
|
||||||
/* Number of swapped out symbols in buffer. */
|
/* Number of swapped out symbols in buffer. */
|
||||||
@ -76,7 +76,7 @@ static bfd_boolean elf_link_output_sym
|
|||||||
(struct elf_final_link_info *, const char *, Elf_Internal_Sym *, asection *,
|
(struct elf_final_link_info *, const char *, Elf_Internal_Sym *, asection *,
|
||||||
struct elf_link_hash_entry *);
|
struct elf_link_hash_entry *);
|
||||||
static bfd_boolean elf_link_flush_output_syms
|
static bfd_boolean elf_link_flush_output_syms
|
||||||
(struct elf_final_link_info *);
|
(struct elf_final_link_info *, const struct elf_backend_data *);
|
||||||
static bfd_boolean elf_link_output_extsym
|
static bfd_boolean elf_link_output_extsym
|
||||||
(struct elf_link_hash_entry *, void *);
|
(struct elf_link_hash_entry *, void *);
|
||||||
static bfd_boolean elf_link_input_bfd
|
static bfd_boolean elf_link_input_bfd
|
||||||
@ -109,13 +109,15 @@ elf_link_adjust_relocs (bfd *abfd,
|
|||||||
bfd_byte *erela;
|
bfd_byte *erela;
|
||||||
void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
|
void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
|
||||||
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
||||||
|
bfd_vma r_type_mask;
|
||||||
|
int r_sym_shift;
|
||||||
|
|
||||||
if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel))
|
if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
|
||||||
{
|
{
|
||||||
swap_in = bed->s->swap_reloc_in;
|
swap_in = bed->s->swap_reloc_in;
|
||||||
swap_out = bed->s->swap_reloc_out;
|
swap_out = bed->s->swap_reloc_out;
|
||||||
}
|
}
|
||||||
else if (rel_hdr->sh_entsize == sizeof (Elf_External_Rela))
|
else if (rel_hdr->sh_entsize == bed->s->sizeof_rela)
|
||||||
{
|
{
|
||||||
swap_in = bed->s->swap_reloca_in;
|
swap_in = bed->s->swap_reloca_in;
|
||||||
swap_out = bed->s->swap_reloca_out;
|
swap_out = bed->s->swap_reloca_out;
|
||||||
@ -126,6 +128,17 @@ elf_link_adjust_relocs (bfd *abfd,
|
|||||||
if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL)
|
if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
|
if (bed->s->arch_size == 32)
|
||||||
|
{
|
||||||
|
r_type_mask = 0xff;
|
||||||
|
r_sym_shift = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r_type_mask = 0xffffffff;
|
||||||
|
r_sym_shift = 32;
|
||||||
|
}
|
||||||
|
|
||||||
erela = rel_hdr->contents;
|
erela = rel_hdr->contents;
|
||||||
for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize)
|
for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize)
|
||||||
{
|
{
|
||||||
@ -139,15 +152,18 @@ elf_link_adjust_relocs (bfd *abfd,
|
|||||||
|
|
||||||
(*swap_in) (abfd, erela, irela);
|
(*swap_in) (abfd, erela, irela);
|
||||||
for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
|
for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
|
||||||
irela[j].r_info = ELF_R_INFO ((*rel_hash)->indx,
|
irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift
|
||||||
ELF_R_TYPE (irela[j].r_info));
|
| (irela[j].r_info & r_type_mask));
|
||||||
(*swap_out) (abfd, irela, erela);
|
(*swap_out) (abfd, irela, erela);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct elf_link_sort_rela
|
struct elf_link_sort_rela
|
||||||
{
|
{
|
||||||
bfd_vma offset;
|
union {
|
||||||
|
bfd_vma offset;
|
||||||
|
bfd_vma sym_mask;
|
||||||
|
} u;
|
||||||
enum elf_reloc_type_class type;
|
enum elf_reloc_type_class type;
|
||||||
/* We use this as an array of size int_rels_per_ext_rel. */
|
/* We use this as an array of size int_rels_per_ext_rel. */
|
||||||
Elf_Internal_Rela rela[1];
|
Elf_Internal_Rela rela[1];
|
||||||
@ -167,9 +183,9 @@ elf_link_sort_cmp1 (const void *A, const void *B)
|
|||||||
return 1;
|
return 1;
|
||||||
if (relativea > relativeb)
|
if (relativea > relativeb)
|
||||||
return -1;
|
return -1;
|
||||||
if (ELF_R_SYM (a->rela->r_info) < ELF_R_SYM (b->rela->r_info))
|
if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask))
|
||||||
return -1;
|
return -1;
|
||||||
if (ELF_R_SYM (a->rela->r_info) > ELF_R_SYM (b->rela->r_info))
|
if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask))
|
||||||
return 1;
|
return 1;
|
||||||
if (a->rela->r_offset < b->rela->r_offset)
|
if (a->rela->r_offset < b->rela->r_offset)
|
||||||
return -1;
|
return -1;
|
||||||
@ -185,9 +201,9 @@ elf_link_sort_cmp2 (const void *A, const void *B)
|
|||||||
const struct elf_link_sort_rela *b = B;
|
const struct elf_link_sort_rela *b = B;
|
||||||
int copya, copyb;
|
int copya, copyb;
|
||||||
|
|
||||||
if (a->offset < b->offset)
|
if (a->u.offset < b->u.offset)
|
||||||
return -1;
|
return -1;
|
||||||
if (a->offset > b->offset)
|
if (a->u.offset > b->u.offset)
|
||||||
return 1;
|
return 1;
|
||||||
copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt);
|
copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt);
|
||||||
copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt);
|
copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt);
|
||||||
@ -215,6 +231,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
|
void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
|
||||||
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
||||||
struct bfd_link_order *lo;
|
struct bfd_link_order *lo;
|
||||||
|
bfd_vma r_sym_mask;
|
||||||
|
|
||||||
reldyn = bfd_get_section_by_name (abfd, ".rela.dyn");
|
reldyn = bfd_get_section_by_name (abfd, ".rela.dyn");
|
||||||
if (reldyn == NULL || reldyn->_raw_size == 0)
|
if (reldyn == NULL || reldyn->_raw_size == 0)
|
||||||
@ -222,13 +239,13 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
reldyn = bfd_get_section_by_name (abfd, ".rel.dyn");
|
reldyn = bfd_get_section_by_name (abfd, ".rel.dyn");
|
||||||
if (reldyn == NULL || reldyn->_raw_size == 0)
|
if (reldyn == NULL || reldyn->_raw_size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
ext_size = sizeof (Elf_External_Rel);
|
ext_size = bed->s->sizeof_rel;
|
||||||
swap_in = bed->s->swap_reloc_in;
|
swap_in = bed->s->swap_reloc_in;
|
||||||
swap_out = bed->s->swap_reloc_out;
|
swap_out = bed->s->swap_reloc_out;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ext_size = sizeof (Elf_External_Rela);
|
ext_size = bed->s->sizeof_rela;
|
||||||
swap_in = bed->s->swap_reloca_in;
|
swap_in = bed->s->swap_reloca_in;
|
||||||
swap_out = bed->s->swap_reloca_out;
|
swap_out = bed->s->swap_reloca_out;
|
||||||
}
|
}
|
||||||
@ -255,6 +272,11 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bed->s->arch_size == 32)
|
||||||
|
r_sym_mask = ~(bfd_vma) 0xff;
|
||||||
|
else
|
||||||
|
r_sym_mask = ~(bfd_vma) 0xffffffff;
|
||||||
|
|
||||||
for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
|
for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
|
||||||
if (lo->type == bfd_indirect_link_order)
|
if (lo->type == bfd_indirect_link_order)
|
||||||
{
|
{
|
||||||
@ -269,6 +291,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
|
struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
|
||||||
(*swap_in) (abfd, erel, s->rela);
|
(*swap_in) (abfd, erel, s->rela);
|
||||||
s->type = (*bed->elf_backend_reloc_type_class) (s->rela);
|
s->type = (*bed->elf_backend_reloc_type_class) (s->rela);
|
||||||
|
s->u.sym_mask = r_sym_mask;
|
||||||
p += sort_elt;
|
p += sort_elt;
|
||||||
erel += ext_size;
|
erel += ext_size;
|
||||||
}
|
}
|
||||||
@ -289,9 +312,9 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
|
|||||||
for (; i < count; i++, p += sort_elt)
|
for (; i < count; i++, p += sort_elt)
|
||||||
{
|
{
|
||||||
struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p;
|
struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p;
|
||||||
if (ELF_R_SYM (sp->rela->r_info) != ELF_R_SYM (sq->rela->r_info))
|
if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0)
|
||||||
sq = sp;
|
sq = sp;
|
||||||
sp->offset = sq->rela->r_offset;
|
sp->u.offset = sq->rela->r_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
|
qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
|
||||||
@ -364,7 +387,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
|
|
||||||
finfo.info = info;
|
finfo.info = info;
|
||||||
finfo.output_bfd = abfd;
|
finfo.output_bfd = abfd;
|
||||||
finfo.symstrtab = elf_stringtab_init ();
|
finfo.symstrtab = _bfd_elf_stringtab_init ();
|
||||||
if (finfo.symstrtab == NULL)
|
if (finfo.symstrtab == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -464,7 +487,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
|
|
||||||
if (elf_bad_symtab (sec->owner))
|
if (elf_bad_symtab (sec->owner))
|
||||||
sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size
|
sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size
|
||||||
/ sizeof (Elf_External_Sym));
|
/ bed->s->sizeof_sym);
|
||||||
else
|
else
|
||||||
sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info;
|
sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info;
|
||||||
|
|
||||||
@ -506,10 +529,9 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
bfd_size_type entsize1;
|
bfd_size_type entsize1;
|
||||||
|
|
||||||
entsize1 = esdi->rel_hdr.sh_entsize;
|
entsize1 = esdi->rel_hdr.sh_entsize;
|
||||||
BFD_ASSERT (entsize1 == sizeof (Elf_External_Rel)
|
BFD_ASSERT (entsize1 == bed->s->sizeof_rel
|
||||||
|| entsize1 == sizeof (Elf_External_Rela));
|
|| entsize1 == bed->s->sizeof_rela);
|
||||||
same_size = (!o->use_rela_p
|
same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel);
|
||||||
== (entsize1 == sizeof (Elf_External_Rel)));
|
|
||||||
|
|
||||||
if (!same_size)
|
if (!same_size)
|
||||||
rel_count1 = &esdo->rel_count2;
|
rel_count1 = &esdo->rel_count2;
|
||||||
@ -521,8 +543,8 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
unsigned int *rel_count2;
|
unsigned int *rel_count2;
|
||||||
|
|
||||||
BFD_ASSERT (entsize2 != entsize1
|
BFD_ASSERT (entsize2 != entsize1
|
||||||
&& (entsize2 == sizeof (Elf_External_Rel)
|
&& (entsize2 == bed->s->sizeof_rel
|
||||||
|| entsize2 == sizeof (Elf_External_Rela)));
|
|| entsize2 == bed->s->sizeof_rela));
|
||||||
|
|
||||||
rel_count2 = &esdo->rel_count2;
|
rel_count2 = &esdo->rel_count2;
|
||||||
if (!same_size)
|
if (!same_size)
|
||||||
@ -603,7 +625,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
/* sh_name is set in prep_headers. */
|
/* sh_name is set in prep_headers. */
|
||||||
symtab_hdr->sh_type = SHT_SYMTAB;
|
symtab_hdr->sh_type = SHT_SYMTAB;
|
||||||
/* sh_flags, sh_addr and sh_size all start off zero. */
|
/* sh_flags, sh_addr and sh_size all start off zero. */
|
||||||
symtab_hdr->sh_entsize = sizeof (Elf_External_Sym);
|
symtab_hdr->sh_entsize = bed->s->sizeof_sym;
|
||||||
/* sh_link is set in assign_section_numbers. */
|
/* sh_link is set in assign_section_numbers. */
|
||||||
/* sh_info is set below. */
|
/* sh_info is set below. */
|
||||||
/* sh_offset is set just below. */
|
/* sh_offset is set just below. */
|
||||||
@ -623,7 +645,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
else
|
else
|
||||||
finfo.symbuf_size = max_sym_count;
|
finfo.symbuf_size = max_sym_count;
|
||||||
amt = finfo.symbuf_size;
|
amt = finfo.symbuf_size;
|
||||||
amt *= sizeof (Elf_External_Sym);
|
amt *= bed->s->sizeof_sym;
|
||||||
finfo.symbuf = bfd_malloc (amt);
|
finfo.symbuf = bfd_malloc (amt);
|
||||||
if (finfo.symbuf == NULL)
|
if (finfo.symbuf == NULL)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
@ -682,7 +704,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
elfsym.st_other = 0;
|
elfsym.st_other = 0;
|
||||||
for (i = 1; i < elf_numsections (abfd); i++)
|
for (i = 1; i < elf_numsections (abfd); i++)
|
||||||
{
|
{
|
||||||
o = section_from_elf_index (abfd, i);
|
o = bfd_section_from_elf_index (abfd, i);
|
||||||
if (o != NULL)
|
if (o != NULL)
|
||||||
o->target_index = bfd_get_symcount (abfd);
|
o->target_index = bfd_get_symcount (abfd);
|
||||||
elfsym.st_shndx = i;
|
elfsym.st_shndx = i;
|
||||||
@ -724,7 +746,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
|
|
||||||
if (max_sym_count != 0)
|
if (max_sym_count != 0)
|
||||||
{
|
{
|
||||||
amt = max_sym_count * sizeof (Elf_External_Sym);
|
amt = max_sym_count * bed->s->sizeof_sym;
|
||||||
finfo.external_syms = bfd_malloc (amt);
|
finfo.external_syms = bfd_malloc (amt);
|
||||||
if (finfo.external_syms == NULL)
|
if (finfo.external_syms == NULL)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
@ -857,8 +879,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
&& finfo.dynsym_sec->output_section != bfd_abs_section_ptr)
|
&& finfo.dynsym_sec->output_section != bfd_abs_section_ptr)
|
||||||
{
|
{
|
||||||
Elf_Internal_Sym sym;
|
Elf_Internal_Sym sym;
|
||||||
Elf_External_Sym *dynsym =
|
bfd_byte *dynsym = finfo.dynsym_sec->contents;
|
||||||
(Elf_External_Sym *) finfo.dynsym_sec->contents;
|
|
||||||
long last_local = 0;
|
long last_local = 0;
|
||||||
|
|
||||||
/* Write out the section symbols for the output sections. */
|
/* Write out the section symbols for the output sections. */
|
||||||
@ -874,14 +895,16 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
for (s = abfd->sections; s != NULL; s = s->next)
|
for (s = abfd->sections; s != NULL; s = s->next)
|
||||||
{
|
{
|
||||||
int indx;
|
int indx;
|
||||||
Elf_External_Sym *dest;
|
bfd_byte *dest;
|
||||||
|
long dynindx;
|
||||||
|
|
||||||
indx = elf_section_data (s)->this_idx;
|
indx = elf_section_data (s)->this_idx;
|
||||||
|
dynindx = elf_section_data (s)->dynindx;
|
||||||
BFD_ASSERT (indx > 0);
|
BFD_ASSERT (indx > 0);
|
||||||
sym.st_shndx = indx;
|
sym.st_shndx = indx;
|
||||||
sym.st_value = s->vma;
|
sym.st_value = s->vma;
|
||||||
dest = dynsym + elf_section_data (s)->dynindx;
|
dest = dynsym + dynindx * bed->s->sizeof_sym;
|
||||||
elf_swap_symbol_out (abfd, &sym, dest, 0);
|
bed->s->swap_symbol_out (abfd, &sym, dest, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_local = bfd_count_sections (abfd);
|
last_local = bfd_count_sections (abfd);
|
||||||
@ -894,7 +917,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
|
for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
|
||||||
{
|
{
|
||||||
asection *s;
|
asection *s;
|
||||||
Elf_External_Sym *dest;
|
bfd_byte *dest;
|
||||||
|
|
||||||
sym.st_size = e->isym.st_size;
|
sym.st_size = e->isym.st_size;
|
||||||
sym.st_other = e->isym.st_other;
|
sym.st_other = e->isym.st_other;
|
||||||
@ -921,8 +944,8 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
if (last_local < e->dynindx)
|
if (last_local < e->dynindx)
|
||||||
last_local = e->dynindx;
|
last_local = e->dynindx;
|
||||||
|
|
||||||
dest = dynsym + e->dynindx;
|
dest = dynsym + e->dynindx * bed->s->sizeof_sym;
|
||||||
elf_swap_symbol_out (abfd, &sym, dest, 0);
|
bed->s->swap_symbol_out (abfd, &sym, dest, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +976,7 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Flush all symbols to the file. */
|
/* Flush all symbols to the file. */
|
||||||
if (! elf_link_flush_output_syms (&finfo))
|
if (! elf_link_flush_output_syms (&finfo, bed))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Now we know the size of the symtab section. */
|
/* Now we know the size of the symtab section. */
|
||||||
@ -1028,43 +1051,41 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
shared library, finish up the dynamic linking information. */
|
shared library, finish up the dynamic linking information. */
|
||||||
if (dynamic)
|
if (dynamic)
|
||||||
{
|
{
|
||||||
Elf_External_Dyn *dyncon, *dynconend;
|
bfd_byte *dyncon, *dynconend;
|
||||||
|
|
||||||
/* Fix up .dynamic entries. */
|
/* Fix up .dynamic entries. */
|
||||||
o = bfd_get_section_by_name (dynobj, ".dynamic");
|
o = bfd_get_section_by_name (dynobj, ".dynamic");
|
||||||
BFD_ASSERT (o != NULL);
|
BFD_ASSERT (o != NULL);
|
||||||
|
|
||||||
dyncon = (Elf_External_Dyn *) o->contents;
|
dyncon = o->contents;
|
||||||
dynconend = (Elf_External_Dyn *) (o->contents + o->_raw_size);
|
dynconend = o->contents + o->_raw_size;
|
||||||
for (; dyncon < dynconend; dyncon++)
|
for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
|
||||||
{
|
{
|
||||||
Elf_Internal_Dyn dyn;
|
Elf_Internal_Dyn dyn;
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
|
||||||
elf_swap_dyn_in (dynobj, dyncon, &dyn);
|
bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
|
||||||
|
|
||||||
switch (dyn.d_tag)
|
switch (dyn.d_tag)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
break;
|
continue;
|
||||||
case DT_NULL:
|
case DT_NULL:
|
||||||
if (relativecount > 0 && dyncon + 1 < dynconend)
|
if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend)
|
||||||
{
|
{
|
||||||
switch (elf_section_data (reldyn)->this_hdr.sh_type)
|
switch (elf_section_data (reldyn)->this_hdr.sh_type)
|
||||||
{
|
{
|
||||||
case SHT_REL: dyn.d_tag = DT_RELCOUNT; break;
|
case SHT_REL: dyn.d_tag = DT_RELCOUNT; break;
|
||||||
case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break;
|
case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break;
|
||||||
default: break;
|
default: continue;
|
||||||
}
|
|
||||||
if (dyn.d_tag != DT_NULL)
|
|
||||||
{
|
|
||||||
dyn.d_un.d_val = relativecount;
|
|
||||||
elf_swap_dyn_out (dynobj, &dyn, dyncon);
|
|
||||||
relativecount = 0;
|
|
||||||
}
|
}
|
||||||
|
dyn.d_un.d_val = relativecount;
|
||||||
|
relativecount = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
case DT_INIT:
|
case DT_INIT:
|
||||||
name = info->init_function;
|
name = info->init_function;
|
||||||
goto get_sym;
|
goto get_sym;
|
||||||
@ -1091,11 +1112,10 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
library and does not apply to this one. */
|
library and does not apply to this one. */
|
||||||
dyn.d_un.d_val = 0;
|
dyn.d_un.d_val = 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
elf_swap_dyn_out (dynobj, &dyn, dyncon);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
case DT_PREINIT_ARRAYSZ:
|
case DT_PREINIT_ARRAYSZ:
|
||||||
name = ".preinit_array";
|
name = ".preinit_array";
|
||||||
@ -1118,7 +1138,6 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
(*_bfd_error_handler)
|
(*_bfd_error_handler)
|
||||||
(_("warning: %s section has zero size"), name);
|
(_("warning: %s section has zero size"), name);
|
||||||
dyn.d_un.d_val = o->_raw_size;
|
dyn.d_un.d_val = o->_raw_size;
|
||||||
elf_swap_dyn_out (dynobj, &dyn, dyncon);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DT_PREINIT_ARRAY:
|
case DT_PREINIT_ARRAY:
|
||||||
@ -1158,7 +1177,6 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
dyn.d_un.d_ptr = o->vma;
|
dyn.d_un.d_ptr = o->vma;
|
||||||
elf_swap_dyn_out (dynobj, &dyn, dyncon);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DT_REL:
|
case DT_REL:
|
||||||
@ -1188,9 +1206,9 @@ elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elf_swap_dyn_out (dynobj, &dyn, dyncon);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
bed->s->swap_dyn_out (dynobj, &dyn, dyncon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,14 +1350,15 @@ elf_link_output_sym (struct elf_final_link_info *finfo,
|
|||||||
asection *input_sec,
|
asection *input_sec,
|
||||||
struct elf_link_hash_entry *h)
|
struct elf_link_hash_entry *h)
|
||||||
{
|
{
|
||||||
Elf_External_Sym *dest;
|
bfd_byte *dest;
|
||||||
Elf_External_Sym_Shndx *destshndx;
|
Elf_External_Sym_Shndx *destshndx;
|
||||||
bfd_boolean (*output_symbol_hook)
|
bfd_boolean (*output_symbol_hook)
|
||||||
(struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
|
(struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
|
||||||
struct elf_link_hash_entry *);
|
struct elf_link_hash_entry *);
|
||||||
|
const struct elf_backend_data *bed;
|
||||||
|
|
||||||
output_symbol_hook = get_elf_backend_data (finfo->output_bfd)->
|
bed = get_elf_backend_data (finfo->output_bfd);
|
||||||
elf_backend_link_output_symbol_hook;
|
output_symbol_hook = bed->elf_backend_link_output_symbol_hook;
|
||||||
if (output_symbol_hook != NULL)
|
if (output_symbol_hook != NULL)
|
||||||
{
|
{
|
||||||
if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h))
|
if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h))
|
||||||
@ -1360,11 +1379,11 @@ elf_link_output_sym (struct elf_final_link_info *finfo,
|
|||||||
|
|
||||||
if (finfo->symbuf_count >= finfo->symbuf_size)
|
if (finfo->symbuf_count >= finfo->symbuf_size)
|
||||||
{
|
{
|
||||||
if (! elf_link_flush_output_syms (finfo))
|
if (! elf_link_flush_output_syms (finfo, bed))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest = finfo->symbuf + finfo->symbuf_count;
|
dest = finfo->symbuf + finfo->symbuf_count * bed->s->sizeof_sym;
|
||||||
destshndx = finfo->symshndxbuf;
|
destshndx = finfo->symshndxbuf;
|
||||||
if (destshndx != NULL)
|
if (destshndx != NULL)
|
||||||
{
|
{
|
||||||
@ -1382,7 +1401,7 @@ elf_link_output_sym (struct elf_final_link_info *finfo,
|
|||||||
destshndx += bfd_get_symcount (finfo->output_bfd);
|
destshndx += bfd_get_symcount (finfo->output_bfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
elf_swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx);
|
bed->s->swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx);
|
||||||
finfo->symbuf_count += 1;
|
finfo->symbuf_count += 1;
|
||||||
bfd_get_symcount (finfo->output_bfd) += 1;
|
bfd_get_symcount (finfo->output_bfd) += 1;
|
||||||
|
|
||||||
@ -1392,7 +1411,8 @@ elf_link_output_sym (struct elf_final_link_info *finfo,
|
|||||||
/* Flush the output symbols to the file. */
|
/* Flush the output symbols to the file. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf_link_flush_output_syms (struct elf_final_link_info *finfo)
|
elf_link_flush_output_syms (struct elf_final_link_info *finfo,
|
||||||
|
const struct elf_backend_data *bed)
|
||||||
{
|
{
|
||||||
if (finfo->symbuf_count > 0)
|
if (finfo->symbuf_count > 0)
|
||||||
{
|
{
|
||||||
@ -1402,7 +1422,7 @@ elf_link_flush_output_syms (struct elf_final_link_info *finfo)
|
|||||||
|
|
||||||
hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr;
|
hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr;
|
||||||
pos = hdr->sh_offset + hdr->sh_size;
|
pos = hdr->sh_offset + hdr->sh_size;
|
||||||
amt = finfo->symbuf_count * sizeof (Elf_External_Sym);
|
amt = finfo->symbuf_count * bed->s->sizeof_sym;
|
||||||
if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0
|
if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0
|
||||||
|| bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt)
|
|| bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1422,6 +1442,7 @@ elf_link_flush_output_syms (struct elf_final_link_info *finfo)
|
|||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf_link_check_versioned_symbol (struct bfd_link_info *info,
|
elf_link_check_versioned_symbol (struct bfd_link_info *info,
|
||||||
|
const struct elf_backend_data *bed,
|
||||||
struct elf_link_hash_entry *h)
|
struct elf_link_hash_entry *h)
|
||||||
{
|
{
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
@ -1481,7 +1502,7 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info,
|
|||||||
|
|
||||||
hdr = &elf_tdata (input)->dynsymtab_hdr;
|
hdr = &elf_tdata (input)->dynsymtab_hdr;
|
||||||
|
|
||||||
symcount = hdr->sh_size / sizeof (Elf_External_Sym);
|
symcount = hdr->sh_size / bed->s->sizeof_sym;
|
||||||
if (elf_bad_symtab (input))
|
if (elf_bad_symtab (input))
|
||||||
{
|
{
|
||||||
extsymcount = symcount;
|
extsymcount = symcount;
|
||||||
@ -1576,6 +1597,7 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
|
|||||||
bfd_boolean strip;
|
bfd_boolean strip;
|
||||||
Elf_Internal_Sym sym;
|
Elf_Internal_Sym sym;
|
||||||
asection *input_sec;
|
asection *input_sec;
|
||||||
|
const struct elf_backend_data *bed;
|
||||||
|
|
||||||
if (h->root.type == bfd_link_hash_warning)
|
if (h->root.type == bfd_link_hash_warning)
|
||||||
{
|
{
|
||||||
@ -1596,6 +1618,8 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bed = get_elf_backend_data (finfo->output_bfd);
|
||||||
|
|
||||||
/* If we have an undefined symbol reference here then it must have
|
/* If we have an undefined symbol reference here then it must have
|
||||||
come from a shared library that is being linked in. (Undefined
|
come from a shared library that is being linked in. (Undefined
|
||||||
references in regular files have already been handled). If we
|
references in regular files have already been handled). If we
|
||||||
@ -1603,7 +1627,7 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
|
|||||||
if (h->root.type == bfd_link_hash_undefined
|
if (h->root.type == bfd_link_hash_undefined
|
||||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
|
||||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
|
||||||
&& ! elf_link_check_versioned_symbol (finfo->info, h)
|
&& ! elf_link_check_versioned_symbol (finfo->info, bed, h)
|
||||||
&& finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
|
&& finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
|
||||||
{
|
{
|
||||||
if (! ((*finfo->info->callbacks->undefined_symbol)
|
if (! ((*finfo->info->callbacks->undefined_symbol)
|
||||||
@ -1622,7 +1646,7 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
|
|||||||
&& (h->elf_link_hash_flags
|
&& (h->elf_link_hash_flags
|
||||||
& (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
|
& (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
|
||||||
== (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC)
|
== (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC)
|
||||||
&& ! elf_link_check_versioned_symbol (finfo->info, h))
|
&& ! elf_link_check_versioned_symbol (finfo->info, bed, h))
|
||||||
{
|
{
|
||||||
(*_bfd_error_handler)
|
(*_bfd_error_handler)
|
||||||
(_("%s: %s symbol `%s' in %s is referenced by DSO"),
|
(_("%s: %s symbol `%s' in %s is referenced by DSO"),
|
||||||
@ -1768,9 +1792,6 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
|
|||||||
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
|
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
|
||||||
&& elf_hash_table (finfo->info)->dynamic_sections_created)
|
&& elf_hash_table (finfo->info)->dynamic_sections_created)
|
||||||
{
|
{
|
||||||
const struct elf_backend_data *bed;
|
|
||||||
|
|
||||||
bed = get_elf_backend_data (finfo->output_bfd);
|
|
||||||
if (! ((*bed->elf_backend_finish_dynamic_symbol)
|
if (! ((*bed->elf_backend_finish_dynamic_symbol)
|
||||||
(finfo->output_bfd, finfo->info, h, &sym)))
|
(finfo->output_bfd, finfo->info, h, &sym)))
|
||||||
{
|
{
|
||||||
@ -1830,11 +1851,11 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
|
|||||||
size_t hash_entry_size;
|
size_t hash_entry_size;
|
||||||
bfd_byte *bucketpos;
|
bfd_byte *bucketpos;
|
||||||
bfd_vma chain;
|
bfd_vma chain;
|
||||||
Elf_External_Sym *esym;
|
bfd_byte *esym;
|
||||||
|
|
||||||
sym.st_name = h->dynstr_index;
|
sym.st_name = h->dynstr_index;
|
||||||
esym = (Elf_External_Sym *) finfo->dynsym_sec->contents + h->dynindx;
|
esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym;
|
||||||
elf_swap_symbol_out (finfo->output_bfd, &sym, esym, 0);
|
bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0);
|
||||||
|
|
||||||
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;
|
||||||
@ -1935,7 +1956,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||||
if (elf_bad_symtab (input_bfd))
|
if (elf_bad_symtab (input_bfd))
|
||||||
{
|
{
|
||||||
locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
|
locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
|
||||||
extsymoff = 0;
|
extsymoff = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1984,7 +2005,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
else if (isym->st_shndx < SHN_LORESERVE
|
else if (isym->st_shndx < SHN_LORESERVE
|
||||||
|| isym->st_shndx > SHN_HIRESERVE)
|
|| isym->st_shndx > SHN_HIRESERVE)
|
||||||
{
|
{
|
||||||
isec = section_from_elf_index (input_bfd, isym->st_shndx);
|
isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
|
||||||
if (isec
|
if (isec
|
||||||
&& isec->sec_info_type == ELF_INFO_TYPE_MERGE
|
&& isec->sec_info_type == ELF_INFO_TYPE_MERGE
|
||||||
&& ELF_ST_TYPE (isym->st_info) != STT_SECTION)
|
&& ELF_ST_TYPE (isym->st_info) != STT_SECTION)
|
||||||
@ -2133,6 +2154,8 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
if ((o->flags & SEC_RELOC) != 0)
|
if ((o->flags & SEC_RELOC) != 0)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela *internal_relocs;
|
Elf_Internal_Rela *internal_relocs;
|
||||||
|
bfd_vma r_type_mask;
|
||||||
|
int r_sym_shift;
|
||||||
|
|
||||||
/* Get the swapped relocs. */
|
/* Get the swapped relocs. */
|
||||||
internal_relocs
|
internal_relocs
|
||||||
@ -2142,6 +2165,17 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
&& o->reloc_count > 0)
|
&& o->reloc_count > 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (bed->s->arch_size == 32)
|
||||||
|
{
|
||||||
|
r_type_mask = 0xff;
|
||||||
|
r_sym_shift = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r_type_mask = 0xffffffff;
|
||||||
|
r_sym_shift = 32;
|
||||||
|
}
|
||||||
|
|
||||||
/* Run through the relocs looking for any against symbols
|
/* Run through the relocs looking for any against symbols
|
||||||
from discarded sections and section symbols from
|
from discarded sections and section symbols from
|
||||||
removed link-once sections. Complain about relocs
|
removed link-once sections. Complain about relocs
|
||||||
@ -2156,7 +2190,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
|
relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
|
||||||
for ( ; rel < relend; rel++)
|
for ( ; rel < relend; rel++)
|
||||||
{
|
{
|
||||||
unsigned long r_symndx = ELF_R_SYM (rel->r_info);
|
unsigned long r_symndx = rel->r_info >> r_sym_shift;
|
||||||
asection *sec;
|
asection *sec;
|
||||||
|
|
||||||
if (r_symndx >= locsymcount
|
if (r_symndx >= locsymcount
|
||||||
@ -2217,8 +2251,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
= sec->kept_section;
|
= sec->kept_section;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rel->r_info
|
rel->r_info &= r_type_mask;
|
||||||
= ELF_R_INFO (0, ELF_R_TYPE (rel->r_info));
|
|
||||||
rel->r_addend = 0;
|
rel->r_addend = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2287,7 +2320,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
input_rel_hdr = &elf_section_data (o)->rel_hdr;
|
input_rel_hdr = &elf_section_data (o)->rel_hdr;
|
||||||
rela_normal = (bed->rela_normal
|
rela_normal = (bed->rela_normal
|
||||||
&& (input_rel_hdr->sh_entsize
|
&& (input_rel_hdr->sh_entsize
|
||||||
== sizeof (Elf_External_Rela)));
|
== bed->s->sizeof_rela));
|
||||||
|
|
||||||
/* Adjust the reloc addresses and symbol indices. */
|
/* Adjust the reloc addresses and symbol indices. */
|
||||||
|
|
||||||
@ -2335,7 +2368,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
|
|
||||||
last_offset = irela->r_offset;
|
last_offset = irela->r_offset;
|
||||||
|
|
||||||
r_symndx = ELF_R_SYM (irela->r_info);
|
r_symndx = irela->r_info >> r_sym_shift;
|
||||||
if (r_symndx == STN_UNDEF)
|
if (r_symndx == STN_UNDEF)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -2459,8 +2492,8 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
|||||||
r_symndx = finfo->indices[r_symndx];
|
r_symndx = finfo->indices[r_symndx];
|
||||||
}
|
}
|
||||||
|
|
||||||
irela->r_info = ELF_R_INFO (r_symndx,
|
irela->r_info = ((bfd_vma) r_symndx << r_sym_shift
|
||||||
ELF_R_TYPE (irela->r_info));
|
| (irela->r_info & r_type_mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Swap out the relocs. */
|
/* Swap out the relocs. */
|
||||||
@ -2674,21 +2707,24 @@ elf_reloc_link_order (bfd *output_bfd,
|
|||||||
irel[i].r_info = 0;
|
irel[i].r_info = 0;
|
||||||
irel[i].r_addend = 0;
|
irel[i].r_addend = 0;
|
||||||
}
|
}
|
||||||
irel[0].r_info = ELF_R_INFO (indx, howto->type);
|
if (bed->s->arch_size == 32)
|
||||||
|
irel[0].r_info = ELF32_R_INFO (indx, howto->type);
|
||||||
|
else
|
||||||
|
irel[0].r_info = ELF64_R_INFO (indx, howto->type);
|
||||||
|
|
||||||
rel_hdr = &elf_section_data (output_section)->rel_hdr;
|
rel_hdr = &elf_section_data (output_section)->rel_hdr;
|
||||||
erel = rel_hdr->contents;
|
erel = rel_hdr->contents;
|
||||||
if (rel_hdr->sh_type == SHT_REL)
|
if (rel_hdr->sh_type == SHT_REL)
|
||||||
{
|
{
|
||||||
erel += (elf_section_data (output_section)->rel_count
|
erel += (elf_section_data (output_section)->rel_count
|
||||||
* sizeof (Elf_External_Rel));
|
* bed->s->sizeof_rel);
|
||||||
(*bed->s->swap_reloc_out) (output_bfd, irel, erel);
|
(*bed->s->swap_reloc_out) (output_bfd, irel, erel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
irel[0].r_addend = addend;
|
irel[0].r_addend = addend;
|
||||||
erel += (elf_section_data (output_section)->rel_count
|
erel += (elf_section_data (output_section)->rel_count
|
||||||
* sizeof (Elf_External_Rela));
|
* bed->s->sizeof_rela);
|
||||||
(*bed->s->swap_reloca_out) (output_bfd, irel, erel);
|
(*bed->s->swap_reloca_out) (output_bfd, irel, erel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2741,6 +2777,7 @@ elf_gc_mark (struct bfd_link_info *info,
|
|||||||
bfd *input_bfd = sec->owner;
|
bfd *input_bfd = sec->owner;
|
||||||
const struct elf_backend_data *bed = get_elf_backend_data (input_bfd);
|
const struct elf_backend_data *bed = get_elf_backend_data (input_bfd);
|
||||||
Elf_Internal_Sym *isym = NULL;
|
Elf_Internal_Sym *isym = NULL;
|
||||||
|
int r_sym_shift;
|
||||||
|
|
||||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||||
sym_hashes = elf_sym_hashes (input_bfd);
|
sym_hashes = elf_sym_hashes (input_bfd);
|
||||||
@ -2748,7 +2785,7 @@ elf_gc_mark (struct bfd_link_info *info,
|
|||||||
/* Read the local symbols. */
|
/* Read the local symbols. */
|
||||||
if (elf_bad_symtab (input_bfd))
|
if (elf_bad_symtab (input_bfd))
|
||||||
{
|
{
|
||||||
nlocsyms = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
|
nlocsyms = symtab_hdr->sh_size / bed->s->sizeof_sym;
|
||||||
extsymoff = 0;
|
extsymoff = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2773,13 +2810,18 @@ elf_gc_mark (struct bfd_link_info *info,
|
|||||||
}
|
}
|
||||||
relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
|
relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
|
||||||
|
|
||||||
|
if (bed->s->arch_size == 32)
|
||||||
|
r_sym_shift = 8;
|
||||||
|
else
|
||||||
|
r_sym_shift = 32;
|
||||||
|
|
||||||
for (rel = relstart; rel < relend; rel++)
|
for (rel = relstart; rel < relend; rel++)
|
||||||
{
|
{
|
||||||
unsigned long r_symndx;
|
unsigned long r_symndx;
|
||||||
asection *rsec;
|
asection *rsec;
|
||||||
struct elf_link_hash_entry *h;
|
struct elf_link_hash_entry *h;
|
||||||
|
|
||||||
r_symndx = ELF_R_SYM (rel->r_info);
|
r_symndx = rel->r_info >> r_sym_shift;
|
||||||
if (r_symndx == 0)
|
if (r_symndx == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -3097,11 +3139,12 @@ elf_gc_record_vtinherit (bfd *abfd,
|
|||||||
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
|
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
|
||||||
struct elf_link_hash_entry **search, *child;
|
struct elf_link_hash_entry **search, *child;
|
||||||
bfd_size_type extsymcount;
|
bfd_size_type extsymcount;
|
||||||
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||||
|
|
||||||
/* The sh_info field of the symtab header tells us where the
|
/* The sh_info field of the symtab header tells us where the
|
||||||
external symbols start. We don't care about the local symbols at
|
external symbols start. We don't care about the local symbols at
|
||||||
this point. */
|
this point. */
|
||||||
extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size/sizeof (Elf_External_Sym);
|
extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym;
|
||||||
if (!elf_bad_symtab (abfd))
|
if (!elf_bad_symtab (abfd))
|
||||||
extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info;
|
extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info;
|
||||||
|
|
||||||
@ -3208,6 +3251,11 @@ elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct alloc_got_off_arg {
|
||||||
|
bfd_vma gotoff;
|
||||||
|
unsigned int got_elt_size;
|
||||||
|
};
|
||||||
|
|
||||||
/* And an accompanying bit to work out final got entry offsets once
|
/* And an accompanying bit to work out final got entry offsets once
|
||||||
we're done. Should be called from final_link. */
|
we're done. Should be called from final_link. */
|
||||||
|
|
||||||
@ -3218,6 +3266,8 @@ elf_gc_common_finalize_got_offsets (bfd *abfd,
|
|||||||
bfd *i;
|
bfd *i;
|
||||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||||
bfd_vma gotoff;
|
bfd_vma gotoff;
|
||||||
|
unsigned int got_elt_size = bed->s->arch_size / 8;
|
||||||
|
struct alloc_got_off_arg gofarg;
|
||||||
|
|
||||||
if (! is_elf_hash_table (info->hash))
|
if (! is_elf_hash_table (info->hash))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -3245,7 +3295,7 @@ elf_gc_common_finalize_got_offsets (bfd *abfd,
|
|||||||
|
|
||||||
symtab_hdr = &elf_tdata (i)->symtab_hdr;
|
symtab_hdr = &elf_tdata (i)->symtab_hdr;
|
||||||
if (elf_bad_symtab (i))
|
if (elf_bad_symtab (i))
|
||||||
locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
|
locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
|
||||||
else
|
else
|
||||||
locsymcount = symtab_hdr->sh_info;
|
locsymcount = symtab_hdr->sh_info;
|
||||||
|
|
||||||
@ -3254,7 +3304,7 @@ elf_gc_common_finalize_got_offsets (bfd *abfd,
|
|||||||
if (local_got[j] > 0)
|
if (local_got[j] > 0)
|
||||||
{
|
{
|
||||||
local_got[j] = gotoff;
|
local_got[j] = gotoff;
|
||||||
gotoff += ARCH_SIZE / 8;
|
gotoff += got_elt_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
local_got[j] = (bfd_vma) -1;
|
local_got[j] = (bfd_vma) -1;
|
||||||
@ -3263,9 +3313,11 @@ elf_gc_common_finalize_got_offsets (bfd *abfd,
|
|||||||
|
|
||||||
/* Then the global .got entries. .plt refcounts are handled by
|
/* Then the global .got entries. .plt refcounts are handled by
|
||||||
adjust_dynamic_symbol */
|
adjust_dynamic_symbol */
|
||||||
|
gofarg.gotoff = gotoff;
|
||||||
|
gofarg.got_elt_size = got_elt_size;
|
||||||
elf_link_hash_traverse (elf_hash_table (info),
|
elf_link_hash_traverse (elf_hash_table (info),
|
||||||
elf_gc_allocate_got_offsets,
|
elf_gc_allocate_got_offsets,
|
||||||
&gotoff);
|
&gofarg);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3273,17 +3325,17 @@ elf_gc_common_finalize_got_offsets (bfd *abfd,
|
|||||||
to real got offsets. */
|
to real got offsets. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *offarg)
|
elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg)
|
||||||
{
|
{
|
||||||
bfd_vma *off = offarg;
|
struct alloc_got_off_arg *gofarg = arg;
|
||||||
|
|
||||||
if (h->root.type == bfd_link_hash_warning)
|
if (h->root.type == bfd_link_hash_warning)
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||||
|
|
||||||
if (h->got.refcount > 0)
|
if (h->got.refcount > 0)
|
||||||
{
|
{
|
||||||
h->got.offset = off[0];
|
h->got.offset = gofarg->gotoff;
|
||||||
off[0] += ARCH_SIZE / 8;
|
gofarg->gotoff += gofarg->got_elt_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
h->got.offset = (bfd_vma) -1;
|
h->got.offset = (bfd_vma) -1;
|
||||||
@ -3322,7 +3374,7 @@ elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
|
|||||||
if (rcookie->rel->r_offset != offset)
|
if (rcookie->rel->r_offset != offset)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r_symndx = ELF_R_SYM (rcookie->rel->r_info);
|
r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift;
|
||||||
if (r_symndx == SHN_UNDEF)
|
if (r_symndx == SHN_UNDEF)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -3356,7 +3408,7 @@ elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
|
|||||||
isym = &rcookie->locsyms[r_symndx];
|
isym = &rcookie->locsyms[r_symndx];
|
||||||
if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
|
if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
|
||||||
{
|
{
|
||||||
isec = section_from_elf_index (rcookie->abfd, isym->st_shndx);
|
isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx);
|
||||||
if (isec != NULL && elf_discarded_section (isec))
|
if (isec != NULL && elf_discarded_section (isec))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -3421,7 +3473,7 @@ elf_bfd_discard_info (bfd *output_bfd, struct bfd_link_info *info)
|
|||||||
cookie.bad_symtab = elf_bad_symtab (abfd);
|
cookie.bad_symtab = elf_bad_symtab (abfd);
|
||||||
if (cookie.bad_symtab)
|
if (cookie.bad_symtab)
|
||||||
{
|
{
|
||||||
cookie.locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
|
cookie.locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
|
||||||
cookie.extsymoff = 0;
|
cookie.extsymoff = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3430,6 +3482,11 @@ elf_bfd_discard_info (bfd *output_bfd, struct bfd_link_info *info)
|
|||||||
cookie.extsymoff = symtab_hdr->sh_info;
|
cookie.extsymoff = symtab_hdr->sh_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bed->s->arch_size == 32)
|
||||||
|
cookie.r_sym_shift = 8;
|
||||||
|
else
|
||||||
|
cookie.r_sym_shift = 32;
|
||||||
|
|
||||||
cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
|
cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
|
||||||
if (cookie.locsyms == NULL && cookie.locsymcount != 0)
|
if (cookie.locsyms == NULL && cookie.locsymcount != 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user