diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2004-07-19 16:40:52 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2004-07-19 16:40:52 +0000 |
commit | e56f61be758d90c463cc220c50ad7f30b955c2af (patch) | |
tree | 44a55597c662b3a96fc3faa041f88962121e02dc /ld/emultempl | |
parent | 756d8c7093fdf0f2134628c2f7514e8231ce4e82 (diff) | |
download | gdb-e56f61be758d90c463cc220c50ad7f30b955c2af.zip gdb-e56f61be758d90c463cc220c50ad7f30b955c2af.tar.gz gdb-e56f61be758d90c463cc220c50ad7f30b955c2af.tar.bz2 |
bfd/
2004-07-19 H.J. Lu <hongjiu.lu@intel.com>
* bfd-in.h (dynamic_lib_link_class): Add DYN_NO_ADD_NEEDED and
DYN_NO_NEEDED.
(bfd_elf_get_dyn_lib_class): New prototype.
* elf.c (bfd_elf_get_dyn_lib_class): New function.
* elflink.c (elf_link_add_object_symbols): Check DYN_AS_NEEDED,
DYN_DT_NEEDED and DYN_NO_NEEDED bits to see if a DT_NEEDED
entry is needed. Issue an error if a DT_NEEDED entry is needed
for a file marked DYN_NO_NEEDED.
(elf_link_check_versioned_symbol): Check the DYN_DT_NEEDED bit
for DT_NEEDED tags.
* bfd-in2.h: Regenerated.
ld/
2004-07-19 H.J. Lu <hongjiu.lu@intel.com>
* emultempl/elf32.em (gld${EMULATION_NAME}_load_symbols): Also
check the add_needed field.
(dt_needed): New struct.
(gld${EMULATION_NAME}_try_needed): Change the first argument
to a pointer to struct dt_needed. Check the DYN_NO_ADD_NEEDED
bit in the file where the DT_NEEDED entry comes from.
(gld${EMULATION_NAME}_search_needed): Change the second
argument to a pointer to struct dt_needed.
(gld${EMULATION_NAME}_check_ld_so_conf): Updated.
(gld${EMULATION_NAME}_after_open): Likewise.
* ld.texinfo: Add --add-needed document.
* ldlang.c (new_afile): Set p->add_needed.
* ldlang.h (lang_input_statement_type): Add add_needed field.
* ldmain.h (add_needed): Declare.
* ldmain.c (add_needed): New global var.
* lexsup.c (option_values): Add OPTION_ADD_NEEDED and
OPTION_NO_ADD_NEEDED.
(ld_options): Likewise.
(parse_args): Handle them.
Diffstat (limited to 'ld/emultempl')
-rw-r--r-- | ld/emultempl/elf32.em | 78 |
1 files changed, 62 insertions, 16 deletions
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 8dbd60a..469f054 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -96,14 +96,25 @@ cat >>e${EMULATION_NAME}.c <<EOF static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry) { - if (!entry->as_needed - || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0) - return FALSE; + int class = 0; /* Tell the ELF linker that we don't want the output file to have a DT_NEEDED entry for this file, unless it is used to resolve references in a regular object. */ - bfd_elf_set_dyn_lib_class (entry->the_bfd, DYN_AS_NEEDED); + if (entry->as_needed) + class = DYN_AS_NEEDED; + + /* Tell the ELF linker that we don't want the output file to have a + DT_NEEDED entry for any dynamic library in DT_NEEDED tags from + this file at all. */ + if (!entry->add_needed) + class |= DYN_NO_ADD_NEEDED; + + if (!class + || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0) + return FALSE; + + bfd_elf_set_dyn_lib_class (entry->the_bfd, class); /* Continue on with normal load_symbols processing. */ return FALSE; @@ -242,16 +253,24 @@ gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s) global_needed->name, global_needed->by, soname); } +struct dt_needed +{ + bfd *by; + const char *name; +}; /* This function is called for each possible name for a dynamic object named by a DT_NEEDED entry. The FORCE parameter indicates whether to skip the check for a conflicting version. */ static bfd_boolean -gld${EMULATION_NAME}_try_needed (const char *name, int force) +gld${EMULATION_NAME}_try_needed (struct dt_needed *needed, + int force) { bfd *abfd; + const char *name = needed->name; const char *soname; + int class; abfd = bfd_openr (name, bfd_get_target (output_bfd)); if (abfd == NULL) @@ -364,7 +383,17 @@ cat >>e${EMULATION_NAME}.c <<EOF /* Tell the ELF linker that we don't want the output file to have a DT_NEEDED entry for this file, unless it is used to resolve references in a regular object. */ - bfd_elf_set_dyn_lib_class (abfd, DYN_DT_NEEDED); + class = DYN_DT_NEEDED; + + /* Tell the ELF linker that we don't want the output file to have a + DT_NEEDED entry for this file at all if the entry is from a file + with DYN_NO_ADD_NEEDED. */ + if (needed->by + && (bfd_elf_get_dyn_lib_class (needed->by) + & DYN_NO_ADD_NEEDED) != 0) + class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED; + + bfd_elf_set_dyn_lib_class (abfd, class); /* Add this file into the symbol table. */ if (! bfd_link_add_symbols (abfd, &link_info)) @@ -377,16 +406,23 @@ cat >>e${EMULATION_NAME}.c <<EOF /* Search for a needed file in a path. */ static bfd_boolean -gld${EMULATION_NAME}_search_needed (const char *path, const char *name, int force) +gld${EMULATION_NAME}_search_needed (const char *path, + struct dt_needed *n, int force) { const char *s; + const char *name = n->name; size_t len; + struct dt_needed needed; if (name[0] == '/') - return gld${EMULATION_NAME}_try_needed (name, force); + return gld${EMULATION_NAME}_try_needed (n, force); if (path == NULL || *path == '\0') return FALSE; + + needed.by = n->by; + needed.name = n->name; + len = strlen (name); while (1) { @@ -407,7 +443,8 @@ gld${EMULATION_NAME}_search_needed (const char *path, const char *name, int forc } strcpy (sset, name); - if (gld${EMULATION_NAME}_try_needed (filename, force)) + needed.name = filename; + if (gld${EMULATION_NAME}_try_needed (&needed, force)) return TRUE; free (filename); @@ -474,6 +511,7 @@ gld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force) { static bfd_boolean initialized; static char *ld_so_conf; + struct dt_needed needed; if (! initialized) { @@ -548,7 +586,10 @@ gld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force) if (ld_so_conf == NULL) return FALSE; - return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force); + + needed.by = NULL; + needed.name = name; + return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force); } EOF @@ -631,6 +672,7 @@ gld${EMULATION_NAME}_after_open (void) for (l = needed; l != NULL; l = l->next) { struct bfd_link_needed_list *ll; + struct dt_needed n, nn; int force; /* If we've already seen this file, skip it. */ @@ -647,6 +689,9 @@ gld${EMULATION_NAME}_after_open (void) if (global_found) continue; + n.by = l->by; + n.name = l->name; + nn.by = l->by; if (trace_file_tries) info_msg (_("%s needed by %B\n"), l->name, l->by); @@ -676,13 +721,13 @@ fi cat >>e${EMULATION_NAME}.c <<EOF if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, - l->name, force)) + &n, force)) break; EOF if [ "x${USE_LIBPATH}" = xyes ] ; then cat >>e${EMULATION_NAME}.c <<EOF if (gld${EMULATION_NAME}_search_needed (command_line.rpath, - l->name, force)) + &n, force)) break; EOF fi @@ -692,12 +737,12 @@ cat >>e${EMULATION_NAME}.c <<EOF && command_line.rpath == NULL) { lib_path = (const char *) getenv ("LD_RUN_PATH"); - if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, + if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force)) break; } lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); - if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force)) + if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force)) break; EOF fi @@ -710,7 +755,7 @@ cat >>e${EMULATION_NAME}.c <<EOF char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name); found = (rp->by == l->by && gld${EMULATION_NAME}_search_needed (tmpname, - l->name, + &n, force)); free (tmpname); } @@ -729,7 +774,8 @@ cat >>e${EMULATION_NAME}.c <<EOF continue; filename = (char *) xmalloc (strlen (search->name) + len + 2); sprintf (filename, "%s/%s", search->name, l->name); - if (gld${EMULATION_NAME}_try_needed (filename, force)) + nn.name = filename; + if (gld${EMULATION_NAME}_try_needed (&nn, force)) break; free (filename); } |