mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-11 13:02:10 +08:00
* elf-bfd.h (_bfd_elf32_link_record_local_dynamic_symbol): Define
as elf_link_record_local_dynamic_symbol. (_bfd_elf64_link_record_local_dynamic_symbol): Likewise. (elf_link_record_local_dynamic_symbol): Declare. Now returns int. * elflink.h (elf_link_record_local_dynamic_symbol): Move to.. * elflink.c: .. here. Use bfd_elf_get_elf_syms. Check whether an attempt is made to record a symbol in a discarded section, and return `2' in that case.
This commit is contained in:
parent
8c554d79d1
commit
8c58d23b6d
@ -1,3 +1,14 @@
|
|||||||
|
2002-07-25 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf-bfd.h (_bfd_elf32_link_record_local_dynamic_symbol): Define
|
||||||
|
as elf_link_record_local_dynamic_symbol.
|
||||||
|
(_bfd_elf64_link_record_local_dynamic_symbol): Likewise.
|
||||||
|
(elf_link_record_local_dynamic_symbol): Declare. Now returns int.
|
||||||
|
* elflink.h (elf_link_record_local_dynamic_symbol): Move to..
|
||||||
|
* elflink.c: .. here. Use bfd_elf_get_elf_syms. Check whether an
|
||||||
|
attempt is made to record a symbol in a discarded section, and
|
||||||
|
return `2' in that case.
|
||||||
|
|
||||||
2002-07-24 Nick Clifton <nickc@redhat.com>
|
2002-07-24 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* po/sv.po: Updated Swedish translation.
|
* po/sv.po: Updated Swedish translation.
|
||||||
|
@ -1558,10 +1558,12 @@ extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
|
|||||||
#define bfd_elf64_link_record_dynamic_symbol \
|
#define bfd_elf64_link_record_dynamic_symbol \
|
||||||
_bfd_elf_link_record_dynamic_symbol
|
_bfd_elf_link_record_dynamic_symbol
|
||||||
|
|
||||||
extern boolean _bfd_elf32_link_record_local_dynamic_symbol
|
extern int elf_link_record_local_dynamic_symbol
|
||||||
PARAMS ((struct bfd_link_info *, bfd *, long));
|
|
||||||
extern boolean _bfd_elf64_link_record_local_dynamic_symbol
|
|
||||||
PARAMS ((struct bfd_link_info *, bfd *, long));
|
PARAMS ((struct bfd_link_info *, bfd *, long));
|
||||||
|
#define _bfd_elf32_link_record_local_dynamic_symbol \
|
||||||
|
elf_link_record_local_dynamic_symbol
|
||||||
|
#define _bfd_elf64_link_record_local_dynamic_symbol \
|
||||||
|
elf_link_record_local_dynamic_symbol
|
||||||
|
|
||||||
extern boolean _bfd_elf_close_and_cleanup
|
extern boolean _bfd_elf_close_and_cleanup
|
||||||
PARAMS ((bfd *));
|
PARAMS ((bfd *));
|
||||||
|
@ -302,6 +302,98 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Record a new local dynamic symbol. Returns 0 on failure, 1 on
|
||||||
|
success, and 2 on a failure caused by attempting to record a symbol
|
||||||
|
in a discarded section, eg. a discarded link-once section symbol. */
|
||||||
|
|
||||||
|
int
|
||||||
|
elf_link_record_local_dynamic_symbol (info, input_bfd, input_indx)
|
||||||
|
struct bfd_link_info *info;
|
||||||
|
bfd *input_bfd;
|
||||||
|
long input_indx;
|
||||||
|
{
|
||||||
|
bfd_size_type amt;
|
||||||
|
struct elf_link_local_dynamic_entry *entry;
|
||||||
|
struct elf_link_hash_table *eht;
|
||||||
|
struct elf_strtab_hash *dynstr;
|
||||||
|
unsigned long dynstr_index;
|
||||||
|
char *name;
|
||||||
|
Elf_External_Sym_Shndx eshndx;
|
||||||
|
char esym[sizeof (Elf64_External_Sym)];
|
||||||
|
|
||||||
|
if (! is_elf_hash_table (info))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* 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 1;
|
||||||
|
|
||||||
|
amt = sizeof (*entry);
|
||||||
|
entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt);
|
||||||
|
if (entry == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Go find the symbol, so that we can find it's name. */
|
||||||
|
if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr,
|
||||||
|
(size_t) 1, (size_t) input_indx,
|
||||||
|
&entry->isym, esym, &eshndx))
|
||||||
|
{
|
||||||
|
bfd_release (input_bfd, entry);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->isym.st_shndx != SHN_UNDEF
|
||||||
|
&& (entry->isym.st_shndx < SHN_LORESERVE
|
||||||
|
|| entry->isym.st_shndx > SHN_HIRESERVE))
|
||||||
|
{
|
||||||
|
asection *s;
|
||||||
|
|
||||||
|
s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx);
|
||||||
|
if (s == NULL || bfd_is_abs_section (s->output_section))
|
||||||
|
{
|
||||||
|
/* We can still bfd_release here as nothing has done another
|
||||||
|
bfd_alloc. We can't do this later in this function. */
|
||||||
|
bfd_release (input_bfd, entry);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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_strtab_init ();
|
||||||
|
if (dynstr == NULL)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynstr_index = _bfd_elf_strtab_add (dynstr, name, false);
|
||||||
|
if (dynstr_index == (unsigned long) -1)
|
||||||
|
return 0;
|
||||||
|
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++;
|
||||||
|
|
||||||
|
/* Whatever binding the symbol had before, it's now local. */
|
||||||
|
entry->isym.st_info
|
||||||
|
= ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info));
|
||||||
|
|
||||||
|
/* The dynindx will be set at the end of size_dynamic_sections. */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the dynindex of a local dynamic symbol. */
|
/* Return the dynindex of a local dynamic symbol. */
|
||||||
|
|
||||||
long
|
long
|
||||||
|
@ -2448,93 +2448,6 @@ elf_add_dynamic_entry (info, tag, val)
|
|||||||
|
|
||||||
return true;
|
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 elf_strtab_hash *dynstr;
|
|
||||||
Elf_External_Sym esym;
|
|
||||||
Elf_External_Sym_Shndx eshndx;
|
|
||||||
Elf_External_Sym_Shndx *shndx;
|
|
||||||
unsigned long dynstr_index;
|
|
||||||
char *name;
|
|
||||||
file_ptr pos;
|
|
||||||
bfd_size_type amt;
|
|
||||||
|
|
||||||
if (! is_elf_hash_table (info))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* 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, (bfd_size_type) sizeof (*entry));
|
|
||||||
if (entry == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Go find the symbol, so that we can find it's name. */
|
|
||||||
amt = sizeof (Elf_External_Sym);
|
|
||||||
pos = elf_tdata (input_bfd)->symtab_hdr.sh_offset + input_indx * amt;
|
|
||||||
if (bfd_seek (input_bfd, pos, SEEK_SET) != 0
|
|
||||||
|| bfd_bread ((PTR) &esym, amt, input_bfd) != amt)
|
|
||||||
return false;
|
|
||||||
shndx = NULL;
|
|
||||||
if (elf_tdata (input_bfd)->symtab_shndx_hdr.sh_size != 0)
|
|
||||||
{
|
|
||||||
amt = sizeof (Elf_External_Sym_Shndx);
|
|
||||||
pos = elf_tdata (input_bfd)->symtab_shndx_hdr.sh_offset;
|
|
||||||
pos += input_indx * amt;
|
|
||||||
shndx = &eshndx;
|
|
||||||
if (bfd_seek (input_bfd, pos, SEEK_SET) != 0
|
|
||||||
|| bfd_bread ((PTR) shndx, amt, input_bfd) != amt)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
elf_swap_symbol_in (input_bfd, (const PTR) &esym, (const PTR) shndx,
|
|
||||||
&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_strtab_init ();
|
|
||||||
if (dynstr == NULL)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dynstr_index = _bfd_elf_strtab_add (dynstr, name, 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++;
|
|
||||||
|
|
||||||
/* Whatever binding the symbol had before, it's now local. */
|
|
||||||
entry->isym.st_info
|
|
||||||
= ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info));
|
|
||||||
|
|
||||||
/* 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
|
/* Read and swap the relocs from the section indicated by SHDR. This
|
||||||
may be either a REL or a RELA section. The relocations are
|
may be either a REL or a RELA section. The relocations are
|
||||||
|
Loading…
Reference in New Issue
Block a user