Skip to content

Commit 0d781f8

Browse files
committed
fix: error on R_X86_64_32/32S relocations in shared objects (#2074)
R_X86_64_32 and R_X86_64_32S cannot be used when making a shared object because the dynamic linker has no way to patch 32-bit absolute relocations at runtime. Wild was silently emitting R_X86_64_64 instead of erroring, producing a broken shared object. Add an early check in apply_relocation to error when these relocation types are encountered while building a shared object, matching the behavior of GNU ld and lld. Also add ExpectErrorWild test directive (analogous to ExpectWarningWild) to allow testing Wild-specific error messages independently. Fixes #2074
1 parent ce74e0b commit 0d781f8

3 files changed

Lines changed: 29 additions & 0 deletions

File tree

libwild/src/elf_writer.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,6 +2899,16 @@ fn apply_relocation<
28992899
.write_to_buffer(value, &mut out[offset_in_section as usize..])?;
29002900
return Ok(RelocationModifier::Normal);
29012901
}
2902+
RelocationKind::Absolute
2903+
if layout.symbol_db.output_kind.is_shared_object()
2904+
&& matches!(r_type, object::elf::R_X86_64_32 | object::elf::R_X86_64_32S) =>
2905+
{
2906+
bail!(
2907+
"relocation type {} cannot be used when making a shared object; \
2908+
recompile with -fPIC",
2909+
A::rel_type_to_string(r_type)
2910+
);
2911+
}
29022912
_ => {}
29032913
}
29042914
let (resolution, symbol_index, local_symbol_id) = get_resolution(rel, object_layout, layout)?;

wild/tests/integration_tests.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@
120120
//!
121121
//! ExpectWarningWild:{message regex} As for ExpectWarning, but only checks Wild's warning output.
122122
//!
123+
//! ExpectErrorWild:{error regex} As for ExpectError, but only checks Wild's error output.
124+
//!
123125
//! Malfunction:{malfunction-id} Run with the specified malfunction enabled. Linking should still
124126
//! succeed, but linker-diff should report a diff. That diff will be snapshot tested.
125127
//!
@@ -1756,6 +1758,13 @@ fn process_directive(
17561758
config.should_run = false;
17571759
config.should_diff = false;
17581760
}
1761+
"ExpectErrorWild" => {
1762+
config.expect_stderr.push(ErrorMatcher::wild_only(arg)?);
1763+
config.should_error = true;
1764+
// If there are errors, then there's nothing to run and nothing to diff.
1765+
config.should_run = false;
1766+
config.should_diff = false;
1767+
}
17591768
"ExpectMessage" => {
17601769
config.expect_stdout.push(ErrorMatcher::new(arg)?);
17611770
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Test that R_X86_64_32 cannot be used when making a shared object.
2+
// .long _shared generates R_X86_64_32 which is illegal in shared objects.
3+
// Both GNU ld and lld error: recompile with -fPIC
4+
//#Arch:x86_64
5+
//#LinkArgs:--no-gc-sections -shared
6+
//#ExpectError:recompile with -fPIC
7+
//#ExpectErrorWild:R_X86_64_32.*cannot be used when making a shared object
8+
9+
.data
10+
.long _shared

0 commit comments

Comments
 (0)