// output.h -- manage the output file for gold -*- C++ -*-
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2013
+// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
bool
is_data_size_fixed() const
{ return this->is_data_size_fixed_; }
-
+
// Return the file offset. This is only valid after
// Layout::finalize is finished. For some non-allocated sections,
// it may not be valid until near the end of the link.
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()
{
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
}
// Fix the data size. Once it is fixed, it cannot be changed
- // and the data size remains always valid.
+ // and the data size remains always valid.
void
fix_data_size()
{
class Output_file_header : public Output_data
{
public:
- Output_file_header(const Target*,
+ Output_file_header(Target*,
const Symbol_table*,
const Output_segment_headers*);
off_t
do_size() const;
- const Target* target_;
+ Target* target_;
const Symbol_table* symtab_;
const Output_segment_headers* segment_header_;
const Output_section_headers* section_header_;
bool use_plt_offset);
Output_reloc(Symbol* gsym, unsigned int type,
- Sized_relobj<size, big_endian>* relobj,
+ Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address, bool is_relative,
bool is_symbolless, bool use_plt_offset);
Output_reloc(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index, unsigned int type,
Output_data* od, Address address, bool is_relative,
- bool is_symbolless, bool is_section_symbol,
- bool use_plt_offset);
+ bool is_symbolless, bool is_section_symbol,
+ bool use_plt_offset);
Output_reloc(Sized_relobj<size, big_endian>* relobj,
unsigned int local_sym_index, unsigned int type,
unsigned int shndx, Address address, bool is_relative,
- bool is_symbolless, bool is_section_symbol,
- bool use_plt_offset);
+ bool is_symbolless, bool is_section_symbol,
+ bool use_plt_offset);
// A reloc against the STT_SECTION symbol of an output section.
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
is_local_section_symbol() const
{
return (this->local_sym_index_ != GSYM_CODE
- && this->local_sym_index_ != SECTION_CODE
- && this->local_sym_index_ != INVALID_CODE
+ && this->local_sym_index_ != SECTION_CODE
+ && this->local_sym_index_ != INVALID_CODE
&& this->local_sym_index_ != TARGET_CODE
- && this->is_section_symbol_);
+ && this->is_section_symbol_);
}
// Return whether this is a target specific relocation.
{ }
Output_reloc(Symbol* gsym, unsigned int type,
- Sized_relobj<size, big_endian>* relobj,
+ Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address, Addend addend,
bool is_relative, bool is_symbolless, bool use_plt_offset)
: rel_(gsym, type, relobj, shndx, address, is_relative,
bool is_symbolless, bool is_section_symbol,
bool use_plt_offset)
: rel_(relobj, local_sym_index, type, od, address, is_relative,
- is_symbolless, is_section_symbol, use_plt_offset),
+ is_symbolless, is_section_symbol, use_plt_offset),
addend_(addend)
{ }
bool is_symbolless, bool is_section_symbol,
bool use_plt_offset)
: rel_(relobj, local_sym_index, type, shndx, address, is_relative,
- is_symbolless, is_section_symbol, use_plt_offset),
+ is_symbolless, is_section_symbol, use_plt_offset),
addend_(addend)
{ }
{ }
Output_reloc(Output_section* os, unsigned int type,
- Sized_relobj<size, big_endian>* relobj,
+ Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address, Addend addend,
bool is_relative)
: 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
void
add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address)
- { this->add(od, Output_reloc_type(gsym, type, od, address, false, false, false)); }
+ {
+ this->add(od, Output_reloc_type(gsym, type, od, address,
+ false, false, false));
+ }
void
add_global(Symbol* gsym, unsigned int type, Output_data* od,
- Sized_relobj<size, big_endian>* relobj,
+ Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address)
- { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
- false, false, false)); }
+ {
+ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
+ false, false, false));
+ }
void
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
void
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
- Address address)
- { this->add(od, Output_reloc_type(gsym, type, od, address, true, true,
- false)); }
+ Address address)
+ {
+ this->add(od, Output_reloc_type(gsym, type, od, address, true, true,
+ false));
+ }
void
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
- Sized_relobj<size, big_endian>* relobj,
- unsigned int shndx, Address address)
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address)
{
this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
- true, true, false));
+ true, true, false));
}
// Add a global relocation which does not use a symbol for the relocation,
void
add_symbolless_global_addend(Symbol* gsym, unsigned int type,
Output_data* od, Address address)
- { this->add(od, Output_reloc_type(gsym, type, od, address, false, true,
- false)); }
+ {
+ this->add(od, Output_reloc_type(gsym, type, od, address, false, true,
+ false));
+ }
void
add_symbolless_global_addend(Symbol* gsym, unsigned int type,
unsigned int shndx, Address address)
{
this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
- false, true, false));
+ false, true, false));
}
// Add a reloc against a local symbol.
Output_data* od, Address address)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
- address, false, false, false, false));
+ address, false, false, false, false));
}
void
void
add_local_relative(Sized_relobj<size, big_endian>* relobj,
- unsigned int local_sym_index, unsigned int type,
- Output_data* od, Address address)
+ unsigned int local_sym_index, unsigned int type,
+ Output_data* od, Address address)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
- address, true, true, false, false));
+ address, true, true, false, false));
}
void
add_local_relative(Sized_relobj<size, big_endian>* relobj,
- unsigned int local_sym_index, unsigned int type,
- Output_data* od, unsigned int shndx, Address address)
+ unsigned int local_sym_index, unsigned int type,
+ Output_data* od, unsigned int shndx, Address address)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
address, true, true, false, false));
Output_data* od, Address address)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
- address, false, true, false, false));
+ address, false, true, false, false));
}
void
void
add_local_section(Sized_relobj<size, big_endian>* relobj,
- unsigned int input_shndx, unsigned int type,
- Output_data* od, Address address)
+ unsigned int input_shndx, unsigned int type,
+ Output_data* od, Address address)
{
this->add(od, Output_reloc_type(relobj, input_shndx, type, od,
- address, false, false, true, false));
+ address, false, false, true, false));
}
void
add_local_section(Sized_relobj<size, big_endian>* relobj,
- unsigned int input_shndx, unsigned int type,
- Output_data* od, unsigned int shndx, Address address)
+ unsigned int input_shndx, unsigned int type,
+ Output_data* od, unsigned int shndx, Address address)
{
this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
- address, false, false, true, false));
+ address, false, false, true, false));
}
// A reloc against the STT_SECTION symbol of an output section.
void
add_output_section(Output_section* os, unsigned int type, Output_data* od,
Sized_relobj<size, big_endian>* relobj,
- unsigned int shndx, Address address)
+ unsigned int shndx, Address address)
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address, false)); }
void
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.
void
add_global(Symbol* gsym, unsigned int type, Output_data* od,
Address address, Addend addend)
- { this->add(od, Output_reloc_type(gsym, type, od, address, addend,
- false, false, false)); }
+ {
+ this->add(od, Output_reloc_type(gsym, type, od, address, addend,
+ false, false, false));
+ }
void
add_global(Symbol* gsym, unsigned int type, Output_data* od,
- Sized_relobj<size, big_endian>* relobj,
+ Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address,
Addend addend)
- { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
- addend, false, false, false)); }
+ {
+ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
+ addend, false, false, false));
+ }
void
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
void
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
- Address address, Addend addend, bool use_plt_offset)
- { this->add(od, Output_reloc_type(gsym, type, od, address, addend, true,
- true, use_plt_offset)); }
+ Address address, Addend addend, bool use_plt_offset)
+ {
+ this->add(od, Output_reloc_type(gsym, type, od, address, addend, true,
+ true, use_plt_offset));
+ }
void
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
- Sized_relobj<size, big_endian>* relobj,
- unsigned int shndx, Address address, Addend addend,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address, Addend addend,
bool use_plt_offset)
- { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
- addend, true, true, use_plt_offset)); }
+ {
+ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
+ addend, true, true, use_plt_offset));
+ }
// Add a global relocation which does not use a symbol for the relocation,
// but which gets its addend from a symbol.
void
add_symbolless_global_addend(Symbol* gsym, unsigned int type, Output_data* od,
Address address, Addend addend)
- { this->add(od, Output_reloc_type(gsym, type, od, address, addend,
- false, true, false)); }
+ {
+ this->add(od, Output_reloc_type(gsym, type, od, address, addend,
+ false, true, false));
+ }
void
add_symbolless_global_addend(Symbol* gsym, 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(gsym, type, relobj, shndx, address,
- addend, false, true, false)); }
+ unsigned int shndx, Address address,
+ Addend addend)
+ {
+ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
+ addend, false, true, false));
+ }
// Add a reloc against a local symbol.
Addend addend)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
- address, addend, false, false, false,
- false));
+ address, addend, false, false, false,
+ false));
}
void
void
add_local_relative(Sized_relobj<size, big_endian>* relobj,
- unsigned int local_sym_index, unsigned int type,
- Output_data* od, Address address, Addend addend,
- bool use_plt_offset)
+ unsigned int local_sym_index, unsigned int type,
+ Output_data* od, Address address, Addend addend,
+ bool use_plt_offset)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
addend, true, true, false,
void
add_local_relative(Sized_relobj<size, big_endian>* relobj,
- unsigned int local_sym_index, unsigned int type,
- Output_data* od, unsigned int shndx, Address address,
- Addend addend, bool use_plt_offset)
+ unsigned int local_sym_index, unsigned int type,
+ Output_data* od, unsigned int shndx, Address address,
+ Addend addend, bool use_plt_offset)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
- address, addend, true, true, false,
- use_plt_offset));
+ address, addend, true, true, false,
+ use_plt_offset));
}
// Add a local relocation which does not use a symbol for the relocation,
Address address, Addend addend)
{
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
- address, addend, false, true, false,
- false));
+ address, addend, false, true, false,
+ false));
}
// Add a reloc against a local section symbol. This will be
void
add_local_section(Sized_relobj<size, big_endian>* relobj,
- unsigned int input_shndx, unsigned int type,
- Output_data* od, Address address, Addend addend)
+ unsigned int input_shndx, unsigned int type,
+ Output_data* od, Address address, Addend addend)
{
this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address,
addend, false, false, true, false));
Addend addend)
{
this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
- address, addend, false, false, true,
- false));
+ address, addend, false, false, true,
+ false));
}
// A reloc against the STT_SECTION symbol of an output section.
void
add_output_section(Output_section* os, unsigned int type, Output_data* od,
- Sized_relobj<size, big_endian>* relobj,
+ Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address, Addend addend)
- { this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
- addend, false)); }
+ {
+ this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
+ addend, false));
+ }
void
add_output_section_generic(Output_section* os, unsigned int type,
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.
add_global_plt(Symbol* gsym, unsigned int got_type);
// Like add_global, but for a TLS symbol where the value will be
- // offset using Target::tls_offset_for_global
+ // offset using Target::tls_offset_for_global.
bool
add_global_tls(Symbol* gsym, unsigned int got_type)
{ return add_global_plt(gsym, got_type); }
// relocation of type R_TYPE for the GOT entry.
void
add_global_with_rel(Symbol* gsym, unsigned int got_type,
- Output_data_reloc_generic* rel_dyn, unsigned int r_type);
+ Output_data_reloc_generic* rel_dyn, unsigned int r_type);
// Add a pair of entries for a global symbol to the GOT, and add
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
void
add_global_pair_with_rel(Symbol* gsym, unsigned int got_type,
- Output_data_reloc_generic* rel_dyn,
+ Output_data_reloc_generic* rel_dyn,
unsigned int r_type_1, unsigned int r_type_2);
// Add an entry for a local symbol to the GOT. This returns true if
add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type);
// Like add_local, but for a TLS symbol where the value will be
- // offset using Target::tls_offset_for_local
+ // offset using Target::tls_offset_for_local.
bool
add_local_tls(Relobj* object, unsigned int sym_index, unsigned int got_type)
{ return add_local_plt(object, sym_index, got_type); }
add_local_pair_with_rel(Relobj* object, unsigned int sym_index,
unsigned int shndx, unsigned int got_type,
Output_data_reloc_generic* rel_dyn,
- unsigned int r_type);
+ unsigned int r_type);
// Add a pair of entries for a local symbol to the GOT, and add
// a dynamic relocation of type R_TYPE using STN_UNDEF on the first.
// entry from the start of the GOT.
unsigned int
add_constant(Valtype constant)
- {
- unsigned int got_offset = this->add_got_entry(Got_entry(constant));
- return got_offset;
- }
+ { return this->add_got_entry(Got_entry(constant)); }
+
+ // Add a pair of constants to the GOT. This returns the offset of
+ // the new entry from the start of the GOT.
+ unsigned int
+ add_constant_pair(Valtype c1, Valtype c2)
+ { return this->add_got_entry_pair(Got_entry(c1), Got_entry(c2)); }
// Replace GOT entry I with a new constant.
void
// plus a constant offset.
void
add_section_plus_offset(elfcpp::DT tag, const Output_data* od,
- unsigned int offset)
+ unsigned int offset)
{ this->add_entry(Dynamic_entry(tag, od, offset)); }
// Add a new dynamic entry with the size of output data.
uint64_t addralign)
: Output_section_data_build(addralign), relobj_(relobj), shndx_(shndx)
{ }
-
+
// Return the Relobj of this relaxed input section.
Relobj*
relobj() const
{ return this->relobj_; }
-
+
// Return the section index of this relaxed input section.
unsigned int
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_;
h = (h ^ static_cast<uint64_t>(this->addralign_)) * prime;
return h;
}
-
+
// Functors for associative containers.
struct equal_to
{
// A cleared map is valid.
this->is_valid_ = true;
}
-
+
// Find a merge section by merge section properties. Return NULL if none
// is found.
Output_merge_base*
this->merge_sections_by_properties_.insert(value);
gold_assert(result.second);
}
-
+
// Add a mapping from a merged input section in OBJECT with index SHNDX
// to a merge output section pointed by POMB.
void
template<int size, bool big_endian>
off_t
add_input_section(Layout* layout, Sized_relobj_file<size, big_endian>* object,
- unsigned int shndx, const char* name,
+ unsigned int shndx, const char* name,
const elfcpp::Shdr<size, big_endian>& shdr,
unsigned int reloc_shndx, bool have_sections_script);
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
this->dynsym_index_ = index;
}
+ // Sort the attached input sections.
+ void
+ sort_attached_input_sections();
+
// Return whether the input sections sections attachd to this output
// section may require sorting. This is used to handle constructor
// priorities compatibly with GNU ld.
void
set_segment_alignment(uint64_t align)
{ this->segment_alignment_ = align; }
-
+
// If a section requires postprocessing, return the buffer to use.
unsigned char*
postprocessing_buffer() const
this->p2align_ = ffsll(static_cast<long long>(addralign));
}
}
-
+
// Return the current required size, without finalization.
off_t
current_data_size() const;
// parameters.
bool
is_merge_section(bool is_string, uint64_t entsize,
- uint64_t addralign) const
+ uint64_t addralign) const
{
return (this->shndx_ == (is_string
? MERGE_STRING_SECTION_CODE
: MERGE_DATA_SECTION_CODE)
&& this->u1_.entsize == entsize
- && this->addralign() == addralign);
+ && this->addralign() == addralign);
}
// Return whether this is a merge section for some input section.
gold_assert(!this->is_input_section());
return this->u2_.posd;
}
-
+
// For a merge section, return the Output_merge_base pointer.
Output_merge_base*
output_merge_base() const
set_output_section(Output_section* os)
{
gold_assert(!this->is_input_section());
- Output_section_data* posd =
- this->is_relaxed_input_section() ? this->u2_.poris : this->u2_.posd;
+ Output_section_data* posd =
+ this->is_relaxed_input_section() ? this->u2_.poris : this->u2_.posd;
posd->set_output_section(os);
}
// with index SHNDX. Return NULL if none is found.
const Output_relaxed_input_section*
find_relaxed_input_section(const Relobj* object, unsigned int shndx) const;
-
+
// Whether section offsets need adjustment due to relaxation.
bool
section_offsets_need_adjustment() const
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
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_; }
+
+ Input_section_list&
+ input_sections()
+ { return this->input_sections_; }
+
protected:
// Return the output section--i.e., the object itself.
Output_section*
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
addralign() const
{ return this->addralign_; }
+ void
+ set_addralign(uint64_t val)
+ { this->addralign_ = val; }
+
// Return the section flags.
elfcpp::Elf_Xword
flags() const
const Input_section_sort_entry&) const;
};
+ // This is the sort comparison function for .text to sort sections with
+ // prefixes .text.{unlikely,exit,startup,hot} before other sections.
+ struct Input_section_sort_section_prefix_special_ordering_compare
+ {
+ bool
+ operator()(const Input_section_sort_entry&,
+ const Input_section_sort_entry&) const;
+ };
+
+ // This is the sort comparison function for sorting sections by name.
+ struct Input_section_sort_section_name_compare
+ {
+ bool
+ operator()(const Input_section_sort_entry&,
+ const Input_section_sort_entry&) const;
+ };
+
// Fill data. This is used to fill in data between input sections.
// It is also used for data statements (BYTE, WORD, etc.) in linker
// scripts. When we have to keep track of the input sections, we
add_output_merge_section(Output_section_data* posd, bool is_string,
uint64_t entsize);
- // Sort the attached input sections.
- void
- sort_attached_input_sections();
-
// Find the merge section into which an input section with index SHNDX in
// OBJECT has been added. Return NULL if none found.
Output_section_data*
uint64_t tls_offset_;
// Additional segment flags, specified via linker plugin, when mapping some
// input sections to unique segments.
- uint64_t extra_segment_flags_;
+ uint64_t extra_segment_flags_;
// Segment alignment specified via linker plugin, when mapping some
// input sections to unique segments.
uint64_t segment_alignment_;
// address of the immediately following segment. Update *POFF and
// *PSHNDX. This should only be called for a PT_LOAD segment.
uint64_t
- set_section_addresses(Layout*, bool reset, uint64_t addr,
+ set_section_addresses(const Target*, Layout*, bool reset, uint64_t addr,
unsigned int* increase_relro, bool* has_relro,
off_t* poff, unsigned int* pshndx);
// Set the section addresses in an Output_data_list.
uint64_t
set_section_list_addresses(Layout*, bool reset, Output_data_list*,
- uint64_t addr, off_t* poff, unsigned int* pshndx,
- bool* in_tls);
+ uint64_t addr, off_t* poff, unsigned int* pshndx,
+ bool* in_tls);
// Return the number of Output_sections in an Output_data_list.
unsigned int
// NOTE: We want to use the copy constructor. Currently, shallow copy
// works for us so we do not need to write our own copy constructor.
-
+
// The list of output data attached to this segment.
Output_data_list output_lists_[ORDER_MAX];
// The segment virtual address.
get_output_view(off_t start, size_t size)
{
gold_assert(start >= 0
- && start + static_cast<off_t>(size) <= this->file_size_);
+ && start + static_cast<off_t>(size) <= this->file_size_);
return this->base_ + start;
}