Conversation
…and implement gdb-index tests
…writer feat: define GDB_INDEX_SECTION_NAME constant and update section definitions
… gdb-index test configuration
davidlattimore
left a comment
There was a problem hiding this comment.
Nice! Have you tried loading a binary with the gdb index into gdb to confirm that it's happy with it?
Any ideas about any other testing - automated or otherwise we could do? Checking that the section exists is a start, but it leaves a lot of scope for things being not quite right.
| self.rela_dyn_relative.len() as u64 * elf::RELA_ENTRY_SIZE, | ||
| *mem_sizes.get(part_id::RELA_DYN_RELATIVE), | ||
| )); | ||
| let remaining = self.rela_dyn_relative.len() as u64 * elf::RELA_ENTRY_SIZE; |
There was a problem hiding this comment.
Is this related to this change? I'm also curious as to the motivation for this bit of the change. It looks like you've inlined the function excessive_allocation into several of its usage sites.
There was a problem hiding this comment.
It’s not required for the .gdb_index work it was just a small refactor to make the error paths explicit, which I forgot to remove before committing. I’ve restored the original code.
| tracing::debug!(loaded_debug_section = %self.object.section_display_name(section_index),); | ||
| common.section_loaded(part_id, header, section); | ||
|
|
||
| if self |
There was a problem hiding this comment.
Currently we read the section names only during section resolution. Doing an extra read of the section name can cause a noticeable slowdown. So I think we likely need to find a different way to do this.
|
|
||
| for (i, &(cu_offset, cu_length)) in cu_entries.iter().enumerate() { | ||
| let off = cu_list_offset + i * CU_ENTRY_SIZE; | ||
| buf[off..off + 8].copy_from_slice(&cu_offset.to_le_bytes()); |
There was a problem hiding this comment.
Would it work to simplify some of this code by using zerocopy?
…ELF writer and layout
Yes. I tested that explicitly. I built a small test binary with In addition, I compared the generated So from GDB’s perspective, it appears to be fully valid and functional. |
I’ve added a |
54feb16 to
8f23f3c
Compare
…integration tests
8f23f3c to
2a20ff7
Compare
davidlattimore
left a comment
There was a problem hiding this comment.
The extra testing is great. Thanks!
| { | ||
| cu_entries.push(elf::GdbIndexCuEntry { | ||
| cu_offset: address - debug_info_start, | ||
| cu_length: section.capacity(), |
There was a problem hiding this comment.
This seems to include alignment padding, making it inappropriate as a proper CU length.
lapla-cogito
left a comment
There was a problem hiding this comment.
While I haven't thoroughly reviewed the updated patch yet (today is a bit busy, so it may take some time), I'll point out one observation immediately: Wild runs mold's test suite in CI. However, some tests fail under Wild's current implementation, so they are excluded from the skip list and ignored during runs. These skipped tests are subsequently verified to ensure they still fail in CI (though false positives occasionally occur, which is why the workflow is configured with continue-on-error: true).
Through 2a20ff7 in this PR, all tests in the GDB index category appear to pass (see this run), but the latest commit seems to cause many of these tests to fail again.
|
Can you delete the lines from Also, I was thinking that it might be good to enable |
… source configuration
…argument parser updates
|
This feature appears to be more complex than I initially estimated. I need to add gdb_index.rs file to implements hashing, hash-table sizing, parsing of .debug_gnu_pubnames/.debug_gnu_pubtypes, and writing of the symbol table + constant-pool required by the GDB index format see this one. |
marxin
left a comment
There was a problem hiding this comment.
Really cool PR, good work. Am curious if we want to support the latest version9 (could be a subsequent PR)? Thank you.
| for &c in name { | ||
| r = r | ||
| .wrapping_mul(67) | ||
| .wrapping_add(u32::from(c)) |
There was a problem hiding this comment.
Looking at the formula: The formula is r = r * 67 + tolower (c) - 113.
Don't we miss the tolower?
| return 0; | ||
| } | ||
| let min_slots = num_symbols * 4 / 3 + 1; | ||
| let mut slots = 4usize; |
There was a problem hiding this comment.
What about slot = (num_symbols * 4 / 3 + 1).next_multiple_of(4)?
| .map(|obj| { | ||
| let pubnames = obj | ||
| .object | ||
| .section_by_name(".debug_gnu_pubnames") |
There was a problem hiding this comment.
|
|
||
| if resources | ||
| .output_sections | ||
| .custom_name_to_id(SectionName(b".debug_info")) |
| ); | ||
| } | ||
|
|
||
| let version = u32::from_le_bytes(data[0..4].try_into().unwrap()); |
There was a problem hiding this comment.
Can't we directly read the GdbIndexHeader here (using the zerocopy library)?
| let constant_pool_offset = u32::from_le_bytes(data[20..24].try_into().unwrap()) as usize; | ||
|
|
||
| // Check version. | ||
| if version != 7 { |
There was a problem hiding this comment.
Maybe we should declare a constant somwhere for the currently supported version.
| .collect(); | ||
|
|
||
| let addr_entry_count = address_area_size / 20; | ||
| for i in 0..addr_entry_count { |
Thanks! I’ll look into supporting the latest version (9) as well. |
This pull request adds support for generating a
.gdb_indexsection in ELF binaries, which is used to speed up debugging with GDB. The implementation introduces a new command-line flag (--gdb-indexand--no-gdb-index), updates the layout and writer logic to allocate and fill in the section, and integrates the section into the ELF output as an optional part. It also updates relevant tests and internal data structures to accommodate the new section.Resolve #811