Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
aef49fe
initial impl
mati865 Mar 16, 2026
fb08959
Renames
mati865 Mar 17, 2026
1aba2b6
Emit required version for glibc
mati865 Mar 17, 2026
540b112
Write addend into value
mati865 Mar 17, 2026
24e0933
Don't write erroneous section link
mati865 Mar 17, 2026
d699ceb
Sort relr entries
mati865 Mar 17, 2026
3e21426
Make the constants nicer
mati865 Mar 17, 2026
0b00c39
Fix wrong symbol versions when there are multiple deps with versions
mati865 Mar 18, 2026
87e82a7
Unskip Mold test
mati865 Mar 18, 2026
e4253a3
simplify glibc symbol handling
mati865 Mar 19, 2026
73bb142
move glibc special symbol writing to the end
mati865 Mar 19, 2026
74414d9
Address review feedback
mati865 Mar 20, 2026
627a32d
Simplify the conditions
mati865 Mar 20, 2026
09b9eef
Fix missed rename
mati865 Mar 20, 2026
0876ccb
clean up
mati865 Mar 24, 2026
3ab8395
wip: almost works with a single thread and input
mati865 Mar 24, 2026
7d26d6b
Proper output ordering (threads and multiple outputs still borked)
mati865 Mar 25, 2026
cba54ec
Use OutputSectionPartMap
mati865 Mar 25, 2026
d73dcfe
nicer printing
mati865 Mar 25, 2026
b333483
hack: use offsets to split output buffer
mati865 Mar 25, 2026
88bb03c
remove debug prints
mati865 Mar 26, 2026
a73f5d4
fix todo
mati865 Mar 26, 2026
4ffd217
wip: try to estimate how much size we can save
mati865 Mar 27, 2026
1c146a0
also print chunks with single relocation
mati865 Mar 28, 2026
73b1f36
remove saving estimation, the assumptions were bad
mati865 Mar 28, 2026
f532714
test: add a simple test
mati865 Mar 29, 2026
a4aadd3
remove borked saving estimation
mati865 Mar 30, 2026
e2bd220
fix: don't emit RELR for odd offset relocs
mati865 Mar 30, 2026
cb8c389
feat: handle RELR in linker-diff
mati865 Mar 30, 2026
98bc6a8
fix: ignore pack-relative-relocs unless amd64 or aarch64
mati865 Mar 30, 2026
65bf4a1
Remove unnecessary diffignores
mati865 Mar 30, 2026
bfc0924
undo the hacks
mati865 Mar 30, 2026
655a51a
use new object constatns
mati865 Mar 30, 2026
9b616ff
Undo accidental change
mati865 Mar 30, 2026
821b8f2
wip: try David's suggestion
mati865 Mar 30, 2026
837a214
test: extend with constructors
mati865 Mar 30, 2026
aa0ce41
wip: add more prints
mati865 Mar 30, 2026
c7bea63
fix allocation verifier
mati865 Mar 30, 2026
c70a746
remove failed attempt leftovers
mati865 Mar 30, 2026
d7ef128
test: format
mati865 Mar 30, 2026
86bc266
back to the offsets
mati865 Mar 30, 2026
78589bf
reset packing status when section changes
mati865 Mar 30, 2026
f150f44
disable prints
mati865 Mar 30, 2026
f55b55a
test: avoid AArch64 failure
mati865 Mar 30, 2026
c2f0b1b
enable relr on loongarch
mati865 Mar 30, 2026
57695a6
test: it doesn't use glibc
mati865 Mar 31, 2026
c6b6669
start cleanup, remove packing
mati865 Mar 31, 2026
143f451
cleanup constants
mati865 Mar 31, 2026
5a49a07
cleanup remove RelrWriter
mati865 Mar 31, 2026
560fe73
cleanup common fns and structs
mati865 Mar 31, 2026
b401dab
plumb Args through abstractions
mati865 Mar 31, 2026
99f38dc
cleanup the cleanups
mati865 Mar 31, 2026
0a13577
address TODO
mati865 Mar 31, 2026
16f6fb6
cleanup unnecessary unwrap
mati865 Mar 31, 2026
e303dff
Add comment
mati865 Mar 31, 2026
7a6790d
add TODO
mati865 Mar 31, 2026
537591d
Revert "Unskip Mold test"
mati865 Mar 31, 2026
7fc9bd6
test: skip on Ubuntu 24.04
mati865 Mar 31, 2026
f0ddd86
test: try to fix openSUSE error
mati865 Mar 31, 2026
4096e58
test: assert existence of relr section and tags
mati865 Apr 1, 2026
fe60c56
test: add comments
mati865 Apr 1, 2026
05b217c
Remove wip change that was suppsed to be removed
mati865 Apr 1, 2026
9ae6790
test: add glibc integration scenario
mati865 Apr 1, 2026
49d1fcf
linker-diff: remove unuseful comments
mati865 Apr 1, 2026
381b89a
chore: add comment to `write_address_relocation`
mati865 Apr 1, 2026
a6e3449
Remove old version impl
mati865 Apr 1, 2026
1e49aab
wip: add half baked attempts
mati865 Apr 1, 2026
11f2613
wip: dunno why this one works but not create_linker_defined_symbols
mati865 Apr 1, 2026
db54cf4
cleanup call sites of `write_address_relocation`
mati865 Apr 1, 2026
6ed8f19
Revert "Revert "Unskip Mold test""
mati865 Apr 1, 2026
d097056
test: add glibc requirement
mati865 Apr 1, 2026
c2f8719
wip: version import
mati865 Apr 2, 2026
45f1b7e
import whole symbol
mati865 Apr 2, 2026
8ad3c46
test: fmt
mati865 Apr 2, 2026
efc88aa
test:add explicit PIE
mati865 Apr 2, 2026
9556386
fix: reenable relr for RV64
mati865 Apr 3, 2026
e6ea553
test: use LLD instead
mati865 Apr 3, 2026
2a67d24
cleanup: revert unnecessary changes
mati865 Apr 3, 2026
630e076
fix comments
mati865 Apr 3, 2026
fcf1830
rename fn
mati865 Apr 3, 2026
d6a98ee
Oops, add help text
mati865 Apr 3, 2026
566bc27
merge main
mati865 Apr 4, 2026
74a4842
fmt
mati865 Apr 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libwild/src/alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub(crate) const GOT_ENTRY: Alignment = Alignment { exponent: 3 };
/// The minimum alignment of a rela entry.
pub(crate) const RELA_ENTRY: Alignment = Alignment { exponent: 3 };

