diff options
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/gold/object.cc b/gold/object.cc index dfe2258..104a8db 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -349,11 +349,11 @@ Relobj::is_section_name_included(const char* name) // Finalize the incremental relocation information. Allocates a block // of relocation entries for each symbol, and sets the reloc_bases_ -// array to point to the first entry in each block. Returns the next -// available relocation index. +// array to point to the first entry in each block. If CLEAR_COUNTS +// is TRUE, also clear the per-symbol relocation counters. void -Relobj::finalize_incremental_relocs(Layout* layout) +Relobj::finalize_incremental_relocs(Layout* layout, bool clear_counts) { unsigned int nsyms = this->get_global_symbols()->size(); this->reloc_bases_ = new unsigned int[nsyms]; @@ -366,7 +366,8 @@ Relobj::finalize_incremental_relocs(Layout* layout) { this->reloc_bases_[i] = rindex; rindex += this->reloc_counts_[i]; - this->reloc_counts_[i] = 0; + if (clear_counts) + this->reloc_counts_[i] = 0; } layout->incremental_inputs()->set_reloc_count(rindex); } @@ -379,7 +380,7 @@ Sized_relobj<size, big_endian>::Sized_relobj( Input_file* input_file, off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr) - : Relobj(name, input_file, offset), + : Sized_relobj_base<size, big_endian>(name, input_file, offset), elf_file_(this, ehdr), symtab_shndx_(-1U), local_symbol_count_(0), @@ -1265,9 +1266,12 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, // Add the section to the incremental inputs layout. Incremental_inputs* incremental_inputs = layout->incremental_inputs(); - if (incremental_inputs != NULL) - incremental_inputs->report_input_section(this, i, - discard ? NULL : name, + if (incremental_inputs != NULL + && !discard + && (shdr.get_sh_type() == elfcpp::SHT_PROGBITS + || shdr.get_sh_type() == elfcpp::SHT_NOBITS + || shdr.get_sh_type() == elfcpp::SHT_NOTE)) + incremental_inputs->report_input_section(this, i, name, shdr.get_sh_size()); if (discard) @@ -1281,7 +1285,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, if (is_gc_pass_one && parameters->options().gc_sections()) { - if (is_section_name_included(name) + if (this->is_section_name_included(name) || shdr.get_sh_type() == elfcpp::SHT_INIT_ARRAY || shdr.get_sh_type() == elfcpp::SHT_FINI_ARRAY) { @@ -1716,6 +1720,26 @@ Sized_relobj<size, big_endian>::do_for_all_global_symbols( } } +// Iterate over local symbols, calling a visitor class V for each GOT offset +// associated with a local symbol. + +template<int size, bool big_endian> +void +Sized_relobj<size, big_endian>::do_for_all_local_got_entries( + Got_offset_list::Visitor* v) const +{ + unsigned int nsyms = this->local_symbol_count(); + for (unsigned int i = 0; i < nsyms; i++) + { + Local_got_offsets::const_iterator p = this->local_got_offsets_.find(i); + if (p != this->local_got_offsets_.end()) + { + const Got_offset_list* got_offsets = p->second; + got_offsets->for_all_got_offsets(v); + } + } +} + // Return whether the local symbol SYMNDX has a PLT offset. template<int size, bool big_endian> @@ -2199,7 +2223,8 @@ Sized_relobj<size, big_endian>::write_local_symbols( const Stringpool* sympool, const Stringpool* dynpool, Output_symtab_xindex* symtab_xindex, - Output_symtab_xindex* dynsym_xindex) + Output_symtab_xindex* dynsym_xindex, + off_t symtab_off) { const bool strip_all = parameters->options().strip_all(); if (strip_all) @@ -2244,7 +2269,8 @@ Sized_relobj<size, big_endian>::write_local_symbols( off_t output_size = this->output_local_symbol_count_ * sym_size; unsigned char* oview = NULL; if (output_size > 0) - oview = of->get_output_view(this->local_symbol_offset_, output_size); + oview = of->get_output_view(symtab_off + this->local_symbol_offset_, + output_size); off_t dyn_output_size = this->output_local_dynsym_count_ * sym_size; unsigned char* dyn_oview = NULL; @@ -2324,7 +2350,8 @@ Sized_relobj<size, big_endian>::write_local_symbols( if (output_size > 0) { gold_assert(ov - oview == output_size); - of->write_output_view(this->local_symbol_offset_, output_size, oview); + of->write_output_view(symtab_off + this->local_symbol_offset_, + output_size, oview); } if (dyn_output_size > 0) @@ -2450,7 +2477,7 @@ Sized_relobj<size, big_endian>::do_get_global_symbol_counts( { *defined = this->defined_count_; size_t count = 0; - for (Symbols::const_iterator p = this->symbols_.begin(); + for (typename Symbols::const_iterator p = this->symbols_.begin(); p != this->symbols_.end(); ++p) if (*p != NULL |