diff options
author | Jakub Jelinek <jakub@redhat.com> | 2004-10-11 14:12:11 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2004-10-11 14:12:11 +0000 |
commit | d3989512d9d920c66be68a543d0c984eda2542a0 (patch) | |
tree | e870ad7fcaa2e41e3db8de0ff58df143efc7a0d5 | |
parent | 7f1204bb4f7b558ade9e406e33d062df04798966 (diff) | |
download | binutils-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/ChangeLog | 7 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 210 |
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; } |