Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f704b10

Browse files
authored
fix: GC of sections referenced from debug info (#1787)
On RISC-V and LoongArch64, debug info sections reference local symbols (e.g. `.LFB0`, `.LFE0`) in code sections via relocations. Previously, processing these relocations during the GC graph traversal sent symbol requests that loaded the referenced code sections, defeating `--gc-sections`. Fix this by not processing debug relocations during the layout phase at all. Instead, resolve them entirely at write time in `apply_debug_relocation()`: - For symbols in live sections, compute the address from the section resolution plus the symbol's offset. - For symbols in GC'd sections, fall through to the existing DWARF tombstone value path.
1 parent 579c493 commit f704b10

13 files changed

Lines changed: 60 additions & 137 deletions

File tree

.typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ flate = "flate"
33
rela = "rela"
44
ot = "ot"
55
FRE = "FRE"
6+
aranges = "aranges"
67

78
[files]
89
extend-exclude = [

libwild/src/elf.rs

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -691,45 +691,6 @@ impl platform::Platform for Elf {
691691
Ok(())
692692
}
693693

694-
fn load_object_debug_relocations<'data, 'scope, A: Arch<Platform = Self>>(
695-
state: &layout::ObjectLayoutState<'data, Self>,
696-
common: &mut layout::CommonGroupState<'data, Self>,
697-
queue: &mut layout::LocalWorkQueue,
698-
resources: &'scope layout::GraphResources<'data, '_, Self>,
699-
section: layout::Section,
700-
scope: &Scope<'scope>,
701-
) -> Result {
702-
if resources.symbol_db.args.should_output_partial_object {
703-
return Ok(());
704-
}
705-
match state.relocations(section.index)? {
706-
RelocationList::Rela(relocations) => {
707-
load_debug_relocations::<A, Rela>(
708-
state,
709-
common,
710-
queue,
711-
resources,
712-
section,
713-
relocations.rel_iter(),
714-
scope,
715-
)?;
716-
}
717-
RelocationList::Crel(relocations) => {
718-
load_debug_relocations::<A, Crel>(
719-
state,
720-
common,
721-
queue,
722-
resources,
723-
section,
724-
relocations.flat_map(|r| r.ok()),
725-
scope,
726-
)?;
727-
}
728-
}
729-
730-
Ok(())
731-
}
732-
733694
fn create_dynamic_symbol_definition<'data>(
734695
symbol_db: &SymbolDb<'data, Self>,
735696
symbol_id: SymbolId,
@@ -4645,41 +4606,6 @@ fn load_section_relocations<'scope, 'data, A: Arch<Platform = Elf>, R: Relocatio
46454606
Ok(())
46464607
}
46474608

4648-
fn load_debug_relocations<'scope, 'data, A: Arch<Platform = Elf>, R: Relocation>(
4649-
state: &layout::ObjectLayoutState<'data, Elf>,
4650-
common: &mut CommonGroupState<'data, Elf>,
4651-
queue: &mut layout::LocalWorkQueue,
4652-
resources: &'scope layout::GraphResources<'data, '_, Elf>,
4653-
section: layout::Section,
4654-
relocations: impl Iterator<Item = R>,
4655-
scope: &Scope<'scope>,
4656-
) -> Result {
4657-
for rel in relocations {
4658-
let modifier = process_relocation::<A, R>(
4659-
state,
4660-
common,
4661-
&rel,
4662-
state.object.section(section.index)?,
4663-
resources,
4664-
queue,
4665-
true,
4666-
scope,
4667-
)
4668-
.with_context(|| {
4669-
format!(
4670-
"Failed to copy section {} from file {state}",
4671-
layout::section_debug::<Elf>(state.object, section.index)
4672-
)
4673-
})?;
4674-
ensure!(
4675-
modifier == RelocationModifier::Normal,
4676-
"All debug relocations must be processed"
4677-
);
4678-
}
4679-
4680-
Ok(())
4681-
}
4682-
46834609
#[inline(always)]
46844610
fn process_relocation<'data, 'scope, A: Arch<Platform = Elf>, R: Relocation>(
46854611
object: &layout::ObjectLayoutState<'data, Elf>,

libwild/src/elf_aarch64.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ impl crate::platform::Arch for ElfAArch64 {
9595
Ok(())
9696
}
9797

98-
fn local_symbols_in_debug_info() -> bool {
99-
false
100-
}
101-
10298
fn tp_offset_start(layout: &Layout<Elf>) -> u64 {
10399
layout.tls_start_address_aarch64()
104100
}

libwild/src/elf_loongarch64.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ impl crate::platform::Arch for ElfLoongArch64 {
7777
0
7878
}
7979

80-
fn local_symbols_in_debug_info() -> bool {
81-
true
82-
}
83-
8480
fn tp_offset_start(layout: &crate::layout::Layout<Elf>) -> u64 {
8581
layout.tls_start_address()
8682
}

libwild/src/elf_riscv64.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ impl crate::platform::Arch for ElfRiscV64 {
9595
RISCV_TLS_DTV_OFFSET
9696
}
9797

98-
fn local_symbols_in_debug_info() -> bool {
99-
true
100-
}
101-
10298
fn tp_offset_start(layout: &crate::layout::Layout<Elf>) -> u64 {
10399
layout.tls_start_address()
104100
}

libwild/src/elf_writer.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2981,7 +2981,24 @@ fn apply_debug_relocation<'data, A: Arch<Platform = Elf>, R: Relocation>(
29812981
.merged_symbol_resolution(object_layout.symbol_id_range.input_to_id(symbol_index))
29822982
.or_else(|| {
29832983
section_index.and_then(|section_index| {
2984-
object_layout.section_resolutions[section_index.0].full_resolution()
2984+
let section_address =
2985+
object_layout.section_resolutions[section_index.0].address()?;
2986+
// Include the symbol's offset within the section (adjusted for any relaxation
2987+
// deltas). This is necessary on architectures like RISC-V and LoongArch64 where
2988+
// debug info references local symbols (e.g. .LFB0, .LFE0) whose value is their
2989+
// offset within the section, rather than section symbols where the offset is
2990+
// encoded in the relocation addend.
2991+
let output_offset = opt_input_to_output(
2992+
object_layout.section_relax_deltas.get(section_index.0),
2993+
crate::platform::Symbol::value(sym),
2994+
);
2995+
2996+
Some(Resolution {
2997+
raw_value: section_address + output_offset,
2998+
dynamic_symbol_index: None,
2999+
flags: ValueFlags::empty(),
3000+
format_specific: Default::default(),
3001+
})
29853002
})
29863003
});
29873004

libwild/src/elf_x86_64.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,6 @@ impl crate::platform::Arch for ElfX86_64 {
8787
x86_64_rel_type_to_string(r_type)
8888
}
8989

90-
fn local_symbols_in_debug_info() -> bool {
91-
false
92-
}
93-
9490
fn tp_offset_start(layout: &crate::layout::Layout<Elf>) -> u64 {
9591
layout.tls_end_address()
9692
}

libwild/src/layout.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3580,14 +3580,7 @@ impl<'data, P: Platform> ObjectLayoutState<'data, P> {
35803580
SectionSlot::UnloadedDebugInfo(part_id) => {
35813581
// On RISC-V, the debug info sections contain relocations to local symbols (e.g.
35823582
// labels).
3583-
self.load_debug_section::<A>(
3584-
common,
3585-
queue,
3586-
*part_id,
3587-
section_index,
3588-
resources,
3589-
scope,
3590-
)?;
3583+
self.load_debug_section::<A>(common, *part_id, section_index, resources)?;
35913584
}
35923585
SectionSlot::Discard => {
35933586
bail!(
@@ -3649,20 +3642,20 @@ impl<'data, P: Platform> ObjectLayoutState<'data, P> {
36493642
fn load_debug_section<'scope, A: Arch<Platform = P>>(
36503643
&mut self,
36513644
common: &mut CommonGroupState<'data, P>,
3652-
queue: &mut LocalWorkQueue,
3653-
36543645
part_id: PartId,
36553646
section_index: SectionIndex,
36563647
resources: &'scope GraphResources<'data, '_, P>,
3657-
scope: &Scope<'scope>,
36583648
) -> Result {
36593649
let header = self.object.section(section_index)?;
36603650
let section = Section::create(header, self, section_index, part_id)?;
3661-
if A::local_symbols_in_debug_info() {
3662-
<A::Platform as Platform>::load_object_debug_relocations::<A>(
3663-
self, common, queue, resources, section, scope,
3664-
)?;
3665-
}
3651+
3652+
// Note: We intentionally do NOT process debug relocations here. On some architectures (like
3653+
// RISC-V and LoongArch64), debug sections reference local symbols (e.g. .LFB0, .LFE0) in
3654+
// code sections. Processing those relocations during GC would send symbol requests that
3655+
// load those code sections, defeating garbage collection. Instead, debug relocations are
3656+
// resolved at write time in `apply_debug_relocation`, which uses tombstone values for
3657+
// symbols in GC'd sections and computes addresses from section resolutions for symbols in
3658+
// live sections.
36663659

36673660
tracing::debug!(loaded_debug_section = %self.object.section_display_name(section_index),);
36683661
common.section_loaded(part_id, header, section, resources.output_sections);

libwild/src/macho.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -808,17 +808,6 @@ impl platform::Platform for MachO {
808808
todo!()
809809
}
810810

811-
fn load_object_debug_relocations<'data, 'scope, A: platform::Arch<Platform = Self>>(
812-
state: &crate::layout::ObjectLayoutState<'data, Self>,
813-
common: &mut crate::layout::CommonGroupState<'data, Self>,
814-
queue: &mut crate::layout::LocalWorkQueue,
815-
resources: &'scope crate::layout::GraphResources<'data, '_, Self>,
816-
section: crate::layout::Section,
817-
scope: &rayon::Scope<'scope>,
818-
) -> crate::error::Result {
819-
todo!()
820-
}
821-
822811
fn create_dynamic_symbol_definition<'data>(
823812
symbol_db: &crate::symbol_db::SymbolDb<'data, Self>,
824813
symbol_id: crate::symbol_db::SymbolId,

libwild/src/macho_aarch64.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ impl crate::platform::Arch for MachOAArch64 {
6161
todo!()
6262
}
6363

64-
fn local_symbols_in_debug_info() -> bool {
65-
todo!()
66-
}
67-
6864
fn tp_offset_start(layout: &crate::layout::Layout<Self::Platform>) -> u64 {
6965
todo!()
7066
}

0 commit comments

Comments
 (0)