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]

gold patch committed: More support for -m option


Until now gold has been ignoring the -m option, which for GNU ld selects
the linker emulation.  PR 12934 reports that the Linux kernel build
relies on -m working, when using -m with -r and no real input files.
This patch implements support for -m along the lines of --oformat: each
target may specify the -m names which it matches.  This is not an exact
match of what GNU ld does, nor does it accept nearly all the names that
GNU ld accepts, but it is probably good enough for actual uses.
Committed to mainline.

Ian


2011-06-28  Ian Lance Taylor  <iant@google.com>

	PR gold/12934
	* target-select.cc (Target_selector::Target_selector): Add
	emulation parameter.  Change all callers.
	(select_target_by_bfd_name): Rename from select_target_by_name.
	Change all callers.
	(select_target_by_emulation): New function.
	(supported_emulation_names): New function.
	* target-select.h (class Target_selector): Add emulation_ field.
	Update declarations.
	(Target_selector::recognize_by_bfd_name): Rename from
	recognize_by_name.  Change all callers.
	(Target_selector::supported_bfd_names): Rename from
	supported_names.  Change all callers.
	(Target_selector::recognize_by_emulation): New function.
	(Target_selector::supported_emulations): New function.
	(Target_selector::emulation): New function.
	(Target_selector::do_recognize_by_bfd_name): Rename from
	do_recognize_by_name.  Change all callers.
	(Target_selector::do_supported_bfd_names): Rename from
	do_supported_names.  Change all callers.
	(Target_selector::do_recognize_by_emulation): New function.
	(Target_selector::do_supported_emulations): New function.
	(select_target_by_bfd_name): Change name in declaration.
	(select_target_by_emulation): Declare.
	(supported_emulation_names): Declare.
	* parameters.cc (parameters_force_valid_target): Try to find
	target based on emulation from -m option.
	* options.h (class General_options): Change doc string for -m.
	* options.cc (help): Print emulations.
	(General_options::parse_V): Likewise.
	* freebsd.h (Target_selector_freebsd::Target_selector_freebsd):
	Add emulation parameter.  Change all callers.


Index: arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.136
diff -u -p -r1.136 arm.cc
--- arm.cc	28 Jun 2011 21:15:42 -0000	1.136
+++ arm.cc	28 Jun 2011 23:04:43 -0000
@@ -11904,7 +11904,8 @@ class Target_selector_arm : public Targe
  public:
   Target_selector_arm()
     : Target_selector(elfcpp::EM_ARM, 32, big_endian,
-		      (big_endian ? "elf32-bigarm" : "elf32-littlearm"))
+		      (big_endian ? "elf32-bigarm" : "elf32-littlearm"),
+		      (big_endian ? "armelfb" : "armelf"))
   { }
 
   Target*
Index: freebsd.h
===================================================================
RCS file: /cvs/src/src/gold/freebsd.h,v
retrieving revision 1.5
diff -u -p -r1.5 freebsd.h
--- freebsd.h	28 Jun 2011 22:25:13 -0000	1.5
+++ freebsd.h	28 Jun 2011 23:04:43 -0000
@@ -38,8 +38,9 @@ class Target_selector_freebsd : public T
  public:
   Target_selector_freebsd(int machine, int size, bool is_big_endian,
 			  const char* bfd_name,
-			  const char* freebsd_bfd_name)
-    : Target_selector(machine, size, is_big_endian, NULL),
+			  const char* freebsd_bfd_name,
+			  const char* emulation)
+    : Target_selector(machine, size, is_big_endian, NULL, emulation),
       bfd_name_(bfd_name), freebsd_bfd_name_(freebsd_bfd_name)
   { }
 
@@ -57,7 +58,7 @@ class Target_selector_freebsd : public T
   
   // Recognize two names.
   virtual Target*
