mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
* elf-bfd.h (struct elf_link_local_dynamic_entry): New.
(struct elf_link_hash_table): Add dynlocal. (_bfd_elf_link_lookup_local_dynindx): Prototype. (_bfd_elf_link_adjust_dynindx): Delete. (_bfd_elf_link_renumber_dynsyms): Prototype. (_bfd_elf,link_record_local_dynamic_symbol): Prototype. * elfcode.h (elf_link_record_local_dynamic_symbol): New alias. * elflink.c (_bfd_elf_link_adjust_dynindx): Delete. (_bfd_elf_link_lookup_local_dynindx): New function. (elf_link_renumber_hash_table_dynsyms): New function. (_bfd_elf_link_renumber_dynsyms): New function. * elflink.h (elf_link_record_local_dynamic_symbol): New function. (struct elf_assign_sym_version_info): Delete removed_dynamic. (bfd_elf,size_dynamic_sections): Use _bfd_strip_section_from_output instead of elf_link_remove_section_and_adjust_dynindices. Remove removed_dynamic code. Use _bfd_elf_link_renumber_dynsyms. (elf_link_assign_sym_version): Remove removed_dynamic code. (elf_link_renumber_dynsyms): Delete. (elf_bfd_final_link): Install section and local symbols into .dynsym. * elf32-m68k.c (elf_m68k_adjust_dynindx): Delete. (elf_m68k_size_dynamic_sections): Don't set section dynindicies. (elf_m68k_finish_dynamic_sections): Don't write section dynsyms. * elf32-mips.c: Similarly. * elf32-ppc.c: Similarly. * elf32-sparc.c: Similarly. * elf64-alpha.c: Similarly. * elf64-sparc.c: Similarly.
This commit is contained in:
parent
e1ee1229a2
commit
30b30c2181
@ -1,3 +1,36 @@
|
||||
1999-07-13 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* elf.c (assign_file_positions_for_segments): Don't overwrite p_flags.
|
||||
|
||||
* elf-bfd.h (struct elf_link_local_dynamic_entry): New.
|
||||
(struct elf_link_hash_table): Add dynlocal.
|
||||
(_bfd_elf_link_lookup_local_dynindx): Prototype.
|
||||
(_bfd_elf_link_adjust_dynindx): Delete.
|
||||
(_bfd_elf_link_renumber_dynsyms): Prototype.
|
||||
(_bfd_elf,link_record_local_dynamic_symbol): Prototype.
|
||||
* elfcode.h (elf_link_record_local_dynamic_symbol): New alias.
|
||||
* elflink.c (_bfd_elf_link_adjust_dynindx): Delete.
|
||||
(_bfd_elf_link_lookup_local_dynindx): New function.
|
||||
(elf_link_renumber_hash_table_dynsyms): New function.
|
||||
(_bfd_elf_link_renumber_dynsyms): New function.
|
||||
* elflink.h (elf_link_record_local_dynamic_symbol): New function.
|
||||
(struct elf_assign_sym_version_info): Delete removed_dynamic.
|
||||
(bfd_elf,size_dynamic_sections): Use _bfd_strip_section_from_output
|
||||
instead of elf_link_remove_section_and_adjust_dynindices.
|
||||
Remove removed_dynamic code. Use _bfd_elf_link_renumber_dynsyms.
|
||||
(elf_link_assign_sym_version): Remove removed_dynamic code.
|
||||
(elf_link_renumber_dynsyms): Delete.
|
||||
(elf_bfd_final_link): Install section and local symbols into .dynsym.
|
||||
|
||||
* elf32-m68k.c (elf_m68k_adjust_dynindx): Delete.
|
||||
(elf_m68k_size_dynamic_sections): Don't set section dynindicies.
|
||||
(elf_m68k_finish_dynamic_sections): Don't write section dynsyms.
|
||||
* elf32-mips.c: Similarly.
|
||||
* elf32-ppc.c: Similarly.
|
||||
* elf32-sparc.c: Similarly.
|
||||
* elf64-alpha.c: Similarly.
|
||||
* elf64-sparc.c: Similarly.
|
||||
|
||||
1999-07-13 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* elf32-mips.c (mips_elf_calculate_relocation): Do not complain
|
||||
|
@ -86,6 +86,16 @@ struct elf_link_hash_entry
|
||||
|
||||
/* Symbol index as a dynamic symbol. Initialized to -1, and remains
|
||||
-1 if this is not a dynamic symbol. */
|
||||
/* ??? Note that this is consistently used as a synonym for tests
|
||||
against whether we can perform various simplifying transformations
|
||||
to the code. (E.g. changing a pc-relative jump to a PLT entry
|
||||
into a pc-relative jump to the target function.) That test, which
|
||||
is often relatively complex, and someplaces wrong or incomplete,
|
||||
should really be replaced by a predicate in elflink.c.
|
||||
|
||||
End result: this field -1 does not indicate that the symbol is
|
||||
not in the dynamic symbol table, but rather that the symbol is
|
||||
not visible outside this DSO. */
|
||||
long dynindx;
|
||||
|
||||
/* String table index in .dynstr if this is a dynamic symbol. */
|
||||
@ -181,6 +191,25 @@ struct elf_link_hash_entry
|
||||
#define ELF_LINK_HASH_MARK 04000
|
||||
};
|
||||
|
||||
/* Records local symbols to be emitted in the dynamic symbol table. */
|
||||
|
||||
struct elf_link_local_dynamic_entry
|
||||
{
|
||||
struct elf_link_local_dynamic_entry *next;
|
||||
|
||||
/* The input bfd this symbol came from. */
|
||||
bfd *input_bfd;
|
||||
|
||||
/* The index of the local symbol being copied. */
|
||||
long input_indx;
|
||||
|
||||
/* The index in the outgoing dynamic symbol table. */
|
||||
long dynindx;
|
||||
|
||||
/* A copy of the input symbol. */
|
||||
Elf_Internal_Sym isym;
|
||||
};
|
||||
|
||||
/* ELF linker hash table. */
|
||||
|
||||
struct elf_link_hash_table
|
||||
@ -209,6 +238,8 @@ struct elf_link_hash_table
|
||||
struct elf_link_hash_entry *hgot;
|
||||
/* A pointer to information used to link stabs in sections. */
|
||||
PTR stab_info;
|
||||
/* A linked list of local symbols to be added to .dynsym. */
|
||||
struct elf_link_local_dynamic_entry *dynlocal;
|
||||
};
|
||||
|
||||
/* Look up an entry in an ELF linker hash table. */
|
||||
@ -956,6 +987,9 @@ struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void));
|
||||
boolean
|
||||
_bfd_elf_link_record_dynamic_symbol PARAMS ((struct bfd_link_info *,
|
||||
struct elf_link_hash_entry *));
|
||||
long
|
||||
_bfd_elf_link_lookup_local_dynindx PARAMS ((struct bfd_link_info *,
|
||||
bfd *, long));
|
||||
boolean
|
||||
_bfd_elf_compute_section_file_positions PARAMS ((bfd *,
|
||||
struct bfd_link_info *));
|
||||
@ -970,8 +1004,8 @@ boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *,
|
||||
struct bfd_link_info *));
|
||||
boolean _bfd_elf_create_got_section PARAMS ((bfd *,
|
||||
struct bfd_link_info *));
|
||||
boolean _bfd_elf_link_adjust_dynindx PARAMS ((struct elf_link_hash_entry *,
|
||||
PTR));
|
||||
unsigned long _bfd_elf_link_renumber_dynsyms PARAMS ((bfd *,
|
||||
struct bfd_link_info *));
|
||||
|
||||
elf_linker_section_t *_bfd_elf_create_linker_section
|
||||
PARAMS ((bfd *abfd,
|
||||
@ -1113,8 +1147,15 @@ extern boolean bfd_elf64_link_create_dynamic_sections
|
||||
extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
|
||||
PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
|
||||
|
||||
#define bfd_elf32_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
|
||||
#define bfd_elf64_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
|
||||
#define bfd_elf32_link_record_dynamic_symbol \
|
||||
_bfd_elf_link_record_dynamic_symbol
|
||||
#define bfd_elf64_link_record_dynamic_symbol \
|
||||
_bfd_elf_link_record_dynamic_symbol
|
||||
|
||||
boolean _bfd_elf32_link_record_local_dynamic_symbol
|
||||
PARAMS ((struct bfd_link_info *, bfd *, long));
|
||||
boolean _bfd_elf64_link_record_local_dynamic_symbol
|
||||
PARAMS ((struct bfd_link_info *, bfd *, long));
|
||||
|
||||
extern boolean _bfd_elf_close_and_cleanup PARAMS ((bfd *));
|
||||
extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
|
||||
|
@ -43,8 +43,6 @@ static boolean elf_m68k_gc_sweep_hook
|
||||
const Elf_Internal_Rela *));
|
||||
static boolean elf_m68k_adjust_dynamic_symbol
|
||||
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
|
||||
static boolean elf_m68k_adjust_dynindx
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf_m68k_size_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean elf_m68k_relocate_section
|
||||
@ -1312,51 +1310,6 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are generating a shared library, we generate a section
|
||||
symbol for each output section for which we might need to copy
|
||||
relocs. These are local symbols, which means that they must come
|
||||
first in the dynamic symbol table. That means we must increment
|
||||
the dynamic symbol index of every other dynamic symbol. */
|
||||
if (info->shared)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = 0;
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
if ((s->flags & SEC_LINKER_CREATED) != 0
|
||||
|| (s->flags & SEC_ALLOC) == 0)
|
||||
continue;
|
||||
|
||||
elf_section_data (s)->dynindx = c + 1;
|
||||
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
|
||||
++c;
|
||||
}
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
elf_m68k_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increment the index of a dynamic symbol by a given amount. Called
|
||||
via elf_link_hash_traverse. */
|
||||
|
||||
static boolean
|
||||
elf_m68k_adjust_dynindx (h, cparg)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR cparg;
|
||||
{
|
||||
int *cp = (int *) cparg;
|
||||
|
||||
if (h->dynindx != -1)
|
||||
h->dynindx += *cp;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2213,50 +2166,6 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
|
||||
|
||||
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *s;
|
||||
Elf_Internal_Sym sym;
|
||||
int c;
|
||||
|
||||
/* Set up the section symbols for the output sections. */
|
||||
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
BFD_ASSERT (sdynsym != NULL);
|
||||
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
c = 0;
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
|
||||
if (elf_section_data (s)->dynindx == 0)
|
||||
continue;
|
||||
|
||||
sym.st_value = s->vma;
|
||||
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
|
||||
bfd_elf32_swap_symbol_out (output_bfd, &sym,
|
||||
(PTR) (((Elf32_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ elf_section_data (s)->dynindx));
|
||||
|
||||
++c;
|
||||
}
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to the
|
||||
index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -7693,32 +7693,6 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If we use dynamic linking, we generate a section symbol for each
|
||||
output section. These are local symbols, which means that they
|
||||
must come first in the dynamic symbol table.
|
||||
That means we must increment the dynamic symbol index of every
|
||||
other dynamic symbol. */
|
||||
{
|
||||
unsigned int c, i;
|
||||
|
||||
c = 0;
|
||||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
{
|
||||
c = bfd_count_sections (output_bfd);
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
_bfd_elf_link_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
|
||||
for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++)
|
||||
{
|
||||
elf_section_data (s)->dynindx = i;
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -8163,59 +8137,32 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
|
||||
= MIPS_ELF_GOT_SIZE (output_bfd);
|
||||
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *smsym;
|
||||
asection *s;
|
||||
Elf_Internal_Sym sym;
|
||||
Elf32_compact_rel cpt;
|
||||
|
||||
/* Set up the section symbols for the output sections. SGI sets
|
||||
the STT_NOTYPE attribute for these symbols. Should we do so? */
|
||||
/* ??? The section symbols for the output sections were set up in
|
||||
_bfd_elf_final_link. SGI sets the STT_NOTYPE attribute for these
|
||||
symbols. Should we do so? */
|
||||
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
smsym = bfd_get_section_by_name (dynobj,
|
||||
MIPS_ELF_MSYM_SECTION_NAME (dynobj));
|
||||
if (sdynsym != NULL)
|
||||
if (smsym != NULL)
|
||||
{
|
||||
Elf32_Internal_Msym msym;
|
||||
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
msym.ms_hash_value = 0;
|
||||
msym.ms_info = ELF32_MS_INFO (0, 1);
|
||||
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
long dynindx;
|
||||
long dynindx = elf_section_data (s)->dynindx;
|
||||
|
||||
sym.st_value = s->vma;
|
||||
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
|
||||
dynindx = elf_section_data (s)->dynindx;
|
||||
|
||||
(*get_elf_backend_data (output_bfd)->s->swap_symbol_out)
|
||||
(output_bfd, &sym,
|
||||
sdynsym->contents
|
||||
+ (dynindx * MIPS_ELF_SYM_SIZE (output_bfd)));
|
||||
|
||||
if (smsym)
|
||||
bfd_mips_elf_swap_msym_out
|
||||
(output_bfd, &msym,
|
||||
(((Elf32_External_Msym *) smsym->contents)
|
||||
+ dynindx));
|
||||
bfd_mips_elf_swap_msym_out
|
||||
(output_bfd, &msym,
|
||||
(((Elf32_External_Msym *) smsym->contents)
|
||||
+ dynindx));
|
||||
}
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to
|
||||
the index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
|
||||
bfd_count_sections (output_bfd) + 1;
|
||||
}
|
||||
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
|
108
bfd/elf32-ppc.c
108
bfd/elf32-ppc.c
@ -80,8 +80,6 @@ static boolean ppc_elf_gc_sweep_hook PARAMS ((bfd *abfd,
|
||||
static boolean ppc_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *,
|
||||
struct elf_link_hash_entry *));
|
||||
|
||||
static boolean ppc_elf_adjust_dynindx PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
|
||||
static boolean ppc_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
|
||||
|
||||
static boolean ppc_elf_relocate_section PARAMS ((bfd *,
|
||||
@ -1880,27 +1878,6 @@ ppc_elf_adjust_dynamic_symbol (info, h)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Increment the index of a dynamic symbol by a given amount. Called
|
||||
via elf_link_hash_traverse. */
|
||||
|
||||
static boolean
|
||||
ppc_elf_adjust_dynindx (h, cparg)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR cparg;
|
||||
{
|
||||
int *cp = (int *) cparg;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "ppc_elf_adjust_dynindx called, h->dynindx = %d, *cp = %d\n", h->dynindx, *cp);
|
||||
#endif
|
||||
|
||||
if (h->dynindx != -1)
|
||||
h->dynindx += *cp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Set the sizes of the dynamic sections. */
|
||||
|
||||
@ -2083,43 +2060,6 @@ ppc_elf_size_dynamic_sections (output_bfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are generating a shared library, we generate a section
|
||||
symbol for each output section. These are local symbols, which
|
||||
means that they must come first in the dynamic symbol table.
|
||||
That means we must increment the dynamic symbol index of every
|
||||
other dynamic symbol.
|
||||
|
||||
FIXME: We assume that there will never be relocations to
|
||||
locations in linker-created sections that do not have
|
||||
externally-visible names. Instead, we should work out precisely
|
||||
which sections relocations are targetted at. */
|
||||
if (info->shared)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0, s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
if ((s->flags & SEC_LINKER_CREATED) != 0
|
||||
|| (s->flags & SEC_ALLOC) == 0)
|
||||
{
|
||||
elf_section_data (s)->dynindx = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
|
||||
elf_section_data (s)->dynindx = c + 1;
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
ppc_elf_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2924,54 +2864,6 @@ ppc_elf_finish_dynamic_sections (output_bfd, info)
|
||||
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
|
||||
}
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *s;
|
||||
Elf_Internal_Sym sym;
|
||||
int maxdindx = 0;
|
||||
|
||||
/* Set up the section symbols for the output sections. */
|
||||
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
BFD_ASSERT (sdynsym != NULL);
|
||||
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx, dindx;
|
||||
|
||||
sym.st_value = s->vma;
|
||||
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
dindx = elf_section_data (s)->dynindx;
|
||||
if (dindx > 0)
|
||||
{
|
||||
BFD_ASSERT(indx > 0);
|
||||
BFD_ASSERT(dindx > 0);
|
||||
|
||||
if (dindx > maxdindx)
|
||||
maxdindx = dindx;
|
||||
|
||||
sym.st_shndx = indx;
|
||||
|
||||
bfd_elf32_swap_symbol_out (output_bfd, &sym,
|
||||
(PTR) (((Elf32_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ dindx));
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to the
|
||||
index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
|
||||
maxdindx + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,6 @@ static boolean elf32_sparc_check_relocs
|
||||
const Elf_Internal_Rela *));
|
||||
static boolean elf32_sparc_adjust_dynamic_symbol
|
||||
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
|
||||
static boolean elf32_sparc_adjust_dynindx
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf32_sparc_size_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean elf32_sparc_relocate_section
|
||||
@ -1043,51 +1041,6 @@ elf32_sparc_size_dynamic_sections (output_bfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are generating a shared library, we generate a section
|
||||
symbol for each output section for which we might need to copy
|
||||
relocs. These are local symbols, which means that they must come
|
||||
first in the dynamic symbol table. That means we must increment
|
||||
the dynamic symbol index of every other dynamic symbol. */
|
||||
if (info->shared)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = 0;
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
if ((s->flags & SEC_LINKER_CREATED) != 0
|
||||
|| (s->flags & SEC_ALLOC) == 0)
|
||||
continue;
|
||||
|
||||
elf_section_data (s)->dynindx = c + 1;
|
||||
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
|
||||
++c;
|
||||
}
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
elf32_sparc_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increment the index of a dynamic symbol by a given amount. Called
|
||||
via elf_link_hash_traverse. */
|
||||
|
||||
static boolean
|
||||
elf32_sparc_adjust_dynindx (h, cparg)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR cparg;
|
||||
{
|
||||
int *cp = (int *) cparg;
|
||||
|
||||
if (h->dynindx != -1)
|
||||
h->dynindx += *cp;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1850,50 +1803,6 @@ elf32_sparc_finish_dynamic_sections (output_bfd, info)
|
||||
|
||||
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *s;
|
||||
Elf_Internal_Sym sym;
|
||||
int c;
|
||||
|
||||
/* Set up the section symbols for the output sections. */
|
||||
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
BFD_ASSERT (sdynsym != NULL);
|
||||
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
c = 0;
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
|
||||
if (elf_section_data (s)->dynindx == 0)
|
||||
continue;
|
||||
|
||||
sym.st_value = s->vma;
|
||||
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
|
||||
bfd_elf32_swap_symbol_out (output_bfd, &sym,
|
||||
(PTR) (((Elf32_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ elf_section_data (s)->dynindx));
|
||||
|
||||
++c;
|
||||
}
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to the
|
||||
index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,6 @@ static boolean elf64_alpha_adjust_dynamic_symbol
|
||||
PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
|
||||
static boolean elf64_alpha_size_dynamic_sections
|
||||
PARAMS((bfd *, struct bfd_link_info *));
|
||||
static boolean elf64_alpha_adjust_dynindx
|
||||
PARAMS((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf64_alpha_relocate_section
|
||||
PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||||
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
|
||||
@ -3264,34 +3262,6 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are generating a shared library, we generate a section
|
||||
symbol for each output section. These are local symbols, which
|
||||
means that they must come first in the dynamic symbol table.
|
||||
That means we must increment the dynamic symbol index of every
|
||||
other dynamic symbol. */
|
||||
if (info->shared)
|
||||
{
|
||||
long c[2], i;
|
||||
asection *p;
|
||||
|
||||
c[0] = 0;
|
||||
c[1] = bfd_count_sections (output_bfd);
|
||||
|
||||
elf_hash_table (info)->dynsymcount += c[1];
|
||||
elf_link_hash_traverse (elf_hash_table(info),
|
||||
elf64_alpha_adjust_dynindx,
|
||||
(PTR) c);
|
||||
|
||||
for (i = 1, p = output_bfd->sections;
|
||||
p != NULL;
|
||||
p = p->next, i++)
|
||||
{
|
||||
elf_section_data (p)->dynindx = i;
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
}
|
||||
}
|
||||
|
||||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
{
|
||||
/* Add some entries to the .dynamic section. We fill in the
|
||||
@ -3332,22 +3302,6 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increment the index of a dynamic symbol by a given amount. Called
|
||||
via elf_link_hash_traverse. */
|
||||
|
||||
static boolean
|
||||
elf64_alpha_adjust_dynindx (h, cparg)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR cparg;
|
||||
{
|
||||
long *cp = (long *)cparg;
|
||||
|
||||
if (h->dynindx >= cp[0])
|
||||
h->dynindx += cp[1];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Relocate an Alpha ELF section. */
|
||||
|
||||
static boolean
|
||||
@ -3991,44 +3945,6 @@ elf64_alpha_finish_dynamic_sections (output_bfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *s;
|
||||
Elf_Internal_Sym sym;
|
||||
|
||||
/* Set up the section symbols for the output sections. */
|
||||
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
BFD_ASSERT (sdynsym != NULL);
|
||||
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
|
||||
sym.st_value = s->vma;
|
||||
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
|
||||
bfd_elf64_swap_symbol_out (output_bfd, &sym,
|
||||
(PTR) (((Elf64_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ elf_section_data (s)->dynindx));
|
||||
}
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to the
|
||||
index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
|
||||
bfd_count_sections (output_bfd) + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,6 @@ static boolean sparc64_elf_adjust_dynamic_symbol
|
||||
PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
|
||||
static boolean sparc64_elf_size_dynamic_sections
|
||||
PARAMS((bfd *, struct bfd_link_info *));
|
||||
static boolean sparc64_elf_adjust_dynindx
|
||||
PARAMS((struct elf_link_hash_entry *, PTR));
|
||||
|
||||
static boolean sparc64_elf_merge_private_bfd_data
|
||||
PARAMS ((bfd *, bfd *));
|
||||
@ -1146,54 +1144,8 @@ sparc64_elf_size_dynamic_sections (output_bfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are generating a shared library, we generate a section
|
||||
symbol for each output section for which we might need to copy
|
||||
relocs. These are local symbols, which means that they must come
|
||||
first in the dynamic symbol table. That means we must increment
|
||||
the dynamic symbol index of every other dynamic symbol. */
|
||||
if (info->shared)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = 0;
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
if ((s->flags & SEC_LINKER_CREATED) != 0
|
||||
|| (s->flags & SEC_ALLOC) == 0)
|
||||
continue;
|
||||
|
||||
elf_section_data (s)->dynindx = c + 1;
|
||||
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
|
||||
++c;
|
||||
}
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
sparc64_elf_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increment the index of a dynamic symbol by a given amount. Called
|
||||
via elf_link_hash_traverse. */
|
||||
|
||||
static boolean
|
||||
sparc64_elf_adjust_dynindx (h, cparg)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR cparg;
|
||||
{
|
||||
int *cp = (int *) cparg;
|
||||
|
||||
if (h->dynindx != -1)
|
||||
h->dynindx += *cp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Relocate a SPARC64 ELF section. */
|
||||
|
||||
@ -2090,50 +2042,6 @@ sparc64_elf_finish_dynamic_sections (output_bfd, info)
|
||||
|
||||
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8;
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *s;
|
||||
Elf_Internal_Sym sym;
|
||||
int c;
|
||||
|
||||
/* Set up the section symbols for the output sections. */
|
||||
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
BFD_ASSERT (sdynsym != NULL);
|
||||
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
c = 0;
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
|
||||
if (elf_section_data (s)->dynindx == 0)
|
||||
continue;
|
||||
|
||||
sym.st_value = s->vma;
|
||||
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
|
||||
bfd_elf64_swap_symbol_out (output_bfd, &sym,
|
||||
(PTR) (((Elf64_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ elf_section_data (s)->dynindx));
|
||||
|
||||
++c;
|
||||
}
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to the
|
||||
index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#define elf_gc_common_final_link NAME(_bfd_elf,gc_common_final_link)
|
||||
#define elf_gc_record_vtinherit NAME(_bfd_elf,gc_record_vtinherit)
|
||||
#define elf_gc_record_vtentry NAME(_bfd_elf,gc_record_vtentry)
|
||||
#define elf_link_record_local_dynamic_symbol \
|
||||
NAME(_bfd_elf,link_record_local_dynamic_symbol)
|
||||
|
||||
#if ARCH_SIZE == 64
|
||||
#define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y)
|
||||
|
@ -260,22 +260,83 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increase the index at which H will appear in the dynamic symbol
|
||||
table by INCREMENT (which is really an `int *'). Called via
|
||||
elf_link_hash_traverse. */
|
||||
/* Return the dynindex of a local dynamic symbol. */
|
||||
|
||||
boolean
|
||||
_bfd_elf_link_adjust_dynindx (h, increment)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR increment;
|
||||
long
|
||||
_bfd_elf_link_lookup_local_dynindx (info, input_bfd, input_indx)
|
||||
struct bfd_link_info *info;
|
||||
bfd *input_bfd;
|
||||
long input_indx;
|
||||
{
|
||||
struct elf_link_local_dynamic_entry *e;
|
||||
|
||||
for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
|
||||
if (e->input_bfd == input_bfd && e->input_indx == input_indx)
|
||||
return e->dynindx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This function is used to renumber the dynamic symbols, if some of
|
||||
them are removed because they are marked as local. This is called
|
||||
via elf_link_hash_traverse. */
|
||||
|
||||
static boolean elf_link_renumber_hash_table_dynsyms
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
|
||||
static boolean
|
||||
elf_link_renumber_hash_table_dynsyms (h, data)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR data;
|
||||
{
|
||||
size_t *count = (size_t *) data;
|
||||
|
||||
if (h->dynindx != -1)
|
||||
h->dynindx += *((int *) increment);
|
||||
|
||||
h->dynindx = ++(*count);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Assign dynsym indicies. In a shared library we generate a section
|
||||
symbol for each output section, which come first. Next come all of
|
||||
the back-end allocated local dynamic syms, followed by the rest of
|
||||
the global symbols. */
|
||||
|
||||
unsigned long
|
||||
_bfd_elf_link_renumber_dynsyms (output_bfd, info)
|
||||
bfd *output_bfd;
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
unsigned long dynsymcount = 0;
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *p;
|
||||
for (p = output_bfd->sections; p ; p = p->next)
|
||||
elf_section_data (p)->dynindx = ++dynsymcount;
|
||||
}
|
||||
|
||||
if (elf_hash_table (info)->dynlocal)
|
||||
{
|
||||
struct elf_link_local_dynamic_entry *p;
|
||||
for (p = elf_hash_table (info)->dynlocal; p ; p = p->next)
|
||||
p->dynindx = ++dynsymcount;
|
||||
}
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
elf_link_renumber_hash_table_dynsyms,
|
||||
&dynsymcount);
|
||||
|
||||
/* There is an unused NULL entry at the head of the table which
|
||||
we must account for in our count. Unless there weren't any
|
||||
symbols, which means we'll have no table at all. */
|
||||
if (dynsymcount != 0)
|
||||
++dynsymcount;
|
||||
|
||||
return elf_hash_table (info)->dynsymcount = dynsymcount;
|
||||
}
|
||||
|
||||
/* Create a special linker section, or return a pointer to a linker section already created */
|
||||
/* Create a special linker section, or return a pointer to a linker
|
||||
section already created */
|
||||
|
||||
elf_linker_section_t *
|
||||
_bfd_elf_create_linker_section (abfd, info, which, defaults)
|
||||
|
239
bfd/elflink.h
239
bfd/elflink.h
@ -48,14 +48,10 @@ static boolean elf_link_find_version_dependencies
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf_link_assign_sym_version
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf_link_renumber_dynsyms
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf_collect_hash_codes
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf_link_read_relocs_from_section
|
||||
PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *));
|
||||
static void elf_link_remove_section_and_adjust_dynindices
|
||||
PARAMS ((struct bfd_link_info *, asection *));
|
||||
static void elf_link_output_relocs
|
||||
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
|
||||
static boolean elf_link_size_reloc_section
|
||||
@ -2051,6 +2047,73 @@ elf_add_dynamic_entry (info, tag, val)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Record a new local dynamic symbol. */
|
||||
|
||||
boolean
|
||||
elf_link_record_local_dynamic_symbol (info, input_bfd, input_indx)
|
||||
struct bfd_link_info *info;
|
||||
bfd *input_bfd;
|
||||
long input_indx;
|
||||
{
|
||||
struct elf_link_local_dynamic_entry *entry;
|
||||
struct elf_link_hash_table *eht;
|
||||
struct bfd_strtab_hash *dynstr;
|
||||
Elf_External_Sym esym;
|
||||
unsigned long dynstr_index;
|
||||
char *name;
|
||||
int elfsec, link;
|
||||
|
||||
/* See if the entry exists already. */
|
||||
for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next)
|
||||
if (entry->input_bfd == input_bfd && entry->input_indx == input_indx)
|
||||
return true;
|
||||
|
||||
entry = (struct elf_link_local_dynamic_entry *)
|
||||
bfd_alloc (input_bfd, sizeof (*entry));
|
||||
if (entry == NULL)
|
||||
return false;
|
||||
|
||||
/* Go find the symbol, so that we can find it's name. */
|
||||
if (bfd_seek (input_bfd,
|
||||
(elf_tdata (input_bfd)->symtab_hdr.sh_offset
|
||||
+ input_indx * sizeof (Elf_External_Sym)),
|
||||
SEEK_SET) != 0
|
||||
|| (bfd_read (&esym, sizeof (Elf_External_Sym), 1, input_bfd)
|
||||
!= sizeof (Elf_External_Sym)))
|
||||
return false;
|
||||
elf_swap_symbol_in (input_bfd, &esym, &entry->isym);
|
||||
|
||||
name = (bfd_elf_string_from_elf_section
|
||||
(input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link,
|
||||
entry->isym.st_name));
|
||||
|
||||
dynstr = elf_hash_table (info)->dynstr;
|
||||
if (dynstr == NULL)
|
||||
{
|
||||
/* Create a strtab to hold the dynamic symbol names. */
|
||||
elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init ();
|
||||
if (dynstr == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
dynstr_index = _bfd_stringtab_add (dynstr, name, true, false);
|
||||
if (dynstr_index == (unsigned long) -1)
|
||||
return false;
|
||||
entry->isym.st_name = dynstr_index;
|
||||
|
||||
eht = elf_hash_table (info);
|
||||
|
||||
entry->next = eht->dynlocal;
|
||||
eht->dynlocal = entry;
|
||||
entry->input_bfd = input_bfd;
|
||||
entry->input_indx = input_indx;
|
||||
eht->dynsymcount++;
|
||||
|
||||
/* The dynindx will be set at the end of size_dynamic_sections. */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Read and swap the relocs from the section indicated by SHDR. This
|
||||
@ -2310,8 +2373,6 @@ struct elf_assign_sym_version_info
|
||||
struct bfd_elf_version_tree *verdefs;
|
||||
/* Whether we are exporting all dynamic symbols. */
|
||||
boolean export_dynamic;
|
||||
/* Whether we removed any symbols from the dynamic symbol table. */
|
||||
boolean removed_dynamic;
|
||||
/* Whether we had a failure. */
|
||||
boolean failed;
|
||||
};
|
||||
@ -2486,42 +2547,6 @@ compute_bucket_count (info)
|
||||
return best_size;
|
||||
}
|
||||
|
||||
/* Remove SECTION from the BFD. If a symbol for SECTION was going to
|
||||
be put into the dynamic symbol table, remove it, and renumber
|
||||
subsequent entries. */
|
||||
|
||||
static void
|
||||
elf_link_remove_section_and_adjust_dynindices (info, section)
|
||||
struct bfd_link_info *info;
|
||||
asection *section;
|
||||
{
|
||||
/* Remove the section from the output list. */
|
||||
_bfd_strip_section_from_output (section);
|
||||
|
||||
if (elf_section_data (section->output_section)->dynindx)
|
||||
{
|
||||
asection *s;
|
||||
int increment = -1;
|
||||
|
||||
/* We were going to output an entry in the dynamic symbol table
|
||||
for the symbol corresponding to this section. Now, the
|
||||
section is gone. So, we must renumber the dynamic indices of
|
||||
all subsequent sections and all other entries in the dynamic
|
||||
symbol table. */
|
||||
elf_section_data (section->output_section)->dynindx = 0;
|
||||
for (s = section->output_section->next; s; s = s->next)
|
||||
if (elf_section_data (s)->dynindx)
|
||||
--elf_section_data (s)->dynindx;
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
_bfd_elf_link_adjust_dynindx,
|
||||
&increment);
|
||||
|
||||
/* There is one less dynamic symbol than there was before. */
|
||||
--elf_hash_table (info)->dynsymcount;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the sizes and contents of the ELF dynamic sections. This is
|
||||
called by the ELF linker emulation before_allocation routine. We
|
||||
must set the sizes of the sections before the linker sets the
|
||||
@ -2545,7 +2570,6 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
bfd_size_type soname_indx;
|
||||
bfd *dynobj;
|
||||
struct elf_backend_data *bed;
|
||||
bfd_size_type old_dynsymcount;
|
||||
struct elf_assign_sym_version_info asvinfo;
|
||||
|
||||
*sinterpptr = NULL;
|
||||
@ -2650,7 +2674,6 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
asvinfo.info = info;
|
||||
asvinfo.verdefs = verdefs;
|
||||
asvinfo.export_dynamic = export_dynamic;
|
||||
asvinfo.removed_dynamic = false;
|
||||
asvinfo.failed = false;
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
@ -2712,7 +2735,6 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
|
||||
/* The backend must work out the sizes of all the other dynamic
|
||||
sections. */
|
||||
old_dynsymcount = elf_hash_table (info)->dynsymcount;
|
||||
if (bed->elf_backend_size_dynamic_sections
|
||||
&& ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
|
||||
return false;
|
||||
@ -2734,7 +2756,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
verdefs = asvinfo.verdefs;
|
||||
|
||||
if (verdefs == NULL)
|
||||
elf_link_remove_section_and_adjust_dynindices (info, s);
|
||||
_bfd_strip_section_from_output (s);
|
||||
else
|
||||
{
|
||||
unsigned int cdefs;
|
||||
@ -2744,23 +2766,6 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
Elf_Internal_Verdef def;
|
||||
Elf_Internal_Verdaux defaux;
|
||||
|
||||
if (asvinfo.removed_dynamic)
|
||||
{
|
||||
/* Some dynamic symbols were changed to be local
|
||||
symbols. In this case, we renumber all of the
|
||||
dynamic symbols, so that we don't have a hole. If
|
||||
the backend changed dynsymcount, then assume that the
|
||||
new symbols are at the start. This is the case on
|
||||
the MIPS. FIXME: The names of the removed symbols
|
||||
will still be in the dynamic string table, wasting
|
||||
space. */
|
||||
elf_hash_table (info)->dynsymcount =
|
||||
1 + (elf_hash_table (info)->dynsymcount - old_dynsymcount);
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
elf_link_renumber_dynsyms,
|
||||
(PTR) info);
|
||||
}
|
||||
|
||||
cdefs = 0;
|
||||
size = 0;
|
||||
|
||||
@ -2927,7 +2932,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
(PTR) &sinfo);
|
||||
|
||||
if (elf_tdata (output_bfd)->verref == NULL)
|
||||
elf_link_remove_section_and_adjust_dynindices (info, s);
|
||||
_bfd_strip_section_from_output (s);
|
||||
else
|
||||
{
|
||||
Elf_Internal_Verneed *t;
|
||||
@ -3018,7 +3023,12 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
}
|
||||
}
|
||||
|
||||
dynsymcount = elf_hash_table (info)->dynsymcount;
|
||||
/* Assign dynsym indicies. In a shared library we generate a
|
||||
section symbol for each output section, which come first.
|
||||
Next come all of the back-end allocated local dynamic syms,
|
||||
followed by the rest of the global symbols. */
|
||||
|
||||
dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
|
||||
|
||||
/* Work out the size of the symbol version section. */
|
||||
s = bfd_get_section_by_name (dynobj, ".gnu.version");
|
||||
@ -3026,10 +3036,10 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
||||
if (dynsymcount == 0
|
||||
|| (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
|
||||
{
|
||||
elf_link_remove_section_and_adjust_dynindices (info, s);
|
||||
_bfd_strip_section_from_output (s);
|
||||
/* The DYNSYMCOUNT might have changed if we were going to
|
||||
output a dynamic symbol table entry for S. */
|
||||
dynsymcount = elf_hash_table (info)->dynsymcount;
|
||||
dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3513,7 +3523,6 @@ elf_link_assign_sym_version (h, data)
|
||||
&& info->shared
|
||||
&& ! sinfo->export_dynamic)
|
||||
{
|
||||
sinfo->removed_dynamic = true;
|
||||
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
|
||||
h->elf_link_hash_flags &=~
|
||||
ELF_LINK_HASH_NEEDS_PLT;
|
||||
@ -3629,7 +3638,6 @@ elf_link_assign_sym_version (h, data)
|
||||
&& info->shared
|
||||
&& ! sinfo->export_dynamic)
|
||||
{
|
||||
sinfo->removed_dynamic = true;
|
||||
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
|
||||
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
|
||||
h->dynindx = -1;
|
||||
@ -3654,7 +3662,6 @@ elf_link_assign_sym_version (h, data)
|
||||
&& info->shared
|
||||
&& ! sinfo->export_dynamic)
|
||||
{
|
||||
sinfo->removed_dynamic = true;
|
||||
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
|
||||
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
|
||||
h->dynindx = -1;
|
||||
@ -3667,26 +3674,6 @@ elf_link_assign_sym_version (h, data)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This function is used to renumber the dynamic symbols, if some of
|
||||
them are removed because they are marked as local. This is called
|
||||
via elf_link_hash_traverse. */
|
||||
|
||||
static boolean
|
||||
elf_link_renumber_dynsyms (h, data)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR data;
|
||||
{
|
||||
struct bfd_link_info *info = (struct bfd_link_info *) data;
|
||||
|
||||
if (h->dynindx != -1)
|
||||
{
|
||||
h->dynindx = elf_hash_table (info)->dynsymcount;
|
||||
++elf_hash_table (info)->dynsymcount;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Final phase of ELF linker. */
|
||||
|
||||
@ -4161,11 +4148,77 @@ elf_bfd_final_link (abfd, info)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The sh_info field records the index of the first non local
|
||||
symbol. */
|
||||
/* The sh_info field records the index of the first non local symbol. */
|
||||
symtab_hdr->sh_info = bfd_get_symcount (abfd);
|
||||
|
||||
if (dynamic)
|
||||
elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1;
|
||||
{
|
||||
Elf_Internal_Sym sym;
|
||||
Elf_External_Sym *dynsym =
|
||||
(Elf_External_Sym *)finfo.dynsym_sec->contents;
|
||||
unsigned long last_local = 0;
|
||||
|
||||
/* Write out the section symbols for the output sections. */
|
||||
if (info->shared)
|
||||
{
|
||||
asection *s;
|
||||
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
for (s = abfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
sym.st_value = s->vma;
|
||||
|
||||
elf_swap_symbol_out (abfd, &sym,
|
||||
dynsym + elf_section_data (s)->dynindx);
|
||||
}
|
||||
|
||||
last_local = bfd_count_sections (abfd);
|
||||
}
|
||||
|
||||
/* Write out the local dynsyms. */
|
||||
if (elf_hash_table (info)->dynlocal)
|
||||
{
|
||||
struct elf_link_local_dynamic_entry *e;
|
||||
for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
|
||||
{
|
||||
asection *s, *os;
|
||||
|
||||
sym.st_size = e->isym.st_size;
|
||||
sym.st_other = e->isym.st_other;
|
||||
|
||||
/* Note that we saved a word of storage and overwrote
|
||||
the original st_name with the dynstr_index. */
|
||||
sym.st_name = e->isym.st_name;
|
||||
|
||||
/* Whatever binding the symbol had before, it's now local. */
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL,
|
||||
ELF_ST_TYPE (e->isym.st_info));
|
||||
|
||||
s = bfd_section_from_elf_index (e->input_bfd, e->isym.st_shndx);
|
||||
|
||||
sym.st_shndx = elf_section_data (s->output_section)->this_idx;
|
||||
sym.st_value = (s->output_section->vma
|
||||
+ s->output_offset
|
||||
+ e->isym.st_value);
|
||||
|
||||
if (last_local < e->dynindx)
|
||||
last_local = e->dynindx;
|
||||
|
||||
elf_swap_symbol_out (abfd, &sym, dynsym + e->dynindx);
|
||||
}
|
||||
}
|
||||
|
||||
elf_section_data (finfo.dynsym_sec->output_section)
|
||||
->this_hdr.sh_info = last_local;
|
||||
}
|
||||
|
||||
/* We get the global symbols from the hash table. */
|
||||
eoinfo.failed = false;
|
||||
|
Loading…
Reference in New Issue
Block a user