* incremental.cc (Sized_incremental_binary::setup_readers): Allocate
global symbol map. (Sized_incremental_binary::do_apply_incremental_relocs): New function. (Sized_incr_relobj::do_add_symbols): Add symbols to global symbol map. (Sized_incr_relobj::do_relocate): Remap section indices in incremental relocations. (Sized_incr_dynobj::do_add_symbols): Add symbols to global symbol map. (Sized_incr_dynobj::do_for_all_global_symbols): Remove FIXME. (Sized_incr_dynobj::do_for_all_local_got_entries): Likewise. * incremental.h (Incremental_inputs_reader::global_symbol_reader_at_offset): New function. (Incremental_binary::apply_incremental_relocs): New function. (Incremental_binary::do_apply_incremental_relocs): New function. (Sized_incremental_binary::Sized_incremental_binary): Initialize new data member. (Sized_incremental_binary::add_global_symbol): New function. (Sized_incremental_binary::global_symbol): New function. (Sized_incremental_binary::do_apply_incremental_relocs): New function. (Sized_incremental_binary::symbol_map_): New data member. * layout.cc (Layout_task_runner::run): Apply incremental relocations. * target.h (Sized_target::apply_relocation): New function. * target-reloc.h (apply_relocation): New function. * x86_64.cc (Target_x86_64::apply_relocation): New function.
This commit is contained in:
parent
c87e430233
commit
94a3fc8b83
7 changed files with 304 additions and 20 deletions
|
@ -1,3 +1,30 @@
|
|||
2011-04-22 Cary Coutant <ccoutant@google.com>
|
||||
|
||||
* incremental.cc (Sized_incremental_binary::setup_readers): Allocate
|
||||
global symbol map.
|
||||
(Sized_incremental_binary::do_apply_incremental_relocs): New function.
|
||||
(Sized_incr_relobj::do_add_symbols): Add symbols to global symbol map.
|
||||
(Sized_incr_relobj::do_relocate): Remap section indices in incremental
|
||||
relocations.
|
||||
(Sized_incr_dynobj::do_add_symbols): Add symbols to global symbol map.
|
||||
(Sized_incr_dynobj::do_for_all_global_symbols): Remove FIXME.
|
||||
(Sized_incr_dynobj::do_for_all_local_got_entries): Likewise.
|
||||
* incremental.h
|
||||
(Incremental_inputs_reader::global_symbol_reader_at_offset): New
|
||||
function.
|
||||
(Incremental_binary::apply_incremental_relocs): New function.
|
||||
(Incremental_binary::do_apply_incremental_relocs): New function.
|
||||
(Sized_incremental_binary::Sized_incremental_binary): Initialize new
|
||||
data member.
|
||||
(Sized_incremental_binary::add_global_symbol): New function.
|
||||
(Sized_incremental_binary::global_symbol): New function.
|
||||
(Sized_incremental_binary::do_apply_incremental_relocs): New function.
|
||||
(Sized_incremental_binary::symbol_map_): New data member.
|
||||
* layout.cc (Layout_task_runner::run): Apply incremental relocations.
|
||||
* target.h (Sized_target::apply_relocation): New function.
|
||||
* target-reloc.h (apply_relocation): New function.
|
||||
* x86_64.cc (Target_x86_64::apply_relocation): New function.
|
||||
|
||||
2011-04-22 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* arm.cc (Arm_output_section::Arm_output_section): Set SHF_LINK_ORDER
|
||||
|
|
|
@ -310,6 +310,10 @@ Sized_incremental_binary<size, big_endian>::setup_readers()
|
|||
}
|
||||
}
|
||||
|
||||
// Initialize the map of global symbols.
|
||||
unsigned int nglobals = this->symtab_reader_.symbol_count();
|
||||
this->symbol_map_.resize(nglobals);
|
||||
|
||||
this->has_incremental_info_ = true;
|
||||
}
|
||||
|
||||
|
@ -519,6 +523,102 @@ Sized_incremental_binary<size, big_endian>::do_reserve_layout(
|
|||
}
|
||||
}
|
||||
|
||||
// Apply incremental relocations for symbols whose values have changed.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Sized_incremental_binary<size, big_endian>::do_apply_incremental_relocs(
|
||||
const Symbol_table* symtab,
|
||||
Layout* layout,
|
||||
Output_file* of)
|
||||
{
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addend;
|
||||
Incremental_symtab_reader<big_endian> isymtab(this->symtab_reader());
|
||||
Incremental_relocs_reader<size, big_endian> irelocs(this->relocs_reader());
|
||||
unsigned int nglobals = isymtab.symbol_count();
|
||||
const unsigned int incr_reloc_size = irelocs.reloc_size;
|
||||
|
||||
Relocate_info<size, big_endian> relinfo;
|
||||
relinfo.symtab = symtab;
|
||||
relinfo.layout = layout;
|
||||
relinfo.object = NULL;
|
||||
relinfo.reloc_shndx = 0;
|
||||
relinfo.reloc_shdr = NULL;
|
||||
relinfo.data_shndx = 0;
|
||||
relinfo.data_shdr = NULL;
|
||||
|
||||
Sized_target<size, big_endian>* target =
|
||||
parameters->sized_target<size, big_endian>();
|
||||
|
||||
for (unsigned int i = 0; i < nglobals; i++)
|
||||
{
|
||||
const Symbol* gsym = this->global_symbol(i);
|
||||
|
||||
// If the symbol is not referenced from any unchanged input files,
|
||||
// we do not need to reapply any of its relocations.
|
||||
if (gsym == NULL)
|
||||
continue;
|
||||
|
||||
// If the symbol is defined in an unchanged file, we do not need to
|
||||
// reapply any of its relocations.
|
||||
if (gsym->source() == Symbol::FROM_OBJECT
|
||||
&& gsym->object()->is_incremental())
|
||||
continue;
|
||||
|
||||
gold_debug(DEBUG_INCREMENTAL,
|
||||
"Applying incremental relocations for global symbol %s [%d]",
|
||||
gsym->name(), i);
|
||||
|
||||
// Follow the linked list of input symbol table entries for this symbol.
|
||||
// We don't bother to figure out whether the symbol table entry belongs
|
||||
// to a changed or unchanged file because it's easier just to apply all
|
||||
// the relocations -- although we might scribble over an area that has
|
||||
// been reallocated, we do this before copying any new data into the
|
||||
// output file.
|
||||
unsigned int offset = isymtab.get_list_head(i);
|
||||
while (offset > 0)
|
||||
{
|
||||
Incremental_global_symbol_reader<big_endian> sym_info =
|
||||
this->inputs_reader().global_symbol_reader_at_offset(offset);
|
||||
unsigned int r_base = sym_info.reloc_offset();
|
||||
unsigned int r_count = sym_info.reloc_count();
|
||||
|
||||
// Apply each relocation for this symbol table entry.
|
||||
for (unsigned int j = 0; j < r_count;
|
||||
++j, r_base += incr_reloc_size)
|
||||
{
|
||||
unsigned int r_type = irelocs.get_r_type(r_base);
|
||||
unsigned int r_shndx = irelocs.get_r_shndx(r_base);
|
||||
Address r_offset = irelocs.get_r_offset(r_base);
|
||||
Addend r_addend = irelocs.get_r_addend(r_base);
|
||||
Output_section* os = this->output_section(r_shndx);
|
||||
Address address = os->address();
|
||||
off_t section_offset = os->offset();
|
||||
size_t view_size = os->data_size();
|
||||
unsigned char* const view = of->get_output_view(section_offset,
|
||||
view_size);
|
||||
|
||||
gold_debug(DEBUG_INCREMENTAL,
|
||||
" %08lx: %s + %d: type %d addend %ld",
|
||||
(long)(section_offset + r_offset),
|
||||
os->name(),
|
||||
(int)r_offset,
|
||||
r_type,
|
||||
(long)r_addend);
|
||||
|
||||
target->apply_relocation(&relinfo, r_offset, r_type, r_addend,
|
||||
gsym, view, address, view_size);
|
||||
|
||||
// FIXME: Do something more efficient if write_output_view
|
||||
// ever becomes more than a no-op.
|
||||
of->write_output_view(section_offset, view_size, view);
|
||||
}
|
||||
offset = sym_info.next_offset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get a view of the main symbol table and the symbol string table.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
|
@ -1652,17 +1752,17 @@ Sized_incr_relobj<size, big_endian>::do_add_symbols(
|
|||
elfcpp::Elf_strtab strtab(NULL, 0);
|
||||
this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
|
||||
|
||||
// Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
|
||||
// Incremental_relocs_reader<size, big_endian> irelocs(this->ibase_->relocs_reader());
|
||||
// unsigned int isym_count = isymtab.symbol_count();
|
||||
// unsigned int first_global = symtab_count - isym_count;
|
||||
Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
|
||||
unsigned int isym_count = isymtab.symbol_count();
|
||||
unsigned int first_global = symtab_count - isym_count;
|
||||
|
||||
unsigned const char* sym_p;
|
||||
for (unsigned int i = 0; i < nsyms; ++i)
|
||||
{
|
||||
Incremental_global_symbol_reader<big_endian> info =
|
||||
this->input_reader_.get_global_symbol_reader(i);
|
||||
sym_p = symtab_view.data() + info.output_symndx() * sym_size;
|
||||
unsigned int output_symndx = info.output_symndx();
|
||||
sym_p = symtab_view.data() + output_symndx * sym_size;
|
||||
elfcpp::Sym<size, big_endian> gsym(sym_p);
|
||||
const char* name;
|
||||
if (!strtab.get_c_string(gsym.get_st_name(), &name))
|
||||
|
@ -1708,6 +1808,8 @@ Sized_incr_relobj<size, big_endian>::do_add_symbols(
|
|||
|
||||
this->symbols_[i] =
|
||||
symtab->add_from_incrobj(this, name, NULL, &sym);
|
||||
this->ibase_->add_global_symbol(output_symndx - first_global,
|
||||
this->symbols_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1993,6 +2095,19 @@ Sized_incr_relobj<size, big_endian>::do_relocate(const Symbol_table*,
|
|||
off_t off = this->incr_reloc_output_index_ * incr_reloc_size;
|
||||
unsigned int len = this->incr_reloc_count_ * incr_reloc_size;
|
||||
memcpy(view + off, this->incr_relocs_, len);
|
||||
|
||||
// The output section table may have changed, so we need to map
|
||||
// the old section index to the new section index for each relocation.
|
||||
for (unsigned int i = 0; i < this->incr_reloc_count_; ++i)
|
||||
{
|
||||
unsigned char* pov = view + off + i * incr_reloc_size;
|
||||
unsigned int shndx = elfcpp::Swap<32, big_endian>::readval(pov + 4);
|
||||
Output_section* os = this->ibase_->output_section(shndx);
|
||||
gold_assert(os != NULL);
|
||||
shndx = os->out_shndx();
|
||||
elfcpp::Swap<32, big_endian>::writeval(pov + 4, shndx);
|
||||
}
|
||||
|
||||
of->write_output_view(off, len, view);
|
||||
}
|
||||
|
||||
|
@ -2068,10 +2183,9 @@ Sized_incr_dynobj<size, big_endian>::do_add_symbols(
|
|||
elfcpp::Elf_strtab strtab(NULL, 0);
|
||||
this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
|
||||
|
||||
// Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
|
||||
// Incremental_relocs_reader<size, big_endian> irelocs(this->ibase_->relocs_reader());
|
||||
// unsigned int isym_count = isymtab.symbol_count();
|
||||
// unsigned int first_global = symtab_count - isym_count;
|
||||
Incremental_symtab_reader<big_endian> isymtab(this->ibase_->symtab_reader());
|
||||
unsigned int isym_count = isymtab.symbol_count();
|
||||
unsigned int first_global = symtab_count - isym_count;
|
||||
|
||||
unsigned const char* sym_p;
|
||||
for (unsigned int i = 0; i < nsyms; ++i)
|
||||
|
@ -2117,6 +2231,8 @@ Sized_incr_dynobj<size, big_endian>::do_add_symbols(
|
|||
|
||||
this->symbols_[i] =
|
||||
symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
|
||||
this->ibase_->add_global_symbol(output_symndx - first_global,
|
||||
this->symbols_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2152,7 +2268,6 @@ void
|
|||
Sized_incr_dynobj<size, big_endian>::do_for_all_local_got_entries(
|
||||
Got_offset_list::Visitor*) const
|
||||
{
|
||||
// FIXME: Implement Sized_incr_dynobj::do_for_all_local_got_entries.
|
||||
}
|
||||
|
||||
// Get the size of a section.
|
||||
|
|
|
@ -898,6 +898,14 @@ class Incremental_inputs_reader
|
|||
return Incremental_input_entry_reader(this, offset);
|
||||
}
|
||||
|
||||
// Return a reader for the global symbol info at OFFSET.
|
||||
Incremental_global_symbol_reader<big_endian>
|
||||
global_symbol_reader_at_offset(unsigned int offset) const
|
||||
{
|
||||
const unsigned char* p = this->p_ + offset;
|
||||
return Incremental_global_symbol_reader<big_endian>(p);
|
||||
}
|
||||
|
||||
private:
|
||||
// Lookup a string in the ELF string table.
|
||||
const char* get_string(unsigned int offset) const
|
||||
|
@ -1207,6 +1215,12 @@ class Incremental_binary
|
|||
reserve_layout(unsigned int input_file_index)
|
||||
{ this->do_reserve_layout(input_file_index); }
|
||||
|
||||
// Apply incremental relocations for symbols whose values have changed.
|
||||
void
|
||||
apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
||||
Output_file* of)
|
||||
{ this->do_apply_incremental_relocs(symtab, layout, of); }
|
||||
|
||||
// Functions and types for the elfcpp::Elf_file interface. This
|
||||
// permit us to use Incremental_binary as the File template parameter for
|
||||
// elfcpp::Elf_file.
|
||||
|
@ -1279,6 +1293,10 @@ class Incremental_binary
|
|||
virtual void
|
||||
do_reserve_layout(unsigned int input_file_index) = 0;
|
||||
|
||||
// Apply incremental relocations for symbols whose values have changed.
|
||||
virtual void
|
||||
do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;
|
||||
|
||||
virtual unsigned int
|
||||
do_input_file_count() const = 0;
|
||||
|
||||
|
@ -1307,8 +1325,8 @@ class Sized_incremental_binary : public Incremental_binary
|
|||
const elfcpp::Ehdr<size, big_endian>& ehdr,
|
||||
Target* target)
|
||||
: Incremental_binary(output, target), elf_file_(this, ehdr),
|
||||
section_map_(), has_incremental_info_(false), inputs_reader_(),
|
||||
symtab_reader_(), relocs_reader_(), got_plt_reader_(),
|
||||
section_map_(), symbol_map_(), has_incremental_info_(false),
|
||||
inputs_reader_(), symtab_reader_(), relocs_reader_(), got_plt_reader_(),
|
||||
input_entry_readers_()
|
||||
{ this->setup_readers(); }
|
||||
|
||||
|
@ -1322,6 +1340,20 @@ class Sized_incremental_binary : public Incremental_binary
|
|||
output_section(unsigned int shndx)
|
||||
{ return this->section_map_[shndx]; }
|
||||
|
||||
// Map a symbol table entry from the input file to the output symbol table.
|
||||
// SYMNDX is relative to the first forced-local or global symbol in the
|
||||
// input file symbol table.
|
||||
void
|
||||
add_global_symbol(unsigned int symndx, Symbol* gsym)
|
||||
{ this->symbol_map_[symndx] = gsym; }
|
||||
|
||||
// Map a symbol table entry from the input file to the output symbol table.
|
||||
// SYMNDX is relative to the first forced-local or global symbol in the
|
||||
// input file symbol table.
|
||||
Symbol*
|
||||
global_symbol(unsigned int symndx) const
|
||||
{ return this->symbol_map_[symndx]; }
|
||||
|
||||
// Readers for the incremental info sections.
|
||||
|
||||
const Incremental_inputs_reader<size, big_endian>&
|
||||
|
@ -1366,6 +1398,11 @@ class Sized_incremental_binary : public Incremental_binary
|
|||
virtual void
|
||||
do_reserve_layout(unsigned int input_file_index);
|
||||
|
||||
// Apply incremental relocations for symbols whose values have changed.
|
||||
virtual void
|
||||
do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
|
||||
Output_file* of);
|
||||
|
||||
// Proxy class for a sized Incremental_input_entry_reader.
|
||||
|
||||
class Sized_input_reader : public Input_reader
|
||||
|
@ -1435,6 +1472,9 @@ class Sized_incremental_binary : public Incremental_binary
|
|||
// Map section index to an Output_section in the updated layout.
|
||||
std::vector<Output_section*> section_map_;
|
||||
|
||||
// Map global symbols from the input file to the symbol table.
|
||||
std::vector<Symbol*> symbol_map_;
|
||||
|
||||
// Readers for the incremental info sections.
|
||||
bool has_incremental_info_;
|
||||
Incremental_inputs_reader<size, big_endian> inputs_reader_;
|
||||
|
|
|
@ -298,10 +298,11 @@ Layout::Relaxation_debug_check::verify_sections(
|
|||
void
|
||||
Layout_task_runner::run(Workqueue* workqueue, const Task* task)
|
||||
{
|
||||
off_t file_size = this->layout_->finalize(this->input_objects_,
|
||||
this->symtab_,
|
||||
this->target_,
|
||||
task);
|
||||
Layout* layout = this->layout_;
|
||||
off_t file_size = layout->finalize(this->input_objects_,
|
||||
this->symtab_,
|
||||
this->target_,
|
||||
task);
|
||||
|
||||
// Now we know the final size of the output file and we know where
|
||||
// each piece of information goes.
|
||||
|
@ -309,11 +310,11 @@ Layout_task_runner::run(Workqueue* workqueue, const Task* task)
|
|||
if (this->mapfile_ != NULL)
|
||||
{
|
||||
this->mapfile_->print_discarded_sections(this->input_objects_);
|
||||
this->layout_->print_to_mapfile(this->mapfile_);
|
||||
layout->print_to_mapfile(this->mapfile_);
|
||||
}
|
||||
|
||||
Output_file* of;
|
||||
if (this->layout_->incremental_base() == NULL)
|
||||
if (layout->incremental_base() == NULL)
|
||||
{
|
||||
of = new Output_file(parameters->options().output_file_name());
|
||||
if (this->options_.oformat_enum() != General_options::OBJECT_FORMAT_ELF)
|
||||
|
@ -322,13 +323,24 @@ Layout_task_runner::run(Workqueue* workqueue, const Task* task)
|
|||
}
|
||||
else
|
||||
{
|
||||
of = this->layout_->incremental_base()->output_file();
|
||||
of = layout->incremental_base()->output_file();
|
||||
|
||||
// Apply the incremental relocations for symbols whose values
|
||||
// have changed. We do this before we resize the file and start
|
||||
// writing anything else to it, so that we can read the old
|
||||
// incremental information from the file before (possibly)
|
||||
// overwriting it.
|
||||
if (parameters->incremental_update())
|
||||
layout->incremental_base()->apply_incremental_relocs(this->symtab_,
|
||||
this->layout_,
|
||||
of);
|
||||
|
||||
of->resize(file_size);
|
||||
}
|
||||
|
||||
// Queue up the final set of tasks.
|
||||
gold::queue_final_tasks(this->options_, this->input_objects_,
|
||||
this->symtab_, this->layout_, workqueue, of);
|
||||
this->symtab_, layout, workqueue, of);
|
||||
}
|
||||
|
||||
// Layout methods.
|
||||
|
|
|
@ -362,6 +362,46 @@ relocate_section(
|
|||
}
|
||||
}
|
||||
|
||||
// Apply an incremental relocation.
|
||||
|
||||
template<int size, bool big_endian, typename Target_type,
|
||||
typename Relocate>
|
||||
void
|
||||
apply_relocation(const Relocate_info<size, big_endian>* relinfo,
|
||||
Target_type* target,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
|
||||
unsigned int r_type,
|
||||
typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
|
||||
const Symbol* gsym,
|
||||
unsigned char* view,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr address,
|
||||
section_size_type view_size)
|
||||
{
|
||||
// Construct the ELF relocation in a temporary buffer.
|
||||
const int reloc_size = elfcpp::Elf_sizes<64>::rela_size;
|
||||
unsigned char relbuf[reloc_size];
|
||||
elfcpp::Rela<64, false> rel(relbuf);
|
||||
elfcpp::Rela_write<64, false> orel(relbuf);
|
||||
orel.put_r_offset(r_offset);
|
||||
orel.put_r_info(elfcpp::elf_r_info<64>(0, r_type));
|
||||
orel.put_r_addend(r_addend);
|
||||
|
||||
// Setup a Symbol_value for the global symbol.
|
||||
const Sized_symbol<64>* sym = static_cast<const Sized_symbol<64>*>(gsym);
|
||||
Symbol_value<64> symval;
|
||||
gold_assert(sym->has_symtab_index() && sym->symtab_index() != -1U);
|
||||
symval.set_output_symtab_index(sym->symtab_index());
|
||||
symval.set_output_value(sym->value());
|
||||
if (gsym->type() == elfcpp::STT_TLS)
|
||||
symval.set_is_tls_symbol();
|
||||
else if (gsym->type() == elfcpp::STT_GNU_IFUNC)
|
||||
symval.set_is_ifunc_symbol();
|
||||
|
||||
Relocate relocate;
|
||||
relocate.relocate(relinfo, target, NULL, -1U, rel, r_type, sym, &symval,
|
||||
view + r_offset, address + r_offset, view_size);
|
||||
}
|
||||
|
||||
// This class may be used as a typical class for the
|
||||
// Scan_relocatable_reloc parameter to scan_relocatable_relocs. The
|
||||
// template parameter Classify_reloc must be a class type which
|
||||
|
|
|
@ -795,6 +795,19 @@ class Sized_target : public Target
|
|||
plt_entry_size() const
|
||||
{ gold_unreachable(); }
|
||||
|
||||
// Apply an incremental relocation.
|
||||
|
||||
virtual void
|
||||
apply_relocation(const Relocate_info<size, big_endian>* /* relinfo */,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr /* r_offset */,
|
||||
unsigned int /* r_type */,
|
||||
typename elfcpp::Elf_types<size>::Elf_Swxword /* r_addend */,
|
||||
const Symbol* /* gsym */,
|
||||
unsigned char* /* view */,
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr /* address */,
|
||||
section_size_type /* view_size */)
|
||||
{ gold_unreachable(); }
|
||||
|
||||
protected:
|
||||
Sized_target(const Target::Target_info* pti)
|
||||
: Target(pti)
|
||||
|
|
|
@ -345,6 +345,17 @@ class Target_x86_64 : public Target_freebsd<64, false>
|
|||
unsigned int
|
||||
plt_entry_size() const;
|
||||
|
||||
// Apply an incremental relocation.
|
||||
void
|
||||
apply_relocation(const Relocate_info<64, false>* relinfo,
|
||||
elfcpp::Elf_types<64>::Elf_Addr r_offset,
|
||||
unsigned int r_type,
|
||||
elfcpp::Elf_types<64>::Elf_Swxword r_addend,
|
||||
const Symbol* gsym,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<64>::Elf_Addr address,
|
||||
section_size_type view_size);
|
||||
|
||||
// Add a new reloc argument, returning the index in the vector.
|
||||
size_t
|
||||
add_tlsdesc_info(Sized_relobj<64, false>* object, unsigned int r_sym)
|
||||
|
@ -3014,6 +3025,32 @@ Target_x86_64::relocate_section(
|
|||
reloc_symbol_changes);
|
||||
}
|
||||
|
||||
// Apply an incremental relocation. Incremental relocations always refer
|
||||
// to global symbols.
|
||||
|
||||
void
|
||||
Target_x86_64::apply_relocation(
|
||||
const Relocate_info<64, false>* relinfo,
|
||||
elfcpp::Elf_types<64>::Elf_Addr r_offset,
|
||||
unsigned int r_type,
|
||||
elfcpp::Elf_types<64>::Elf_Swxword r_addend,
|
||||
const Symbol* gsym,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<64>::Elf_Addr address,
|
||||
section_size_type view_size)
|
||||
{
|
||||
gold::apply_relocation<64, false, Target_x86_64, Target_x86_64::Relocate>(
|
||||
relinfo,
|
||||
this,
|
||||
r_offset,
|
||||
r_type,
|
||||
r_addend,
|
||||
gsym,
|
||||
view,
|
||||
address,
|
||||
view_size);
|
||||
}
|
||||
|
||||
// Return the size of a relocation while scanning during a relocatable
|
||||
// link.
|
||||
|
||||
|
|
Loading…
Reference in a new issue