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:
parent
4193618c3c
commit
a963dc6ade
6 changed files with 106 additions and 0 deletions
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
14
bfd/elf.c
14
bfd/elf.c
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue