Skip to content

Commit e6d44a8

Browse files
committed
std: look for build-id section
1 parent 3a9bae6 commit e6d44a8

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

std/debug.zig

+12-1
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ pub fn openElfDebugInfo(
10231023
var debug_line: ?DwarfInfo.Section = null;
10241024
var debug_ranges: ?DwarfInfo.Section = null;
10251025
var gnu_debuglink: ?DwarfInfo.Section = null;
1026+
var note_gnu_build_id: ?elf.SectionHeader.NoteDescription = null;
10261027
var n: usize = 0; // count number of sections found to exit loop early
10271028

10281029
var it = efile.sectionIterator();
@@ -1056,12 +1057,19 @@ pub fn openElfDebugInfo(
10561057
};
10571058
} else {
10581059
// don't want to increment `n`
1060+
1061+
if (note_gnu_build_id == null) if (try elf_section.isNote(&efile, "GNU", elf.NT_GNU_BUILD_ID)) |note_description| {
1062+
// is allowed to be in any note section, not just .note.gnu.build-id
1063+
note_gnu_build_id = note_description;
1064+
};
1065+
10591066
if (gnu_debuglink == null and try elf_section.nameIs(&efile, ".gnu_debuglink")) {
10601067
gnu_debuglink = DwarfInfo.Section{
10611068
.offset = elf_section.offset,
10621069
.size = elf_section.size,
10631070
};
10641071
}
1072+
10651073
continue;
10661074
}
10671075

@@ -1085,7 +1093,10 @@ pub fn openElfDebugInfo(
10851093

10861094
// Look for external debug info
10871095

1088-
// TODO: look for note.gnu.build-id. build-id should be preferred over debuglink
1096+
// build-id is preferred over debuglink
1097+
if (note_gnu_build_id) |note_description| {
1098+
// TODO: look in global debug directories for .build-id/nn/nnnnnnnn.debug
1099+
}
10891100

10901101
if (gnu_debuglink) |debuglink| {
10911102
if (openGNUDebugLink(allocator, debuglink, elf_seekable_stream, elf_in_stream, efile.endian)) |di| {

std/elf.zig

+43
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ pub const SHT_HIPROC = 0x7fffffff;
267267
pub const SHT_LOUSER = 0x80000000;
268268
pub const SHT_HIUSER = 0xffffffff;
269269

270+
pub const NT_GNU_BUILD_ID = 3;
271+
270272
pub const STB_LOCAL = 0;
271273
pub const STB_GLOBAL = 1;
272274
pub const STB_WEAK = 2;
@@ -362,6 +364,47 @@ pub const SectionHeader = struct {
362364
try elf.seekable_stream.seekTo(name_offset);
363365
return try isString(elf, name);
364366
}
367+
368+
pub const NoteDescription = struct {
369+
elf: *Elf,
370+
start_pos: usize,
371+
len: usize,
372+
};
373+
pub fn isNote(elf_section: SectionHeader, elf: *Elf, name: []const u8, wanted_type: u64) !?NoteDescription {
374+
if (elf_section.sh_type != SHT_NOTE) return null;
375+
376+
try elf.seekable_stream.seekTo(elf_section.offset);
377+
378+
var desc_len: usize = undefined;
379+
380+
if (elf.is_64) {
381+
const hdr = Elf64_Nhdr {
382+
.n_namesz = try elf.in_stream.readInt(Elf64_Word, elf.endian),
383+
.n_descsz = try elf.in_stream.readInt(Elf64_Word, elf.endian),
384+
.n_type = try elf.in_stream.readInt(Elf64_Word, elf.endian),
385+
};
386+
if (name.len + 1 != hdr.n_namesz) return null;
387+
if (wanted_type != hdr.n_type) return null;
388+
desc_len = hdr.n_descsz;
389+
} else {
390+
const hdr = Elf32_Nhdr {
391+
.n_namesz = try elf.in_stream.readInt(Elf32_Word, elf.endian),
392+
.n_descsz = try elf.in_stream.readInt(Elf32_Word, elf.endian),
393+
.n_type = try elf.in_stream.readInt(Elf32_Word, elf.endian),
394+
};
395+
if (name.len + 1 != hdr.n_namesz) return null;
396+
if (wanted_type != hdr.n_type) return null;
397+
desc_len = hdr.n_descsz;
398+
}
399+
400+
if (!try isString(elf, name)) return null;
401+
402+
return NoteDescription {
403+
.elf = elf,
404+
.start_pos = try elf.seekable_stream.getPos(),
405+
.len = desc_len,
406+
};
407+
}
365408
};
366409

367410
pub const Elf = struct {

0 commit comments

Comments
 (0)