This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gold patch committed: Handle odd section symbols with -r
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Fri, 27 Feb 2009 16:15:00 -0800
- Subject: gold patch committed: Handle odd section symbols with -r
The last case in PR 7091 is about a section symbol for a SHT_REL section
when linking with -r. Such a case can not be generated by current
versions of gas. However, they are valid ELF. gold was crashing trying
to determine the value to use for such a section symbol. In fact gold
will never emit the section symbol, and it would be bizarre in the
extreme if a relocation entry referenced the symbol. However, there is
no need to crash. I committed this patch to fall back to using the
start of the output section as the address for such a section symbol.
This is not really right, but then nothing is really right if anything
actually needs the value of the symbol.
Ian
2009-02-27 Ian Lance Taylor <iant@google.com>
PR 7091
* output.cc (Output_section::find_starting_output_address): Rename
from starting_output_address; add PADDR parameter; change return
type.
* output.h (class Output_section): Declare
find_starting_output_address instead of starting_output_address.
* object.cc (Sized_relobj::do_finalize_local_symbols): Handle a
section symbol for which we can't find a merge section.
Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.84
diff -p -u -r1.84 object.cc
--- object.cc 13 Feb 2009 19:04:44 -0000 1.84
+++ object.cc 28 Feb 2009 00:02:32 -0000
@@ -1554,20 +1554,31 @@ Sized_relobj<size, big_endian>::do_final
}
else if (out_offsets[shndx] == invalid_address)
{
+ uint64_t start;
+
// This is a SHF_MERGE section or one which otherwise
- // requires special handling. We get the output address
- // of the start of the merged section. If this is not a
- // section symbol, we can then determine the final
- // value. If it is a section symbol, we can not, as in
- // that case we have to consider the addend to determine
- // the value to use in a relocation.
+ // requires special handling.
if (!lv.is_section_symbol())
- lv.set_output_value(os->output_address(this, shndx,
- lv.input_value()));
+ {
+ // This is not a section symbol. We can determine
+ // the final value now.
+ lv.set_output_value(os->output_address(this, shndx,
+ lv.input_value()));
+ }
+ else if (!os->find_starting_output_address(this, shndx, &start))
+ {
+ // This is a section symbol, but apparently not one
+ // in a merged section. Just use the start of the
+ // output section. This happens with relocatable
+ // links when the input object has section symbols
+ // for arbitrary non-merge sections.
+ lv.set_output_value(os->address());
+ }
else
{
- section_offset_type start =
- os->starting_output_address(this, shndx);
+ // We have to consider the addend to determine the
+ // value to use in a relocation. START is the start
+ // of this input section.
Merged_symbol_value<size>* msv =
new Merged_symbol_value<size>(lv.input_value(), start);
lv.set_merged_symbol_value(msv);
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.85
diff -p -u -r1.85 output.cc
--- output.cc 15 Jan 2009 02:18:11 -0000 1.85
+++ output.cc 28 Feb 2009 00:02:33 -0000
@@ -1,6 +1,6 @@
// output.cc -- manage the output file for gold
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -2057,12 +2057,13 @@ Output_section::output_address(const Rel
gold_unreachable();
}
-// Return the output address of the start of the merged section for
+// Find the output address of the start of the merged section for
// input section SHNDX in object OBJECT.
-uint64_t
-Output_section::starting_output_address(const Relobj* object,
- unsigned int shndx) const
+bool
+Output_section::find_starting_output_address(const Relobj* object,
+ unsigned int shndx,
+ uint64_t* paddr) const
{
uint64_t addr = this->address() + this->first_input_offset_;
for (Input_section_list::const_iterator p = this->input_sections_.begin();
@@ -2076,11 +2077,16 @@ Output_section::starting_output_address(
// Unfortunately we don't know for sure that input offset 0 is
// mapped at all.
if (p->is_merge_section_for(object, shndx))
- return addr;
+ {
+ *paddr = addr;
+ return true;
+ }
addr += p->data_size();
}
- gold_unreachable();
+
+ // We couldn't find a merge output section for this input section.
+ return false;
}
// Set the data size of an Output_section. This is where we handle
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.76
diff -p -u -r1.76 output.h
--- output.h 29 Sep 2008 21:10:26 -0000 1.76
+++ output.h 28 Feb 2009 00:02:33 -0000
@@ -1,6 +1,6 @@
// output.h -- manage the output file for gold -*- C++ -*-
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -2260,12 +2260,14 @@ class Output_section : public Output_dat
output_address(const Relobj* object, unsigned int shndx,
off_t offset) const;
- // Return the output address of the start of the merged section for
- // input section SHNDX in object OBJECT. This is not necessarily
- // the offset corresponding to input offset 0 in the section, since
- // the section may be mapped arbitrarily.
- uint64_t
- starting_output_address(const Relobj* object, unsigned int shndx) const;
+ // Look for the merged section for input section SHNDX in object
+ // OBJECT. If found, return true, and set *ADDR to the address of
+ // the start of the merged section. This is not necessary the
+ // output offset corresponding to input offset 0 in the section,
+ // since the section may be mapped arbitrarily.
+ bool
+ find_starting_output_address(const Relobj* object, unsigned int shndx,
+ uint64_t* addr) const;
// Record that this output section was found in the SECTIONS clause
// of a linker script.