From: Ian Lance Taylor Date: Sat, 28 Feb 2009 00:12:26 +0000 (+0000) Subject: PR 7091 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e29e076ab80ed58ab0343c9910e02df7220233f8;p=binutils-gdb.git 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. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index 51592553312..5c0f9c39e4a 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,14 @@ 2009-02-27 Ian Lance Taylor + 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. + PR 9836 * symtab.cc (Symbol_table::add_from_object): If the visibility is hidden or internal, force the symbol to be local. diff --git a/gold/object.cc b/gold/object.cc index 76858021bcd..82c5dd6e30d 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1554,20 +1554,31 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, } 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* msv = new Merged_symbol_value(lv.input_value(), start); lv.set_merged_symbol_value(msv); diff --git a/gold/output.cc b/gold/output.cc index 0f45ca14426..f2ec6ee906e 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -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 . // This file is part of gold. @@ -2057,12 +2057,13 @@ Output_section::output_address(const Relobj* object, unsigned int shndx, 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(const Relobj* object, // 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 diff --git a/gold/output.h b/gold/output.h index 9f075bec464..6c37dfd0191 100644 --- a/gold/output.h +++ b/gold/output.h @@ -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 . // This file is part of gold. @@ -2260,12 +2260,14 @@ class Output_section : public Output_data 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.