diff options
author | Alan Modra <amodra@gmail.com> | 2012-12-03 05:30:59 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-12-03 05:30:59 +0000 |
commit | ec661b9dca95a55df264edaaa430dd6183ad2adf (patch) | |
tree | 3fe1dd21cc67d3af02e77b2a761128f3f5052e4b /gold/output.h | |
parent | 0f6752b51fa8d4e6119c662eb17520f7ee5a6007 (diff) | |
download | binutils-ec661b9dca95a55df264edaaa430dd6183ad2adf.zip binutils-ec661b9dca95a55df264edaaa430dd6183ad2adf.tar.gz binutils-ec661b9dca95a55df264edaaa430dd6183ad2adf.tar.bz2 |
* layout.h (Layout::get_executable_sections): Declare.
* layout.cc (Layout::get_executable_sections): New function.
* arm.cc (Target_arm::group_sections): Use it.
(Arm_output_section::group_sections): Delete now redundant test.
* output.cc (Output_reloc::Output_reloc): Add is_relative.
param to handle relative relocs.
* output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise.
(Output_data_reloc::add_absolute): Adjust.
(Output_data_reloc::add_relative): New function.
(Output_data::reset_data_size): New function.
(Output_relaxed_input_section::set_relobj, set_shndx): New functions.
(Output_section::set_addralign): New function.
(Output_section::checkpoint_set_addralign): New function.
(Output_section::clear_section_offsets_need_adjustment): New function.
(Output_section::input_sections): Make public.
* powerpc.cc (class Output_data_brlt_powerpc): New.
(class Stub_table, class Stub_control): New.
(Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch,
stub_table_, set_stub_table, stub_table): New vectors and accessor
functions.
(Target_powerpc::do_may_relax, do_relax, push_branch,
new_stub_table, stub_tables, brlt_section, group_sections,
add_branch_lookup_table, find_branch_lookup_table,
write_branch_lookup_table, make_brlt_section): New functions.
(Target_powerpc::struct Sort_sections, class Branch_info): New.
(Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_,
branch_info_): New vars.
(Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't
make call stubs here.
(Output_data_glink): Remove all call stub handling from this class.
(Target_powerpc::Scan::local, global): Save interesting branch
relocs and relocs for ifunc. Adjust calls to plt entry functions.
(Target_powerpc::do_finalize_sections): Only make reg save/restore
functions on final link.
(Target_powerpc::Relocate::relocate): Adjust lookup of call stubs.
Handle long branch destinations too.
(Target_powerpc::do_dynsym_value, do_plt_address_for_global,
do_plt_address_for_local): Adjust lookup of plt call stubs.
Diffstat (limited to 'gold/output.h')
-rw-r--r-- | gold/output.h | 104 |
1 files changed, 83 insertions, 21 deletions
diff --git a/gold/output.h b/gold/output.h index d52d075..138712d 100644 --- a/gold/output.h +++ b/gold/output.h @@ -103,8 +103,8 @@ class Output_data return this->offset_; } - // Reset the address and file offset. This essentially disables the - // sanity testing about duplicate and unknown settings. + // Reset the address, file offset and data size. This essentially + // disables the sanity testing about duplicate and unknown settings. void reset_address_and_file_offset() { @@ -115,6 +115,14 @@ class Output_data this->do_reset_address_and_file_offset(); } + // As above, but just for data size. + void + reset_data_size() + { + if (!this->is_data_size_fixed_) + this->is_data_size_valid_ = false; + } + // Return true if address and file offset already have reset values. In // other words, calling reset_address_and_file_offset will not change them. bool @@ -1052,12 +1060,13 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, bool is_relative); - // An absolute relocation with no symbol. + // An absolute or relative relocation with no symbol. - Output_reloc(unsigned int type, Output_data* od, Address address); + Output_reloc(unsigned int type, Output_data* od, Address address, + bool is_relative); Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj, - unsigned int shndx, Address address); + unsigned int shndx, Address address, bool is_relative); // A target specific relocation. The target will be called to get // the symbol index, passing ARG. The type and offset will be set @@ -1307,16 +1316,17 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> : rel_(os, type, relobj, shndx, address, is_relative), addend_(addend) { } - // An absolute relocation with no symbol. + // An absolute or relative relocation with no symbol. Output_reloc(unsigned int type, Output_data* od, Address address, - Addend addend) - : rel_(type, od, address), addend_(addend) + Addend addend, bool is_relative) + : rel_(type, od, address, is_relative), addend_(addend) { } Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj, - unsigned int shndx, Address address, Addend addend) - : rel_(type, relobj, shndx, address), addend_(addend) + unsigned int shndx, Address address, Addend addend, + bool is_relative) + : rel_(type, relobj, shndx, address, is_relative), addend_(addend) { } // A target specific relocation. The target will be called to get @@ -1797,13 +1807,25 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> void add_absolute(unsigned int type, Output_data* od, Address address) - { this->add(od, Output_reloc_type(type, od, address)); } + { this->add(od, Output_reloc_type(type, od, address, false)); } void add_absolute(unsigned int type, Output_data* od, Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address) - { this->add(od, Output_reloc_type(type, relobj, shndx, address)); } + { this->add(od, Output_reloc_type(type, relobj, shndx, address, false)); } + + // Add a relative relocation + + void + add_relative(unsigned int type, Output_data* od, Address address) + { this->add(od, Output_reloc_type(type, od, address, true)); } + + void + add_relative(unsigned int type, Output_data* od, + Sized_relobj<size, big_endian>* relobj, + unsigned int shndx, Address address) + { this->add(od, Output_reloc_type(type, relobj, shndx, address, true)); } // Add a target specific relocation. A target which calls this must // define the reloc_symbol_index and reloc_addend virtual functions. @@ -2095,13 +2117,28 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> void add_absolute(unsigned int type, Output_data* od, Address address, Addend addend) - { this->add(od, Output_reloc_type(type, od, address, addend)); } + { this->add(od, Output_reloc_type(type, od, address, addend, false)); } void add_absolute(unsigned int type, Output_data* od, Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Addend addend) - { this->add(od, Output_reloc_type(type, relobj, shndx, address, addend)); } + { this->add(od, Output_reloc_type(type, relobj, shndx, address, addend, + false)); } + + // Add a relative relocation + + void + add_relative(unsigned int type, Output_data* od, Address address, + Addend addend) + { this->add(od, Output_reloc_type(type, od, address, addend, true)); } + + void + add_relative(unsigned int type, Output_data* od, + Sized_relobj<size, big_endian>* relobj, + unsigned int shndx, Address address, Addend addend) + { this->add(od, Output_reloc_type(type, relobj, shndx, address, addend, + true)); } // Add a target specific relocation. A target which calls this must // define the reloc_symbol_index and reloc_addend virtual functions. @@ -2700,6 +2737,15 @@ class Output_relaxed_input_section : public Output_section_data_build shndx() const { return this->shndx_; } + protected: + void + set_relobj(Relobj* relobj) + { this->relobj_ = relobj; } + + void + set_shndx(unsigned int shndx) + { this->shndx_ = shndx; } + private: Relobj* relobj_; unsigned int shndx_; @@ -3162,6 +3208,13 @@ class Output_section : public Output_data set_addralign(uint64_t v) { this->addralign_ = v; } + void + checkpoint_set_addralign(uint64_t val) + { + if (this->checkpoint_ != NULL) + this->checkpoint_->set_addralign(val); + } + // Whether the output section index has been set. bool has_out_shndx() const @@ -3794,6 +3847,11 @@ class Output_section : public Output_data set_section_offsets_need_adjustment() { this->section_offsets_need_adjustment_ = true; } + // Set section_offsets_need_adjustment to be false. + void + clear_section_offsets_need_adjustment() + { this->section_offsets_need_adjustment_ = false; } + // Adjust section offsets of input sections in this. This is // requires if relaxation caused some input sections to change sizes. void @@ -3848,6 +3906,13 @@ class Output_section : public Output_data off_t allocate(off_t len, uint64_t addralign); + typedef std::vector<Input_section> Input_section_list; + + // Allow access to the input sections. + const Input_section_list& + input_sections() const + { return this->input_sections_; } + protected: // Return the output section--i.e., the object itself. Output_section* @@ -3970,13 +4035,6 @@ class Output_section : public Output_data void write_to_postprocessing_buffer(); - typedef std::vector<Input_section> Input_section_list; - - // Allow a child class to access the input sections. - const Input_section_list& - input_sections() const - { return this->input_sections_; } - // Whether this always keeps an input section list bool always_keeps_input_sections() const @@ -4015,6 +4073,10 @@ class Output_section : public Output_data addralign() const { return this->addralign_; } + void + set_addralign(uint64_t val) + { this->addralign_ = val; } + // Return the section flags. elfcpp::Elf_Xword flags() const |