mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-26 03:24:41 +08:00
2010-01-11 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_relobj::do_gc_process_relocs): New method. (Target_arm::do_finalize_sections): Define special EXIDX section symbols only if referenced. * gc.h (Garbage_collection::add_reference): New method. (gc_process_relocs): Use Garbage_collection::add_reference to avoid code duplication.
This commit is contained in:
parent
d0a91bd8c7
commit
99e5bff2f9
@ -1,3 +1,12 @@
|
||||
2010-01-11 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* arm.cc (Arm_relobj::do_gc_process_relocs): New method.
|
||||
(Target_arm::do_finalize_sections): Define special EXIDX section
|
||||
symbols only if referenced.
|
||||
* gc.h (Garbage_collection::add_reference): New method.
|
||||
(gc_process_relocs): Use Garbage_collection::add_reference to avoid
|
||||
code duplication.
|
||||
|
||||
2010-01-11 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* script.cc (Version_script_info::build_expression_list_lookup):
|
||||
|
46
gold/arm.cc
46
gold/arm.cc
@ -1178,6 +1178,10 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
|
||||
void
|
||||
do_read_symbols(Read_symbols_data* sd);
|
||||
|
||||
// Process relocs for garbage collection.
|
||||
void
|
||||
do_gc_process_relocs(Symbol_table*, Layout*, Read_relocs_data*);
|
||||
|
||||
private:
|
||||
// List of stub tables.
|
||||
typedef std::vector<Stub_table<big_endian>*> Stub_table_list;
|
||||
@ -4235,6 +4239,44 @@ Arm_relobj<big_endian>::do_read_symbols(Read_symbols_data* sd)
|
||||
read_arm_attributes_section<big_endian>(this, sd);
|
||||
}
|
||||
|
||||
// Process relocations for garbage collection. The ARM target uses .ARM.exidx
|
||||
// sections for unwinding. These sections are referenced implicitly by
|
||||
// text sections linked in the section headers. If we ignore these implict
|
||||
// references, the .ARM.exidx sections and any .ARM.extab sections they use
|
||||
// will be garbage-collected incorrectly. Hence we override the same function
|
||||
// in the base class to handle these implicit references.
|
||||
|
||||
template<bool big_endian>
|
||||
void
|
||||
Arm_relobj<big_endian>::do_gc_process_relocs(Symbol_table* symtab,
|
||||
Layout* layout,
|
||||
Read_relocs_data* rd)
|
||||
{
|
||||
// First, call base class method to process relocations in this object.
|
||||
Sized_relobj<32, big_endian>::do_gc_process_relocs(symtab, layout, rd);
|
||||
|
||||
unsigned int shnum = this->shnum();
|
||||
const unsigned int shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
|
||||
const unsigned char* pshdrs = this->get_view(this->elf_file()->shoff(),
|
||||
shnum * shdr_size,
|
||||
true, true);
|
||||
|
||||
// Scan section headers for sections of type SHT_ARM_EXIDX. Add references
|
||||
// to these from the linked text sections.
|
||||
const unsigned char* ps = pshdrs + shdr_size;
|
||||
for (unsigned int i = 1; i < shnum; ++i, ps += shdr_size)
|
||||
{
|
||||
elfcpp::Shdr<32, big_endian> shdr(ps);
|
||||
if (shdr.get_sh_type() == elfcpp::SHT_ARM_EXIDX)
|
||||
{
|
||||
// Found an .ARM.exidx section, add it to the set of reachable
|
||||
// sections from its linked text section.
|
||||
unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_link());
|
||||
symtab->gc()->add_reference(this, text_shndx, this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Arm_dynobj methods.
|
||||
|
||||
// Read the symbol information.
|
||||
@ -5081,12 +5123,12 @@ Target_arm<big_endian>::do_finalize_sections(
|
||||
Symbol_table::PREDEFINED,
|
||||
exidx_section, 0, 0, elfcpp::STT_OBJECT,
|
||||
elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
|
||||
false, false);
|
||||
false, true);
|
||||
symtab->define_in_output_data("__exidx_end", NULL,
|
||||
Symbol_table::PREDEFINED,
|
||||
exidx_section, 0, 0, elfcpp::STT_OBJECT,
|
||||
elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
|
||||
true, false);
|
||||
true, true);
|
||||
|
||||
// For the ARM target, we need to add a PT_ARM_EXIDX segment for
|
||||
// the .ARM.exidx section.
|
||||
|
30
gold/gc.h
30
gold/gc.h
@ -108,6 +108,21 @@ class Garbage_collection
|
||||
Section_id secn)
|
||||
{ this->cident_sections_[section_name].insert(secn); }
|
||||
|
||||
// Add a reference from the SRC_SHNDX-th section of SRC_OBJECT to
|
||||
// DST_SHNDX-th section of DST_OBJECT.
|
||||
void
|
||||
add_reference(Object* src_object, unsigned int src_shndx,
|
||||
Object* dst_object, unsigned int dst_shndx)
|
||||
{
|
||||
Section_id src_id(src_object, src_shndx);
|
||||
Section_id dst_id(dst_object, dst_shndx);
|
||||
Section_ref::iterator p = this->section_reloc_map_.find(src_id);
|
||||
if (p == this->section_reloc_map_.end())
|
||||
this->section_reloc_map_[src_id].insert(dst_id);
|
||||
else
|
||||
p->second.insert(dst_id);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Worklist_type work_list_;
|
||||
@ -261,25 +276,14 @@ gc_process_relocs(
|
||||
}
|
||||
if (parameters->options().gc_sections())
|
||||
{
|
||||
Section_id src_id(src_obj, src_indx);
|
||||
Section_id dst_id(dst_obj, dst_indx);
|
||||
Garbage_collection::Section_ref::iterator map_it;
|
||||
map_it = symtab->gc()->section_reloc_map().find(src_id);
|
||||
if (map_it == symtab->gc()->section_reloc_map().end())
|
||||
{
|
||||
symtab->gc()->section_reloc_map()[src_id].insert(dst_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Garbage_collection::Sections_reachable& v(map_it->second);
|
||||
v.insert(dst_id);
|
||||
}
|
||||
symtab->gc()->add_reference(src_obj, src_indx, dst_obj, dst_indx);
|
||||
if (cident_section_name != NULL)
|
||||
{
|
||||
Garbage_collection::Cident_section_map::iterator ele =
|
||||
symtab->gc()->cident_sections()->find(std::string(cident_section_name));
|
||||
if (ele == symtab->gc()->cident_sections()->end())
|
||||
continue;
|
||||
Section_id src_id(src_obj, src_indx);
|
||||
Garbage_collection::Sections_reachable&
|
||||
v(symtab->gc()->section_reloc_map()[src_id]);
|
||||
Garbage_collection::Sections_reachable& cident_secn(ele->second);
|
||||
|
Loading…
Reference in New Issue
Block a user