mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
2010-01-26 Doug Kwan <dougkwan@google.com>
* arm.cc (set): Include. (class Arm_exidx_fixup): Change type of last_input_section_ to const pointer type. (Arm_output_section::Text_section_list): New type. (Arm_output_section::append_text_sections_to_list): New method. (Arm_output_section::fix_exidx_coverage): Ditto. (Arm_relobj::Arm_relobj): Initialize exidx_section_map_. (Arm_relobj::convert_input_section_to_relaxed_section): Use Relobj::set_section_offset() instead of Sized_relobj::invalidate_section_offset(). (Arm_relobj::section_needs_reloc_stub_scanning): Add an extra parameter for section headers. Ignore relocation sections for unallocated sections and EXIDX sections. (Target_arm::fix_exidx_coverage): New method. (Target_arm::output_section_address_less_than): New type. (Arm_exidx_fixup::add_exidx_cantunwind_as_needed): Use index of the linked text section instead of the EXIDX section. (Arm_output_section::create_stub_group): Add an assertion to check that this is not an EXIDX output section. (Arm_output_section::append_text_sections_to_list): New method. (Arm_output_section::fix_exidx_coverage): Ditto. (Arm_relobj::scan_sections_for_stubs): Adjust call to Arm_relobj::section_needs_reloc_stub_scanning. (Target_arm::do_relax): Fix EXIDX output section coverage in the first pass. (Target_arm::fix_exidx_coverage): New method. * object.h (Relobj::set_output_section): New method. (Sized_relobj::invalidate_section_offset): Remove method. (Sized_relobj::do_invalidate_section_offset): Remove method. (Sized_relobj::do_set_section_offset): Handle offset value -1.
This commit is contained in:
parent
708ead4e05
commit
2b328d4ec5
@ -1,3 +1,36 @@
|
||||
2010-01-26 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* arm.cc (set): Include.
|
||||
(class Arm_exidx_fixup): Change type of last_input_section_ to const
|
||||
pointer type.
|
||||
(Arm_output_section::Text_section_list): New type.
|
||||
(Arm_output_section::append_text_sections_to_list): New method.
|
||||
(Arm_output_section::fix_exidx_coverage): Ditto.
|
||||
(Arm_relobj::Arm_relobj): Initialize exidx_section_map_.
|
||||
(Arm_relobj::convert_input_section_to_relaxed_section): Use
|
||||
Relobj::set_section_offset() instead of
|
||||
Sized_relobj::invalidate_section_offset().
|
||||
(Arm_relobj::section_needs_reloc_stub_scanning): Add an extra
|
||||
parameter for section headers. Ignore relocation sections for
|
||||
unallocated sections and EXIDX sections.
|
||||
(Target_arm::fix_exidx_coverage): New method.
|
||||
(Target_arm::output_section_address_less_than): New type.
|
||||
(Arm_exidx_fixup::add_exidx_cantunwind_as_needed): Use index of the
|
||||
linked text section instead of the EXIDX section.
|
||||
(Arm_output_section::create_stub_group): Add an assertion to check
|
||||
that this is not an EXIDX output section.
|
||||
(Arm_output_section::append_text_sections_to_list): New method.
|
||||
(Arm_output_section::fix_exidx_coverage): Ditto.
|
||||
(Arm_relobj::scan_sections_for_stubs): Adjust call to
|
||||
Arm_relobj::section_needs_reloc_stub_scanning.
|
||||
(Target_arm::do_relax): Fix EXIDX output section coverage in the
|
||||
first pass.
|
||||
(Target_arm::fix_exidx_coverage): New method.
|
||||
* object.h (Relobj::set_output_section): New method.
|
||||
(Sized_relobj::invalidate_section_offset): Remove method.
|
||||
(Sized_relobj::do_invalidate_section_offset): Remove method.
|
||||
(Sized_relobj::do_set_section_offset): Handle offset value -1.
|
||||
|
||||
2010-01-25 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* arm.cc (Arm_exidx_merged_section::do_output_offset):
|
||||
|
288
gold/arm.cc
288
gold/arm.cc
@ -32,6 +32,7 @@
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <set>
|
||||
|
||||
#include "elfcpp.h"
|
||||
#include "parameters.h"
|
||||
@ -1288,7 +1289,7 @@ class Arm_exidx_fixup
|
||||
// Last seen inlined EXIDX entry.
|
||||
uint32_t last_inlined_entry_;
|
||||
// Last processed EXIDX input section.
|
||||
Arm_exidx_input_section* last_input_section_;
|
||||
const Arm_exidx_input_section* last_input_section_;
|
||||
// Section offset map created in process_exidx_section.
|
||||
Arm_exidx_section_offset_map* section_offset_map_;
|
||||
};
|
||||
@ -1300,6 +1301,8 @@ template<bool big_endian>
|
||||
class Arm_output_section : public Output_section
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::pair<Relobj*, unsigned int> > Text_section_list;
|
||||
|
||||
Arm_output_section(const char* name, elfcpp::Elf_Word type,
|
||||
elfcpp::Elf_Xword flags)
|
||||
: Output_section(name, type, flags)
|
||||
@ -1318,6 +1321,17 @@ class Arm_output_section : public Output_section
|
||||
as_arm_output_section(Output_section* os)
|
||||
{ return static_cast<Arm_output_section<big_endian>*>(os); }
|
||||
|
||||
// Append all input text sections in this into LIST.
|
||||
void
|
||||
append_text_sections_to_list(Text_section_list* list);
|
||||
|
||||
// Fix EXIDX coverage of this EXIDX output section. SORTED_TEXT_SECTION
|
||||
// is a list of text input sections sorted in ascending order of their
|
||||
// output addresses.
|
||||
void
|
||||
fix_exidx_coverage(const Text_section_list& sorted_text_section,
|
||||
Symbol_table* symtab);
|
||||
|
||||
private:
|
||||
// For convenience.
|
||||
typedef Output_section::Input_section Input_section;
|
||||
@ -1401,7 +1415,7 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
|
||||
: Sized_relobj<32, big_endian>(name, input_file, offset, ehdr),
|
||||
stub_tables_(), local_symbol_is_thumb_function_(),
|
||||
attributes_section_data_(NULL), mapping_symbols_info_(),
|
||||
section_has_cortex_a8_workaround_(NULL)
|
||||
section_has_cortex_a8_workaround_(NULL), exidx_section_map_()
|
||||
{ }
|
||||
|
||||
~Arm_relobj()
|
||||
@ -1443,7 +1457,7 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
|
||||
{
|
||||
// The stubs have relocations and we need to process them after writing
|
||||
// out the stubs. So relocation now must follow section write.
|
||||
this->invalidate_section_offset(shndx);
|
||||
this->set_section_offset(shndx, -1ULL);
|
||||
this->set_relocs_must_follow_section_writes();
|
||||
}
|
||||
|
||||
@ -1563,7 +1577,7 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
|
||||
bool
|
||||
section_needs_reloc_stub_scanning(const elfcpp::Shdr<32, big_endian>&,
|
||||
const Relobj::Output_sections&,
|
||||
const Symbol_table *);
|
||||
const Symbol_table *, const unsigned char*);
|
||||
|
||||
// Whether a section needs to be scanned for the Cortex-A8 erratum.
|
||||
bool
|
||||
@ -2365,6 +2379,18 @@ class Target_arm : public Sized_target<32, big_endian>
|
||||
elfcpp::Elf_types<32>::Elf_Addr view_address,
|
||||
section_size_type);
|
||||
|
||||
// Fix .ARM.exidx section coverage.
|
||||
void
|
||||
fix_exidx_coverage(Layout*, Arm_output_section<big_endian>*, Symbol_table*);
|
||||
|
||||
// Functors for STL set.
|
||||
struct output_section_address_less_than
|
||||
{
|
||||
bool
|
||||
operator()(const Output_section* s1, const Output_section* s2) const
|
||||
{ return s1->address() < s2->address(); }
|
||||
};
|
||||
|
||||
// Information about this specific target which we pass to the
|
||||
// general Target structure.
|
||||
static const Target::Target_info arm_info;
|
||||
@ -4684,9 +4710,9 @@ Arm_exidx_fixup::add_exidx_cantunwind_as_needed()
|
||||
&& this->last_input_section_ != NULL)
|
||||
{
|
||||
Relobj* relobj = this->last_input_section_->relobj();
|
||||
unsigned int shndx = this->last_input_section_->shndx();
|
||||
unsigned int text_shndx = this->last_input_section_->link();
|
||||
Arm_exidx_cantunwind* cantunwind =
|
||||
new Arm_exidx_cantunwind(relobj, shndx);
|
||||
new Arm_exidx_cantunwind(relobj, text_shndx);
|
||||
this->exidx_output_section_->add_output_section_data(cantunwind);
|
||||
this->last_unwind_type_ = UT_EXIDX_CANTUNWIND;
|
||||
}
|
||||
@ -4830,6 +4856,12 @@ Arm_output_section<big_endian>::create_stub_group(
|
||||
Target_arm<big_endian>* target,
|
||||
std::vector<Output_relaxed_input_section*>* new_relaxed_sections)
|
||||
{
|
||||
// We use a different kind of relaxed section in an EXIDX section.
|
||||
// The static casting from Output_relaxed_input_section to
|
||||
// Arm_input_section is invalid in an EXIDX section. We are okay
|
||||
// because we should not be calling this for an EXIDX section.
|
||||
gold_assert(this->type() != elfcpp::SHT_ARM_EXIDX);
|
||||
|
||||
// Currently we convert ordinary input sections into relaxed sections only
|
||||
// at this point but we may want to support creating relaxed input section
|
||||
// very early. So we check here to see if owner is already a relaxed
|
||||
@ -5025,6 +5057,172 @@ Arm_output_section<big_endian>::group_sections(
|
||||
}
|
||||
}
|
||||
|
||||
// Append non empty text sections in this to LIST in ascending
|
||||
// order of their position in this.
|
||||
|
||||
template<bool big_endian>
|
||||
void
|
||||
Arm_output_section<big_endian>::append_text_sections_to_list(
|
||||
Text_section_list* list)
|
||||
{
|
||||
// We only care about text sections.
|
||||
if ((this->flags() & elfcpp::SHF_EXECINSTR) == 0)
|
||||
return;
|
||||
|
||||
gold_assert((this->flags() & elfcpp::SHF_ALLOC) != 0);
|
||||
|
||||
for (Input_section_list::const_iterator p = this->input_sections().begin();
|
||||
p != this->input_sections().end();
|
||||
++p)
|
||||
{
|
||||
// We only care about plain or relaxed input sections. We also
|
||||
// ignore any merged sections.
|
||||
if ((p->is_input_section() || p->is_relaxed_input_section())
|
||||
&& p->data_size() != 0)
|
||||
list->push_back(Text_section_list::value_type(p->relobj(),
|
||||
p->shndx()));
|
||||
}
|
||||
}
|
||||
|
||||
template<bool big_endian>
|
||||
void
|
||||
Arm_output_section<big_endian>::fix_exidx_coverage(
|
||||
const Text_section_list& sorted_text_sections,
|
||||
Symbol_table* symtab)
|
||||
{
|
||||
// We should only do this for the EXIDX output section.
|
||||
gold_assert(this->type() == elfcpp::SHT_ARM_EXIDX);
|
||||
|
||||
// We don't want the relaxation loop to undo these changes, so we discard
|
||||
// the current saved states and take another one after the fix-up.
|
||||
this->discard_states();
|
||||
|
||||
// Remove all input sections.
|
||||
uint64_t address = this->address();
|
||||
typedef std::list<Simple_input_section> Simple_input_section_list;
|
||||
Simple_input_section_list input_sections;
|
||||
this->reset_address_and_file_offset();
|
||||
this->get_input_sections(address, std::string(""), &input_sections);
|
||||
|
||||
if (!this->input_sections().empty())
|
||||
gold_error(_("Found non-EXIDX input sections in EXIDX output section"));
|
||||
|
||||
// Go through all the known input sections and record them.
|
||||
typedef Unordered_set<Section_id, Section_id_hash> Section_id_set;
|
||||
Section_id_set known_input_sections;
|
||||
for (Simple_input_section_list::const_iterator p = input_sections.begin();
|
||||
p != input_sections.end();
|
||||
++p)
|
||||
{
|
||||
// This should never happen. At this point, we should only see
|
||||
// plain EXIDX input sections.
|
||||
gold_assert(!p->is_relaxed_input_section());
|
||||
known_input_sections.insert(Section_id(p->relobj(), p->shndx()));
|
||||
}
|
||||
|
||||
Arm_exidx_fixup exidx_fixup(this);
|
||||
|
||||
// Go over the sorted text sections.
|
||||
Section_id_set processed_input_sections;
|
||||
for (Text_section_list::const_iterator p = sorted_text_sections.begin();
|
||||
p != sorted_text_sections.end();
|
||||
++p)
|
||||
{
|
||||
Relobj* relobj = p->first;
|
||||
unsigned int shndx = p->second;
|
||||
|
||||
Arm_relobj<big_endian>* arm_relobj =
|
||||
Arm_relobj<big_endian>::as_arm_relobj(relobj);
|
||||
const Arm_exidx_input_section* exidx_input_section =
|
||||
arm_relobj->exidx_input_section_by_link(shndx);
|
||||
|
||||
// If this text section has no EXIDX section, force an EXIDX_CANTUNWIND
|
||||
// entry pointing to the end of the last seen EXIDX section.
|
||||
if (exidx_input_section == NULL)
|
||||
{
|
||||
exidx_fixup.add_exidx_cantunwind_as_needed();
|
||||
continue;
|
||||
}
|
||||
|
||||
Relobj* exidx_relobj = exidx_input_section->relobj();
|
||||
unsigned int exidx_shndx = exidx_input_section->shndx();
|
||||
Section_id sid(exidx_relobj, exidx_shndx);
|
||||
if (known_input_sections.find(sid) == known_input_sections.end())
|
||||
{
|
||||
// This is odd. We have not seen this EXIDX input section before.
|
||||
// We cannot do fix-up.
|
||||
gold_error(_("EXIDX section %u of %s is not in EXIDX output section"),
|
||||
exidx_shndx, exidx_relobj->name().c_str());
|
||||
exidx_fixup.add_exidx_cantunwind_as_needed();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fix up coverage and append input section to output data list.
|
||||
Arm_exidx_section_offset_map* section_offset_map = NULL;
|
||||
uint32_t deleted_bytes =
|
||||
exidx_fixup.process_exidx_section<big_endian>(exidx_input_section,
|
||||
§ion_offset_map);
|
||||
|
||||
if (deleted_bytes == exidx_input_section->size())
|
||||
{
|
||||
// The whole EXIDX section got merged. Remove it from output.
|
||||
gold_assert(section_offset_map == NULL);
|
||||
exidx_relobj->set_output_section(exidx_shndx, NULL);
|
||||
}
|
||||
else if (deleted_bytes > 0)
|
||||
{
|
||||
// Some entries are merged. We need to convert this EXIDX input
|
||||
// section into a relaxed section.
|
||||
gold_assert(section_offset_map != NULL);
|
||||
Arm_exidx_merged_section* merged_section =
|
||||
new Arm_exidx_merged_section(*exidx_input_section,
|
||||
*section_offset_map, deleted_bytes);
|
||||
this->add_relaxed_input_section(merged_section);
|
||||
arm_relobj->convert_input_section_to_relaxed_section(exidx_shndx);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just add back the EXIDX input section.
|
||||
gold_assert(section_offset_map == NULL);
|
||||
Output_section::Simple_input_section sis(exidx_relobj, exidx_shndx);
|
||||
this->add_simple_input_section(sis, exidx_input_section->size(),
|
||||
exidx_input_section->addralign());
|
||||
}
|
||||
|
||||
processed_input_sections.insert(Section_id(exidx_relobj, exidx_shndx));
|
||||
}
|
||||
|
||||
// Insert an EXIDX_CANTUNWIND entry at the end of output if necessary.
|
||||
exidx_fixup.add_exidx_cantunwind_as_needed();
|
||||
|
||||
// Remove any known EXIDX input sections that are not processed.
|
||||
for (Simple_input_section_list::const_iterator p = input_sections.begin();
|
||||
p != input_sections.end();
|
||||
++p)
|
||||
{
|
||||
if (processed_input_sections.find(Section_id(p->relobj(), p->shndx()))
|
||||
== processed_input_sections.end())
|
||||
{
|
||||
// We only discard a known EXIDX section because its linked
|
||||
// text section has been folded by ICF.
|
||||
Arm_relobj<big_endian>* arm_relobj =
|
||||
Arm_relobj<big_endian>::as_arm_relobj(p->relobj());
|
||||
const Arm_exidx_input_section* exidx_input_section =
|
||||
arm_relobj->exidx_input_section_by_shndx(p->shndx());
|
||||
gold_assert(exidx_input_section != NULL);
|
||||
unsigned int text_shndx = exidx_input_section->link();
|
||||
gold_assert(symtab->is_section_folded(p->relobj(), text_shndx));
|
||||
|
||||
// Remove this from link.
|
||||
p->relobj()->set_output_section(p->shndx(), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Make changes permanent.
|
||||
this->save_states();
|
||||
this->set_section_offsets_need_adjustment();
|
||||
}
|
||||
|
||||
// Arm_relobj methods.
|
||||
|
||||
// Determine if we want to scan the SHNDX-th section for relocation stubs.
|
||||
@ -5035,7 +5233,8 @@ bool
|
||||
Arm_relobj<big_endian>::section_needs_reloc_stub_scanning(
|
||||
const elfcpp::Shdr<32, big_endian>& shdr,
|
||||
const Relobj::Output_sections& out_sections,
|
||||
const Symbol_table *symtab)
|
||||
const Symbol_table *symtab,
|
||||
const unsigned char* pshdrs)
|
||||
{
|
||||
unsigned int sh_type = shdr.get_sh_type();
|
||||
if (sh_type != elfcpp::SHT_REL && sh_type != elfcpp::SHT_RELA)
|
||||
@ -5058,6 +5257,14 @@ Arm_relobj<big_endian>::section_needs_reloc_stub_scanning(
|
||||
if (out_sections[index] == NULL || symtab->is_section_folded(this, index))
|
||||
return false;
|
||||
|
||||
// Check the section to which relocations are applied. Ignore relocations
|
||||
// to unallocated sections or EXIDX sections.
|
||||
const unsigned int shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
|
||||
const elfcpp::Shdr<32, big_endian> data_shdr(pshdrs + index * shdr_size);
|
||||
if ((data_shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0
|
||||
|| data_shdr.get_sh_type() == elfcpp::SHT_ARM_EXIDX)
|
||||
return false;
|
||||
|
||||
// Ignore reloc section with unexpected symbol table. The
|
||||
// error will be reported in the final link.
|
||||
if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx())
|
||||
@ -5211,7 +5418,8 @@ Arm_relobj<big_endian>::scan_sections_for_stubs(
|
||||
for (unsigned int i = 1; i < shnum; ++i, p += shdr_size)
|
||||
{
|
||||
const elfcpp::Shdr<32, big_endian> shdr(p);
|
||||
if (this->section_needs_reloc_stub_scanning(shdr, out_sections, symtab))
|
||||
if (this->section_needs_reloc_stub_scanning(shdr, out_sections, symtab,
|
||||
pshdrs))
|
||||
{
|
||||
unsigned int index = this->adjust_shndx(shdr.get_sh_info());
|
||||
Arm_address output_offset = this->get_output_section_offset(index);
|
||||
@ -8647,6 +8855,7 @@ Target_arm<big_endian>::do_relax(
|
||||
|
||||
// If this is the first pass, we need to group input sections into
|
||||
// stub groups.
|
||||
bool done_exidx_fixup = false;
|
||||
if (pass == 1)
|
||||
{
|
||||
// Determine the stub group size. The group size is the absolute
|
||||
@ -8679,6 +8888,16 @@ Target_arm<big_endian>::do_relax(
|
||||
}
|
||||
|
||||
group_sections(layout, stub_group_size, stubs_always_after_branch);
|
||||
|
||||
// Also fix .ARM.exidx section coverage.
|
||||
Output_section* os = layout->find_output_section(".ARM.exidx");
|
||||
if (os != NULL && os->type() == elfcpp::SHT_ARM_EXIDX)
|
||||
{
|
||||
Arm_output_section<big_endian>* exidx_output_section =
|
||||
Arm_output_section<big_endian>::as_arm_output_section(os);
|
||||
this->fix_exidx_coverage(layout, exidx_output_section, symtab);
|
||||
done_exidx_fixup = true;
|
||||
}
|
||||
}
|
||||
|
||||
// The Cortex-A8 stubs are sensitive to layout of code sections. At the
|
||||
@ -8750,14 +8969,17 @@ Target_arm<big_endian>::do_relax(
|
||||
(*p)->set_section_offsets_need_adjustment();
|
||||
}
|
||||
|
||||
// Stop relaxation if no EXIDX fix-up and no stub table change.
|
||||
bool continue_relaxation = done_exidx_fixup || any_stub_table_changed;
|
||||
|
||||
// Finalize the stubs in the last relaxation pass.
|
||||
if (!any_stub_table_changed)
|
||||
if (!continue_relaxation)
|
||||
for (Stub_table_iterator sp = this->stub_tables_.begin();
|
||||
(sp != this->stub_tables_.end()) && !any_stub_table_changed;
|
||||
++sp)
|
||||
(*sp)->finalize_stubs();
|
||||
|
||||
return any_stub_table_changed;
|
||||
return continue_relaxation;
|
||||
}
|
||||
|
||||
// Relocate a stub.
|
||||
@ -9089,6 +9311,52 @@ class Target_selector_arm : public Target_selector
|
||||
{ return new Target_arm<big_endian>(); }
|
||||
};
|
||||
|
||||
// Fix .ARM.exidx section coverage.
|
||||
|
||||
template<bool big_endian>
|
||||
void
|
||||
Target_arm<big_endian>::fix_exidx_coverage(
|
||||
Layout* layout,
|
||||
Arm_output_section<big_endian>* exidx_section,
|
||||
Symbol_table* symtab)
|
||||
{
|
||||
// We need to look at all the input sections in output in ascending
|
||||
// order of of output address. We do that by building a sorted list
|
||||
// of output sections by addresses. Then we looks at the output sections
|
||||
// in order. The input sections in an output section are already sorted
|
||||
// by addresses within the output section.
|
||||
|
||||
typedef std::set<Output_section*, output_section_address_less_than>
|
||||
Sorted_output_section_list;
|
||||
Sorted_output_section_list sorted_output_sections;
|
||||
Layout::Section_list section_list;
|
||||
layout->get_allocated_sections(§ion_list);
|
||||
for (Layout::Section_list::const_iterator p = section_list.begin();
|
||||
p != section_list.end();
|
||||
++p)
|
||||
{
|
||||
// We only care about output sections that contain executable code.
|
||||
if (((*p)->flags() & elfcpp::SHF_EXECINSTR) != 0)
|
||||
sorted_output_sections.insert(*p);
|
||||
}
|
||||
|
||||
// Go over the output sections in ascending order of output addresses.
|
||||
typedef typename Arm_output_section<big_endian>::Text_section_list
|
||||
Text_section_list;
|
||||
Text_section_list sorted_text_sections;
|
||||
for(typename Sorted_output_section_list::iterator p =
|
||||
sorted_output_sections.begin();
|
||||
p != sorted_output_sections.end();
|
||||
++p)
|
||||
{
|
||||
Arm_output_section<big_endian>* arm_output_section =
|
||||
Arm_output_section<big_endian>::as_arm_output_section(*p);
|
||||
arm_output_section->append_text_sections_to_list(&sorted_text_sections);
|
||||
}
|
||||
|
||||
exidx_section->fix_exidx_coverage(sorted_text_sections, symtab);
|
||||
}
|
||||
|
||||
Target_selector_arm<false> target_selector_arm;
|
||||
Target_selector_arm<true> target_selector_armbe;
|
||||
|
||||
|
@ -747,6 +747,16 @@ class Relobj : public Object
|
||||
return this->output_sections_[shndx];
|
||||
}
|
||||
|
||||
// The the output section of the input section with index SHNDX.
|
||||
// This is only used currently to remove a section from the link in
|
||||
// relaxation.
|
||||
void
|
||||
set_output_section(unsigned int shndx, Output_section* os)
|
||||
{
|
||||
gold_assert(shndx < this->output_sections_.size());
|
||||
this->output_sections_[shndx] = os;
|
||||
}
|
||||
|
||||
// Given a section index, return the offset in the Output_section.
|
||||
// The return value will be -1U if the section is specially mapped,
|
||||
// such as a merge section.
|
||||
@ -1484,11 +1494,6 @@ class Sized_relobj : public Relobj
|
||||
Address
|
||||
map_to_kept_section(unsigned int shndx, bool* found) const;
|
||||
|
||||
// Make section offset invalid. This is needed for relaxation.
|
||||
void
|
||||
invalidate_section_offset(unsigned int shndx)
|
||||
{ this->do_invalidate_section_offset(shndx); }
|
||||
|
||||
protected:
|
||||
// Set up.
|
||||
virtual void
|
||||
@ -1626,15 +1631,10 @@ class Sized_relobj : public Relobj
|
||||
do_set_section_offset(unsigned int shndx, uint64_t off)
|
||||
{
|
||||
gold_assert(shndx < this->section_offsets_.size());
|
||||
this->section_offsets_[shndx] = convert_types<Address, uint64_t>(off);
|
||||
}
|
||||
|
||||
// Set the offset of a section to invalid_address.
|
||||
virtual void
|
||||
do_invalidate_section_offset(unsigned int shndx)
|
||||
{
|
||||
gold_assert(shndx < this->section_offsets_.size());
|
||||
this->section_offsets_[shndx] = invalid_address;
|
||||
this->section_offsets_[shndx] =
|
||||
(off == static_cast<uint64_t>(-1)
|
||||
? invalid_address
|
||||
: convert_types<Address, uint64_t>(off));
|
||||
}
|
||||
|
||||
// Adjust a section index if necessary.
|
||||
|
Loading…
Reference in New Issue
Block a user