This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH COMMITTED: Add support for -u to gold


This patch adds support for the -u option to gold.

This is slightly complicated by the fact that gold postpones the
decision as to the output format until it sees an input object.  This
means that we can not simply add the symbols to the symbol table at
the start of the link, since we don't know the size to use for the
Sized_symbol template class until we find an input object.  Since the
first input file might be an archive, we can't ignore the -u options
until we see an input file.  So I changed the archive code to
explicitly check the -u options when deciding whether to include a
member.  I was then able to postpone adding the -u symbols to the
symbol table until we've seen all the symbols.  At that time, if there
are any -u symbols which we never saw, we add them to the symbol table
to be emitted as undefined symbols.  This is what happens with GNU ld
as well.

I jumped the gun in handling --no-undefined as the reverse of
--undefined, because it turns out that for GNU ld --undefined is the
long form of -u.  So now both --undefined and --no-undefined are
listed, and they are not antonyms.

Because I was adding a new type of symbol--IS_UNDEFINED--I took the
opportunity to clean up the initialization functions to they no longer
rely on overloading to decide what to do.  I also renamed CONSTANT to
IS_CONSTANT to make preprocessor collisions less likely.

Ian


2008-05-06  Ian Lance Taylor  <iant@google.com>

	PR 6049
	* options.h (DEFINE_set): Add VARNAME_begin and VARNAME_end
	functions.
	(class General_options): Remove existing --undefined, and add
	--no-undefined instead.  Add new --undefined as synonym for -u.
	* archive.cc (Archive::add_symbols): Check whether symbol was
	named with -u.
	* gold.cc (queue_middle_tasks): Add -u symbols to symbol table.
	* symtab.h (class Symbol): Rename CONSTANT to IS_CONSTANT; change
	all uses.  Add IS_UNDEFINED.  Update declarations to split
	different versions of init_base.  Declare init_base_undefined.
	(Symbol::is_defined): Handle IS_UNDEFINED.
	(Symbol::is_undefined): Likewise.
	(Symbol::is_weak_undefined): Call is_undefined.
	(Symbol::is_absolute): Handle IS_CONSTANT.
	(class Sized_symbol): Update declarations to split different
	versions of init.  Declare init_undefined.
	(class Symbol_table): Declare new functions.
	* symtab.cc (Symbol::init_base_object): Rename from init_base.
	Change all callers.
	(Symbol::init_base_output_data): Likewise.
	(Symbol::init_base_output_segment): Likewise.
	(Symbol::init_base_constant): Likewise.
	(Symbol::init_base_undefined): New function.
	(Sized_symbol::init_object): Rename from init.  Change all
	callers.
	(Sized_symbol::init_output_data): Likewise.
	(Sized_symbol::init_output_segment): Likewise.
	(Sized_symbol::init_constant): Likewise.
	(Sized_symbol::init_undefined): New function.
	(Symbol_table::add_undefined_symbols_from_command_line): New
	function.
	(Symbol_table::do_add_undefined_symbols_from_command_line): New
	function.
	(Symbol::final_value_is_known): Handle IS_UNDEFINED.
	(Symbol::output_section): Likewise.
	(Symbol::set_output_section): Likewise.
	(Symbol_table::sized_finalize_symbol): Likewise.
	(Symbol_table::sized_write_globals): Likewise.
	* resolve.cc (Symbol_table::should_override): Likewise.
	(Symbol::override_base_with_special): Likewise.


Index: archive.cc
===================================================================
RCS file: /cvs/src/src/gold/archive.cc,v
retrieving revision 1.29
diff -u -p -r1.29 archive.cc
--- archive.cc	23 Apr 2008 17:29:04 -0000	1.29
+++ archive.cc	7 May 2008 05:56:28 -0000
@@ -326,7 +326,11 @@ Archive::add_symbols(Symbol_table* symta
 				  + this->armap_[i].name_offset);
 	  Symbol* sym = symtab->lookup(sym_name);
 	  if (sym == NULL)