-  do_recognize_by_name(const char* name)
+  do_recognize_by_bfd_name(const char* name)
   {
     if (strcmp(name, this->bfd_name_) == 0)
       return this->instantiate_target();
@@ -73,7 +74,7 @@ class Target_selector_freebsd : public T
 
   // Print both names in --help output.
   virtual void
-  do_supported_names(std::vector<const char*>* names)
+  do_supported_bfd_names(std::vector<const char*>* names)
   {
     names->push_back(this->bfd_name_);
     names->push_back(this->freebsd_bfd_name_);
Index: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.130
diff -u -p -r1.130 i386.cc
--- i386.cc	28 Jun 2011 22:25:13 -0000	1.130
+++ i386.cc	28 Jun 2011 23:04:43 -0000
@@ -3284,7 +3284,8 @@ class Target_selector_i386 : public Targ
 public:
   Target_selector_i386()
     : Target_selector_freebsd(elfcpp::EM_386, 32, false,
-			      "elf32-i386", "elf32-i386-freebsd")
+			      "elf32-i386", "elf32-i386-freebsd",
+			      "elf_i386")
   { }
 
   Target*
Index: options.cc
===================================================================
RCS file: /cvs/src/src/gold/options.cc,v
retrieving revision 1.109
diff -u -p -r1.109 options.cc
--- options.cc	12 Apr 2011 00:44:48 -0000	1.109
+++ options.cc	28 Jun 2011 23:04:43 -0000
@@ -1,6 +1,6 @@
 // options.c -- handle command line options for gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -170,6 +170,15 @@ help()
     printf(" %s", *p);
   printf("\n");
 
+  printf(_("%s: supported emulations:"), gold::program_name);
+  supported_names.clear();
+  gold::supported_emulation_names(&supported_names);
+  for (std::vector<const char*>::const_iterator p = supported_names.begin();
+       p != supported_names.end();
+       ++p)
+    printf(" %s", *p);
+  printf("\n");
+
   // REPORT_BUGS_TO is defined in bfd/bfdver.h.
   const char* report = REPORT_BUGS_TO;
   if (*report != '\0')
@@ -300,6 +309,7 @@ General_options::parse_V(const char*, co
 {
   gold::print_version(true);
   this->printed_version_ = true;
+
   printf(_("  Supported targets:\n"));
   std::vector<const char*> supported_names;
   gold::supported_target_names(&supported_names);
@@ -307,6 +317,14 @@ General_options::parse_V(const char*, co
        p != supported_names.end();
        ++p)
     printf("   %s\n", *p);
+
+  printf(_("  Supported emulations:\n"));
+  supported_names.clear();
+  gold::supported_emulation_names(&supported_names);
+  for (std::vector<const char*>::const_iterator p = supported_names.begin();
+       p != supported_names.end();
+       ++p)
+    printf("   %s\n", *p);
 }
 
 void
Index: options.h
===================================================================
RCS file: /cvs/src/src/gold/options.h,v
retrieving revision 1.160
diff -u -p -r1.160 options.h
--- options.h	23 Jun 2011 00:46:13 -0000	1.160
+++ options.h	28 Jun 2011 23:04:43 -0000
@@ -835,7 +835,7 @@ class General_options
               NULL);
 
   DEFINE_string(m, options::EXACTLY_ONE_DASH, 'm', "",
-                N_("Ignored for compatibility"), N_("EMULATION"));
+                N_("Set GNU linker emulation; obsolete"), N_("EMULATION"));
 
   DEFINE_bool(print_map, options::TWO_DASHES, 'M', false,
 	      N_("Write map file on standard output"), NULL);
Index: parameters.cc
===================================================================
RCS file: /cvs/src/src/gold/parameters.cc,v
retrieving revision 1.35
diff -u -p -r1.35 parameters.cc
--- parameters.cc	25 May 2011 00:17:47 -0000	1.35
+++ parameters.cc	28 Jun 2011 23:04:43 -0000
@@ -1,6 +1,6 @@
 // parameters.cc -- general parameters for a link using gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -299,15 +299,28 @@ parameters_force_valid_target()
   gold_assert(parameters->options_valid());
   if (parameters->options().user_set_oformat())
     {
-      Target* target = select_target_by_name(parameters->options().oformat());
+      const char* bfd_name = parameters->options().oformat();
+      Target* target = select_target_by_bfd_name(bfd_name);
       if (target != NULL)
 	{
 	  set_parameters_target(target);
 	  return;
 	}
 
-      gold_error(_("unrecognized output format %s"),
-                 parameters->options().oformat());
+      gold_error(_("unrecognized output format %s"), bfd_name);
+    }
+
+  if (parameters->options().user_set_m())
+    {
+      const char* emulation = parameters->options().m();
+      Target* target = select_target_by_emulation(emulation);
+      if (target != NULL)
+	{
+	  set_parameters_target(target);
+	  return;
+	}
+
+      gold_error(_("unrecognized emulation %s"), emulation);
     }
 
   // The GOLD_DEFAULT_xx macros are defined by the configure script.
