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] Adjust specified address to include headers


If the user specifies the address of a section via --section-start, and
that section then sets the address of the first load segment, gold was
deliberately not including the file and program headers in that segment.
PR 11712 complains about this rather odd case.  This patch changes gold
to include the headers if possible.  Committed to mainline.

Ian


2010-08-03  Ian Lance Taylor  <iant@google.com>

	PR 11712
	* layout.cc (relaxation_loop_body): If address of load segment is
	set, adjust address to include headers if possible.


Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.173
diff -p -u -r1.173 layout.cc
--- layout.cc	3 Aug 2010 14:07:13 -0000	1.173
+++ layout.cc	3 Aug 2010 15:02:49 -0000
@@ -1655,17 +1655,41 @@ Layout::relaxation_loop_body(
 	      || 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.
+  // --section-start rather than by a script, then adjust the VMA and
+  // LMA downward if possible to include the file and section headers.
+  uint64_t header_gap = 0;
   if (load_seg != NULL
       && load_seg->are_addresses_set()
-      && !this->script_options_->saw_sections_clause())
-    load_seg = NULL;
+      && !this->script_options_->saw_sections_clause()
+      && !parameters->options().relocatable())
+    {
+      file_header->finalize_data_size();
+      segment_headers->finalize_data_size();
+      size_t sizeof_headers = (file_header->data_size()
+			       + segment_headers->data_size());
+      const uint64_t abi_pagesize = target->abi_pagesize();
+      uint64_t hdr_paddr = load_seg->paddr() - sizeof_headers;
+      hdr_paddr &= ~(abi_pagesize - 1);
+      uint64_t subtract = load_seg->paddr() - hdr_paddr;
+      if (load_seg->paddr() < subtract || load_seg->vaddr() < subtract)
+	load_seg = NULL;
+      else
+	{
+	  load_seg->set_addresses(load_seg->vaddr() - subtract,
+				  load_seg->paddr() - subtract);
+	  header_gap = subtract - sizeof_headers;
+	}
+    }
 
   // Lay out the segment headers.
   if (!parameters->options().relocatable())
     {
       gold_assert(segment_headers != NULL);
+      if (header_gap != 0 && load_seg != NULL)
+	{
+	  Output_data_zero_fill* z = new Output_data_zero_fill(header_gap, 1);
+	  load_seg->add_initial_output_data(z);
+	}
       if (load_seg != NULL)
         load_seg->add_initial_output_data(segment_headers);
       if (phdr_seg != NULL)

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