mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-10 01:42:21 +08:00
From Cary Coutant: Fix x86_64 TLS. Also set DT_TEXTREL as well as
DF_TEXTREL.
This commit is contained in:
@ -1728,7 +1728,11 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
|
|||||||
// post-link tools can easily modify these flags if desired.
|
// post-link tools can easily modify these flags if desired.
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
if (have_textrel)
|
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);
|
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 Sized_symbol<64>* gsym,
|
||||||
const Symbol_value<64>* psymval,
|
const Symbol_value<64>* psymval,
|
||||||
unsigned char* view,
|
unsigned char* view,
|
||||||
elfcpp::Elf_types<64>::Elf_Addr,
|
elfcpp::Elf_types<64>::Elf_Addr address,
|
||||||
off_t view_size)
|
off_t view_size)
|
||||||
{
|
{
|
||||||
Output_segment* tls_segment = relinfo->layout->tls_segment();
|
Output_segment* tls_segment = relinfo->layout->tls_segment();
|
||||||
|
|
||||||
const Sized_relobj<64, false>* object = relinfo->object;
|
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);
|
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
|
// Relocate the field with the offset of the pair of GOT
|
||||||
// entries.
|
// 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;
|
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)
|
got_offset = (object->local_tls_got_offset(r_sym, false)
|
||||||
- target->got_size());
|
- 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;
|
break;
|
||||||
}
|
}
|
||||||
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
|
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:
|
case elfcpp::R_X86_64_DTPOFF32:
|
||||||
gold_assert(tls_segment != NULL);
|
gold_assert(tls_segment != NULL);
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
value -= tls_segment->memsz();
|
||||||
else
|
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||||
value = value - tls_segment->vaddr();
|
|
||||||
Relocate_functions<64, false>::rel32(view, value);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_DTPOFF64:
|
case elfcpp::R_X86_64_DTPOFF64:
|
||||||
gold_assert(tls_segment != NULL);
|
gold_assert(tls_segment != NULL);
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
value -= tls_segment->memsz();
|
||||||
else
|
Relocate_functions<64, false>::rela64(view, value, 0);
|
||||||
value = value - tls_segment->vaddr();
|
|
||||||
Relocate_functions<64, false>::rel64(view, value);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
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)
|
got_offset = (object->local_got_offset(r_sym)
|
||||||
- target->got_size());
|
- 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;
|
break;
|
||||||
}
|
}
|
||||||
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
|
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;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_TPOFF32: // Local-exec
|
case elfcpp::R_X86_64_TPOFF32: // Local-exec
|
||||||
value = value - (tls_segment->vaddr() + tls_segment->memsz());
|
value -= tls_segment->memsz();
|
||||||
Relocate_functions<64, false>::rel32(view, value);
|
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||||
break;
|
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);
|
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);
|
Relocate_functions<64, false>::rela32(view + 8, value, 0);
|
||||||
|
|
||||||
// The next reloc should be a PLT32 reloc against __tls_get_addr.
|
// 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);
|
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);
|
Relocate_functions<64, false>::rela32(view + 8, value, 0);
|
||||||
|
|
||||||
// The next reloc should be a PLT32 reloc against __tls_get_addr.
|
// 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);
|
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);
|
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user