Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cdf84dd
Add section name constant and part/section IDs
lapla-cogito May 27, 2026
ea7a302
Add `--gdb-index` and `--no-gdb-index`
lapla-cogito May 27, 2026
0e2139c
Implement `.gdb_index` section generation
lapla-cogito May 27, 2026
4bcb28a
Update skip tests list
lapla-cogito May 27, 2026
634c7cc
Add integration tests
lapla-cogito May 27, 2026
9534ac8
Eliminate duplicate parse_cu_boundaries in compute_gdb_index_size
lapla-cogito May 27, 2026
36fae04
Merge address and symbol table construction into single object scan
lapla-cogito May 27, 2026
66ffff8
clippy fix
lapla-cogito May 27, 2026
aa288f0
Extract shared pubnames/pubtypes iteration into a helper
lapla-cogito May 27, 2026
e3cc626
Use more idiomatic APIs and fix step calc
lapla-cogito May 29, 2026
31ff301
Calculate hashslots using zerocopy
lapla-cogito May 29, 2026
ac5bbc4
Add a comment for `cv_bytes` addition
lapla-cogito May 29, 2026
121674b
Add consts for `.debug_info`
lapla-cogito May 29, 2026
aef860f
Write constant pool directly to output buffer
lapla-cogito May 29, 2026
b8f4da7
Use itertools `sorted_unstable_by_key()`
lapla-cogito May 29, 2026
d9abf65
Unify object scannig logic
lapla-cogito May 29, 2026
9d099f3
Refactor pubnames collection
lapla-cogito May 29, 2026
21b9dca
Use `BTreeSet` for `cv_entries`
lapla-cogito May 29, 2026
55610bc
Improve error handling
lapla-cogito May 31, 2026
9de1cc6
Use `sorted_names` rather than `sorted` as a variable name
lapla-cogito May 31, 2026
638e550
Emit errors when GDB indices are corrupted
lapla-cogito Jun 1, 2026
fac7c23
Add some comments and warnings
lapla-cogito Jun 1, 2026
70df43a
Revert "Emit errors when GDB indices are corrupted"
lapla-cogito Jun 1, 2026
1aa313a
Add a comment about CU
lapla-cogito Jun 1, 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
26 changes: 25 additions & 1 deletion libwild/src/args/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ pub struct ElfArgs {
experimental_sframe: bool,

pub(crate) debug_compression_kind: Option<CompressionKind>,

pub(crate) gdb_index: bool,
}

#[derive(Debug)]
Expand Down Expand Up @@ -234,7 +236,6 @@ const SILENTLY_IGNORED_SHORT_FLAGS: &[&str] = &[
];

const IGNORED_FLAGS: &[&str] = &[
"gdb-index",
"fix-cortex-a53-835769",
"fix-cortex-a53-843419",
"discard-all",
Expand Down Expand Up @@ -334,6 +335,7 @@ impl Default for ElfArgs {

experimental_sframe: false,
debug_compression_kind: None,
gdb_index: false,
}
}
}
Expand Down Expand Up @@ -1098,6 +1100,24 @@ fn setup_argument_parser() -> ArgumentParser<ElfArgs> {
Ok(())
});

parser
.declare()
.long("gdb-index")
.help("Create .gdb_index section")
.execute(|args, _modifier_stack| {
args.gdb_index = true;
Ok(())
});

parser
.declare()
.long("no-gdb-index")
.help("Don't create .gdb_index section")
.execute(|args, _modifier_stack| {
args.gdb_index = false;
Ok(())
});

parser
.declare()
.long("export-dynamic")
Expand Down Expand Up @@ -2086,6 +2106,10 @@ impl platform::Args for ElfArgs {
self.trace
}

fn should_write_gdb_index(&self) -> bool {
self.gdb_index
}

fn relocation_model(&self) -> crate::args::RelocationModel {
self.relocation_model
}
Expand Down
12 changes: 12 additions & 0 deletions libwild/src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,7 @@ impl platform::Platform for Elf {
builder.add_sections(&custom.bss);

builder.add_sections(&custom.nonalloc);
builder.add_section(output_section_id::GDB_INDEX);
builder.add_section(output_section_id::COMMENT);
builder.add_section(output_section_id::RISCV_ATTRIBUTES);
builder.add_section(output_section_id::SHSTRTAB);
Expand Down Expand Up @@ -1994,6 +1995,12 @@ impl platform::Platform for Elf {
total_sizes.merge(&extra_sizes);
}

fn compute_gdb_index_size(
groups: &[crate::layout::GroupState<Self>],
) -> crate::error::Result<u64> {
crate::gdb_index::compute_gdb_index_size(groups)
}

fn align_load_segment_start(
_segment_def: Self::ProgramSegmentDef,
segment_alignment: Alignment,
Expand Down Expand Up @@ -4644,6 +4651,11 @@ const SECTION_DEFINITIONS: [BuiltInSectionDetails; NUM_BUILT_IN_SECTIONS] = {
kind: SectionKind::Secondary(output_section_id::SYMTAB_SHNDX_LOCAL),
..DEFAULT_DEFS
};
defs[output_section_id::GDB_INDEX.as_usize()] = BuiltInSectionDetails {
kind: SectionKind::Primary(SectionName(GDB_INDEX_SECTION_NAME)),
ty: sht::PROGBITS,
..DEFAULT_DEFS
};
// Start of regular sections
defs[output_section_id::RODATA.as_usize()] = BuiltInSectionDetails {
kind: SectionKind::Primary(SectionName(RODATA_SECTION_NAME)),
Expand Down
21 changes: 21 additions & 0 deletions libwild/src/elf_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ pub(crate) fn write<'data, A: Arch<Platform = Elf>>(
crate::validation::validate_bytes(layout, &sized_output.out)?;
}

// Write .gdb_index before splitting, since it needs to read .debug_info from the output.
write_gdb_index_section(&mut sized_output.out, layout)?;

let mut section_buffers = split_output_into_sections(layout, &mut sized_output.out).0;

if layout.args().should_write_eh_frame_hdr {
Expand Down Expand Up @@ -313,6 +316,24 @@ fn fill_padding(mut section_buffers: OutputSectionMap<&mut [u8]>) {
});
}

fn write_gdb_index_section(output: &mut [u8], layout: &ElfLayout) -> Result {
use crate::platform::Args as _;
if !layout.args().should_write_gdb_index() {
return Ok(());
}
let sl = layout.section_layouts.get(output_section_id::GDB_INDEX);
if sl.file_size == 0 {
return Ok(());
}
timing_phase!("Write .gdb_index");
let start = sl.file_offset;
// Split the output buffer so that the part before our section is readable (for .debug_info)
// and our section is writable.
let (before, rest) = output.split_at_mut(start);
let gdb_buf = &mut rest[..sl.file_size];
crate::gdb_index::write_gdb_index(gdb_buf, before, layout)
}

fn write_sframe_section(sframe_buffer: &mut [u8], layout: &ElfLayout) -> Result {
if layout.args().discard_sframe || sframe_buffer.is_empty() {
return Ok(());
Expand Down
Loading
Loading