// Return whether SYM is defined by the ABI.
bool
- do_is_defined_by_abi(Symbol* sym) const
+ do_is_defined_by_abi(const Symbol* sym) const
{ return strcmp(sym->name(), "__tls_get_addr") == 0; }
// Return the size of the GOT section.
void
make_plt_entry(Symbol_table*, Layout*, Symbol*);
- // Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+ // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
void
define_tls_base_symbol(Symbol_table*, Layout*);
// Add a potential copy relocation.
void
- copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object,
+ copy_reloc(Symbol_table* symtab, Layout* layout,
+ Sized_relobj<64, false>* object,
unsigned int shndx, Output_section* output_section,
Symbol* sym, const elfcpp::Rela<64, false>& reloc)
{
// create another set of data in the .got section. Note that we
// always create a PLT if we create a GOT, although the PLT
// might be empty.
- this->got_plt_ = new Output_data_space(8);
+ this->got_plt_ = new Output_data_space(8, "** GOT PLT");
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
(elfcpp::SHF_ALLOC
| elfcpp::SHF_WRITE),
void
do_adjust_output_section(Output_section* os);
+ // Write to a map file.
+ void
+ do_print_to_mapfile(Mapfile* mapfile) const
+ { mapfile->print_output_data(this, _("** PLT")); }
+
private:
// The size of an entry in the PLT.
static const int plt_entry_size = 16;
this->plt_->add_entry(gsym);
}
-// Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
void
Target_x86_64::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
Output_segment* tls_segment = layout->tls_segment();
if (tls_segment != NULL)
{
+ bool is_exec = parameters->options().output_is_executable();
symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
tls_segment, 0, 0,
elfcpp::STT_TLS,
elfcpp::STB_LOCAL,
elfcpp::STV_HIDDEN, 0,
- Symbol::SEGMENT_END, true);
+ (is_exec
+ ? Symbol::SEGMENT_END
+ : Symbol::SEGMENT_START),
+ true);
}
this->tls_base_symbol_defined_ = true;
}
// Pick the value to use for symbols defined in shared objects.
Symbol_value<64> symval;
if (gsym != NULL
- && (gsym->is_from_dynobj()
- || (parameters->options().shared()
- && (gsym->is_undefined() || gsym->is_preemptible())))
- && gsym->has_plt_offset())
+ && gsym->use_plt_offset(r_type == elfcpp::R_X86_64_PC64
+ || r_type == elfcpp::R_X86_64_PC32
+ || r_type == elfcpp::R_X86_64_PC16
+ || r_type == elfcpp::R_X86_64_PC8))
{
symval.set_output_value(target->plt_section()->address()
+ gsym->plt_offset());
if (this->saw_tls_block_reloc_)
value -= tls_segment->memsz();
}
- Relocate_functions<64, false>::rela32(view, value, 0);
+ Relocate_functions<64, false>::rela32(view, value, addend);
break;
case elfcpp::R_X86_64_DTPOFF64:
if (this->saw_tls_block_reloc_)
value -= tls_segment->memsz();
}
- Relocate_functions<64, false>::rela64(view, value, 0);
+ Relocate_functions<64, false>::rela64(view, value, addend);
break;
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
case elfcpp::R_X86_64_TPOFF32: // Local-exec
value -= tls_segment->memsz();
- Relocate_functions<64, false>::rela32(view, value, 0);
+ Relocate_functions<64, false>::rela32(view, value, addend);
break;
}
}