aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1993-11-19 19:29:49 +0000
committerIan Lance Taylor <ian@airs.com>1993-11-19 19:29:49 +0000
commit973e421e6705f6428eca3d79047066e39335891f (patch)
tree9ca7d4cc80228be418b61e658fe01f17a2730972 /ld
parent4c01d9b5beb93f270b99281cfd7067810867fdeb (diff)
downloadgdb-973e421e6705f6428eca3d79047066e39335891f.zip
gdb-973e421e6705f6428eca3d79047066e39335891f.tar.gz
gdb-973e421e6705f6428eca3d79047066e39335891f.tar.bz2
* ldmain.c (enter_file_symbols): Removed duplicate tests of p. If
p is in a common section, make sure the BFD has a section of that name.
Diffstat (limited to 'ld')
-rw-r--r--ld/ldmain.c142
1 files changed, 98 insertions, 44 deletions
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 5b00ad4..30baa96 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -144,12 +144,9 @@ main (argc, argv)
ldsym_init ();
ldfile_add_arch ("");
- set_scripts_dir ();
-
config.make_executable = true;
force_make_executable = false;
-
/* Initialize the cumulative counts of symbols. */
undefined_global_sym_count = 0;
multiple_def_count = 0;
@@ -167,6 +164,10 @@ main (argc, argv)
lang_has_input_file = false;
parse_args (argc, argv);
+ /* This essentially adds another -L directory so this must be done after
+ the -L's in argv have been processed. */
+ set_scripts_dir ();
+
if (had_script == false)
{
/* Read the emulation's appropriate default script. */
@@ -194,12 +195,12 @@ main (argc, argv)
if (lang_has_input_file == false)
{
- einfo ("%P%F: No input files\n");
+ einfo ("%P%F: no input files\n");
}
if (trace_files)
{
- info ("%P: mode %s\n", emulation);
+ info_msg ("%P: mode %s\n", emulation);
}
ldemul_after_parse ();
@@ -255,7 +256,7 @@ main (argc, argv)
{
if (trace_files == true)
{
- einfo ("%P: Link errors found, deleting executable `%s'\n",
+ einfo ("%P: link errors found, deleting executable `%s'\n",
output_filename);
}
@@ -316,9 +317,21 @@ get_emulation (argc, argv)
}
else
{
- einfo("%P%F missing argument to -m\n");
+ einfo("%P%F: missing argument to -m\n");
}
}
+ else if (strcmp (argv[i], "-mips1") == 0
+ || strcmp (argv[i], "-mips2") == 0
+ || strcmp (argv[i], "-mips3") == 0)
+ {
+ /* FIXME: The arguments -mips1, -mips2 and -mips3 are
+ passed to the linker by some MIPS compilers. They
+ generally tell the linker to use a slightly different
+ library path. Perhaps someday these should be
+ implemented as emulations; until then, we just ignore
+ the arguments and hope that nobody ever creates
+ emulations named ips1, ips2 or ips3. */
+ }
else
{
/* -mEMUL */
@@ -426,7 +439,11 @@ refize (sp, nlist_p)
asymbol *sym = *nlist_p;
sym->value = 0;
- sym->flags = 0;
+
+ /* FIXME: Why do we clear the flags here? This used to set the
+ flags to zero, but we must not clear BSF_WEAK. */
+ sym->flags &= BSF_WEAK;
+
sym->section = &bfd_und_section;
sym->udata = (PTR) (sp->srefs_chain);
sp->srefs_chain = nlist_p;
@@ -486,7 +503,7 @@ enter_global_ref (nlist_p, name)
return;
- if (flag_is_constructor (this_symbol_flags))
+ if (this_symbol_flags & BSF_CONSTRUCTOR)
{
/* Add this constructor to the list we keep */
ldlang_add_constructor (sp);
@@ -497,6 +514,15 @@ enter_global_ref (nlist_p, name)
sp->scoms_chain = 0;
}
}
+ else if ((sym->flags & BSF_WEAK) != 0
+ && (sp->sdefs_chain != NULL || sp->scoms_chain != NULL))
+ {
+ /* SYM is a weak symbol for which we already have a definition.
+ Just ignore it. The UnixWare linker is order dependent: if a
+ global symbol follows a weak symbol it gives an error; if a
+ weak symbol follows a global symbol it does not. We are
+ compatible. */
+ }
else
{
if (bfd_is_com_section (sym->section))
@@ -578,7 +604,6 @@ enter_global_ref (nlist_p, name)
/* This is the definition of a symbol, add to def chain */
if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section)
{
- /* Multiple definition */
multiple_warn("%X%C: multiple definition of `%s'\n",
sym,
"%X%C: first defined here\n",
@@ -590,8 +615,9 @@ enter_global_ref (nlist_p, name)
sym->udata = (PTR) (sp->sdefs_chain);
sp->sdefs_chain = nlist_p;
}
+
/* A definition overrides a common symbol */
- if (sp->scoms_chain)
+ if (sp->scoms_chain != NULL)
{
if (config.warn_common)
multiple_warn("%C: warning: definition of `%s' overriding common\n",
@@ -624,8 +650,6 @@ enter_global_ref (nlist_p, name)
ASSERT (sp->sdefs_chain == 0 || sp->scoms_chain == 0);
ASSERT (sp->scoms_chain == 0 || (*(sp->scoms_chain))->udata == 0);
-
-
}
static void
@@ -642,7 +666,7 @@ enter_file_symbols (entry)
if (trace_files || trace_file_tries)
{
- info ("%I\n", entry);
+ info_msg ("%I\n", entry);
}
total_symbols_seen += entry->symbol_count;
@@ -656,7 +680,7 @@ enter_file_symbols (entry)
if (had_y && p->name)
{
/* look up the symbol anyway to see if the trace bit was
- set */
+ set */
ldsym_type *s = ldsym_get (p->name);
if (s->flags & SYM_Y)
{
@@ -666,7 +690,8 @@ enter_file_symbols (entry)
}
}
- if (p->section == &bfd_ind_section)
+ if (p->section == &bfd_ind_section
+ || (p->flags & BSF_INDIRECT) != 0)
{
add_indirect (q);
}
@@ -674,33 +699,35 @@ enter_file_symbols (entry)
{
add_warning (p);
}
+ else if (bfd_is_com_section (p->section))
+ {
+ enter_global_ref (q, p->name);
+
+ /* If this is not bfd_com_section, make sure we have a
+ section of this name in the bfd. We need this
+ because some targets that use multiple common
+ sections do not actually put the common section in
+ the BFD, but we need it there so that a wildcard
+ specification in the linker script (e.g.,
+ *(.scommon)) will find the section and attach it to
+ the right output section. When an section is chosed
+ for the common symbols (in lang_common) that section
+ must have been correctly given an output section.
+ For normal common symbols we just use
+ entry->common_section, initialized above. */
+ if (p->section != &bfd_com_section
+ && p->section->owner != entry->the_bfd)
+ bfd_make_section (entry->the_bfd,
+ bfd_get_section_name (p->section->owner,
+ p->section));
+ }
else if (p->section == &bfd_und_section
|| (p->flags & BSF_GLOBAL)
- || bfd_is_com_section (p->section)
- || (p->flags & BSF_CONSTRUCTOR))
-
+ || (p->flags & BSF_CONSTRUCTOR)
+ || (p->flags & BSF_WEAK))
{
-
- asymbol *p = *q;
-
- if (p->flags & BSF_INDIRECT)
- {
- add_indirect (q);
- }
- else if (p->flags & BSF_WARNING)
- {
- add_warning (p);
- }
- else if (p->section == &bfd_und_section
- || (p->flags & BSF_GLOBAL)
- || bfd_is_com_section (p->section)
- || (p->flags & BSF_CONSTRUCTOR))
- {
- enter_global_ref (q, p->name);
- }
-
+ enter_global_ref (q, p->name);
}
-
}
}
}
@@ -1088,7 +1115,8 @@ subfile_wanted_p (entry)
if (bfd_is_com_section (p->section)
|| (p->flags & BSF_GLOBAL)
- || (p->flags & BSF_INDIRECT))
+ || (p->flags & BSF_INDIRECT)
+ || (p->flags & BSF_WEAK))
{
register ldsym_type *sp = ldsym_get_soft (p->name);
@@ -1097,11 +1125,37 @@ subfile_wanted_p (entry)
if (sp != (ldsym_type *) NULL
&& sp->sdefs_chain == (asymbol **) NULL)
{
- if (sp->srefs_chain != (asymbol **) NULL
- || sp->scoms_chain != (asymbol **) NULL)
+ int check;
+
+ /* A weak symbol is not considered to be a reference
+ when pulling files out of an archive. An unresolved
+ weak symbol winds up with a value of zero. See the
+ SVR4 ABI, p. 4-27. */
+ if (sp->scoms_chain != (asymbol **) NULL)
+ check = 1;
+ else if (sp->srefs_chain == (asymbol **) NULL)
+ check = 0;
+ else
+ {
+ asymbol **ptr;
+
+ check = 0;
+ for (ptr = sp->srefs_chain;
+ ptr != (asymbol **) NULL;
+ ptr = (asymbol **) ((*ptr)->udata))
+ {
+ if (((*ptr)->flags & BSF_WEAK) == 0)
+ {
+ check = 1;
+ break;
+ }
+ }
+ }
+
+ if (check)
{
/* This is a symbol we are looking for. It is
- either not yet defined or common. If this is a
+ either common or not yet defined. If this is a
common symbol, then if the symbol in the object
file is common, we need to combine sizes. But if
we already have a common symbol, and the symbol
@@ -1168,7 +1222,7 @@ subfile_wanted_p (entry)
{
if (write_map)
{
- info ("%I needed due to %s\n", entry, sp->name);
+ info_msg ("%I needed due to %s\n", entry, sp->name);
}
return true;
}