// output.h -- manage the output file for gold -*- C++ -*-
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
{ }
// Return the output section.
+ Output_section*
+ output_section()
+ { return this->output_section_; }
+
const Output_section*
output_section() const
{ return this->output_section_; }
bool
output_offset(const Relobj* object, unsigned int shndx,
section_offset_type offset,
- section_offset_type *poutput) const
+ section_offset_type* poutput) const
{ return this->do_output_offset(object, shndx, offset, poutput); }
// Return whether this is the merge section for the input section
// Set the entry size and the link.
void
- do_adjust_output_section(Output_section *os);
+ do_adjust_output_section(Output_section* os);
// Write to a map file.
void
// Add a relocation entry.
void
- add(Output_data *od, const Output_reloc_type& reloc)
+ add(Output_data* od, const Output_reloc_type& reloc)
{
this->relocs_.push_back(reloc);
this->set_current_data_size(this->relocs_.size() * reloc_size);
void
add_output_section(Output_section* os, unsigned int type, Output_data* od,
Address address, Addend addend)
- { this->add(os, Output_reloc_type(os, type, od, address, addend)); }
+ { this->add(od, Output_reloc_type(os, type, od, address, addend)); }
void
- add_output_section(Output_section* os, unsigned int type,
+ add_output_section(Output_section* os, unsigned int type, Output_data* od,
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address, Addend addend)
- { this->add(os, Output_reloc_type(os, type, relobj, shndx, address,
+ { this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
addend)); }
// Add an absolute relocation.
bool
add_global(Symbol* gsym, unsigned int got_type);
+ // Like add_global, but use the PLT offset of the global symbol if
+ // it has one.
+ bool
+ add_global_plt(Symbol* gsym, unsigned int got_type);
+
// Add an entry for a global symbol to the GOT, and add a dynamic
// relocation of type R_TYPE for the GOT entry.
void
add_local(Sized_relobj<size, big_endian>* object, unsigned int sym_index,
unsigned int got_type);
+ // Like add_local, but use the PLT offset of the local symbol if it
+ // has one.
+ bool
+ add_local_plt(Sized_relobj<size, big_endian>* object, unsigned int sym_index,
+ unsigned int got_type);
+
// Add an entry for a local symbol to the GOT, and add a dynamic
// relocation of type R_TYPE for the GOT entry.
void
public:
// Create a zero entry.
Got_entry()
- : local_sym_index_(CONSTANT_CODE)
+ : local_sym_index_(CONSTANT_CODE), use_plt_offset_(false)
{ this->u_.constant = 0; }
// Create a global symbol entry.
- explicit Got_entry(Symbol* gsym)
- : local_sym_index_(GSYM_CODE)
+ Got_entry(Symbol* gsym, bool use_plt_offset)
+ : local_sym_index_(GSYM_CODE), use_plt_offset_(use_plt_offset)
{ this->u_.gsym = gsym; }
// Create a local symbol entry.
Got_entry(Sized_relobj<size, big_endian>* object,
- unsigned int local_sym_index)
- : local_sym_index_(local_sym_index)
+ unsigned int local_sym_index, bool use_plt_offset)
+ : local_sym_index_(local_sym_index), use_plt_offset_(use_plt_offset)
{
gold_assert(local_sym_index != GSYM_CODE
- && local_sym_index != CONSTANT_CODE);
+ && local_sym_index != CONSTANT_CODE
+ && local_sym_index == this->local_sym_index_);
this->u_.object = object;
}
// Create a constant entry. The constant is a host value--it will
// be swapped, if necessary, when it is written out.
explicit Got_entry(Valtype constant)
- : local_sym_index_(CONSTANT_CODE)
+ : local_sym_index_(CONSTANT_CODE), use_plt_offset_(false)
{ this->u_.constant = constant; }
// Write the GOT entry to an output view.
private:
enum
{
- GSYM_CODE = -1U,
- CONSTANT_CODE = -2U
+ GSYM_CODE = 0x7fffffff,
+ CONSTANT_CODE = 0x7ffffffe
};
union
} u_;
// For a local symbol, the local symbol index. This is GSYM_CODE
// for a global symbol, or CONSTANT_CODE for a constant.
- unsigned int local_sym_index_;
+ unsigned int local_sym_index_ : 31;
+ // Whether to use the PLT offset of the symbol if it has one.
+ bool use_plt_offset_ : 1;
};
typedef std::vector<Got_entry> Got_entries;
template<int size, bool big_endian>
off_t
add_input_section(Layout* layout, Sized_relobj<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);
void
add_output_section_data(Output_section_data* posd);
- // Add a relaxed input section PORIS to this output section.
+ // Add a relaxed input section PORIS called NAME to this output section
+ // with LAYOUT.
void
- add_relaxed_input_section(Output_relaxed_input_section* poris);
+ add_relaxed_input_section(Layout* layout,
+ Output_relaxed_input_section* poris,
+ const std::string& name);
// Return the section name.
const char*
}
// For a relaxed input section.
- Input_section(Output_relaxed_input_section *psection)
+ Input_section(Output_relaxed_input_section* psection)
: shndx_(RELAXED_INPUT_SECTION_CODE), p2align_(0),
section_order_index_(0)
{
set_output_section(Output_section* os)
{
gold_assert(!this->is_input_section());
- Output_section_data *posd =
+ Output_section_data* posd =
this->is_relaxed_input_section() ? this->u2_.poris : this->u2_.posd;
posd->set_output_section(os);
}
bool
output_offset(const Relobj* object, unsigned int shndx,
section_offset_type offset,
- section_offset_type *poutput) const;
+ section_offset_type* poutput) const;
// Return whether this is the merge section for the input section
// SHNDX in OBJECT.
// *PSHNDX. This should only be called for a PT_LOAD segment.
uint64_t
set_section_addresses(const Layout*, bool reset, uint64_t addr,
- unsigned int increase_relro, off_t* poff,
- unsigned int* pshndx);
+ unsigned int* increase_relro, bool* has_relro,
+ off_t* poff, unsigned int* pshndx);
// Set the minimum alignment of this segment. This may be adjusted
// upward based on the section alignments.