aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf-bfd.h8
-rw-r--r--bfd/elflink.c92
-rw-r--r--bfd/elflink.h87
4 files changed, 108 insertions, 90 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9b46913..e626129 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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>
* po/sv.po: Updated Swedish translation.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 4623e78..8a7fff1 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1558,10 +1558,12 @@ extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
#define bfd_elf64_link_record_dynamic_symbol \
_bfd_elf_link_record_dynamic_symbol
-extern boolean _bfd_elf32_link_record_local_dynamic_symbol
- PARAMS ((struct bfd_link_info *, bfd *, long));
-extern boolean _bfd_elf64_link_record_local_dynamic_symbol
+extern int elf_link_record_local_dynamic_symbol
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
PARAMS ((bfd *));
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c32ff1c..f8cc645 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -302,6 +302,98 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
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. */
long
diff --git a/bfd/elflink.h b/bfd/elflink.h
index 956f691..29c5551 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -2448,93 +2448,6 @@ 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 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
may be either a REL or a RELA section. The relocations are