static void
gld${EMULATION_NAME}_before_parse()
{
- ldfile_output_architecture = bfd_arch_${ARCH};
+ ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
config.dynamic_link = ${DYNAMIC_LINK-true};
}
return true;
}
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+
+/* For a native linker, check the file /etc/ld.so.conf for directories
+ in which we may find shared libraries. /etc/ld.so.conf is really
+ only meaningful on Linux, but we check it on other systems anyhow. */
+
+static boolean gld${EMULATION_NAME}_check_ld_so_conf PARAMS ((const char *));
+
+static boolean
+gld${EMULATION_NAME}_check_ld_so_conf (name)
+ const char *name;
+{
+ static boolean initialized;
+ static char *ld_so_conf;
+
+ if (! initialized)
+ {
+ FILE *f;
+
+ f = fopen ("/etc/ld.so.conf", FOPEN_RT);
+ if (f != NULL)
+ {
+ char *b;
+ size_t len, alloc;
+ int c;
+
+ len = 0;
+ alloc = 100;
+ b = (char *) xmalloc (alloc);
+
+ while ((c = getc (f)) != EOF)
+ {
+ 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;
+ }
+ }
+ }
+
+ if (len > 0 && b[len - 1] == ':')
+ --len;
+
+ if (len > 0)
+ b[len] = '\0';
+ else
+ {
+ free (b);
+ b = NULL;
+ }
+
+ fclose (f);
+
+ ld_so_conf = b;
+ }
+
+ initialized = true;
+ }
+
+ if (ld_so_conf == NULL)
+ return false;
+
+ return gld${EMULATION_NAME}_search_needed (ld_so_conf, name);
+}
+
+EOF
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+
/* These variables are required to pass information back and forth
between after_open and check_needed and stat_needed. */
}
if (search != NULL)
continue;
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+ if (gld${EMULATION_NAME}_check_ld_so_conf (l->name))
+ continue;
+EOF
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
einfo ("%P: warning: %s, needed by %B, not found\n",
l->name, l->by);
gld${EMULATION_NAME}_check_needed (s)
lang_input_statement_type *s;
{
+ if (global_found)
+ return;
+
if (s->filename != NULL
&& strcmp (s->filename, global_needed->name) == 0)
- global_found = true;
- else if (s->search_dirs_flag
- && s->filename != NULL
- && strchr (global_needed->name, '/') == NULL)
+ {
+ global_found = true;
+ return;
+ }
+
+ if (s->the_bfd != NULL)
+ {
+ const char *soname;
+
+ soname = bfd_elf_get_dt_soname (s->the_bfd);
+ if (soname != NULL
+ && strcmp (soname, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+ }
+
+ if (s->search_dirs_flag
+ && s->filename != NULL
+ && strchr (global_needed->name, '/') == NULL)
{
const char *f;
f = strrchr (s->filename, '/');
if (f != NULL
&& strcmp (f + 1, global_needed->name) == 0)
- global_found = true;
+ {
+ global_found = true;
+ return;
+ }
}
}
lang_input_statement_type *s;
{
struct stat st;
- const char *f, *g;
+ const char *suffix;
+ const char *soname;
+ const char *f;
if (global_found)
return;
/* We issue a warning if it looks like we are including two
different versions of the same shared library. For example,
there may be a problem if -lc picks up libc.so.6 but some other
- shared library has a DT_NEEDED entry of libc.so.5. */
+ shared library has a DT_NEEDED entry of libc.so.5. This is a
+ hueristic test, and it will only work if the name looks like
+ NAME.so.VERSION. FIXME: Depending on file names is error-prone.
+ If we really want to issue warnings about mixing version numbers
+ of shared libraries, we need to find a better way. */
if (strchr (global_needed->name, '/') != NULL)
return;
+ suffix = strstr (global_needed->name, ".so.");
+ if (suffix == NULL)
+ return;
+ suffix += sizeof ".so." - 1;
+
+ soname = bfd_elf_get_dt_soname (s->the_bfd);
+ if (soname == NULL)
+ soname = s->filename;
- f = strrchr (s->filename, '/');
+ f = strrchr (soname, '/');
if (f != NULL)
++f;
else
- f = s->filename;
- g = global_needed->name;
-
- while (*f != '\0' && *f == *g)
- {
- ++f;
- ++g;
- }
+ f = soname;
- /* We have now skipped past the identical prefixes. If the
- remainder of both names is nothing but numbers and dots, we issue
- a warning. */
- if (f[strspn (f, "0123456789.")] == '\0'
- && g[strspn (g, "0123456789.")] == '\0')
+ if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
- global_needed->name, global_needed->by, s->filename);
+ global_needed->name, global_needed->by, f);
}
/* This is called after the sections have been attached to output
break;
case etree_trinary:
- gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
break;