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: Add --section-start


I committed this patch to gold to add the --section-start option.

Ian


2010-01-06  Ian Lance Taylor  <iant@google.com>

	PR 10980
	* options.cc (General_options::parse_section_start): New function.
	(General_options::section_start): New function.
	(General_options::General_options): Initialize all members.
	* options.h: Include <map>
	(class General_options): Add --section-start.  Add section_starts_
	member.
	* layout.cc (Layout::attach_allocated_section_to_segment): If
	--section-start was used, set the address of the segment.  Remove
	local sort_sections.
	(Layout::relaxation_loop_body): If the address of the load segment
	has been set by --section-start, don't use it.
	* output.h (Output_segment::update_flags_for_output_section): New
	function.
	* output.cc (Output_segment::add_output_section): Call
	update_flags_for_output_section.


Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.155
diff -p -u -r1.155 layout.cc
--- layout.cc	31 Dec 2009 05:43:29 -0000	1.155
+++ layout.cc	6 Jan 2010 22:34:06 -0000
@@ -1025,7 +1025,9 @@ Layout::attach_allocated_section_to_segm
 
   elfcpp::Elf_Word seg_flags = Layout::section_flags_to_segment(flags);
 
-  bool sort_sections = !this->script_options_->saw_sections_clause();
+  // Check for --section-start.
+  uint64_t addr;
+  bool is_address_set = parameters->options().section_start(os->name(), &addr);
 
   // In general the only thing we really care about for PT_LOAD
   // segments is whether or not they are writable, so that is how we
@@ -1054,7 +1056,18 @@ Layout::attach_allocated_section_to_segm
       if (os->is_large_data_section() && !(*p)->is_large_data_segment())
 	continue;
 
-      (*p)->add_output_section(os, seg_flags, sort_sections);
+      if (is_address_set)
+	{
+	  if ((*p)->are_addresses_set())
+	    continue;
+
+	  (*p)->add_initial_output_data(os);
+	  (*p)->update_flags_for_output_section(seg_flags);
+	  (*p)->set_addresses(addr, addr);
+	  break;
+	}
+
+      (*p)->add_output_section(os, seg_flags, true);
       break;
     }
 
@@ -1064,7 +1077,9 @@ Layout::attach_allocated_section_to_segm
                                                        seg_flags);
       if (os->is_large_data_section())
 	oseg->set_is_large_data_segment();
-      oseg->add_output_section(os, seg_flags, sort_sections);
+      oseg->add_output_section(os, seg_flags, true);
+      if (is_address_set)
+	oseg->set_addresses(addr, addr);
     }
 
   // If we see a loadable SHT_NOTE section, we create a PT_NOTE
@@ -1492,6 +1507,14 @@ Layout::relaxation_loop_body(
 	      || load_seg != NULL
 	      || this->script_options_->saw_sections_clause());
 
