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.
This commit is contained in:
H.J. Lu 2000-08-22 19:33:16 +00:00
parent 4193618c3c
commit a963dc6ade
6 changed files with 106 additions and 0 deletions

View file

@ -1,3 +1,17 @@
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.
2000-08-22 Alexandre Oliva <aoliva@redhat.com> 2000-08-22 Alexandre Oliva <aoliva@redhat.com>
* elf32-sh.c (sh_elf_relocate_section) [R_SH_IND12W, * elf32-sh.c (sh_elf_relocate_section) [R_SH_IND12W,

View file

@ -629,6 +629,8 @@ extern boolean bfd_elf64_size_dynamic_sections
extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *)); extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *)); extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *)); extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
PARAMS ((bfd *, struct bfd_link_info *));
/* Return an upper bound on the number of bytes required to store a /* Return an upper bound on the number of bytes required to store a
copy of ABFD's program header table entries. Return -1 if an error copy of ABFD's program header table entries. Return -1 if an error

View file

@ -629,6 +629,8 @@ extern boolean bfd_elf64_size_dynamic_sections
extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *)); extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *)); extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *)); extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
PARAMS ((bfd *, struct bfd_link_info *));
/* Return an upper bound on the number of bytes required to store a /* Return an upper bound on the number of bytes required to store a
copy of ABFD's program header table entries. Return -1 if an error copy of ABFD's program header table entries. Return -1 if an error

View file

@ -243,6 +243,9 @@ struct elf_link_hash_table
PTR stab_info; PTR stab_info;
/* A linked list of local symbols to be added to .dynsym. */ /* A linked list of local symbols to be added to .dynsym. */
struct elf_link_local_dynamic_entry *dynlocal; struct elf_link_local_dynamic_entry *dynlocal;
/* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic
objects included in the link. */
struct bfd_link_needed_list *runpath;
}; };
/* Look up an entry in an ELF linker hash table. */ /* Look up an entry in an ELF linker hash table. */

View file

@ -1007,6 +1007,7 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc)
table->dynstr = NULL; table->dynstr = NULL;
table->bucketcount = 0; table->bucketcount = 0;
table->needed = NULL; table->needed = NULL;
table->runpath = NULL;
table->hgot = NULL; table->hgot = NULL;
table->stab_info = NULL; table->stab_info = NULL;
table->dynlocal = NULL; table->dynlocal = NULL;
@ -1073,6 +1074,19 @@ bfd_elf_get_needed_list (abfd, info)
return elf_hash_table (info)->needed; return elf_hash_table (info)->needed;
} }
/* Get the list of DT_RPATH/DT_RUNPATH entries for a link. This is a
hook for the linker ELF emulation code. */
struct bfd_link_needed_list *
bfd_elf_get_runpath_list (abfd, info)
bfd *abfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
if (info->hash->creator->flavour != bfd_target_elf_flavour)
return NULL;
return elf_hash_table (info)->runpath;
}
/* Get the name actually used for a dynamic object for a link. This /* Get the name actually used for a dynamic object for a link. This
is the SONAME entry if there is one. Otherwise, it is the string is the SONAME entry if there is one. Otherwise, it is the string
passed to bfd_elf_set_dt_needed_name, or it is the filename. */ passed to bfd_elf_set_dt_needed_name, or it is the filename. */

View file

@ -1112,6 +1112,8 @@ elf_link_add_object_symbols (abfd, info)
Elf_External_Dyn *extdynend; Elf_External_Dyn *extdynend;
int elfsec; int elfsec;
unsigned long link; unsigned long link;
int rpath;
int runpath;
dynbuf = (Elf_External_Dyn *) bfd_malloc ((size_t) s->_raw_size); dynbuf = (Elf_External_Dyn *) bfd_malloc ((size_t) s->_raw_size);
if (dynbuf == NULL) if (dynbuf == NULL)
@ -1145,6 +1147,8 @@ elf_link_add_object_symbols (abfd, info)
extdyn = dynbuf; extdyn = dynbuf;
extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn); extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn);
rpath = 0;
runpath = 0;
for (; extdyn < extdynend; extdyn++) for (; extdyn < extdynend; extdyn++)
{ {
Elf_Internal_Dyn dyn; Elf_Internal_Dyn dyn;
@ -1181,6 +1185,73 @@ elf_link_add_object_symbols (abfd, info)
; ;
*pn = n; *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); free (dynbuf);