authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-30 16:57:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-30 16:57:55-04:00
log72185e7dd36d9b87c57a3ed3719b9824ca11edf9
tree33d246343abb11bc670fc1bbbc7530d130bcc142
parent44f908d2e63d761e183e266248e777fe74184f44

finding the function that an address is in


2 files changed, 57 insertions(+), 9 deletions(-)

std/coff.zig+1-1
...@@ -215,7 +215,7 @@ const OptionalHeader = struct {...@@ -215,7 +215,7 @@ const OptionalHeader = struct {
215 data_directory: [IMAGE_NUMBEROF_DIRECTORY_ENTRIES]DataDirectory,215 data_directory: [IMAGE_NUMBEROF_DIRECTORY_ENTRIES]DataDirectory,
216};216};
217217
218const Section = struct {218pub const Section = struct {
219 header: SectionHeader,219 header: SectionHeader,
220};220};
221221
std/pdb.zig+56-8
...@@ -5,7 +5,7 @@ const math = std.math;...@@ -5,7 +5,7 @@ const math = std.math;
5const mem = std.mem;5const mem = std.mem;
6const os = std.os;6const os = std.os;
7const warn = std.debug.warn;7const warn = std.debug.warn;
8const Coff = std.coff.Coff;8const coff = std.coff;
99
10const ArrayList = std.ArrayList;10const ArrayList = std.ArrayList;
1111
...@@ -153,7 +153,7 @@ pub const SymbolRecordKind = enum(u16) {...@@ -153,7 +153,7 @@ pub const SymbolRecordKind = enum(u16) {
153153
154/// Duplicate copy of SymbolRecordKind, but using the official CV names. Useful154/// Duplicate copy of SymbolRecordKind, but using the official CV names. Useful
155/// for reference purposes and when dealing with unknown record types.155/// for reference purposes and when dealing with unknown record types.
156pub const SymbolKind = enum(u16) {156pub const SymbolKind = packed enum(u16) {
157 S_COMPILE = 1,157 S_COMPILE = 1,
158 S_REGISTER_16t = 2,158 S_REGISTER_16t = 2,
159 S_CONSTANT_16t = 3,159 S_CONSTANT_16t = 3,
...@@ -352,6 +352,33 @@ pub const SymbolKind = enum(u16) {...@@ -352,6 +352,33 @@ pub const SymbolKind = enum(u16) {
352 S_GTHREAD32 = 4371,352 S_GTHREAD32 = 4371,
353};353};
354354
355const TypeIndex = u32;
356
357const ProcSym = packed struct {
358 Parent: u32 ,
359 End: u32 ,
360 Next: u32 ,
361 CodeSize: u32 ,
362 DbgStart: u32 ,
363 DbgEnd: u32 ,
364 FunctionType: TypeIndex ,
365 CodeOffset: u32,
366 Segment: u16,
367 Flags: ProcSymFlags,
368 Name: u8,
369};
370
371const ProcSymFlags = packed struct {
372 HasFP: bool,
373 HasIRET: bool,
374 HasFRET: bool,
375 IsNoReturn: bool,
376 IsUnreachable: bool,
377 HasCustomCallingConv: bool,
378 IsNoInline: bool,
379 HasOptimizedDebugInfo: bool,
380};
381
355const SectionContrSubstreamVersion = enum(u32) {382const SectionContrSubstreamVersion = enum(u32) {
356 Ver60 = 0xeffe0000 + 19970605,383 Ver60 = 0xeffe0000 + 19970605,
357 V2 = 0xeffe0000 + 20140516384 V2 = 0xeffe0000 + 20140516
...@@ -359,20 +386,20 @@ const SectionContrSubstreamVersion = enum(u32) {...@@ -359,20 +386,20 @@ const SectionContrSubstreamVersion = enum(u32) {
359386
360const RecordPrefix = packed struct {387const RecordPrefix = packed struct {
361 RecordLen: u16, /// Record length, starting from &RecordKind.388 RecordLen: u16, /// Record length, starting from &RecordKind.
362 RecordKind: u16, /// Record kind enum (SymRecordKind or TypeRecordKind)389 RecordKind: SymbolKind, /// Record kind enum (SymRecordKind or TypeRecordKind)
363};390};
364391
365pub const Pdb = struct {392pub const Pdb = struct {
366 in_file: os.File,393 in_file: os.File,
367 allocator: *mem.Allocator,394 allocator: *mem.Allocator,
368 coff: *Coff,395 coff: *coff.Coff,
369396
370 msf: Msf,397 msf: Msf,
371398
372 pub fn openFile(self: *Pdb, coff: *Coff, file_name: []u8) !void {399 pub fn openFile(self: *Pdb, coff_ptr: *coff.Coff, file_name: []u8) !void {
373 self.in_file = try os.File.openRead(file_name);400 self.in_file = try os.File.openRead(file_name);
374 self.allocator = coff.allocator;401 self.allocator = coff_ptr.allocator;
375 self.coff = coff;402 self.coff = coff_ptr;
376403
377 try self.msf.openFile(self.allocator, self.in_file);404 try self.msf.openFile(self.allocator, self.in_file);
378 }405 }
...@@ -468,8 +495,9 @@ pub const Pdb = struct {...@@ -468,8 +495,9 @@ pub const Pdb = struct {
468 // std.debug.warn("{}\n", sect_entry);495 // std.debug.warn("{}\n", sect_entry);
469 //}496 //}
470497
498 var coff_section: *coff.Section = undefined;
471 const mod_index = for (sect_contribs.toSlice()) |sect_contrib| {499 const mod_index = for (sect_contribs.toSlice()) |sect_contrib| {
472 const coff_section = self.coff.sections.toSlice()[sect_contrib.Section];500 coff_section = &self.coff.sections.toSlice()[sect_contrib.Section];
473 std.debug.warn("looking in coff name: {}\n", mem.toSliceConst(u8, &coff_section.header.name));501 std.debug.warn("looking in coff name: {}\n", mem.toSliceConst(u8, &coff_section.header.name));
474502
475 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;503 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;
...@@ -490,6 +518,26 @@ pub const Pdb = struct {...@@ -490,6 +518,26 @@ pub const Pdb = struct {
490 const symbols = try self.allocator.alloc(u8, mod.mod_info.SymByteSize - 4);518 const symbols = try self.allocator.alloc(u8, mod.mod_info.SymByteSize - 4);
491 std.debug.warn("read {} bytes of symbol info\n", symbols.len);519 std.debug.warn("read {} bytes of symbol info\n", symbols.len);
492 try modi.stream.readNoEof(symbols);520 try modi.stream.readNoEof(symbols);
521 var symbol_i: usize = 0;
522 const proc_sym = while (symbol_i != symbols.len) {
523 const prefix = @ptrCast(*RecordPrefix, &symbols[symbol_i]);
524 if (prefix.RecordLen < 2)
525 return error.InvalidDebugInfo;
526 if (prefix.RecordKind == SymbolKind.S_LPROC32) {
527 const proc_sym = @ptrCast(*ProcSym, &symbols[symbol_i + @sizeOf(RecordPrefix)]);
528 const vaddr_start = coff_section.header.virtual_address + proc_sym.CodeOffset;
529 const vaddr_end = vaddr_start + proc_sym.CodeSize;
530 std.debug.warn(" {}\n", proc_sym);
531 if (address >= vaddr_start and address < vaddr_end) {
532 break proc_sym;
533 }
534 }
535 symbol_i += prefix.RecordLen + @sizeOf(u16);
536 if (symbol_i > symbols.len)
537 return error.InvalidDebugInfo;
538 } else return error.MissingDebugInfo;
539
540 std.debug.warn("found in {s}: {}\n", ([*]u8)((*[1]u8)(&proc_sym.Name)), proc_sym);
493541
494 if (mod.mod_info.C11ByteSize != 0)542 if (mod.mod_info.C11ByteSize != 0)
495 return error.InvalidDebugInfo;543 return error.InvalidDebugInfo;