Rewrite add_sysroot
authorAlan Modra <amodra@gmail.com>
Sat, 11 Mar 2017 12:27:29 +0000 (22:57 +1030)
committerAlan Modra <amodra@gmail.com>
Sat, 11 Mar 2017 13:10:20 +0000 (23:40 +1030)
Relative paths shouldn't have the sysroot prefix added.  The patch
also makes some attempt at supporting DOS paths, and tidies code using
the new add_sysroot.

* emultempl/elf32.em (gld${EMULATION_NAME}_add_sysroot): Rewrite.
Only prefix absolute paths with sysroot.  Handle DOS paths.
(gld${EMULATION_NAME}_check_ld_elf_hints): Constify variable.
(gld${EMULATION_NAME}_check_ld_so_conf): Likewise.
(gld${EMULATION_NAME}_after_open): Short-circuit NULL path
searches.  Rename variable.  Simplify get_runpath search.

ld/ChangeLog
ld/emultempl/elf32.em

index 47c07b9a5e17fb40f8a73e5a2522f2fb196e19ad..f4baea87d82e56e5e8fbad83e2f7e794669acee2 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-11  Alan Modra  <amodra@gmail.com>
+
+       * emultempl/elf32.em (gld${EMULATION_NAME}_add_sysroot): Rewrite.
+       Only prefix absolute paths with sysroot.  Handle DOS paths.
+       (gld${EMULATION_NAME}_check_ld_elf_hints): Constify variable.
+       (gld${EMULATION_NAME}_check_ld_so_conf): Likewise.
+       (gld${EMULATION_NAME}_after_open): Short-circuit NULL path
+       searches.  Rename variable.  Simplify get_runpath search.
+
 2017-03-11  Alan Modra  <amodra@gmail.com>
 
        * testsuite/ld-elf/shared.exp: Use -Wl,-export-dynamic rather
index 84adaef6dfe181b8e3b09e306702b916e1bcfb21..16220d56d6f3fc55ea400d333dd98099091d4b26 100644 (file)
@@ -691,41 +691,85 @@ EOF
 if [ "x${USE_LIBPATH}" = xyes ] ; then
   fragment <<EOF
 
-/* Add the sysroot to every entry in a path separated by
-   config.rpath_separator.  */
+/* Prefix the sysroot to absolute paths in PATH, a string containing
+   paths separated by config.rpath_separator.  If running on a DOS
+   file system, paths containing a drive spec won't have the sysroot
+   prefix added, unless the sysroot also specifies the same drive.  */
 
-static char *
+static const char *
 gld${EMULATION_NAME}_add_sysroot (const char *path)
 {
-  int len, colons, i;
-  char *ret, *p;
-
-  len = strlen (path);
-  colons = 0;
-  i = 0;
-  while (path[i])
-    if (path[i++] == config.rpath_separator)
-      colons++;
-
-  if (path[i])
-    colons++;
-
-  len = len + (colons + 1) * strlen (ld_sysroot);
-  ret = xmalloc (len + 1);
-  strcpy (ret, ld_sysroot);
-  p = ret + strlen (ret);
-  i = 0;
-  while (path[i])
-    if (path[i] == config.rpath_separator)
-      {
-       *p++ = path[i++];
-       strcpy (p, ld_sysroot);
-       p = p + strlen (p);
-      }
-    else
-      *p++ = path[i++];
+  size_t len, extra;
+  const char *p;
+  char *ret, *q;
+  int dos_drive_sysroot = HAS_DRIVE_SPEC (ld_sysroot);
+
+  len = strlen (ld_sysroot);
+  for (extra = 0, p = path; ; )
+    {
+      int dos_drive = HAS_DRIVE_SPEC (p);
+
+      if (dos_drive)
+       p += 2;
+      if (IS_DIR_SEPARATOR (*p)
+         && (!dos_drive
+             || (dos_drive_sysroot
+                 && ld_sysroot[0] == p[-2])))
+       {
+         if (dos_drive && dos_drive_sysroot)
+           extra += len - 2;
+         else
+           extra += len;
+       }
+      p = strchr (p, config.rpath_separator);
+      if (!p)
+       break;
+      ++p;
+    }
+
+  ret = xmalloc (strlen (path) + extra + 1);
+
+  for (q = ret, p = path; ; )
+    {
+      const char *end;
+      int dos_drive = HAS_DRIVE_SPEC (p);
+
+      if (dos_drive)
+       {
+         *q++ = *p++;
+         *q++ = *p++;
+       }
+      if (IS_DIR_SEPARATOR (*p)
+         && (!dos_drive
+             || (dos_drive_sysroot
+                 && ld_sysroot[0] == p[-2])))
+       {
+         if (dos_drive && dos_drive_sysroot)
+           {
+             strcpy (q, ld_sysroot + 2);
+             q += len - 2;
+           }
+         else
+           {
+             strcpy (q, ld_sysroot);
+             q += len;
+           }
+       }
+      end = strchr (p, config.rpath_separator);
+      if (end)
+       {
+         size_t n = end - p + 1;
+         strncpy (q, p, n);
+         q += n;
+         p += n;
+       }
+      else
+       {
+         strcpy (q, p);
+         break;
+       }
+    }
 
-  *p = 0;
   return ret;
 }
 
