From Craig Silverstein: New version of x86_64.cc.

This commit is contained in:
Ian Lance Taylor 2007-10-01 22:21:58 +00:00
parent 2e30d253b7
commit e822f2b19a

View file

@ -58,8 +58,8 @@ class Output_data_plt_x86_64;
class Target_x86_64 : public Sized_target<64, false> class Target_x86_64 : public Sized_target<64, false>
{ {
public: public:
// In the x86_64 ABI, it says "The AMD64 ABI architectures uses only // In the x86_64 ABI (p 68), it says "The AMD64 ABI architectures
// Elf64_Rela relocation entries with explicit addends." // uses only Elf64_Rela relocation entries with explicit addends."
typedef Output_data_reloc<elfcpp::SHT_RELA, true, 64, false> Reloc_section; typedef Output_data_reloc<elfcpp::SHT_RELA, true, 64, false> Reloc_section;
Target_x86_64() Target_x86_64()
@ -696,6 +696,8 @@ Target_x86_64::Scan::local(const General_options&,
switch (r_type) switch (r_type)
{ {
case elfcpp::R_X86_64_NONE: case elfcpp::R_X86_64_NONE:
case elfcpp::R_386_GNU_VTINHERIT:
case elfcpp::R_386_GNU_VTENTRY:
break; break;
case elfcpp::R_X86_64_64: case elfcpp::R_X86_64_64:
@ -714,8 +716,14 @@ Target_x86_64::Scan::local(const General_options&,
case elfcpp::R_X86_64_PC8: case elfcpp::R_X86_64_PC8:
break; break;
case elfcpp::R_X86_64_GOTOFF64:
case elfcpp::R_X86_64_GOTPCREL: case elfcpp::R_X86_64_GOTPCREL:
case elfcpp::R_X86_64_GOTPC32: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOT64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOTOFF64:
case elfcpp::R_X86_64_GOTPC64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOTPCREL64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOTPLT64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_PLTOFF64: // TODO(csilvers): correct?
// We need a GOT section. // We need a GOT section.
target->got_section(symtab, layout); target->got_section(symtab, layout);
break; break;
@ -729,21 +737,27 @@ Target_x86_64::Scan::local(const General_options&,
case elfcpp::R_X86_64_DTPMOD64: case elfcpp::R_X86_64_DTPMOD64:
case elfcpp::R_X86_64_DTPOFF64: case elfcpp::R_X86_64_DTPOFF64:
case elfcpp::R_X86_64_DTPOFF32: case elfcpp::R_X86_64_DTPOFF32:
case elfcpp::R_X86_64_GOTTPOFF: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLSDESC: case elfcpp::R_X86_64_TLSDESC:
case elfcpp::R_X86_64_GOTPC32_TLSDESC: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLSDESC_CALL: // TODO(csilvers): correct?
fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
program_name, object->name().c_str(), r_type); program_name, object->name().c_str(), r_type);
gold_exit(false); gold_exit(false);
break; break;
#if 0 #if 0
case elfcpp::R_X86_64_TLS_IE: case elfcpp::R_X86_64_TLSGD: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_GOTIE: case elfcpp::R_X86_64_TLSLD: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_LE:
case elfcpp::R_X86_64_TLS_GD: case elfcpp::R_386_TLS_IE:
case elfcpp::R_X86_64_TLS_LDM: case elfcpp::R_386_TLS_GOTIE:
case elfcpp::R_X86_64_TLS_LDO_64: case elfcpp::R_386_TLS_LE:
case elfcpp::R_X86_64_TLS_IE_64: case elfcpp::R_386_TLS_GD:
case elfcpp::R_X86_64_TLS_LE_64: case elfcpp::R_386_TLS_LDM:
case elfcpp::R_386_TLS_LDO_64:
case elfcpp::R_386_TLS_IE_64:
case elfcpp::R_386_TLS_LE_64:
{ {
bool output_is_shared = parameters->output_is_shared(); bool output_is_shared = parameters->output_is_shared();
r_type = Target_x86_64::optimize_tls_reloc(!output_is_shared, r_type = Target_x86_64::optimize_tls_reloc(!output_is_shared,
@ -772,17 +786,19 @@ Target_x86_64::Scan::local(const General_options&,
break; break;
#endif #endif
#if 0
case elfcpp::R_X86_64_GOT32: case elfcpp::R_X86_64_GOT32:
case elfcpp::R_X86_64_PLT32: case elfcpp::R_X86_64_PLT32:
case elfcpp::R_X86_64_TLS_GD_64: case elfcpp::R_X86_64_SIZE32: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_GD_PUSH: case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_GD_CALL: #if 0
case elfcpp::R_X86_64_TLS_GD_POP: case elfcpp::R_386_TLS_GD_64:
case elfcpp::R_X86_64_TLS_LDM_64: case elfcpp::R_386_TLS_GD_PUSH:
case elfcpp::R_X86_64_TLS_LDM_PUSH: case elfcpp::R_386_TLS_GD_CALL:
case elfcpp::R_X86_64_TLS_LDM_CALL: case elfcpp::R_386_TLS_GD_POP:
case elfcpp::R_X86_64_TLS_LDM_POP: case elfcpp::R_386_TLS_LDM_64:
case elfcpp::R_386_TLS_LDM_PUSH:
case elfcpp::R_386_TLS_LDM_CALL:
case elfcpp::R_386_TLS_LDM_POP:
#endif #endif
default: default:
fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"), fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
@ -808,6 +824,8 @@ Target_x86_64::Scan::global(const General_options& options,
switch (r_type) switch (r_type)
{ {
case elfcpp::R_X86_64_NONE: case elfcpp::R_X86_64_NONE:
case elfcpp::R_386_GNU_VTINHERIT:
case elfcpp::R_386_GNU_VTENTRY:
break; break;
case elfcpp::R_X86_64_64: case elfcpp::R_X86_64_64:
@ -865,57 +883,66 @@ Target_x86_64::Scan::global(const General_options& options,
target->make_plt_entry(symtab, layout, gsym); target->make_plt_entry(symtab, layout, gsym);
break; break;
case elfcpp::R_X86_64_GOTOFF64:
case elfcpp::R_X86_64_GOTPC32:
case elfcpp::R_X86_64_GOTPCREL: case elfcpp::R_X86_64_GOTPCREL:
case elfcpp::R_X86_64_GOTPC32: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOT64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOTOFF64:
case elfcpp::R_X86_64_GOTPC64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOTPCREL64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_GOTPLT64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_PLTOFF64: // TODO(csilvers): correct?
// We need a GOT section. // We need a GOT section.
target->got_section(symtab, layout); target->got_section(symtab, layout);
break; break;
#if 0
case elfcpp::R_X86_64_COPY: case elfcpp::R_X86_64_COPY:
case elfcpp::R_X86_64_GLOB_DAT: case elfcpp::R_X86_64_GLOB_DAT:
case elfcpp::R_X86_64_JUMP_SLOT: case elfcpp::R_X86_64_JUMP_SLOT:
case elfcpp::R_X86_64_RELATIVE: case elfcpp::R_X86_64_RELATIVE:
case elfcpp::R_X86_64_TLS_TPOFF: case elfcpp::R_X86_64_TPOFF64:
case elfcpp::R_X86_64_TPOFF32:
case elfcpp::R_X86_64_DTPMOD64: case elfcpp::R_X86_64_DTPMOD64:
case elfcpp::R_X86_64_DTPOFF64: case elfcpp::R_X86_64_DTPOFF64:
case elfcpp::R_X86_64_DTPOFF32: case elfcpp::R_X86_64_DTPOFF32:
case elfcpp::R_X86_64_TLS_TPOFF64: case elfcpp::R_X86_64_GOTTPOFF: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_DESC: case elfcpp::R_X86_64_TLSDESC:
case elfcpp::R_X86_64_GOTPC32_TLSDESC: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLSDESC_CALL: // TODO(csilvers): correct?
fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
program_name, object->name().c_str(), r_type); program_name, object->name().c_str(), r_type);
gold_exit(false); gold_exit(false);
break; break;
#endif
#if 0 #if 0
case elfcpp::R_X86_64_TLS_IE: case elfcpp::R_X86_64_TLSGD: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_GOTIE: case elfcpp::R_X86_64_TLSLD: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_LE:
case elfcpp::R_X86_64_TLS_GD: case elfcpp::R_386_TLS_IE:
case elfcpp::R_X86_64_TLS_LDM: case elfcpp::R_386_TLS_GOTIE:
case elfcpp::R_X86_64_TLS_LDO_64: case elfcpp::R_386_TLS_LE:
case elfcpp::R_X86_64_TLS_IE_64: case elfcpp::R_386_TLS_GD:
case elfcpp::R_X86_64_TLS_LE_64: case elfcpp::R_386_TLS_LDM:
case elfcpp::R_386_TLS_LDO_64:
case elfcpp::R_386_TLS_IE_64:
case elfcpp::R_386_TLS_LE_64:
{ {
const bool is_final = gsym->final_value_is_known(); const bool is_final = gsym->final_value_is_known();
r_type = Target_x86_64::optimize_tls_reloc(is_final, r_type); r_type = Target_x86_64::optimize_tls_reloc(is_final, r_type);
switch (r_type) switch (r_type)
{ {
case elfcpp::R_X86_64_TLS_LE: case elfcpp::R_386_TLS_LE:
case elfcpp::R_X86_64_TLS_LE_64: case elfcpp::R_386_TLS_LE_64:
// FIXME: If generating a shared object, we need to copy // FIXME: If generating a shared object, we need to copy
// this relocation into the object. // this relocation into the object.
gold_assert(!parameters->output_is_shared()); gold_assert(!parameters->output_is_shared());
break; break;
case elfcpp::R_X86_64_TLS_IE: case elfcpp::R_386_TLS_IE:
case elfcpp::R_X86_64_TLS_GOTIE: case elfcpp::R_386_TLS_GOTIE:
case elfcpp::R_X86_64_TLS_GD: case elfcpp::R_386_TLS_GD:
case elfcpp::R_X86_64_TLS_LDM: case elfcpp::R_386_TLS_LDM:
case elfcpp::R_X86_64_TLS_LDO_64: case elfcpp::R_386_TLS_LDO_64:
case elfcpp::R_X86_64_TLS_IE_64: case elfcpp::R_386_TLS_IE_64:
fprintf(stderr, fprintf(stderr,
_("%s: %s: unsupported reloc %u " _("%s: %s: unsupported reloc %u "
"against global symbol %s\n"), "against global symbol %s\n"),
@ -927,15 +954,17 @@ Target_x86_64::Scan::global(const General_options& options,
break; break;
#endif #endif
case elfcpp::R_X86_64_SIZE32: // TODO(csilvers): correct?
case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct?
#if 0 #if 0
case elfcpp::R_X86_64_TLS_GD_64: case elfcpp::R_386_TLS_GD_64:
case elfcpp::R_X86_64_TLS_GD_PUSH: case elfcpp::R_386_TLS_GD_PUSH:
case elfcpp::R_X86_64_TLS_GD_CALL: case elfcpp::R_386_TLS_GD_CALL:
case elfcpp::R_X86_64_TLS_GD_POP: case elfcpp::R_386_TLS_GD_POP:
case elfcpp::R_X86_64_TLS_LDM_64: case elfcpp::R_386_TLS_LDM_64:
case elfcpp::R_X86_64_TLS_LDM_PUSH: case elfcpp::R_386_TLS_LDM_PUSH:
case elfcpp::R_X86_64_TLS_LDM_CALL: case elfcpp::R_386_TLS_LDM_CALL:
case elfcpp::R_X86_64_TLS_LDM_POP: case elfcpp::R_386_TLS_LDM_POP:
#endif #endif
default: default:
fprintf(stderr, fprintf(stderr,
@ -1078,6 +1107,8 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
switch (r_type) switch (r_type)
{ {
case elfcpp::R_X86_64_NONE: case elfcpp::R_X86_64_NONE:
case elfcpp::R_386_GNU_VTINHERIT:
case elfcpp::R_386_GNU_VTENTRY:
break; break;
case elfcpp::R_X86_64_64: case elfcpp::R_X86_64_64:
@ -1090,12 +1121,10 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
break; break;
case elfcpp::R_X86_64_32: case elfcpp::R_X86_64_32:
// FIXME: Needs error checking.
Relocate_functions<64, false>::rela32(view, object, psymval, addend); Relocate_functions<64, false>::rela32(view, object, psymval, addend);
break; break;
case elfcpp::R_X86_64_32S: case elfcpp::R_X86_64_32S:
// FIXME: Needs error checking.
Relocate_functions<64, false>::rela32(view, object, psymval, addend); Relocate_functions<64, false>::rela32(view, object, psymval, addend);
break; break;
@ -1136,6 +1165,34 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
Relocate_functions<64, false>::rela32(view, gsym->got_offset(), addend); Relocate_functions<64, false>::rela32(view, gsym->got_offset(), addend);
break; break;
case elfcpp::R_X86_64_GOTPC32:
{
gold_assert(gsym);
elfcpp::Elf_types<64>::Elf_Addr value;
value = target->got_section(NULL, NULL)->address();
Relocate_functions<64, false>::pcrela32(view, value, addend, address);
}
break;
case elfcpp::R_X86_64_GOT64:
// The ABI doc says "Like GOT64, but indicates a PLT entry is needed."
// Since we always add a PLT entry, this is equivalent.
case elfcpp::R_X86_64_GOTPLT64: // TODO(csilvers): correct?
// Local GOT offsets not yet supported.
gold_assert(gsym);
gold_assert(gsym->has_got_offset());
Relocate_functions<64, false>::rela64(view, gsym->got_offset(), addend);
break;
case elfcpp::R_X86_64_GOTPC64:
{
gold_assert(gsym);
elfcpp::Elf_types<64>::Elf_Addr value;
value = target->got_section(NULL, NULL)->address();
Relocate_functions<64, false>::pcrela64(view, value, addend, address);
}
break;
case elfcpp::R_X86_64_GOTOFF64: case elfcpp::R_X86_64_GOTOFF64:
{ {
elfcpp::Elf_types<64>::Elf_Addr value; elfcpp::Elf_types<64>::Elf_Addr value;
@ -1156,6 +1213,17 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
} }
break; break;
case elfcpp::R_X86_64_GOTPCREL64:
{
gold_assert(gsym);
elfcpp::Elf_types<64>::Elf_Addr value;
// FIXME(csilvers): this is probably totally wrong for G + GOT
value = (target->got_section(NULL, NULL)->address()
+ (gsym->has_got_offset() ? gsym->got_offset() : 0));
Relocate_functions<64, false>::pcrela64(view, value, addend, address);
}
break;
case elfcpp::R_X86_64_COPY: case elfcpp::R_X86_64_COPY:
case elfcpp::R_X86_64_GLOB_DAT: case elfcpp::R_X86_64_GLOB_DAT:
case elfcpp::R_X86_64_JUMP_SLOT: case elfcpp::R_X86_64_JUMP_SLOT:
@ -1165,7 +1233,10 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
case elfcpp::R_X86_64_DTPMOD64: case elfcpp::R_X86_64_DTPMOD64:
case elfcpp::R_X86_64_DTPOFF64: case elfcpp::R_X86_64_DTPOFF64:
case elfcpp::R_X86_64_DTPOFF32: case elfcpp::R_X86_64_DTPOFF32:
case elfcpp::R_X86_64_GOTTPOFF: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLSDESC: case elfcpp::R_X86_64_TLSDESC:
case elfcpp::R_X86_64_GOTPC32_TLSDESC: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLSDESC_CALL: // TODO(csilvers): correct?
fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"), fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
program_name, program_name,
relinfo->location(relnum, rel.get_r_offset()).c_str(), relinfo->location(relnum, rel.get_r_offset()).c_str(),
@ -1174,14 +1245,17 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
break; break;
#if 0 #if 0
case elfcpp::R_X86_64_TLS_IE: case elfcpp::R_X86_64_TLSGD: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_GOTIE: case elfcpp::R_X86_64_TLSLD: // TODO(csilvers): correct?
case elfcpp::R_X86_64_TLS_LE:
case elfcpp::R_X86_64_TLS_GD: case elfcpp::R_386_TLS_IE:
case elfcpp::R_X86_64_TLS_LDM: case elfcpp::R_386_TLS_GOTIE:
case elfcpp::R_X86_64_TLS_LDO_64: case elfcpp::R_386_TLS_LE:
case elfcpp::R_X86_64_TLS_IE_64: case elfcpp::R_386_TLS_GD:
case elfcpp::R_X86_64_TLS_LE_64: case elfcpp::R_386_TLS_LDM:
case elfcpp::R_386_TLS_LDO_64:
case elfcpp::R_386_TLS_IE_64:
case elfcpp::R_386_TLS_LE_64:
this->relocate_tls(relinfo, relnum, rel, r_type, gsym, psymval, view, this->relocate_tls(relinfo, relnum, rel, r_type, gsym, psymval, view,
address, view_size); address, view_size);
break; break;
@ -1189,15 +1263,18 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
view_size++; // this is to make view_size used view_size++; // this is to make view_size used
#endif #endif
case elfcpp::R_X86_64_SIZE32: // TODO(csilvers): correct?
case elfcpp::R_X86_64_SIZE64: // TODO(csilvers): correct?
case elfcpp::R_X86_64_PLTOFF64: // TODO(csilvers): implement me!
#if 0 #if 0
case elfcpp::R_X86_64_TLS_GD_64: case elfcpp::R_386_TLS_GD_64:
case elfcpp::R_X86_64_TLS_GD_PUSH: case elfcpp::R_386_TLS_GD_PUSH:
case elfcpp::R_X86_64_TLS_GD_CALL: case elfcpp::R_386_TLS_GD_CALL:
case elfcpp::R_X86_64_TLS_GD_POP: case elfcpp::R_386_TLS_GD_POP:
case elfcpp::R_X86_64_TLS_LDM_64: case elfcpp::R_386_TLS_LDM_64:
case elfcpp::R_X86_64_TLS_LDM_PUSH: case elfcpp::R_386_TLS_LDM_PUSH:
case elfcpp::R_X86_64_TLS_LDM_CALL: case elfcpp::R_386_TLS_LDM_CALL:
case elfcpp::R_X86_64_TLS_LDM_POP: case elfcpp::R_386_TLS_LDM_POP:
#endif #endif
default: default:
fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),