/// The minimum alignment of a relr entry.
pub(crate) const RELR_ENTRY: Alignment = Alignment { exponent: 3 };

/// Alignment of the .gnu.hash section.
pub(crate) const GNU_HASH: Alignment = Alignment { exponent: 3 };

Expand Down
18 changes: 18 additions & 0 deletions libwild/src/args/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub struct ElfArgs {
pub(crate) z_stack_size: Option<NonZeroU64>,
pub(crate) max_page_size: Option<Alignment>,
pub(crate) trace: bool,
pub(crate) pack_relative_relocs: bool,

pub(crate) relocation_model: RelocationModel,
pub(crate) should_output_executable: bool,
Expand Down Expand Up @@ -283,6 +284,7 @@ impl Default for ElfArgs {
relax: true,
hash_style: HashStyle::Both,
trace: false,
pack_relative_relocs: false,

unresolved_symbols: UnresolvedSymbols::ReportAll,
error_unresolved_symbols: true,
Expand Down Expand Up @@ -597,6 +599,22 @@ fn setup_argument_parser() -> ArgumentParser<ElfArgs> {
Ok(())
},
)
.sub_option(
"pack-relative-relocs",
"Pack relative relocations into SHT_RELR",
|args, _| {
args.pack_relative_relocs = true;
Ok(())
},
)
.sub_option(
"nopack-relative-relocs",
"Do not pack relative relocations into SHT_RELR (default)",
|args, _| {
args.pack_relative_relocs = false;
Ok(())
},
)
.sub_option(
"x86-64-baseline",
"Mark x86-64-baseline ISA as needed",
Expand Down
46 changes: 41 additions & 5 deletions libwild/src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ pub(crate) type SectionHeader = object::elf::SectionHeader64<LittleEndian>;
pub(crate) type SymtabEntry = object::elf::Sym64<LittleEndian>;
pub(crate) type DynamicEntry = object::elf::Dyn64<LittleEndian>;
pub(crate) type Rela = object::elf::Rela64<LittleEndian>;
pub(crate) type Relr = object::elf::Relr64<LittleEndian>;
pub(crate) type GnuHashHeader = object::elf::GnuHashHeader<LittleEndian>;
pub(crate) type Verdef = object::elf::Verdef<LittleEndian>;
pub(crate) type Verdaux = object::elf::Verdaux<LittleEndian>;
Expand Down Expand Up @@ -549,7 +550,7 @@ impl platform::Platform for Elf {
) -> Result<Self::DynamicLayoutExt<'data>> {
let mut is_last_verneed = false;

if let Some(v) = state.format_specific_state.verneed_info.as_ref()
if let Some(v) = &state.format_specific_state.verneed_info
&& v.version_count > 0
{
memory_offsets.increment(
Expand Down Expand Up @@ -764,13 +765,15 @@ impl platform::Platform for Elf {
output_kind: OutputKind,
mem_sizes: &OutputSectionPartMap<u64>,
resolution: &layout::Resolution<Elf>,
args: &ElfArgs,
) -> Result {
crate::elf_writer::verify_resolution_allocation(
output_sections,
output_order,
output_kind,
mem_sizes,
resolution,
args,
)
}

Expand Down Expand Up @@ -908,6 +911,15 @@ impl platform::Platform for Elf {
elf_symbol_type: stt::TLS,
is_hidden: false,
});

// When `-z pack-relative-relocs` is used, Glibc requires this special version to be
// defined.
if args.pack_relative_relocs {
symbols.add_symbol(InternalSymDefInfo::new(
SymbolPlacement::ImportDynamicSymbol,
b"GLIBC_ABI_DT_RELR",
));
}
}

fn built_in_section_infos<'data>()
Expand Down Expand Up @@ -1369,6 +1381,7 @@ impl platform::Platform for Elf {
flags: ValueFlags,
mem_sizes: &mut OutputSectionPartMap<u64>,
output_kind: OutputKind,
args: &Self::Args,
) {
let has_dynamic_symbol = flags.is_dynamic() || flags.needs_export_dynamic();

Expand All @@ -1382,14 +1395,22 @@ impl platform::Platform for Elf {
} else if flags.is_interposable() && has_dynamic_symbol {
mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE);
} else if flags.is_address() && output_kind.is_relocatable() {
mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE);
if args.pack_relative_relocs {
mem_sizes.increment(part_id::RELR_DYN, elf::RELR_ENTRY_SIZE);
} else {
mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE);
}
}
}

