#include "elfcpp_file.h"
#include "fileread.h"
#include "target.h"
+#include "archive.h"
namespace gold
{
class General_options;
class Task;
class Cref;
-class Archive;
class Layout;
class Output_section;
class Output_file;
struct Read_symbols_data
{
+ Read_symbols_data()
+ : section_headers(NULL), section_names(NULL), symbols(NULL),
+ symbol_names(NULL), versym(NULL), verdef(NULL), verneed(NULL)
+ { }
+
+ ~Read_symbols_data();
+
// Section headers.
File_view* section_headers;
// Section names.
struct Section_relocs
{
+ Section_relocs()
+ : contents(NULL)
+ { }
+
+ ~Section_relocs()
+ { delete this->contents; }
+
// Index of reloc section.
unsigned int reloc_shndx;
// Index of section that relocs apply to.
struct Read_relocs_data
{
+ Read_relocs_data()
+ : local_symbols(NULL)
+ { }
+
+ ~Read_relocs_data()
+ { delete this->local_symbols; }
+
typedef std::vector<Section_relocs> Relocs_list;
// The relocations.
Relocs_list relocs;
add_symbols(Symbol_table* symtab, Read_symbols_data* sd, Layout *layout)
{ this->do_add_symbols(symtab, sd, layout); }
+ // Add symbol information to the global symbol table.
+ Archive::Should_include
+ should_include_member(Symbol_table* symtab, Read_symbols_data* sd,
+ std::string* why)
+ { return this->do_should_include_member(symtab, sd, why); }
+
// Functions and types for the elfcpp::Elf_file interface. This
// permit us to use Object as the File template parameter for
// elfcpp::Elf_file.
virtual void
do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*) = 0;
+ virtual Archive::Should_include
+ do_should_include_member(Symbol_table* symtab, Read_symbols_data*,
+ std::string* why) = 0;
+
// Return the location of the contents of a section. Implemented by
// child class.
virtual Location
return this->output_sections_[shndx];
}
+ // The the output section of the input section with index SHNDX.
+ // This is only used currently to remove a section from the link in
+ // relaxation.
+ void
+ set_output_section(unsigned int shndx, Output_section* os)
+ {
+ gold_assert(shndx < this->output_sections_.size());
+ this->output_sections_[shndx] = os;
+ }
+
// Given a section index, return the offset in the Output_section.
// The return value will be -1U if the section is specially mapped,
// such as a merge section.
input_value() const
{ return this->u_.value; }
- // Return whether this symbol should go into the output symbol
+ // Return whether we have set the index in the output symbol table
+ // yet.
+ bool
+ is_output_symtab_index_set() const
+ {
+ return (this->output_symtab_index_ != 0
+ && this->output_symtab_index_ != -2U);
+ }
+
+ // Return whether this symbol may be discarded from the normal
+ // symbol table.
+ bool
+ may_be_discarded_from_output_symtab() const
+ {
+ gold_assert(!this->is_output_symtab_index_set());
+ return this->output_symtab_index_ != -2U;
+ }
+
+ // Return whether this symbol has an entry in the output symbol
// table.
bool
- needs_output_symtab_entry() const
- { return this->output_symtab_index_ != -1U; }
+ has_output_symtab_entry() const
+ {
+ gold_assert(this->is_output_symtab_index_set());
+ return this->output_symtab_index_ != -1U;
+ }
// Return the index in the output symbol table.
unsigned int
output_symtab_index() const
{
- gold_assert(this->output_symtab_index_ != 0);
+ gold_assert(this->is_output_symtab_index_set()
+ && this->output_symtab_index_ != -1U);
return this->output_symtab_index_;
}
void
set_output_symtab_index(unsigned int i)
{
- gold_assert(this->output_symtab_index_ == 0);
+ gold_assert(!this->is_output_symtab_index_set());
+ gold_assert(i != 0 && i != -1U && i != -2U);
this->output_symtab_index_ = i;
}
this->output_symtab_index_ = -1U;
}
+ // Record that this symbol must go into the output symbol table,
+ // because it there is a relocation that uses it.
+ void
+ set_must_have_output_symtab_entry()
+ {
+ gold_assert(!this->is_output_symtab_index_set());
+ this->output_symtab_index_ = -2U;
+ }
+
// Set the index in the output dynamic symbol table.
void
set_needs_output_dynsym_entry()
this->output_dynsym_index_ = 0;
}
- // Return whether this symbol should go into the output symbol
+ // Return whether this symbol should go into the dynamic symbol
// table.
bool
needs_output_dynsym_entry() const
return this->output_dynsym_index_ != -1U;
}
+ // Return whether this symbol has an entry in the dynamic symbol
+ // table.
+ bool
+ has_output_dynsym_entry() const
+ {
+ gold_assert(this->output_dynsym_index_ != 0);
+ return this->output_dynsym_index_ != -1U;
+ }
+
// Record that this symbol should go into the dynamic symbol table.
void
set_output_dynsym_index(unsigned int i)
{
gold_assert(this->output_dynsym_index_ == 0);
+ gold_assert(i != 0 && i != -1U);
this->output_dynsym_index_ = i;
}
private:
// The index of this local symbol in the output symbol table. This
- // will be -1 if the symbol should not go into the symbol table.
+ // will be 0 if no value has been assigned yet, and the symbol may
+ // be omitted. This will be -1U if the symbol should not go into
+ // the symbol table. This will be -2U if the symbol must go into
+ // the symbol table, but no index has been assigned yet.
unsigned int output_symtab_index_;
// The index of this local symbol in the dynamic symbol table. This
- // will be -1 if the symbol should not go into the symbol table.
+ // will be -1U if the symbol should not go into the symbol table.
unsigned int output_dynsym_index_;
// The section index in the input file in which this symbol is
// defined.
return this->local_values_[sym].input_shndx(is_ordinary);
}
+ // Record that local symbol SYM must be in the output symbol table.
+ void
+ set_must_have_output_symtab_entry(unsigned int sym)
+ {
+ gold_assert(sym < this->local_values_.size());
+ this->local_values_[sym].set_must_have_output_symtab_entry();
+ }
+
// Record that local symbol SYM needs a dynamic symbol entry.
void
set_needs_output_dynsym_entry(unsigned int sym)
Address
map_to_kept_section(unsigned int shndx, bool* found) const;
- // Make section offset invalid. This is needed for relaxation.
- void
- invalidate_section_offset(unsigned int shndx)
- { this->do_invalidate_section_offset(shndx); }
-
protected:
// Set up.
virtual void
void
do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
+ Archive::Should_include
+ do_should_include_member(Symbol_table* symtab, Read_symbols_data*,
+ std::string* why);
+
// Read the relocs.
void
do_read_relocs(Read_relocs_data*);
do_set_section_offset(unsigned int shndx, uint64_t off)
{
gold_assert(shndx < this->section_offsets_.size());
- this->section_offsets_[shndx] = convert_types<Address, uint64_t>(off);
- }
-
- // Set the offset of a section to invalid_address.
- virtual void
- do_invalidate_section_offset(unsigned int shndx)
- {
- gold_assert(shndx < this->section_offsets_.size());
- this->section_offsets_[shndx] = invalid_address;
+ this->section_offsets_[shndx] =
+ (off == static_cast<uint64_t>(-1)
+ ? invalid_address
+ : convert_types<Address, uint64_t>(off));
}
// Adjust a section index if necessary.
do_relocate_sections(const Symbol_table* symtab, const Layout* layout,
const unsigned char* pshdrs, Views* pviews);
+ // Allow a child to set output local symbol count.
+ void
+ set_output_local_symbol_count(unsigned int value)
+ { this->output_local_symbol_count_ = value; }
+
private:
// For convenience.
typedef Sized_relobj<size, big_endian> This;
any_dynamic() const
{ return !this->dynobj_list_.empty(); }
+ // Return the number of non dynamic objects.
+ int
+ number_of_relobjs() const
+ { return this->relobj_list_.size(); }
+
// Return the number of input objects.
int
number_of_input_objects() const