aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-10-11 14:12:11 +0000
committerJakub Jelinek <jakub@redhat.com>2004-10-11 14:12:11 +0000
commitd3989512d9d920c66be68a543d0c984eda2542a0 (patch)
treee870ad7fcaa2e41e3db8de0ff58df143efc7a0d5
parent7f1204bb4f7b558ade9e406e33d062df04798966 (diff)
downloadbinutils-d3989512d9d920c66be68a543d0c984eda2542a0.zip
binutils-d3989512d9d920c66be68a543d0c984eda2542a0.tar.gz
binutils-d3989512d9d920c66be68a543d0c984eda2542a0.tar.bz2
* emultempl/elf32.em (gld${EMULATION_NAME}_ld_so_conf): New structure.
(gld${EMULATION_NAME}_parse_ld_so_conf, gld${EMULATION_NAME}_parse_ld_so_conf_include): New functions. (gld${EMULATION_NAME}_check_ld_so_conf): Use them.
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/emultempl/elf32.em210
2 files changed, 159 insertions, 58 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 1f805b3..efb7abc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2004-10-11 Jakub Jelinek <jakub@redhat.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_ld_so_conf): New structure.
+ (gld${EMULATION_NAME}_parse_ld_so_conf,
+ gld${EMULATION_NAME}_parse_ld_so_conf_include): New functions.
+ (gld${EMULATION_NAME}_check_ld_so_conf): Use them.
+
2004-10-11 Alan Modra <amodra@bigpond.net.au>
PR 423
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index bb1f92c..a4e2f1e 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -63,6 +63,16 @@ static void gld${EMULATION_NAME}_finish (void);
EOF
+if [ "x${USE_LIBPATH}" = xyes ] ; then
+ case ${target} in
+ *-*-linux-gnu*)
+ cat >>e${EMULATION_NAME}.c <<EOF
+#include <glob.h>
+EOF
+ ;;
+ esac
+fi
+
# Import any needed special functions and/or overrides.
#
if test -n "$EXTRA_EM_FILE" ; then
@@ -506,80 +516,164 @@ EOF
in which we may find shared libraries. /etc/ld.so.conf is really
only meaningful on Linux. */
-static bfd_boolean
-gld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force)
+struct gld${EMULATION_NAME}_ld_so_conf
{
- static bfd_boolean initialized;
- static char *ld_so_conf;
- struct dt_needed needed;
+ char *path;
+ size_t len, alloc;
+};
- if (! initialized)
+static void
+gld${EMULATION_NAME}_parse_ld_so_conf
+ (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename);
+
+static void
+gld${EMULATION_NAME}_parse_ld_so_conf_include
+ (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename,
+ const char *pattern)
+{
+ char *newp = NULL;
+ glob_t gl;
+
+ if (pattern[0] != '/')
{
- FILE *f;
- char *tmppath;
+ char *p = strrchr (filename, '/');
+ size_t patlen = strlen (pattern) + 1;
- tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL);
- f = fopen (tmppath, FOPEN_RT);
- free (tmppath);
- if (f != NULL)
- {
- char *b;
- size_t len, alloc;
- int c;
+ newp = xmalloc (p - filename + 1 + patlen);
+ memcpy (newp, filename, p - filename + 1);
+ memcpy (newp + (p - filename + 1), pattern, patlen);
+ pattern = newp;
+ }
- len = 0;
- alloc = 100;
- b = (char *) xmalloc (alloc);
+ if (glob (pattern, 0, NULL, &gl) == 0)
+ {
+ size_t i;
+
+ for (i = 0; i < gl.gl_pathc; ++i)
+ gld${EMULATION_NAME}_parse_ld_so_conf (info, gl.gl_pathv[i]);
+ globfree (&gl);
+ }
+
+ if (newp)
+ free (newp);
+}
+
+static void
+gld${EMULATION_NAME}_parse_ld_so_conf
+ (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename)
+{
+ FILE *f = fopen (filename, FOPEN_RT);
+ char *line = NULL;
+ size_t linelen = 0;
+
+ if (f == NULL)
+ return;
+
+ while (getline (&line, &linelen, f) != -1)
+ {
+ char *p;
+
+ p = strchr (line, '\n');
+ if (p)
+ *p = '\0';
+
+ /* Because the file format does not know any form of quoting we
+ can search forward for the next '#' character and if found
+ make it terminating the line. */
+ p = strchr (line, '#');
+ if (p)
+ *p = '\0';
+
+ /* Remove leading whitespace. NUL is no whitespace character. */
+ p = line;
+ while (*p == ' ' || *p == '\f' || *p == '\r' || *p == '\t' || *p == '\v')
+ ++p;
+
+ /* If the line is blank it is ignored. */
+ if (p[0] == '\0')
+ continue;
- while ((c = getc (f)) != EOF)
+ if (!strncmp (p, "include", 7) && (p[7] == ' ' || p[7] == '\t'))
+ {
+ char *dir, c;
+ p += 8;
+ do
{
- if (len + 1 >= alloc)
- {
- alloc *= 2;
- b = (char *) xrealloc (b, alloc);
- }
- if (c != ':'
- && c != ' '
- && c != '\t'
- && c != '\n'
- && c != ',')
- {
- b[len] = c;
- ++len;
- }
- else
- {
- if (len > 0 && b[len - 1] != ':')
- {
- b[len] = ':';
- ++len;
- }
- }
- }
+ while (*p == ' ' || *p == '\t')
+ ++p;
- if (len > 0 && b[len - 1] == ':')
- --len;
+ if (*p == '\0')
+ break;
- if (len > 0)
- b[len] = '\0';
+ dir = p;
+
+ while (*p != ' ' && *p != '\t' && *p)
+ ++p;
+
+ c = *p;
+ *p++ = '\0';
+ if (dir[0] != '\0')
+ gld${EMULATION_NAME}_parse_ld_so_conf_include (info, filename,
+ dir);
+ }
+ while (c != '\0');
+ }
+ else
+ {
+ char *dir = p;
+ while (*p && *p != '=' && *p != ' ' && *p != '\t' && *p != '\f'
+ && *p != '\r' && *p != '\v')
+ ++p;
+
+ while (p != dir && p[-1] == '/')
+ --p;
+ if (info->path == NULL)
+ {
+ info->alloc = p - dir + 1 + 256;
+ info->path = xmalloc (info->alloc);
+ info->len = 0;
+ }
else
{
- free (b);
- b = NULL;
+ if (info->len + 1 + (p - dir) >= info->alloc)
+ {
+ info->alloc += p - dir + 256;
+ info->path = xrealloc (info->path, info->alloc);
+ }
+ info->path[info->len++] = ':';
}
+ memcpy (info->path + info->len, dir, p - dir);
+ info->len += p - dir;
+ info->path[info->len] = '\0';
+ }
+ }
+ free (line);
+ fclose (f);
+}
- fclose (f);
+static bfd_boolean
+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 (b)
- {
- char *d = gld${EMULATION_NAME}_add_sysroot (b);
- free (b);
- b = d;
- }
+ if (! initialized)
+ {
+ char *tmppath;
+ struct gld${EMULATION_NAME}_ld_so_conf info;
- ld_so_conf = b;
+ tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL);
+ info.path = NULL;
+ info.len = info.alloc = 0;
+ gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath);
+ free (tmppath);
+ if (info.path)
+ {
+ char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
+ free (info.path);
+ ld_so_conf = d;
}
-
initialized = TRUE;
}