This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[gold patch committed] Adjust specified address to include headers
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Tue, 03 Aug 2010 08:06:18 -0700
- Subject: [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)