Line 66... |
Line 66... |
{
|
{
|
INCREMENTAL_INPUT_IN_SYSTEM_DIR = 0x8000,
|
INCREMENTAL_INPUT_IN_SYSTEM_DIR = 0x8000,
|
INCREMENTAL_INPUT_AS_NEEDED = 0x4000
|
INCREMENTAL_INPUT_AS_NEEDED = 0x4000
|
};
|
};
|
|
|
|
// Symbol flags for the incremental symbol table.
|
|
// These flags are stored in the top two bits of
|
|
// the symbol index field.
|
|
|
|
enum Incremental_shlib_symbol_flags
|
|
{
|
|
// Symbol is defined in this library.
|
|
INCREMENTAL_SHLIB_SYM_DEF = 2,
|
|
// Symbol is defined in this library, with a COPY relocation.
|
|
INCREMENTAL_SHLIB_SYM_COPY = 3
|
|
};
|
|
|
|
static const int INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT = 30;
|
|
|
// Create an Incremental_binary object for FILE. Returns NULL is this is not
|
// Create an Incremental_binary object for FILE. Returns NULL is this is not
|
// possible, e.g. FILE is not an ELF file or has an unsupported target.
|
// possible, e.g. FILE is not an ELF file or has an unsupported target.
|
|
|
Incremental_binary*
|
Incremental_binary*
|
open_incremental_binary(Output_file* file);
|
open_incremental_binary(Output_file* file);
|
Line 1010... |
Line 1024... |
return this->inputs_->get_string(name_offset);
|
return this->inputs_->get_string(name_offset);
|
}
|
}
|
|
|
// Return the output symbol index for the Nth global symbol -- for shared
|
// Return the output symbol index for the Nth global symbol -- for shared
|
// libraries only. Sets *IS_DEF to TRUE if the symbol is defined in this
|
// libraries only. Sets *IS_DEF to TRUE if the symbol is defined in this
|
// input file.
|
// input file. Sets *IS_COPY to TRUE if the symbol was copied from this
|
|
// input file with a COPY relocation.
|
unsigned int
|
unsigned int
|
get_output_symbol_index(unsigned int n, bool* is_def)
|
get_output_symbol_index(unsigned int n, bool* is_def, bool* is_copy)
|
{
|
{
|
gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
|
gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
|
const unsigned char* p = (this->inputs_->p_
|
const unsigned char* p = (this->inputs_->p_
|
+ this->info_offset_ + 8
|
+ this->info_offset_ + 8
|
+ n * 4);
|
+ n * 4);
|
unsigned int output_symndx = Swap32::readval(p);
|
unsigned int output_symndx = Swap32::readval(p);
|
*is_def = (output_symndx & (1U << 31)) != 0;
|
unsigned int flags = output_symndx >> INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT;
|
return output_symndx & ((1U << 31) - 1);
|
output_symndx &= ((1U << INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT) - 1);
|
|
switch (flags)
|
|
{
|
|
case INCREMENTAL_SHLIB_SYM_DEF:
|
|
*is_def = true;
|
|
*is_copy = false;
|
|
break;
|
|
case INCREMENTAL_SHLIB_SYM_COPY:
|
|
*is_def = true;
|
|
*is_copy = true;
|
|
break;
|
|
default:
|
|
*is_def = false;
|
|
*is_copy = false;
|
|
}
|
|
return output_symndx;
|
}
|
}
|
|
|
private:
|
private:
|
// Size of an input section entry.
|
// Size of an input section entry.
|
static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
|
static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
|
Line 1395... |
Line 1425... |
// Process the GOT and PLT entries from the existing output file.
|
// Process the GOT and PLT entries from the existing output file.
|
void
|
void
|
process_got_plt(Symbol_table* symtab, Layout* layout)
|
process_got_plt(Symbol_table* symtab, Layout* layout)
|
{ this->do_process_got_plt(symtab, layout); }
|
{ this->do_process_got_plt(symtab, layout); }
|
|
|
|
// Emit COPY relocations from the existing output file.
|
|
void
|
|
emit_copy_relocs(Symbol_table* symtab)
|
|
{ this->do_emit_copy_relocs(symtab); }
|
|
|
// Apply incremental relocations for symbols whose values have changed.
|
// Apply incremental relocations for symbols whose values have changed.
|
void
|
void
|
apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
Output_file* of)
|
Output_file* of)
|
{ this->do_apply_incremental_relocs(symtab, layout, of); }
|
{ this->do_apply_incremental_relocs(symtab, layout, of); }
|
Line 1477... |
Line 1512... |
|
|
// Process the GOT and PLT entries from the existing output file.
|
// Process the GOT and PLT entries from the existing output file.
|
virtual void
|
virtual void
|
do_process_got_plt(Symbol_table* symtab, Layout* layout) = 0;
|
do_process_got_plt(Symbol_table* symtab, Layout* layout) = 0;
|
|
|
|
// Emit COPY relocations from the existing output file.
|
|
virtual void
|
|
do_emit_copy_relocs(Symbol_table* symtab) = 0;
|
|
|
// Apply incremental relocations for symbols whose values have changed.
|
// Apply incremental relocations for symbols whose values have changed.
|
virtual void
|
virtual void
|
do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;
|
do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;
|
|
|
virtual unsigned int
|
virtual unsigned int
|
Line 1512... |
Line 1551... |
public:
|
public:
|
Sized_incremental_binary(Output_file* output,
|
Sized_incremental_binary(Output_file* output,
|
const elfcpp::Ehdr<size, big_endian>& ehdr,
|
const elfcpp::Ehdr<size, big_endian>& ehdr,
|
Target* target)
|
Target* target)
|
: Incremental_binary(output, target), elf_file_(this, ehdr),
|
: Incremental_binary(output, target), elf_file_(this, ehdr),
|
input_objects_(), section_map_(), symbol_map_(), main_symtab_loc_(),
|
input_objects_(), section_map_(), symbol_map_(), copy_relocs_(),
|
main_strtab_loc_(), has_incremental_info_(false), inputs_reader_(),
|
main_symtab_loc_(), main_strtab_loc_(), has_incremental_info_(false),
|
symtab_reader_(), relocs_reader_(), got_plt_reader_(),
|
inputs_reader_(), symtab_reader_(), relocs_reader_(), got_plt_reader_(),
|
input_entry_readers_()
|
input_entry_readers_()
|
{ this->setup_readers(); }
|
{ this->setup_readers(); }
|
|
|
// Returns TRUE if the file contains incremental info.
|
// Returns TRUE if the file contains incremental info.
|
bool
|
bool
|
Line 1556... |
Line 1595... |
// input file symbol table.
|
// input file symbol table.
|
Symbol*
|
Symbol*
|
global_symbol(unsigned int symndx) const
|
global_symbol(unsigned int symndx) const
|
{ return this->symbol_map_[symndx]; }
|
{ return this->symbol_map_[symndx]; }
|
|
|
|
// Add a COPY relocation for a global symbol.
|
|
void
|
|
add_copy_reloc(Symbol* gsym, Output_section* os, off_t offset)
|
|
{ this->copy_relocs_.push_back(Copy_reloc(gsym, os, offset)); }
|
|
|
// Readers for the incremental info sections.
|
// Readers for the incremental info sections.
|
|
|
const Incremental_inputs_reader<size, big_endian>&
|
const Incremental_inputs_reader<size, big_endian>&
|
inputs_reader() const
|
inputs_reader() const
|
{ return this->inputs_reader_; }
|
{ return this->inputs_reader_; }
|
Line 1604... |
Line 1648... |
|
|
// Process the GOT and PLT entries from the existing output file.
|
// Process the GOT and PLT entries from the existing output file.
|
virtual void
|
virtual void
|
do_process_got_plt(Symbol_table* symtab, Layout* layout);
|
do_process_got_plt(Symbol_table* symtab, Layout* layout);
|
|
|
|
// Emit COPY relocations from the existing output file.
|
|
virtual void
|
|
do_emit_copy_relocs(Symbol_table* symtab);
|
|
|
// Apply incremental relocations for symbols whose values have changed.
|
// Apply incremental relocations for symbols whose values have changed.
|
virtual void
|
virtual void
|
do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
Output_file* of);
|
Output_file* of);
|
|
|
Line 1662... |
Line 1710... |
gold_assert(n < this->input_entry_readers_.size());
|
gold_assert(n < this->input_entry_readers_.size());
|
return &this->input_entry_readers_[n];
|
return &this->input_entry_readers_[n];
|
}
|
}
|
|
|
private:
|
private:
|
|
// List of symbols that need COPY relocations.
|
|
struct Copy_reloc
|
|
{
|
|
Copy_reloc(Symbol* sym, Output_section* os, off_t off)
|
|
: symbol(sym), output_section(os), offset(off)
|
|
{ }
|
|
|
|
// The global symbol to copy.
|
|
Symbol* symbol;
|
|
// The output section into which the symbol was copied.
|
|
Output_section* output_section;
|
|
// The offset within that output section.
|
|
off_t offset;
|
|
};
|
|
typedef std::vector<Copy_reloc> Copy_relocs;
|
|
|
bool
|
bool
|
find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
|
find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
|
unsigned int* p_symtab_shndx,
|
unsigned int* p_symtab_shndx,
|
unsigned int* p_relocs_shndx,
|
unsigned int* p_relocs_shndx,
|
unsigned int* p_got_plt_shndx,
|
unsigned int* p_got_plt_shndx,
|
Line 1685... |
Line 1749... |
std::vector<Output_section*> section_map_;
|
std::vector<Output_section*> section_map_;
|
|
|
// Map global symbols from the input file to the symbol table.
|
// Map global symbols from the input file to the symbol table.
|
std::vector<Symbol*> symbol_map_;
|
std::vector<Symbol*> symbol_map_;
|
|
|
|
// List of symbols that need COPY relocations.
|
|
Copy_relocs copy_relocs_;
|
|
|
// Locations of the main symbol table and symbol string table.
|
// Locations of the main symbol table and symbol string table.
|
Location main_symtab_loc_;
|
Location main_symtab_loc_;
|
Location main_strtab_loc_;
|
Location main_strtab_loc_;
|
|
|
// Readers for the incremental info sections.
|
// Readers for the incremental info sections.
|