diff options
author | Ian Lance Taylor <ian@airs.com> | 1998-04-27 15:51:27 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1998-04-27 15:51:27 +0000 |
commit | 0d3887ba8f5ac936b40c98099814398bf78b4147 (patch) | |
tree | c965872e254f424ab7115f5eb1b18b893c55caf4 /bfd/elf.c | |
parent | f68cdf65e80f834ee83c7f903ddf3ec6d3638117 (diff) | |
download | gdb-0d3887ba8f5ac936b40c98099814398bf78b4147.zip gdb-0d3887ba8f5ac936b40c98099814398bf78b4147.tar.gz gdb-0d3887ba8f5ac936b40c98099814398bf78b4147.tar.bz2 |
Based on patch from H.J. Lu <hjl@gnu.org>:
* elf.c (bfd_elf_get_bfd_needed_list): New function.
* bfd-in.h (bfd_elf_get_bfd_needed_list): Declare.
* bfd-in2.h: Rebuild.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 87 |
1 files changed, 86 insertions, 1 deletions
@@ -916,7 +916,7 @@ bfd_elf_set_dt_needed_name (abfd, name) } /* Get the list of DT_NEEDED entries for a link. This is a hook for - the ELF emulation code. */ + the linker ELF emulation code. */ struct bfd_link_needed_list * bfd_elf_get_needed_list (abfd, info) @@ -941,6 +941,91 @@ bfd_elf_get_dt_soname (abfd) return elf_dt_name (abfd); return NULL; } + +/* Get the list of DT_NEEDED entries from a BFD. This is a hook for + the ELF linker emulation code. */ + +boolean +bfd_elf_get_bfd_needed_list (abfd, pneeded) + bfd *abfd; + struct bfd_link_needed_list **pneeded; +{ + asection *s; + bfd_byte *dynbuf = NULL; + int elfsec; + unsigned long link; + bfd_byte *extdyn, *extdynend; + size_t extdynsize; + void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); + + *pneeded = NULL; + + if (bfd_get_flavour (abfd) != bfd_target_elf_flavour + || bfd_get_format (abfd) != bfd_object) + return true; + + s = bfd_get_section_by_name (abfd, ".dynamic"); + if (s == NULL || s->_raw_size == 0) + return true; + + dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size); + if (dynbuf == NULL) + goto error_return; + + if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0, + s->_raw_size)) + goto error_return; + + elfsec = _bfd_elf_section_from_bfd_section (abfd, s); + if (elfsec == -1) + goto error_return; + + link = elf_elfsections (abfd)[elfsec]->sh_link; + + extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; + swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; + + extdyn = dynbuf; + extdynend = extdyn + s->_raw_size; + for (; extdyn < extdynend; extdyn += extdynsize) + { + Elf_Internal_Dyn dyn; + + (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn); + + if (dyn.d_tag == DT_NULL) + break; + + if (dyn.d_tag == DT_NEEDED) + { + const char *string; + struct bfd_link_needed_list *l; + + string = bfd_elf_string_from_elf_section (abfd, link, + dyn.d_un.d_val); + if (string == NULL) + goto error_return; + + l = (struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof *l); + if (l == NULL) + goto error_return; + + l->by = abfd; + l->name = string; + l->next = *pneeded; + *pneeded = l; + } + } + + free (dynbuf); + + return true; + + error_return: + if (dynbuf != NULL) + free (dynbuf); + return false; +} /* Allocate an ELF string table--force the first byte to be zero. */ |