diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2000-08-22 19:33:16 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2000-08-22 19:33:16 +0000 |
commit | a963dc6ade92e7fc92756912815fc7d852576792 (patch) | |
tree | d941b146c520e2529ef48d2110634cb3c6447e47 /bfd/elflink.h | |
parent | 4193618c3cda64e4e5d75a8abdee88894d8b5285 (diff) | |
download | gdb-a963dc6ade92e7fc92756912815fc7d852576792.zip gdb-a963dc6ade92e7fc92756912815fc7d852576792.tar.gz gdb-a963dc6ade92e7fc92756912815fc7d852576792.tar.bz2 |
2000-08-22 H.J. Lu <hjl@gnu.org>
* elf-bfd.h (elf_link_hash_table): Add runpath.
* bfd-in.h (bfd_elf_get_runpath_list): New prototype.
* bfd-in2.h: Rebuilt.
* elf.c (_bfd_elf_link_hash_table_init): Initialize the
"runpath" field to NULL.
(bfd_elf_get_runpath_list): New function.
* elflink.h (elf_link_add_object_symbols): Record DT_RPATH and
DT_RUNPATH entries.
Diffstat (limited to 'bfd/elflink.h')
-rw-r--r-- | bfd/elflink.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/bfd/elflink.h b/bfd/elflink.h index 1dadc49..cd55664 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -1112,6 +1112,8 @@ elf_link_add_object_symbols (abfd, info) Elf_External_Dyn *extdynend; int elfsec; unsigned long link; + int rpath; + int runpath; dynbuf = (Elf_External_Dyn *) bfd_malloc ((size_t) s->_raw_size); if (dynbuf == NULL) @@ -1145,6 +1147,8 @@ elf_link_add_object_symbols (abfd, info) extdyn = dynbuf; extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn); + rpath = 0; + runpath = 0; for (; extdyn < extdynend; extdyn++) { Elf_Internal_Dyn dyn; @@ -1181,6 +1185,73 @@ elf_link_add_object_symbols (abfd, info) ; *pn = n; } + if (dyn.d_tag == DT_RUNPATH) + { + struct bfd_link_needed_list *n, **pn; + char *fnm, *anm; + + /* When we see DT_RPATH before DT_RUNPATH, we have + to free runpath. */ + if (rpath && elf_hash_table (info)->runpath) + { + struct bfd_link_needed_list *nn; + for (n = elf_hash_table (info)->runpath; + n != NULL; n = nn) + { + nn = n->next; + bfd_release (abfd, n); + } + bfd_release (abfd, elf_hash_table (info)->runpath); + elf_hash_table (info)->runpath = NULL; + } + + n = ((struct bfd_link_needed_list *) + bfd_alloc (abfd, sizeof (struct bfd_link_needed_list))); + fnm = bfd_elf_string_from_elf_section (abfd, link, + dyn.d_un.d_val); + if (n == NULL || fnm == NULL) + goto error_return; + anm = bfd_alloc (abfd, strlen (fnm) + 1); + if (anm == NULL) + goto error_return; + strcpy (anm, fnm); + n->name = anm; + n->by = abfd; + n->next = NULL; + for (pn = &elf_hash_table (info)->runpath; + *pn != NULL; + pn = &(*pn)->next) + ; + *pn = n; + runpath = 1; + rpath = 0; + } + /* Ignore DT_RPATH if we have seen DT_RUNPATH. */ + if (!runpath && dyn.d_tag == DT_RPATH) + { + struct bfd_link_needed_list *n, **pn; + char *fnm, *anm; + + n = ((struct bfd_link_needed_list *) + bfd_alloc (abfd, sizeof (struct bfd_link_needed_list))); + fnm = bfd_elf_string_from_elf_section (abfd, link, + dyn.d_un.d_val); + if (n == NULL || fnm == NULL) + goto error_return; + anm = bfd_alloc (abfd, strlen (fnm) + 1); + if (anm == NULL) + goto error_return; + strcpy (anm, fnm); + n->name = anm; + n->by = abfd; + n->next = NULL; + for (pn = &elf_hash_table (info)->runpath; + *pn != NULL; + pn = &(*pn)->next) + ; + *pn = n; + rpath = 1; + } } free (dynbuf); |