if flags.needs_ifunc_got_for_address() {
mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE);
if output_kind.is_relocatable() {
mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE);
if args.pack_relative_relocs {
mem_sizes.increment(part_id::RELR_DYN, elf::RELR_ENTRY_SIZE);
} else {
mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE);
}
}
}

Expand Down Expand Up @@ -1758,6 +1779,7 @@ impl platform::Platform for Elf {
builder.add_section(output_section_id::GNU_VERSION_D);
builder.add_section(output_section_id::GNU_VERSION_R);
builder.add_section(output_section_id::RELA_DYN_RELATIVE);
builder.add_section(output_section_id::RELR_DYN);
builder.add_section(output_section_id::RELA_PLT);
builder.add_section(output_section_id::RODATA);
builder.add_section(output_section_id::EH_FRAME_HDR);
Expand Down Expand Up @@ -2899,7 +2921,8 @@ pub(crate) const GOT_ENTRY_SIZE: u64 = 0x8;
// TODO: Right now, both x86_64 and AArch64 have 16 byte long entries, but
// the size should be generic over A: Arch.
pub(crate) const PLT_ENTRY_SIZE: u64 = 0x10;
pub(crate) const RELA_ENTRY_SIZE: u64 = 0x18;
pub(crate) const RELA_ENTRY_SIZE: u64 = size_of::<Rela>() as u64;
pub(crate) const RELR_ENTRY_SIZE: u64 = size_of::<Relr>() as u64;

pub(crate) const SYMTAB_ENTRY_SIZE: u64 = size_of::<SymtabEntry>() as u64;
pub(crate) const GNU_VERSION_ENTRY_SIZE: u64 = size_of::<Versym>() as u64;
Expand Down Expand Up @@ -4454,6 +4477,14 @@ const SECTION_DEFINITIONS: [BuiltInSectionDetails; NUM_BUILT_IN_SECTIONS] = {
kind: SectionKind::Secondary(output_section_id::RELA_DYN_RELATIVE),
..DEFAULT_DEFS
};
defs[output_section_id::RELR_DYN.as_usize()] = BuiltInSectionDetails {
kind: SectionKind::Primary(SectionName(RELR_DYN_SECTION_NAME)),
ty: sht::RELR,
section_flags: shf::ALLOC,
element_size: RELR_ENTRY_SIZE,
min_alignment: alignment::RELR_ENTRY,
..DEFAULT_DEFS
};
defs[output_section_id::RISCV_ATTRIBUTES.as_usize()] = BuiltInSectionDetails {
kind: SectionKind::Primary(SectionName(RISCV_ATTRIBUTES_SECTION_NAME)),
ty: sht::RISCV_ATTRIBUTES,
Expand Down Expand Up @@ -4714,7 +4745,12 @@ fn process_relocation<'data, 'scope, A: Arch<Platform = Elf>, R: Relocation>(
&& flags.is_address()
{
if section_is_writable {
common.allocate(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE);
// Odd offsets mean bitmaps in RELR, so we need to fall back to RELA for them.
if resources.symbol_db.args.pack_relative_relocs && rel.offset().is_multiple_of(2) {
common.allocate(part_id::RELR_DYN, elf::RELR_ENTRY_SIZE);
} else {
common.allocate(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE);
}
} else if !is_debug_section {
bail!(
"Cannot apply relocation {} to read-only section. \
Expand Down
Loading
Loading