aboutsummaryrefslogtreecommitdiff
path: root/gold/output.h
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-12-03 05:30:59 +0000
committerAlan Modra <amodra@gmail.com>2012-12-03 05:30:59 +0000
commitec661b9dca95a55df264edaaa430dd6183ad2adf (patch)
tree3fe1dd21cc67d3af02e77b2a761128f3f5052e4b /gold/output.h
parent0f6752b51fa8d4e6119c662eb17520f7ee5a6007 (diff)
downloadbinutils-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.h104
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