-	    continue;
+	    {
+	      // Check whether the symbol was named in a -u option.
+	      if (!parameters->options().is_undefined(sym_name))
+		continue;
+	    }
 	  else if (!sym->is_undefined())
 	    {
               this->armap_checked_[i] = true;
Index: gold.cc
===================================================================
RCS file: /cvs/src/src/gold/gold.cc,v
retrieving revision 1.54
diff -u -p -r1.54 gold.cc
--- gold.cc	19 Apr 2008 18:30:58 -0000	1.54
+++ gold.cc	7 May 2008 05:56:28 -0000
@@ -212,6 +212,9 @@ queue_middle_tasks(const General_options
   // Define symbols from any linker scripts.
   layout->define_script_symbols(symtab);
 
+  // Add any symbols named with -u options to the symbol table.
+  symtab->add_undefined_symbols_from_command_line();
+
   // Attach sections to segments.
   layout->attach_sections_to_segments();
 
Index: options.h
===================================================================
RCS file: /cvs/src/src/gold/options.h,v
retrieving revision 1.76
diff -u -p -r1.76 options.h
--- options.h	6 May 2008 20:40:33 -0000	1.76
+++ options.h	7 May 2008 05:56:29 -0000
@@ -369,13 +369,22 @@ struct Struct_special : public Struct_va
   bool                                                                    \
   any_##varname__() const                                                 \
   { return !this->varname__##_.value.empty(); }                           \
+									  \
   bool                                                                    \
   is_##varname__(const char* symbol) const                                \
   {                                                                       \
     return (!this->varname__##_.value.empty()                             \
             && (this->varname__##_.value.find(std::string(symbol))        \
                 != this->varname__##_.value.end()));                      \
-  }
+  }									  \
+									  \
+  options::String_set::const_iterator					  \
+  varname__##_begin() const						  \
+  { return this->varname__##_.value.begin(); }				  \
+									  \
+  options::String_set::const_iterator					  \
+  varname__##_end() const						  \
+  { return this->varname__##_.value.end(); }
 
 // When you have a list of possible values (expressed as string)
 // After helparg__ should come an initializer list, like
@@ -652,6 +661,10 @@ class General_options
   DEFINE_bool(noinhibit_exec, options::TWO_DASHES, '\0', false,
 	      N_("Create an output file even if errors occur"), NULL);
 
+  DEFINE_bool_alias(no_undefined, defs, options::TWO_DASHES, '\0',
+		    N_("Report undefined symbols (even with --shared)"),
+		    NULL, false);
+
   DEFINE_string(output, options::TWO_DASHES, 'o', "a.out",
                 N_("Set output file name"), N_("FILE"));
 
@@ -733,10 +746,8 @@ class General_options
   DEFINE_uint64(Ttext, options::ONE_DASH, '\0', -1U,
                 N_("Set the address of the text segment"), N_("ADDRESS"));
 
-  DEFINE_bool_alias(undefined, defs, options::TWO_DASHES, '\0',
-		    "Allow undefined symbols with --shared",
-		    "Report undefined symbols (even with --shared)",
-		    true);
+  DEFINE_set(undefined, options::TWO_DASHES, 'u',
+	     N_("Create undefined reference to SYMBOL"), N_("SYMBOL"));
 
   DEFINE_bool(verbose, options::TWO_DASHES, '\0', false,
               N_("Synonym for --debug=files"), NULL);
Index: resolve.cc
===================================================================
RCS file: /cvs/src/src/gold/resolve.cc,v
retrieving revision 1.34
diff -u -p -r1.34 resolve.cc
--- resolve.cc	19 Apr 2008 18:30:58 -0000	1.34
+++ resolve.cc	7 May 2008 05:56:29 -0000
@@ -281,7 +281,10 @@ Symbol_table::should_override(const Symb
   *adjust_common_sizes = false;
 
   unsigned int tobits;
-  if (to->source() != Symbol::FROM_OBJECT)
+  if (to->source() == Symbol::IS_UNDEFINED)
+    tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_UNDEF, true,
+			    to->type());
+  else if (to->source() != Symbol::FROM_OBJECT)
     tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_ABS, false,
 			    to->type());
   else
@@ -662,7 +665,8 @@ Symbol::override_base_with_special(const
     case IN_OUTPUT_SEGMENT:
       this->u_.in_output_segment = from->u_.in_output_segment;
       break;
-    case CONSTANT:
+    case IS_CONSTANT:
+    case IS_UNDEFINED:
       break;
     default:
       gold_unreachable();
Index: symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.96
diff -u -p -r1.96 symtab.cc
--- symtab.cc	6 May 2008 22:24:26 -0000	1.96
+++ symtab.cc	7 May 2008 05:56:29 -0000
@@ -105,9 +105,9 @@ Symbol::demangled_name() const
 
 template<int size, bool big_endian>
 void
-Symbol::init_base(const char* name, const char* version, Object* object,
-		  const elfcpp::Sym<size, big_endian>& sym,
-		  unsigned int st_shndx, bool is_ordinary)
+Symbol::init_base_object(const char* name, const char* version, Object* object,
+			 const elfcpp::Sym<size, big_endian>& sym,
+			 unsigned int st_shndx, bool is_ordinary)
 {
   this->init_fields(name, version, sym.get_st_type(), sym.get_st_bind(),
 		    sym.get_st_visibility(), sym.get_st_nonvis());
@@ -123,9 +123,10 @@ Symbol::init_base(const char* name, cons
 // in an Output_data.
 
 void
-Symbol::init_base(const char* name, Output_data* od, elfcpp::STT type,
-		  elfcpp::STB binding, elfcpp::STV visibility,
-		  unsigned char nonvis, bool offset_is_from_end)
+Symbol::init_base_output_data(const char* name, Output_data* od,
+			      elfcpp::STT type, elfcpp::STB binding,
+			      elfcpp::STV visibility, unsigned char nonvis,
+			      bool offset_is_from_end)
 {
   this->init_fields(name, NULL, type, binding, visibility, nonvis);
   this->u_.in_output_data.output_data = od;
@@ -138,9 +139,10 @@ Symbol::init_base(const char* name, Outp
 // in an Output_segment.
 
 void
-Symbol::init_base(const char* name, Output_segment* os, elfcpp::STT type,
-		  elfcpp::STB binding, elfcpp::STV visibility,
-		  unsigned char nonvis, Segment_offset_base offset_base)
+Symbol::init_base_output_segment(const char* name, Output_segment* os,
+				 elfcpp::STT type, elfcpp::STB binding,
+				 elfcpp::STV visibility, unsigned char nonvis,
+				 Segment_offset_base offset_base)
 {
   this->init_fields(name, NULL, type, binding, visibility, nonvis);
   this->u_.in_output_segment.output_segment = os;
@@ -153,12 +155,25 @@ Symbol::init_base(const char* name, Outp
 // as a constant.
 
 void
-Symbol::init_base(const char* name, elfcpp::STT type,
-		  elfcpp::STB binding, elfcpp::STV visibility,
-		  unsigned char nonvis)
+Symbol::init_base_constant(const char* name, elfcpp::STT type,
+			   elfcpp::STB binding, elfcpp::STV visibility,
+			   unsigned char nonvis)
+{
+  this->init_fields(name, NULL, type, binding, visibility, nonvis);
+  this->source_ = IS_CONSTANT;
+  this->in_reg_ = true;
+}
+
+// Initialize the fields in the base class Symbol for an undefined
+// symbol.
+
+void
+Symbol::init_base_undefined(const char* name, elfcpp::STT type,
+			    elfcpp::STB binding, elfcpp::STV visibility,
+			    unsigned char nonvis)
 {
   this->init_fields(name, NULL, type, binding, visibility, nonvis);
-  this->source_ = CONSTANT;
+  this->source_ = IS_UNDEFINED;
   this->in_reg_ = true;
 }
 
@@ -178,11 +193,12 @@ Symbol::allocate_base_common(Output_data
 template<int size>
 template<bool big_endian>
 void
-Sized_symbol<size>::init(const char* name, const char* version, Object* object,
-			 const elfcpp::Sym<size, big_endian>& sym,
-			 unsigned int st_shndx, bool is_ordinary)
+Sized_symbol<size>::init_object(const char* name, const char* version,
+				Object* object,
+				const elfcpp::Sym<size, big_endian>& sym,
+				unsigned int st_shndx, bool is_ordinary)
 {
-  this->init_base(name, version, object, sym, st_shndx, is_ordinary);
+  this->init_base_object(name, version, object, sym, st_shndx, is_ordinary);
   this->value_ = sym.get_st_value();
   this->symsize_ = sym.get_st_size();
 }
@@ -192,14 +208,15 @@ Sized_symbol<size>::init(const char* nam
 
 template<int size>
 void
-Sized_symbol<size>::init(const char* name, Output_data* od,
-			 Value_type value, Size_type symsize,
-			 elfcpp::STT type, elfcpp::STB binding,
-			 elfcpp::STV visibility, unsigned char nonvis,
-			 bool offset_is_from_end)
+Sized_symbol<size>::init_output_data(const char* name, Output_data* od,
+				     Value_type value, Size_type symsize,
+				     elfcpp::STT type, elfcpp::STB binding,
+				     elfcpp::STV visibility,
+				     unsigned char nonvis,
+				     bool offset_is_from_end)
 {
-  this->init_base(name, od, type, binding, visibility, nonvis,
-		  offset_is_from_end);
+  this->init_base_output_data(name, od, type, binding, visibility, nonvis,
+			      offset_is_from_end);
   this->value_ = value;
   this->symsize_ = symsize;
 }
@@ -209,13 +226,15 @@ Sized_symbol<size>::init(const char* nam
 
 template<int size>
 void
-Sized_symbol<size>::init(const char* name, Output_segment* os,
-			 Value_type value, Size_type symsize,
-			 elfcpp::STT type, elfcpp::STB binding,
-			 elfcpp::STV visibility, unsigned char nonvis,
-			 Segment_offset_base offset_base)
+Sized_symbol<size>::init_output_segment(const char* name, Output_segment* os,
+					Value_type value, Size_type symsize,
+					elfcpp::STT type, elfcpp::STB binding,
+					elfcpp::STV visibility,
+					unsigned char nonvis,
+					Segment_offset_base offset_base)
 {
-  this->init_base(name, os, type, binding, visibility, nonvis, offset_base);
+  this->init_base_output_segment(name, os, type, binding, visibility, nonvis,
+				 offset_base);
   this->value_ = value;
   this->symsize_ = symsize;
 }
@@ -225,15 +244,29 @@ Sized_symbol<size>::init(const char* nam
 
 template<int size>
 void
-Sized_symbol<size>::init(const char* name, Value_type value, Size_type symsize,
-			 elfcpp::STT type, elfcpp::STB binding,
-			 elfcpp::STV visibility, unsigned char nonvis)
+Sized_symbol<size>::init_constant(const char* name, Value_type value,
+				  Size_type symsize, elfcpp::STT type,
+				  elfcpp::STB binding, elfcpp::STV visibility,
+				  unsigned char nonvis)
 {
-  this->init_base(name, type, binding, visibility, nonvis);
+  this->init_base_constant(name, type, binding, visibility, nonvis);
   this->value_ = value;
   this->symsize_ = symsize;
 }
 
+// Initialize the fields in Sized_symbol for an undefined symbol.
+
+template<int size>
+void
+Sized_symbol<size>::init_undefined(const char* name, elfcpp::STT type,
+				   elfcpp::STB binding, elfcpp::STV visibility,
+				   unsigned char nonvis)
+{
+  this->init_base_undefined(name, type, binding, visibility, nonvis);
+  this->value_ = 0;
+  this->symsize_ = 0;
+}
+
 // Allocate a common symbol.
 
 template<int size>
@@ -280,20 +313,25 @@ Symbol::final_value_is_known() const
   if (parameters->options().shared() || parameters->options().relocatable())
     return false;
 
-  // If the symbol is not from an object file, then it is defined, and
-  // known.
+  // If the symbol is not from an object file, and is not undefined,
+  // then it is defined, and known.
   if (this->source_ != FROM_OBJECT)
-    return true;
-
-  // If the symbol is from a dynamic object, then the final value is
-  // not known.
-  if (this->object()->is_dynamic())
-    return false;
+    {
+      if (this->source_ != IS_UNDEFINED)
+	return true;
+    }
+  else
+    {
+      // If the symbol is from a dynamic object, then the final value
+      // is not known.
+      if (this->object()->is_dynamic())
+	return false;
 
-  // If the symbol is not undefined (it is defined or common), then
-  // the final value is known.
-  if (!this->is_undefined())
-    return true;
+      // If the symbol is not undefined (it is defined or common),
+      // then the final value is known.
+      if (!this->is_undefined())
+	return true;
+    }
 
   // If the symbol is undefined, then whether the final value is known
   // depends on whether we are doing a static link.  If we are doing a
@@ -326,7 +364,8 @@ Symbol::output_section() const
       return this->u_.in_output_data.output_data->output_section();
 
     case IN_OUTPUT_SEGMENT:
-    case CONSTANT:
+    case IS_CONSTANT:
+    case IS_UNDEFINED:
       return NULL;
 
     default:
@@ -347,12 +386,13 @@ Symbol::set_output_section(Output_sectio
     case IN_OUTPUT_DATA:
       gold_assert(this->output_section() == os);
       break;
-    case CONSTANT:
+    case IS_CONSTANT:
       this->source_ = IN_OUTPUT_DATA;
       this->u_.in_output_data.output_data = os;
       this->u_.in_output_data.offset_is_from_end = false;
       break;
     case IN_OUTPUT_SEGMENT:
+    case IS_UNDEFINED:
     default:
       gold_unreachable();
     }
@@ -714,7 +754,7 @@ Symbol_table::add_from_object(Object* ob
 		}
 	    }
 
-	  ret->init(name, version, object, sym, st_shndx, is_ordinary);
+	  ret->init_object(name, version, object, sym, st_shndx, is_ordinary);
 
 	  ins.first->second = ret;
 	  if (def)
@@ -1332,8 +1372,8 @@ Symbol_table::do_define_in_output_data(
     return NULL;
 
   gold_assert(version == NULL || oldsym != NULL);
-  sym->init(name, od, value, symsize, type, binding, visibility, nonvis,
-	    offset_is_from_end);
+  sym->init_output_data(name, od, value, symsize, type, binding, visibility,
+			nonvis, offset_is_from_end);
 
   if (oldsym == NULL)
     {
@@ -1432,8 +1472,8 @@ Symbol_table::do_define_in_output_segmen
     return NULL;
 
   gold_assert(version == NULL || oldsym != NULL);
-  sym->init(name, os, value, symsize, type, binding, visibility, nonvis,
-	    offset_base);
+  sym->init_output_segment(name, os, value, symsize, type, binding,
+			   visibility, nonvis, offset_base);
 
   if (oldsym == NULL)
     {
@@ -1532,7 +1572,7 @@ Symbol_table::do_define_as_constant(
     return NULL;
 
   gold_assert(version == NULL || version == name || oldsym != NULL);
-  sym->init(name, value, symsize, type, binding, visibility, nonvis);
+  sym->init_constant(name, value, symsize, type, binding, visibility, nonvis);
 
   if (oldsym == NULL)
     {
@@ -1668,6 +1708,79 @@ Symbol_table::get_copy_source(const Symb
   return p->second;
 }
 
+// Add any undefined symbols named on the command line.
+
+void
+Symbol_table::add_undefined_symbols_from_command_line()
+{
+  if (parameters->options().any_undefined())
+    {
+      if (parameters->target().get_size() == 32)
+	{
+#if defined(HAVE_TARGET_32_LITTL) || defined(HAVE_TARGET_32_BIG)
+	  this->do_add_undefined_symbols_from_command_line<32>();
+#else
+	  gold_unreachable();
+#endif
+	}
+      else if (parameters->target().get_size() == 64)
+	{
+#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
+	  this->do_add_undefined_symbols_from_command_line<64>();
+#else
+	  gold_unreachable();
+#endif
+	}
+      else
+	gold_unreachable();
+    }
+}
+
+template<int size>
+void
+Symbol_table::do_add_undefined_symbols_from_command_line()
+{
+  for (options::String_set::const_iterator p =
+	 parameters->options().undefined_begin();
+       p != parameters->options().undefined_end();
+       ++p)
+    {
+      const char* name = p->c_str();
+
+      if (this->lookup(name) != NULL)
+	continue;
+
+      const char* version = NULL;
+
+      Sized_symbol<size>* sym;
+      Sized_symbol<size>* oldsym;
+      if (parameters->target().is_big_endian())
+	{
+#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
+	  sym = this->define_special_symbol<size, true>(&name, &version,
+							false, &oldsym);
+#else
+	  gold_unreachable();
+#endif
+	}
+      else
+	{
+#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
+	  sym = this->define_special_symbol<size, false>(&name, &version,
+							 false, &oldsym);
+#else
+	  gold_unreachable();
+#endif
+	}
+
+      gold_assert(oldsym == NULL);
+
+      sym->init_undefined(name, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
+			  elfcpp::STV_DEFAULT, 0);
+      ++this->saw_undefined_;
+    }
+}
+
 // Set the dynamic symbol indexes.  INDEX is the index of the first
 // global dynamic symbol.  Pointers to the symbols are stored into the
 // vector SYMS.  The names are added to DYNPOOL.  This returns an
@@ -1927,10 +2040,14 @@ Symbol_table::sized_finalize_symbol(Symb
       }
       break;
 
-    case Symbol::CONSTANT:
+    case Symbol::IS_CONSTANT:
       value = sym->value();
       break;
 
+    case Symbol::IS_UNDEFINED:
+      value = 0;
+      break;
+
     default:
       gold_unreachable();
     }
@@ -2123,10 +2240,14 @@ Symbol_table::sized_write_globals(const 
 	  shndx = elfcpp::SHN_ABS;
 	  break;
 
-	case Symbol::CONSTANT:
+	case Symbol::IS_CONSTANT:
 	  shndx = elfcpp::SHN_ABS;
 	  break;
 
+	case Symbol::IS_UNDEFINED:
+	  shndx = elfcpp::SHN_UNDEF;
+	  break;
+
 	default:
 	  gold_unreachable();
 	}
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gold/symtab.h,v
retrieving revision 1.76
diff -u -p -r1.76 symtab.h
--- symtab.h	6 May 2008 17:46:31 -0000	1.76
+++ symtab.h	7 May 2008 05:56:29 -0000
@@ -78,7 +78,9 @@ class Symbol
     // section.
     IN_OUTPUT_SEGMENT,
     // Symbol value is constant.
-    CONSTANT
+    IS_CONSTANT,
+    // Symbol is undefined.
+    IS_UNDEFINED
   };
 
   // When the source is IN_OUTPUT_SEGMENT, we need to describe what
@@ -390,7 +392,7 @@ class Symbol
   {
     bool is_ordinary;
     if (this->source_ != FROM_OBJECT)
-      return true;
+      return this->source_ != IS_UNDEFINED;
     unsigned int shndx = this->shndx(&is_ordinary);
     return (is_ordinary
 	    ? shndx != elfcpp::SHN_UNDEF
@@ -409,30 +411,26 @@ class Symbol
   is_undefined() const
   {
     bool is_ordinary;
-    return (this->source_ == FROM_OBJECT
-	    && this->shndx(&is_ordinary) == elfcpp::SHN_UNDEF
-	    && is_ordinary);
+    return ((this->source_ == FROM_OBJECT
+	     && this->shndx(&is_ordinary) == elfcpp::SHN_UNDEF
+	     && is_ordinary)
+	    || this->source_ == IS_UNDEFINED);
   }
 
   // Return whether this is a weak undefined symbol.
   bool
   is_weak_undefined() const
-  {
-    bool is_ordinary;
-    return (this->source_ == FROM_OBJECT
-            && this->binding() == elfcpp::STB_WEAK
-            && this->shndx(&is_ordinary) == elfcpp::SHN_UNDEF
-	    && is_ordinary);
-  }
+  { return this->is_undefined() && this->binding() == elfcpp::STB_WEAK; }
 
   // Return whether this is an absolute symbol.
   bool
   is_absolute() const
   {
     bool is_ordinary;
-    return (this->source_ == FROM_OBJECT
-	    && this->shndx(&is_ordinary) == elfcpp::SHN_ABS
-	    && !is_ordinary);
+    return ((this->source_ == FROM_OBJECT
+	     && this->shndx(&is_ordinary) == elfcpp::SHN_ABS
+	     && !is_ordinary)
+	    || this->source_ == IS_CONSTANT);
   }
 
   // Return whether this is a common symbol.
@@ -664,25 +662,32 @@ class Symbol
   // index rather than a special code.
   template<int size, bool big_endian>
   void
-  init_base(const char *name, const char* version, Object* object,
-	    const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
-	    bool is_ordinary);
+  init_base_object(const char *name, const char* version, Object* object,
+		   const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
+		   bool is_ordinary);
 
   // Initialize fields for an Output_data.
   void
-  init_base(const char* name, Output_data*, elfcpp::STT, elfcpp::STB,
-	    elfcpp::STV, unsigned char nonvis, bool offset_is_from_end);
+  init_base_output_data(const char* name, Output_data*, elfcpp::STT,
+			elfcpp::STB, elfcpp::STV, unsigned char nonvis,
+			bool offset_is_from_end);
 
   // Initialize fields for an Output_segment.
   void
-  init_base(const char* name, Output_segment* os, elfcpp::STT type,
-	    elfcpp::STB binding, elfcpp::STV visibility,
-	    unsigned char nonvis, Segment_offset_base offset_base);
+  init_base_output_segment(const char* name, Output_segment* os,
+			   elfcpp::STT type, elfcpp::STB binding,
+			   elfcpp::STV visibility, unsigned char nonvis,
+			   Segment_offset_base offset_base);
 
   // Initialize fields for a constant.
   void
-  init_base(const char* name, elfcpp::STT type, elfcpp::STB binding,
-	    elfcpp::STV visibility, unsigned char nonvis);
+  init_base_constant(const char* name, elfcpp::STT type, elfcpp::STB binding,
+		     elfcpp::STV visibility, unsigned char nonvis);
+
+  // Initialize fields for an undefined symbol.
+  void
+  init_base_undefined(const char* name, elfcpp::STT type, elfcpp::STB binding,
+		      elfcpp::STV visibility, unsigned char nonvis);
 
   // Override existing symbol.
   template<int size, bool big_endian>
@@ -838,26 +843,31 @@ class Sized_symbol : public Symbol
   // index rather than a special code.
   template<bool big_endian>
   void
-  init(const char *name, const char* version, Object* object,
-       const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
-       bool is_ordinary);
+  init_object(const char *name, const char* version, Object* object,
+	      const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
+	      bool is_ordinary);
 
   // Initialize fields for an Output_data.
   void
-  init(const char* name, Output_data*, Value_type value, Size_type symsize,
-       elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis,
-       bool offset_is_from_end);
+  init_output_data(const char* name, Output_data*, Value_type value,
+		   Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV,
+		   unsigned char nonvis, bool offset_is_from_end);
 
   // Initialize fields for an Output_segment.
   void
-  init(const char* name, Output_segment*, Value_type value, Size_type symsize,
-       elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis,
-       Segment_offset_base offset_base);
+  init_output_segment(const char* name, Output_segment*, Value_type value,
+		      Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV,
+		      unsigned char nonvis, Segment_offset_base offset_base);
 
   // Initialize fields for a constant.
   void
-  init(const char* name, Value_type value, Size_type symsize,
-       elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis);
+  init_constant(const char* name, Value_type value, Size_type symsize,
+		elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis);
+
+  // Initialize fields for an undefined symbol.
+  void
+  init_undefined(const char* name, elfcpp::STT, elfcpp::STB, elfcpp::STV,
+		 unsigned char nonvis);
 
   // Override existing symbol.
   template<bool big_endian>
@@ -1184,6 +1194,11 @@ class Symbol_table
   void
   detect_odr_violations(const Task*, const char* output_file_name) const;
 
+  // Add any undefined symbols named on the command line to the symbol
+  // table.
+  void
+  add_undefined_symbols_from_command_line();
+
   // SYM is defined using a COPY reloc.  Return the dynamic object
   // where the original definition was found.
   Dynobj*
@@ -1340,6 +1355,12 @@ class Symbol_table
     elfcpp::STV visibility, unsigned char nonvis,
     bool only_if_ref, bool force_override);
 
+  // Add any undefined symbols named on the command line to the symbol
+  // table, sized version.
+  template<int size>
+  void
+  do_add_undefined_symbols_from_command_line();
+
   // Allocate the common symbols, sized version.
   template<int size>
   void

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]