mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 22:48:57 +08:00
* copy-relocs.cc (Copy_relocs::copy_reloc): Call make_copy_reloc
instead of emit_copy_reloc. (Copy_relocs::emit_copy_reloc): Refactor. (Copy_relocs::make_copy_reloc): New function. (Copy_relocs::add_copy_reloc): Remove. * copy-relocs.h (Copy_relocs::emit_copy_reloc): Move to public section. (Copy_relocs::make_copy_reloc): New function. (Copy_relocs::add_copy_reloc): Remove. * gold.cc (queue_middle_tasks): Emit old COPY relocations from unchanged input files. * incremental-dump.cc (dump_incremental_inputs): Print "COPY" flag. * incremental.cc (Sized_incremental_binary::do_reserve_layout): Reserve BSS space for COPY relocations. (Sized_incremental_binary::do_emit_copy_relocs): New function. (Output_section_incremental_inputs::write_info_blocks): Record whether a symbol is copied from a shared object. (Sized_incr_dynobj::do_add_symbols): Record COPY relocations. * incremental.h (enum Incremental_shlib_symbol_flags): New type. (INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT): New constant. (Incremental_input_entry_reader::get_output_symbol_index): Add is_copy parameter. (Incremental_binary::emit_copy_relocs): New function. (Incremental_binary::do_emit_copy_relocs): New function. (Sized_incremental_binary::Sized_incremental_binary): Initialize new data member. (Sized_incremental_binary::add_copy_reloc): New function. (Sized_incremental_binary::do_emit_copy_relocs): New function. (Sized_incremental_binary::Copy_reloc): New struct. (Sized_incremental_binary::Copy_relocs): New typedef. (Sized_incremental_binary::copy_relocs_): New data member. * symtab.cc (Symbol_table::add_from_incrobj): Change return type. * symtab.h (Symbol_table::add_from_incrobj): Change return type. * target.h (Sized_target::emit_copy_reloc): New function. * x86_64.cc (Target_x86_64::emit_copy_reloc): New function.
This commit is contained in:
@ -68,6 +68,20 @@ enum Incremental_input_flags
|
||||
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
|
||||
// possible, e.g. FILE is not an ELF file or has an unsupported target.
|
||||
|
||||
@ -1012,17 +1026,33 @@ class Incremental_inputs_reader
|
||||
|
||||
// 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
|
||||
// input file.
|
||||
// input file. Sets *IS_COPY to TRUE if the symbol was copied from this
|
||||
// input file with a COPY relocation.
|
||||
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);
|
||||
const unsigned char* p = (this->inputs_->p_
|
||||
+ this->info_offset_ + 8
|
||||
+ n * 4);
|
||||
unsigned int output_symndx = Swap32::readval(p);
|
||||
*is_def = (output_symndx & (1U << 31)) != 0;
|
||||
return output_symndx & ((1U << 31) - 1);
|
||||
unsigned int flags = output_symndx >> INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT;
|
||||
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:
|
||||
@ -1397,6 +1427,11 @@ class Incremental_binary
|
||||
process_got_plt(Symbol_table* symtab, Layout* 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.
|
||||
void
|
||||
apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
||||
@ -1479,6 +1514,10 @@ class Incremental_binary
|
||||
virtual void
|
||||
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.
|
||||
virtual void
|
||||
do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;
|
||||
@ -1514,9 +1553,9 @@ class Sized_incremental_binary : public Incremental_binary
|
||||
const elfcpp::Ehdr<size, big_endian>& ehdr,
|
||||
Target* target)
|
||||
: Incremental_binary(output, target), elf_file_(this, ehdr),
|
||||
input_objects_(), section_map_(), symbol_map_(), main_symtab_loc_(),
|
||||
main_strtab_loc_(), has_incremental_info_(false), inputs_reader_(),
|
||||
symtab_reader_(), relocs_reader_(), got_plt_reader_(),
|
||||
input_objects_(), section_map_(), symbol_map_(), copy_relocs_(),
|
||||
main_symtab_loc_(), main_strtab_loc_(), has_incremental_info_(false),
|
||||
inputs_reader_(), symtab_reader_(), relocs_reader_(), got_plt_reader_(),
|
||||
input_entry_readers_()
|
||||
{ this->setup_readers(); }
|
||||
|
||||
@ -1558,6 +1597,11 @@ class Sized_incremental_binary : public Incremental_binary
|
||||
global_symbol(unsigned int symndx) const
|
||||
{ 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.
|
||||
|
||||
const Incremental_inputs_reader<size, big_endian>&
|
||||
@ -1606,6 +1650,10 @@ class Sized_incremental_binary : public Incremental_binary
|
||||
virtual void
|
||||
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.
|
||||
virtual void
|
||||
do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
||||
@ -1664,6 +1712,22 @@ class Sized_incremental_binary : public Incremental_binary
|
||||
}
|
||||
|
||||
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
|
||||
find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
|
||||
unsigned int* p_symtab_shndx,
|
||||
@ -1687,6 +1751,9 @@ class Sized_incremental_binary : public Incremental_binary
|
||||
// Map global symbols from the input file to the symbol table.
|
||||
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.
|
||||
Location main_symtab_loc_;
|
||||
Location main_strtab_loc_;
|
||||
|
Reference in New Issue
Block a user