Skip to content

Commit

Permalink
Split TlsLdToLocalExec relaxation into two
Browse files Browse the repository at this point in the history
This makes it so that we know based on the relaxation what range of bytes it
might operate on, which will make changes to linker-diff easier.
  • Loading branch information
davidlattimore committed Jan 6, 2025
1 parent d584502 commit 9db8710
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 16 deletions.
8 changes: 8 additions & 0 deletions libwild/src/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,14 @@ impl crate::arch::Relaxation for Relaxation {
}
object::elf::R_X86_64_TLSLD if output_kind.is_executable() => {
if section_bytes.get(offset - 3..offset)? == [0x48, 0x8d, 0x3d] {
if section_bytes.get(offset + 4..offset + 6) == Some(&[0x48, 0xb8]) {
// The previous instruction was 64 bit, so we use a slightly different
// relaxation with extra padding.
return create(
RelaxationKind::TlsLdToLocalExec64,
object::elf::R_X86_64_NONE,
);
}
return create(RelaxationKind::TlsLdToLocalExec, object::elf::R_X86_64_NONE);
}
}
Expand Down
33 changes: 17 additions & 16 deletions linker-utils/src/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ pub enum RelaxationKind {
/// Transform local dynamic (LD) into local exec.
TlsLdToLocalExec,

/// Transform local dynamic (LD) into local exec with extra padding because the previous
/// instruction was 64 bit.
TlsLdToLocalExec64,

/// Transform general dynamic (GD) into initial exec
TlsGdToInitialExec,
}
Expand Down Expand Up @@ -119,22 +123,19 @@ impl RelaxationKind {
*next_modifier = RelocationModifier::SkipNextRelocation;
}
RelaxationKind::TlsLdToLocalExec => {
// Transforms to: `mov %fs:0x0,%rax` with some amount of padding depending on
// whether the subsequent instruction is 64 bit (first) or 32 bit (second).
if section_bytes.get(offset + 4..offset + 6) == Some(&[0x48, 0xb8]) {
section_bytes[offset - 3..offset + 19].copy_from_slice(&[
// nopw (%rax,%rax)
0x66, 0x66, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0,
// mov %fs:0,%rax
0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0,
]);
*offset_in_section += 15;
} else {
section_bytes[offset - 3..offset + 9].copy_from_slice(&[
0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0,
]);
*offset_in_section += 5;
}
section_bytes[offset - 3..offset + 9]
.copy_from_slice(&[0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0]);
*offset_in_section += 5;
*next_modifier = RelocationModifier::SkipNextRelocation;
}
RelaxationKind::TlsLdToLocalExec64 => {
section_bytes[offset - 3..offset + 19].copy_from_slice(&[
// nopw (%rax,%rax)
0x66, 0x66, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0,
// mov %fs:0,%rax
0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0,
]);
*offset_in_section += 15;
*next_modifier = RelocationModifier::SkipNextRelocation;
}
RelaxationKind::NoOp => {}
Expand Down

0 comments on commit 9db8710

Please sign in to comment.