aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2000-08-22 19:33:16 +0000
committerH.J. Lu <hjl.tools@gmail.com>2000-08-22 19:33:16 +0000
commita963dc6ade92e7fc92756912815fc7d852576792 (patch)
treed941b146c520e2529ef48d2110634cb3c6447e47 /bfd/elflink.h
parent4193618c3cda64e4e5d75a8abdee88894d8b5285 (diff)
downloadgdb-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.h71
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);