+  // If the address of the load segment we found has been set by
+  // --section-start rather than by a script, then we don't want to
+  // use it for the file and segment headers.
+  if (load_seg != NULL
+      && load_seg->are_addresses_set()
+      && !this->script_options_->saw_sections_clause())
+    load_seg = NULL;
+
   // Lay out the segment headers.
   if (!parameters->options().relocatable())
     {
Index: options.cc
===================================================================
RCS file: /cvs/src/src/gold/options.cc,v
retrieving revision 1.97
diff -p -u -r1.97 options.cc
--- options.cc	30 Dec 2009 22:35:48 -0000	1.97
+++ options.cc	6 Jan 2010 22:34:06 -0000
@@ -398,6 +398,63 @@ General_options::parse_just_symbols(cons
   cmdline->inputs().add_file(file);
 }
 
+// Handle --section-start.
+
+void
+General_options::parse_section_start(const char*, const char* arg,
+				     Command_line*)
+{
+  const char* eq = strchr(arg, '=');
+  if (eq == NULL)
+    {
+      gold_error(_("invalid argument to --section-start; "
+		   "must be SECTION=ADDRESS"));
+      return;
+    }
+
+  std::string section_name(arg, eq - arg);
+
+  ++eq;
+  const char* val_start = eq;
+  if (eq[0] == '0' && (eq[1] == 'x' || eq[1] == 'X'))
+    eq += 2;
+  if (*eq == '\0')
+    {
+      gold_error(_("--section-start address missing"));
+      return;
+    }
+  uint64_t addr = 0;
+  hex_init();
+  for (; *eq != '\0'; ++eq)
+    {
+      if (!hex_p(*eq))
+	{
+	  gold_error(_("--section-start argument %s is not a valid hex number"),
+		     val_start);
+	  return;
+	}
+      addr <<= 4;
+      addr += hex_value(*eq);
+    }
+
+  this->section_starts_[section_name] = addr;
+}
+
+// Look up a --section-start value.
+
+bool
+General_options::section_start(const char* secname, uint64_t* paddr) const
+{
+  if (this->section_starts_.empty())
+    return false;
+  std::map<std::string, uint64_t>::const_iterator p =
+    this->section_starts_.find(secname);
+  if (p == this->section_starts_.end())
+    return false;
+  *paddr = p->second;
+  return true;
+}
+
 void
 General_options::parse_static(const char*, const char*, Command_line*)
 {
@@ -749,9 +806,17 @@ namespace gold
 
 General_options::General_options()
   : printed_version_(false),
-    execstack_status_(General_options::EXECSTACK_FROM_INPUT), static_(false),
-    do_demangle_(false), plugins_(),
-    incremental_disposition_(INCREMENTAL_CHECK), implicit_incremental_(false)
+    execstack_status_(EXECSTACK_FROM_INPUT),
+    icf_status_(ICF_NONE),
+    static_(false),
+    do_demangle_(false),
+    plugins_(NULL),
+    dynamic_list_(),
+    incremental_disposition_(INCREMENTAL_CHECK),
+    implicit_incremental_(false),
+    excluded_libs_(),
+    symbols_to_retain_(),
+    section_starts_()
 {
   // Turn off option registration once construction is complete.
   gold::options::ready_to_register = false;
Index: options.h
===================================================================
RCS file: /cvs/src/src/gold/options.h,v
retrieving revision 1.131
diff -p -u -r1.131 options.h
--- options.h	6 Jan 2010 05:30:24 -0000	1.131
+++ options.h	6 Jan 2010 22:34:06 -0000
@@ -39,6 +39,7 @@
 #include <cstdlib>
 #include <cstring>
 #include <list>
+#include <map>
 #include <string>
 #include <vector>
 
@@ -845,6 +846,9 @@ class General_options
                  N_("Add DIR to link time shared library search path"),
                  N_("DIR"));
 
+  DEFINE_special(section_start, options::TWO_DASHES, '\0',
+		 N_("Set address of section"), N_("SECTION=ADDRESS"));
+
   DEFINE_optional_string(sort_common, options::TWO_DASHES, '\0', NULL,
 			 N_("Sort common symbols by alignment"),
 			 N_("[={ascending,descending}]"));
@@ -1174,6 +1178,12 @@ class General_options
   bool
   check_excluded_libs (const std::string &s) const;
 
+  // If an explicit start address was given for section SECNAME with
+  // the --section-start option, return true and set *PADDR to the
+  // address.  Otherwise return false.
+  bool
+  section_start(const char* secname, uint64_t* paddr) const;
+
  private:
   // Don't copy this structure.
   General_options(const General_options&);
@@ -1261,6 +1271,8 @@ class General_options
   Unordered_set<std::string> excluded_libs_;
   // List of symbol-names to keep, via -retain-symbol-info.
   Unordered_set<std::string> symbols_to_retain_;
+  // Map from section name to address from --section-start.
+  std::map<std::string, uint64_t> section_starts_;
 };
 
 // The position-dependent options.  We use this to store the state of
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.111
diff -p -u -r1.111 output.cc
--- output.cc	30 Dec 2009 19:29:20 -0000	1.111
+++ output.cc	6 Jan 2010 22:34:06 -0000
@@ -3081,11 +3081,7 @@ Output_segment::add_output_section(Outpu
   gold_assert(os->is_large_data_section() == this->is_large_data_segment());
   gold_assert(this->type() == elfcpp::PT_LOAD || !do_sort);
 
-  // Update the segment flags.  The ELF ABI specifies that a PT_TLS
-  // segment should always have PF_R as the flags, regardless of the
-  // associated sections.
-  if (this->type() != elfcpp::PT_TLS)
-    this->flags_ |= seg_flags;
+  this->update_flags_for_output_section(seg_flags);
 
   Output_segment::Output_data_list* pdl;
   if (os->type() == elfcpp::SHT_NOBITS)
@@ -3363,8 +3359,8 @@ Output_segment::remove_output_section(Ou
   gold_unreachable();
 }
 
-// Add an Output_data (which is not an Output_section) to the start of
-// a segment.
+// Add an Output_data (which need not be an Output_section) to the
+// start of a segment.
 
 void
 Output_segment::add_initial_output_data(Output_data* od)
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.93
diff -p -u -r1.93 output.h
--- output.h	30 Dec 2009 06:57:17 -0000	1.93
+++ output.h	6 Jan 2010 22:34:06 -0000
@@ -3483,8 +3483,8 @@ class Output_segment
   void
   remove_output_section(Output_section* os);
 
-  // Add an Output_data (which is not an Output_section) to the start
-  // of this segment.
+  // Add an Output_data (which need not be an Output_section) to the
+  // start of this segment.
   void
   add_initial_output_data(Output_data*);
 
@@ -3516,6 +3516,17 @@ class Output_segment
     this->are_addresses_set_ = true;
   }
 
+  // Update the flags for the flags of an output section added to this
+  // segment.
+  void
+  update_flags_for_output_section(elfcpp::Elf_Xword flags)
+  {
+    // The ELF ABI specifies that a PT_TLS segment should always have
+    // PF_R as the flags.
+    if (this->type() != elfcpp::PT_TLS)
+      this->flags_ |= flags;
+  }
+
   // Set the segment flags.  This is only used if we have a PHDRS
   // clause which explicitly specifies the flags.
   void

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