Skip to content

Commit

Permalink
write/elf: x86-64 branches should always use R_X86_64_PLT32 (#590)
Browse files Browse the repository at this point in the history
This matches the behaviour of gcc and clang, and allows us to remove
the hack to change relocations to use section symbols.
  • Loading branch information
philipc authored Nov 10, 2023
1 parent 16b6d90 commit 88554fa
Showing 1 changed file with 3 additions and 44 deletions.
47 changes: 3 additions & 44 deletions src/write/elf/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,50 +153,6 @@ impl<'a> Object<'a> {
}

pub(crate) fn elf_fixup_relocation(&mut self, relocation: &mut Relocation) -> Result<i64> {
// Return true if we should use a section symbol to avoid preemption.
fn want_section_symbol(relocation: &Relocation, symbol: &Symbol) -> bool {
if symbol.scope != SymbolScope::Dynamic {
// Only dynamic symbols can be preemptible.
return false;
}
match symbol.kind {
SymbolKind::Text | SymbolKind::Data => {}
_ => return false,
}
match relocation.kind {
// Anything using GOT or PLT is preemptible.
// We also require that `Other` relocations must already be correct.
RelocationKind::Got
| RelocationKind::GotRelative
| RelocationKind::GotBaseRelative
| RelocationKind::PltRelative
| RelocationKind::Elf(_) => return false,
// Absolute relocations are preemptible for non-local data.
// TODO: not sure if this rule is exactly correct
// This rule was added to handle global data references in debuginfo.
// Maybe this should be a new relocation kind so that the caller can decide.
RelocationKind::Absolute => {
if symbol.kind == SymbolKind::Data {
return false;
}
}
_ => {}
}
true
}

// Use section symbols for relocations where required to avoid preemption.
// Otherwise, the linker will fail with:
// relocation R_X86_64_PC32 against symbol `SomeSymbolName' can not be used when
// making a shared object; recompile with -fPIC
let symbol = &self.symbols[relocation.symbol.0];
if want_section_symbol(relocation, symbol) {
if let Some(section) = symbol.section.id() {
relocation.addend += symbol.value as i64;
relocation.symbol = self.section_symbol(section);
}
}

// Determine whether the addend is stored in the relocation or the data.
if self.elf_has_relocation_addend()? {
Ok(0)
Expand Down Expand Up @@ -581,6 +537,9 @@ impl<'a> Object<'a> {
(RelocationKind::Absolute, RelocationEncoding::Generic, 64) => {
elf::R_X86_64_64
}
(RelocationKind::Relative, RelocationEncoding::X86Branch, 32) => {
elf::R_X86_64_PLT32
}
(RelocationKind::Relative, _, 32) => elf::R_X86_64_PC32,
(RelocationKind::Got, _, 32) => elf::R_X86_64_GOT32,
(RelocationKind::PltRelative, _, 32) => elf::R_X86_64_PLT32,
Expand Down

0 comments on commit 88554fa

Please sign in to comment.