@@ -745,7 +789,7 @@ gld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
                                         int force)
 {
   static bfd_boolean initialized;
-  static char *ld_elf_hints;
+  static const char *ld_elf_hints;
   struct dt_needed needed;
 
   if (!initialized)
@@ -963,7 +1007,7 @@ gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
                                       int force)
 {
   static bfd_boolean initialized;
-  static char *ld_so_conf;
+  static const char *ld_so_conf;
   struct dt_needed needed;
 
   if (! initialized)
@@ -986,9 +1030,8 @@ gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
 
       if (info.path)
        {
-         char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
+         ld_so_conf = gld${EMULATION_NAME}_add_sysroot (info.path);
          free (info.path);
-         ld_so_conf = d;
        }
       initialized = TRUE;
     }
@@ -1381,9 +1424,9 @@ gld${EMULATION_NAME}_after_open (void)
          size_t len;
          search_dirs_type *search;
 EOF
-if [ "x${NATIVE}" = xyes ] ; then
+if [ "x${NATIVE}" = xyes ] || [ "x${USE_LIBPATH}" = xyes ] ; then
 fragment <<EOF
-         const char *lib_path;
+         const char *path;
 EOF
 fi
 if [ "x${USE_LIBPATH}" = xyes ] ; then
@@ -1400,9 +1443,13 @@ fragment <<EOF
 EOF
 if [ "x${USE_LIBPATH}" = xyes ] ; then
 fragment <<EOF
-         if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
-                                                 &n, force))
-           break;
+         path = command_line.rpath;
+         if (path)
+           {
+             found = gld${EMULATION_NAME}_search_needed (path, &n, force);
+             if (found)
+               break;
+           }
 EOF
 fi
 if [ "x${NATIVE}" = xyes ] ; then
@@ -1410,13 +1457,14 @@ fragment <<EOF
          if (command_line.rpath_link == NULL
              && command_line.rpath == NULL)
            {
-             lib_path = (const char *) getenv ("LD_RUN_PATH");
-             if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
-                                                     force))
+             path = (const char *) getenv ("LD_RUN_PATH");
+             if (path
+                 && gld${EMULATION_NAME}_search_needed (path, &n, force))
                break;
            }
-         lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
-         if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force))
+         path = (const char *) getenv ("LD_LIBRARY_PATH");
+         if (path
+             && gld${EMULATION_NAME}_search_needed (path, &n, force))
            break;
 EOF
 fi
@@ -1426,16 +1474,11 @@ fragment <<EOF
          rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info);
          for (; !found && rp != NULL; rp = rp->next)
            {
-             const char *tmpname = rp->name;
-
-             if (IS_ABSOLUTE_PATH (tmpname))
-               tmpname = gld${EMULATION_NAME}_add_sysroot (tmpname);
+             path = gld${EMULATION_NAME}_add_sysroot (rp->name);
              found = (rp->by == l->by
-                      && gld${EMULATION_NAME}_search_needed (tmpname,
-                                                             &n,
+                      && gld${EMULATION_NAME}_search_needed (path, &n,
                                                              force));
-             if (tmpname != rp->name)
-               free ((char *) tmpname);
+             free ((char *) path);
            }
          if (found)
            break;