Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/gnu/dist Pull up code from binutils 2.11.3 to fix a problem ...



details:   https://anonhg.NetBSD.org/src/rev/fb26b6eb4ca4
branches:  trunk
changeset: 517598:fb26b6eb4ca4
user:      skrll <skrll%NetBSD.org@localhost>
date:      Thu Nov 15 20:06:27 2001 +0000

description:
Pull up code from binutils 2.11.3 to fix a problem when linking against
libraries that have their dependencies recorded via NEEDED/RPATH so
that the location of the dependent libraries doesn't have to be supplied.

This closes bin/14583 by myself.

OK'd by Todd Vierling <tv%netbsd.org@localhost>

diffstat:

 gnu/dist/bfd/bfd-in.h          |   2 +
 gnu/dist/bfd/bfd-in2.h         |   2 +
 gnu/dist/bfd/elf-bfd.h         |   3 ++
 gnu/dist/bfd/elf.c             |  14 +++++++++
 gnu/dist/bfd/elflink.h         |  63 ++++++++++++++++++++++++++++++++++++++++++
 gnu/dist/include/elf/common.h  |   1 +
 gnu/dist/ld/emultempl/elf32.em |  24 ++++++++++++++++
 7 files changed, 109 insertions(+), 0 deletions(-)

diffs (207 lines):

diff -r 2f28e57bf4fd -r fb26b6eb4ca4 gnu/dist/bfd/bfd-in.h
--- a/gnu/dist/bfd/bfd-in.h     Thu Nov 15 19:35:31 2001 +0000
+++ b/gnu/dist/bfd/bfd-in.h     Thu Nov 15 20:06:27 2001 +0000
@@ -622,6 +622,8 @@
           struct bfd_elf_version_tree *));
 extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
 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 *));
 
 /* SunOS shared library support routines for the linker.  */
 
diff -r 2f28e57bf4fd -r fb26b6eb4ca4 gnu/dist/bfd/bfd-in2.h
--- a/gnu/dist/bfd/bfd-in2.h    Thu Nov 15 19:35:31 2001 +0000
+++ b/gnu/dist/bfd/bfd-in2.h    Thu Nov 15 20:06:27 2001 +0000
@@ -622,6 +622,8 @@
           struct bfd_elf_version_tree *));
 extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
 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 *));
 
 /* SunOS shared library support routines for the linker.  */
 
diff -r 2f28e57bf4fd -r fb26b6eb4ca4 gnu/dist/bfd/elf-bfd.h
--- a/gnu/dist/bfd/elf-bfd.h    Thu Nov 15 19:35:31 2001 +0000
+++ b/gnu/dist/bfd/elf-bfd.h    Thu Nov 15 20:06:27 2001 +0000
@@ -184,6 +184,9 @@
   struct elf_link_hash_entry *hgot;
   /* A pointer to information used to link stabs in sections.  */
   PTR stab_info;
+  /* 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.  */
diff -r 2f28e57bf4fd -r fb26b6eb4ca4 gnu/dist/bfd/elf.c
--- a/gnu/dist/bfd/elf.c        Thu Nov 15 19:35:31 2001 +0000
+++ b/gnu/dist/bfd/elf.c        Thu Nov 15 20:06:27 2001 +0000
@@ -873,6 +873,7 @@
   table->dynstr = NULL;
   table->bucketcount = 0;
   table->needed = NULL;
+  table->runpath = NULL;
   table->hgot = NULL;
   table->stab_info = NULL;
   return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
@@ -928,6 +929,19 @@
   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;
+     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
    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.  */
diff -r 2f28e57bf4fd -r fb26b6eb4ca4 gnu/dist/bfd/elflink.h
--- a/gnu/dist/bfd/elflink.h    Thu Nov 15 19:35:31 2001 +0000
+++ b/gnu/dist/bfd/elflink.h    Thu Nov 15 20:06:27 2001 +0000
@@ -851,6 +851,8 @@
          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)
@@ -867,6 +869,8 @@
 
          extdyn = dynbuf;
          extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn);
+         rpath = 0;
+         runpath = 0;
          for (; extdyn < extdynend; extdyn++)
            {
              Elf_Internal_Dyn dyn;
@@ -903,6 +907,65 @@
                    ;
                  *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 clear runpath.  Do _NOT_ bfd_release, as that
+                    frees all more recently bfd_alloc'd blocks as
+                    well.  */
+                 if (rpath && 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);
diff -r 2f28e57bf4fd -r fb26b6eb4ca4 gnu/dist/include/elf/common.h
--- a/gnu/dist/include/elf/common.h     Thu Nov 15 19:35:31 2001 +0000
+++ b/gnu/dist/include/elf/common.h     Thu Nov 15 20:06:27 2001 +0000
@@ -273,6 +273,7 @@
 #define DT_DEBUG       21
 #define DT_TEXTREL     22
 #define DT_JMPREL      23
+#define DT_RUNPATH      29
 
 /* The next four dynamic tags are used on Solaris.  We support them
    everywhere.  */
diff -r 2f28e57bf4fd -r fb26b6eb4ca4 gnu/dist/ld/emultempl/elf32.em
--- a/gnu/dist/ld/emultempl/elf32.em    Thu Nov 15 19:35:31 2001 +0000
+++ b/gnu/dist/ld/emultempl/elf32.em    Thu Nov 15 20:06:27 2001 +0000
@@ -292,6 +292,17 @@
          size_t len;
          search_dirs_type *search;
 
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+         struct bfd_link_needed_list *rp;
+         int found;
+EOF
+  fi
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+
          if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
                                                  l->name, force))
            break;
@@ -313,6 +324,19 @@
          lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
          if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
            break;
+
+          found = 0;
+          rp = bfd_elf_get_runpath_list (output_bfd, &link_info);
+          for (; !found && rp != NULL; rp = rp->next)
+            {
+              found = (rp->by == l->by
+                       && gld${EMULATION_NAME}_search_needed (rp->name,
+                                                              l->name,
+                                                              force));
+            }
+          if (found)
+            break;
+
 EOF
   fi
 fi



Home | Main Index | Thread Index | Old Index