Index: powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.38
diff -u -p -r1.38 powerpc.cc
--- powerpc.cc	28 Jun 2011 21:15:42 -0000	1.38
+++ powerpc.cc	28 Jun 2011 23:04:43 -0000
@@ -2124,9 +2124,12 @@ class Target_selector_powerpc : public T
 public:
   Target_selector_powerpc()
     : Target_selector(elfcpp::EM_NONE, size, big_endian,
-		      (size == 64 ?
-		       (big_endian ? "elf64-powerpc" : "elf64-powerpcle") :
-		       (big_endian ? "elf32-powerpc" : "elf32-powerpcle")))
+		      (size == 64
+		       ? (big_endian ? "elf64-powerpc" : "elf64-powerpcle")
+		       : (big_endian ? "elf32-powerpc" : "elf32-powerpcle")),
+		      (size == 64
+		       ? (big_endian ? "elf64ppc" : "elf64lppc")
+		       : (big_endian ? "elf32ppc" : "elf32lppc")))
   { }
 
   Target* do_recognize(int machine, int, int)
Index: script.cc
===================================================================
RCS file: /cvs/src/src/gold/script.cc,v
retrieving revision 1.82
diff -u -p -r1.82 script.cc
--- script.cc	12 Apr 2011 00:44:48 -0000	1.82
+++ script.cc	28 Jun 2011 23:04:43 -0000
@@ -1,6 +1,6 @@
 // script.cc -- handle linker scripts for gold.
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -2804,7 +2804,7 @@ script_check_output_format(void* closure
 {
   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
   std::string name(default_name, default_length);
-  Target* target = select_target_by_name(name.c_str());
+  Target* target = select_target_by_bfd_name(name.c_str());
   if (target == NULL || !parameters->is_compatible_target(target))
     {
       if (closure->skip_on_incompatible_target())
Index: sparc.cc
===================================================================
RCS file: /cvs/src/src/gold/sparc.cc,v
retrieving revision 1.47
diff -u -p -r1.47 sparc.cc
--- sparc.cc	28 Jun 2011 21:15:42 -0000	1.47
+++ sparc.cc	28 Jun 2011 23:04:43 -0000
@@ -3481,7 +3481,8 @@ class Target_selector_sparc : public Tar
 public:
   Target_selector_sparc()
     : Target_selector(elfcpp::EM_NONE, size, big_endian,
-		      (size == 64 ? "elf64-sparc" : "elf32-sparc"))
+		      (size == 64 ? "elf64-sparc" : "elf32-sparc"),
+		      (size == 64 ? "elf64_sparc" : "elf32_sparc"))
   { }
 
   Target* do_recognize(int machine, int, int)
Index: target-select.cc
===================================================================
RCS file: /cvs/src/src/gold/target-select.cc,v
retrieving revision 1.13
diff -u -p -r1.13 target-select.cc
--- target-select.cc	12 Feb 2010 03:23:26 -0000	1.13
+++ target-select.cc	28 Jun 2011 23:04:43 -0000
@@ -1,6 +1,6 @@
 // target-select.cc -- select a target for an object file
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -52,9 +52,10 @@ Set_target_once::do_run_once(void*)
 // fast.
 
 Target_selector::Target_selector(int machine, int size, bool is_big_endian,
-				 const char* bfd_name)
+				 const char* bfd_name, const char* emulation)
   : machine_(machine), size_(size), is_big_endian_(is_big_endian),
-    bfd_name_(bfd_name), instantiated_target_(NULL), set_target_once_(this)
+    bfd_name_(bfd_name), emulation_(emulation), instantiated_target_(NULL),
+    set_target_once_(this)
 {
   this->next_ = target_selectors;
   target_selectors = this;
@@ -104,14 +105,33 @@ select_target(int machine, int size, boo
 // --oformat option.
 
 Target*
-select_target_by_name(const char* name)
+select_target_by_bfd_name(const char* name)
 {
   for (Target_selector* p = target_selectors; p != NULL; p = p->next())
     {
       const char* pname = p->bfd_name();
       if (pname == NULL || strcmp(pname, name) == 0)
 	{
-	  Target* ret = p->recognize_by_name(name);
+	  Target* ret = p->recognize_by_bfd_name(name);
+	  if (ret != NULL)
+	    return ret;
+	}
+    }
+  return NULL;
+}
+
+// Find a target using a GNU linker emulation.  This is used to
+// support the -m option.
+
+Target*
+select_target_by_emulation(const char* name)
+{
+  for (Target_selector* p = target_selectors; p != NULL; p = p->next())
+    {
+      const char* pname = p->emulation();
+      if (pname == NULL || strcmp(pname, name) == 0)
+	{
+	  Target* ret = p->recognize_by_emulation(name);
 	  if (ret != NULL)
 	    return ret;
 	}
@@ -125,7 +145,16 @@ void
 supported_target_names(std::vector<const char*>* names)
 {
   for (Target_selector* p = target_selectors; p != NULL; p = p->next())
-    p->supported_names(names);
+    p->supported_bfd_names(names);
+}
+
+// Push all the supported emulations onto a vector.
+
+void
+supported_emulation_names(std::vector<const char*>* names)
+{
+  for (Target_selector* p = target_selectors; p != NULL; p = p->next())
+    p->supported_emulations(names);
 }
 
 } // End namespace gold.
Index: target-select.h
===================================================================
RCS file: /cvs/src/src/gold/target-select.h,v
retrieving revision 1.12
diff -u -p -r1.12 target-select.h
--- target-select.h	12 Feb 2010 03:23:26 -0000	1.12
+++ target-select.h	28 Jun 2011 23:04:43 -0000
@@ -1,6 +1,6 @@
 // target-select.h -- select a target for an object file  -*- C++ -*-
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -65,9 +65,10 @@ class Target_selector
   // or 64), and endianness.  The machine number can be EM_NONE to
   // test for any machine number.  BFD_NAME is the name of the target
   // used by the GNU linker, for backward compatibility; it may be
-  // NULL.
+  // NULL.  EMULATION is the name of the emulation used by the GNU
+  // linker; it is similar to BFD_NAME.
   Target_selector(int machine, int size, bool is_big_endian,
-		  const char* bfd_name);
+		  const char* bfd_name, const char* emulation);
 
   virtual ~Target_selector()
   { }
@@ -81,14 +82,26 @@ class Target_selector
   // If NAME matches the target, return a pointer to a target
   // structure.
   Target*
-  recognize_by_name(const char* name)
-  { return this->do_recognize_by_name(name); }
+  recognize_by_bfd_name(const char* name)
+  { return this->do_recognize_by_bfd_name(name); }
 
-  // Push all supported names onto the vector.  This is only used for
-  // help output.
+  // Push all supported BFD names onto the vector.  This is only used
+  // for help output.
   void
-  supported_names(std::vector<const char*>* names)
-  { this->do_supported_names(names); }
+  supported_bfd_names(std::vector<const char*>* names)
+  { this->do_supported_bfd_names(names); }
+
+  // If NAME matches the target emulation, return a pointer to a
+  // target structure.
+  Target*
+  recognize_by_emulation(const char* name)
+  { return this->do_recognize_by_emulation(name); }
+
+  // Push all supported emulations onto the vector.  This is only used
+  // for help output.
+  void
+  supported_emulations(std::vector<const char*>* names)
+  { this->do_supported_emulations(names); }
 
   // Return the next Target_selector in the linked list.
   Target_selector*
@@ -114,12 +127,19 @@ class Target_selector
   { return this->is_big_endian_; }
 
   // Return the BFD name.  This may return NULL, in which case the
-  // do_recognize_by_name hook will be responsible for matching the
-  // BFD name.
+  // do_recognize_by_bfd_name hook will be responsible for matching
+  // the BFD name.
   const char*
   bfd_name() const
   { return this->bfd_name_; }
 
+  // Return the emulation.  This may return NULL, in which case the
+  // do_recognize_by_emulation hook will be responsible for matching
+  // the emulation.
+  const char*
+  emulation() const
+  { return this->emulation_; }
+
  protected:
   // Return an instance of the real target.  This must be implemented
   // by the child class.
@@ -141,19 +161,37 @@ class Target_selector
   // child class may implement a different version of this to
   // recognize more than one name.
   virtual Target*
-  do_recognize_by_name(const char*)
+  do_recognize_by_bfd_name(const char*)
   { return this->instantiate_target(); }
 
   // Return a list of supported BFD names.  The child class may
   // implement a different version of this to handle more than one
   // name.
   virtual void
-  do_supported_names(std::vector<const char*>* names)
+  do_supported_bfd_names(std::vector<const char*>* names)
   {
     gold_assert(this->bfd_name_ != NULL);
     names->push_back(this->bfd_name_);
   }
 
+  // Recognize a target by emulation.  When this is called we already
+  // know that the name matches (or that the emulation_ field is
+  // NULL).  The child class may implement a different version of this
+  // to recognize more than one emulation.
+  virtual Target*
+  do_recognize_by_emulation(const char*)
+  { return this->instantiate_target(); }
+
+  // Return a list of supported emulations.  The child class may
+  // implement a different version of this to handle more than one
+  // emulation.
+  virtual void
+  do_supported_emulations(std::vector<const char*>* emulations)
+  {
+    gold_assert(this->emulation_ != NULL);
+    emulations->push_back(this->emulation_);
+  }
+
   // Instantiate the target and return it.
   Target*
   instantiate_target();
@@ -173,6 +211,8 @@ class Target_selector
   const bool is_big_endian_;
   // BFD name of target, for compatibility.
   const char* const bfd_name_;
+  // GNU linker emulation for this target, for compatibility.
+  const char* const emulation_;
   // Next entry in list built at global constructor time.
   Target_selector* next_;
   // The singleton Target structure--this points to an instance of the
@@ -191,7 +231,12 @@ select_target(int machine, int size, boo
 // Select a target using a BFD name.
 
 extern Target*
-select_target_by_name(const char* name);
+select_target_by_bfd_name(const char* name);
+
+// Select a target using a GNU linker emulation.
+
+extern Target*
+select_target_by_emulation(const char* name);
 
 // Fill in a vector with the list of supported targets.  This returns
 // a list of BFD names.
@@ -199,6 +244,11 @@ select_target_by_name(const char* name);
 extern void
 supported_target_names(std::vector<const char*>*);
 
+// Fill in a vector with the list of supported emulations.
+
+extern void
+supported_emulation_names(std::vector<const char*>*);
+
 } // End namespace gold.
 
 #endif // !defined(GOLD_TARGET_SELECT_H)
Index: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.129
diff -u -p -r1.129 x86_64.cc
--- x86_64.cc	28 Jun 2011 22:25:14 -0000	1.129
+++ x86_64.cc	28 Jun 2011 23:04:43 -0000
@@ -3648,7 +3648,7 @@ class Target_selector_x86_64 : public Ta
 public:
   Target_selector_x86_64()
     : Target_selector_freebsd(elfcpp::EM_X86_64, 64, false, "elf64-x86-64",
-			      "elf64-x86-64-freebsd")
+			      "elf64-x86-64-freebsd", "elf_x86_64")
   { }
 
   Target*
Index: testsuite/testfile.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/testfile.cc,v
retrieving revision 1.20
diff -u -p -r1.20 testfile.cc
--- testsuite/testfile.cc	28 Jun 2011 21:15:42 -0000	1.20
+++ testsuite/testfile.cc	28 Jun 2011 23:04:43 -0000
@@ -151,7 +151,7 @@ class Target_selector_test : public Targ
 {
  public:
   Target_selector_test()
-    : Target_selector(0xffff, size, big_endian, NULL)
+    : Target_selector(0xffff, size, big_endian, NULL, NULL)
   { }
 
   Target*

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