authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-02 17:58:50-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-02 17:58:50-04:00
log4cd50865bffab670040f20b69da13d2f3e89f86f
tree9866c4bd46e3897fef6091d225edcb3de0ed72d5
parent98dc943c0784b93ed28099bb75044c536174a144

fix source file lookup


1 files changed, 72 insertions(+), 82 deletions(-)

std/debug/index.zig+72-82
...@@ -28,7 +28,7 @@ const Module = struct {...@@ -28,7 +28,7 @@ const Module = struct {
28 populated: bool,28 populated: bool,
29 symbols: []u8,29 symbols: []u8,
30 subsect_info: []u8,30 subsect_info: []u8,
31 checksums: []u32,31 checksum_offset: ?usize,
32};32};
3333
34/// Tries to write to stderr, unbuffered, and ignores any error returned.34/// Tries to write to stderr, unbuffered, and ignores any error returned.
...@@ -276,6 +276,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres...@@ -276,6 +276,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
276276
277 var coff_section: *coff.Section = undefined;277 var coff_section: *coff.Section = undefined;
278 const mod_index = for (di.sect_contribs) |sect_contrib| {278 const mod_index = for (di.sect_contribs) |sect_contrib| {
279 if (sect_contrib.Section >= di.coff.sections.len) continue;
279 coff_section = &di.coff.sections.toSlice()[sect_contrib.Section];280 coff_section = &di.coff.sections.toSlice()[sect_contrib.Section];
280281
281 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;282 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;
...@@ -326,72 +327,80 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres...@@ -326,72 +327,80 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
326327
327 var sect_offset: usize = 0;328 var sect_offset: usize = 0;
328 var skip_len: usize = undefined;329 var skip_len: usize = undefined;
329 const opt_line_info = subsections: while (sect_offset != subsect_info.len) : (sect_offset += skip_len) {330 const opt_line_info = subsections: {
330 const subsect_hdr = @ptrCast(*pdb.DebugSubsectionHeader, &subsect_info[sect_offset]);331 const checksum_offset = mod.checksum_offset orelse break :subsections null;
331 skip_len = subsect_hdr.Length;332 while (sect_offset != subsect_info.len) : (sect_offset += skip_len) {
332 sect_offset += @sizeOf(pdb.DebugSubsectionHeader);333 const subsect_hdr = @ptrCast(*pdb.DebugSubsectionHeader, &subsect_info[sect_offset]);
333334 skip_len = subsect_hdr.Length;
334 switch (subsect_hdr.Kind) {335 sect_offset += @sizeOf(pdb.DebugSubsectionHeader);
335 pdb.DebugSubsectionKind.Lines => {336
336 var line_index: usize = sect_offset;337 switch (subsect_hdr.Kind) {
337338 pdb.DebugSubsectionKind.Lines => {
338 const line_hdr = @ptrCast(*pdb.LineFragmentHeader, &subsect_info[line_index]);339 var line_index: usize = sect_offset;
339 if (line_hdr.RelocSegment == 0) return error.MissingDebugInfo;340
340 line_index += @sizeOf(pdb.LineFragmentHeader);341 const line_hdr = @ptrCast(*pdb.LineFragmentHeader, &subsect_info[line_index]);
341342 if (line_hdr.RelocSegment == 0) return error.MissingDebugInfo;
342 const block_hdr = @ptrCast(*pdb.LineBlockFragmentHeader, &subsect_info[line_index]);343 line_index += @sizeOf(pdb.LineFragmentHeader);
343 line_index += @sizeOf(pdb.LineBlockFragmentHeader);344
344345 const block_hdr = @ptrCast(*pdb.LineBlockFragmentHeader, &subsect_info[line_index]);
345 const has_column = line_hdr.Flags.LF_HaveColumns;346 line_index += @sizeOf(pdb.LineBlockFragmentHeader);
346347
347 const frag_vaddr_start = coff_section.header.virtual_address + line_hdr.RelocOffset;348 const has_column = line_hdr.Flags.LF_HaveColumns;
348 const frag_vaddr_end = frag_vaddr_start + line_hdr.CodeSize;349
349 if (relative_address >= frag_vaddr_start and relative_address < frag_vaddr_end) {350 const frag_vaddr_start = coff_section.header.virtual_address + line_hdr.RelocOffset;
350 var line_i: usize = 0;351 const frag_vaddr_end = frag_vaddr_start + line_hdr.CodeSize;
351 const start_line_index = line_index;352 if (relative_address >= frag_vaddr_start and relative_address < frag_vaddr_end) {
352 while (line_i < block_hdr.NumLines) : (line_i += 1) {353 var line_i: usize = 0;
353 const line_num_entry = @ptrCast(*pdb.LineNumberEntry, &subsect_info[line_index]);354 const start_line_index = line_index;
354 line_index += @sizeOf(pdb.LineNumberEntry);355 while (line_i < block_hdr.NumLines) : (line_i += 1) {
355 const flags = @ptrCast(*pdb.LineNumberEntry.Flags, &line_num_entry.Flags);356 const line_num_entry = @ptrCast(*pdb.LineNumberEntry, &subsect_info[line_index]);
356 const vaddr_start = frag_vaddr_start + line_num_entry.Offset;357 line_index += @sizeOf(pdb.LineNumberEntry);
357 const vaddr_end = if (flags.End == 0) frag_vaddr_end else vaddr_start + flags.End;358 const flags = @ptrCast(*pdb.LineNumberEntry.Flags, &line_num_entry.Flags);
358 if (relative_address >= vaddr_start and relative_address < vaddr_end) {359 const vaddr_start = frag_vaddr_start + line_num_entry.Offset;
359 const chksum_index = block_hdr.NameIndex;360 const vaddr_end = if (flags.End == 0) frag_vaddr_end else vaddr_start + flags.End;
360 std.debug.warn("looking up checksum {}\n", chksum_index);361 if (relative_address >= vaddr_start and relative_address < vaddr_end) {
361 const strtab_offset = mod.checksums[chksum_index];362 const subsect_index = checksum_offset + block_hdr.NameIndex;
362 try di.pdb.string_table.seekTo(@sizeOf(pdb.PDBStringTableHeader) + strtab_offset);363 const chksum_hdr = @ptrCast(*pdb.FileChecksumEntryHeader, &mod.subsect_info[subsect_index]);
363 const source_file_name = try di.pdb.string_table.readNullTermString(allocator);364 const strtab_offset = @sizeOf(pdb.PDBStringTableHeader) + chksum_hdr.FileNameOffset;
364 const line = flags.Start;365 try di.pdb.string_table.seekTo(strtab_offset);
365 const column = if (has_column) blk: {366 const source_file_name = try di.pdb.string_table.readNullTermString(allocator);
366 line_index = start_line_index + @sizeOf(pdb.LineNumberEntry) * block_hdr.NumLines;367 const line = flags.Start;
367 line_index += @sizeOf(pdb.ColumnNumberEntry) * line_i;368 const column = if (has_column) blk: {
368 const col_num_entry = @ptrCast(*pdb.ColumnNumberEntry, &subsect_info[line_index]);369 line_index = start_line_index + @sizeOf(pdb.LineNumberEntry) * block_hdr.NumLines;
369 break :blk col_num_entry.StartColumn;370 line_index += @sizeOf(pdb.ColumnNumberEntry) * line_i;
370 } else 0;371 const col_num_entry = @ptrCast(*pdb.ColumnNumberEntry, &subsect_info[line_index]);
371 break :subsections LineInfo{372 break :blk col_num_entry.StartColumn;
372 .allocator = allocator,373 } else 0;
373 .file_name = source_file_name,374 break :subsections LineInfo{
374 .line = line,375 .allocator = allocator,
375 .column = column,376 .file_name = source_file_name,
376 };377 .line = line,
378 .column = column,
379 };
380 }
377 }381 }
382 break :subsections null;
378 }383 }
379 break :subsections null;384 },
380 }385 else => {},
381 },386 }
382 else => {},
383 }
384387
385 if (sect_offset > subsect_info.len)388 if (sect_offset > subsect_info.len)
386 return error.InvalidDebugInfo;389 return error.InvalidDebugInfo;
387 } else null;390 } else {
391 break :subsections null;
392 }
393 };
388 394
389 if (tty_color) {395 if (tty_color) {
396 setTtyColor(TtyColor.White);
390 if (opt_line_info) |li| {397 if (opt_line_info) |li| {
391 try out_stream.print("{}:{}:{}: ", li.file_name, li.line, li.column);398 try out_stream.print("{}:{}:{}", li.file_name, li.line, li.column);
392 } else {399 } else {
393 try out_stream.print("???:?:?: ");400 try out_stream.print("???:?:?");
394 }401 }
402 setTtyColor(TtyColor.Reset);
403 try out_stream.print(": ");
395 setTtyColor(TtyColor.Dim);404 setTtyColor(TtyColor.Dim);
396 try out_stream.print("0x{x} in {} ({})", relocated_address, symbol_name, obj_basename);405 try out_stream.print("0x{x} in {} ({})", relocated_address, symbol_name, obj_basename);
397 setTtyColor(TtyColor.Reset);406 setTtyColor(TtyColor.Reset);
...@@ -470,8 +479,7 @@ fn setTtyColor(tty_color: TtyColor) void {...@@ -470,8 +479,7 @@ fn setTtyColor(tty_color: TtyColor) void {
470 windows.FOREGROUND_RED|windows.FOREGROUND_GREEN|windows.FOREGROUND_BLUE|windows.FOREGROUND_INTENSITY);479 windows.FOREGROUND_RED|windows.FOREGROUND_GREEN|windows.FOREGROUND_BLUE|windows.FOREGROUND_INTENSITY);
471 },480 },
472 TtyColor.Dim => {481 TtyColor.Dim => {
473 _ = windows.SetConsoleTextAttribute(stderr_file.handle,482 _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY);
474 windows.FOREGROUND_RED|windows.FOREGROUND_GREEN|windows.FOREGROUND_BLUE);
475 },483 },
476 TtyColor.Reset => {484 TtyColor.Reset => {
477 _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs);485 _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs);
...@@ -502,7 +510,6 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {...@@ -502,7 +510,6 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {
502 mod.subsect_info = try allocator.alloc(u8, mod.mod_info.C13ByteSize);510 mod.subsect_info = try allocator.alloc(u8, mod.mod_info.C13ByteSize);
503 try modi.stream.readNoEof(mod.subsect_info);511 try modi.stream.readNoEof(mod.subsect_info);
504512
505 var checksum_list = ArrayList(u32).init(allocator);
506 var sect_offset: usize = 0;513 var sect_offset: usize = 0;
507 var skip_len: usize = undefined;514 var skip_len: usize = undefined;
508 while (sect_offset != mod.subsect_info.len) : (sect_offset += skip_len) {515 while (sect_offset != mod.subsect_info.len) : (sect_offset += skip_len) {
...@@ -512,18 +519,8 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {...@@ -512,18 +519,8 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {
512519
513 switch (subsect_hdr.Kind) {520 switch (subsect_hdr.Kind) {
514 pdb.DebugSubsectionKind.FileChecksums => {521 pdb.DebugSubsectionKind.FileChecksums => {
515 var chksum_index: usize = sect_offset;522 mod.checksum_offset = sect_offset;
516523 break;
517 while (chksum_index != mod.subsect_info.len) {
518 const chksum_hdr = @ptrCast(*pdb.FileChecksumEntryHeader, &mod.subsect_info[chksum_index]);
519 std.debug.warn("{} {}\n", checksum_list.len, chksum_hdr);
520 try checksum_list.append(chksum_hdr.FileNameOffset);
521 const len = @sizeOf(pdb.FileChecksumEntryHeader) + chksum_hdr.ChecksumSize;
522 chksum_index += len + (len % 4);
523 if (chksum_index > mod.subsect_info.len)
524 return error.InvalidDebugInfo;
525 }
526
527 },524 },
528 else => {},525 else => {},
529 }526 }
...@@ -531,13 +528,6 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {...@@ -531,13 +528,6 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {
531 if (sect_offset > mod.subsect_info.len)528 if (sect_offset > mod.subsect_info.len)
532 return error.InvalidDebugInfo;529 return error.InvalidDebugInfo;
533 }530 }
534 mod.checksums = checksum_list.toOwnedSlice();
535
536 for (mod.checksums) |strtab_offset| {
537 try di.pdb.string_table.seekTo(@sizeOf(pdb.PDBStringTableHeader) + strtab_offset);
538 const source_file_name = try di.pdb.string_table.readNullTermString(allocator);
539 std.debug.warn("{}={}\n", strtab_offset, source_file_name);
540 }
541531
542 mod.populated = true;532 mod.populated = true;
543}533}
...@@ -807,7 +797,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {...@@ -807,7 +797,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
807 .populated = false,797 .populated = false,
808 .symbols = undefined,798 .symbols = undefined,
809 .subsect_info = undefined,799 .subsect_info = undefined,
810 .checksums = undefined,800 .checksum_offset = null,
811 });801 });
812802
813 mod_info_offset += this_record_len;803 mod_info_offset += this_record_len;