From Cary Coutant: Fix x86_64 TLS. Also set DT_TEXTREL as well as
DF_TEXTREL.
This commit is contained in:
parent
2e53a11d03
commit
6a41d30bc2
2 changed files with 24 additions and 18 deletions
|
@ -1728,7 +1728,11 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
|
|||
// post-link tools can easily modify these flags if desired.
|
||||
unsigned int flags = 0;
|
||||
if (have_textrel)
|
||||
flags |= elfcpp::DF_TEXTREL;
|
||||
{
|
||||
// Add a DT_TEXTREL for compatibility with older loaders.
|
||||
odyn->add_constant(elfcpp::DT_TEXTREL, 0);
|
||||
flags |= elfcpp::DF_TEXTREL;
|
||||
}
|
||||
odyn->add_constant(elfcpp::DT_FLAGS, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -1585,12 +1585,13 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
const Sized_symbol<64>* gsym,
|
||||
const Symbol_value<64>* psymval,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<64>::Elf_Addr,
|
||||
elfcpp::Elf_types<64>::Elf_Addr address,
|
||||
off_t view_size)
|
||||
{
|
||||
Output_segment* tls_segment = relinfo->layout->tls_segment();
|
||||
|
||||
const Sized_relobj<64, false>* object = relinfo->object;
|
||||
const elfcpp::Elf_Xword addend = rela.get_r_addend();
|
||||
|
||||
elfcpp::Elf_types<64>::Elf_Addr value = psymval->value(relinfo->object, 0);
|
||||
|
||||
|
@ -1638,7 +1639,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
{
|
||||
// Relocate the field with the offset of the pair of GOT
|
||||
// entries.
|
||||
Relocate_functions<64, false>::rel64(view, got_offset);
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
Relocate_functions<64, false>::pcrela32(view, value, addend,
|
||||
address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1671,7 +1674,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
got_offset = (object->local_tls_got_offset(r_sym, false)
|
||||
- target->got_size());
|
||||
}
|
||||
Relocate_functions<64, false>::rel64(view, got_offset);
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
Relocate_functions<64, false>::pcrela32(view, value, addend,
|
||||
address);
|
||||
break;
|
||||
}
|
||||
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
|
||||
|
@ -1681,19 +1686,15 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
case elfcpp::R_X86_64_DTPOFF32:
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
||||
else
|
||||
value = value - tls_segment->vaddr();
|
||||
Relocate_functions<64, false>::rel32(view, value);
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_DTPOFF64:
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
||||
else
|
||||
value = value - tls_segment->vaddr();
|
||||
Relocate_functions<64, false>::rel64(view, value);
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela64(view, value, 0);
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
||||
|
@ -1722,7 +1723,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
got_offset = (object->local_got_offset(r_sym)
|
||||
- target->got_size());
|
||||
}
|
||||
Relocate_functions<64, false>::rel64(view, got_offset);
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
Relocate_functions<64, false>::pcrela32(view, value, addend, address);
|
||||
break;
|
||||
}
|
||||
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
|
||||
|
@ -1731,8 +1733,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
break;
|
||||
|
||||
case elfcpp::R_X86_64_TPOFF32: // Local-exec
|
||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
||||
Relocate_functions<64, false>::rel32(view, value);
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1764,7 +1766,7 @@ Target_x86_64::Relocate::tls_gd_to_ie(const Relocate_info<64, false>* relinfo,
|
|||
|
||||
memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0\0", 16);
|
||||
|
||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view + 8, value, 0);
|
||||
|
||||
// The next reloc should be a PLT32 reloc against __tls_get_addr.
|
||||
|
@ -1799,7 +1801,7 @@ Target_x86_64::Relocate::tls_gd_to_le(const Relocate_info<64, false>* relinfo,
|
|||
|
||||
memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0\0", 16);
|
||||
|
||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view + 8, value, 0);
|
||||
|
||||
// The next reloc should be a PLT32 reloc against __tls_get_addr.
|
||||
|
@ -1888,7 +1890,7 @@ Target_x86_64::Relocate::tls_ie_to_le(const Relocate_info<64, false>* relinfo,
|
|||
view[-1] = 0x80 | reg | (reg << 3);
|
||||
}
|
||||
|
||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue