authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-09 00:00:35+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-13 10:56:03+02:00
log6e3f82ef28aa17c9fb7933af07b9823c1331f884
tree43b25688ca21c80516b675b7eb836f7d2accffd0
parent65c27d51f691524f63e964ad04cb12e3a77c5a9b

zld: fix parsing debug info


3 files changed, 32 insertions(+), 6 deletions(-)

src/link/MachO/Archive.zig+7-1
...@@ -211,10 +211,16 @@ pub fn parseObject(self: Archive, offset: u32) !Object {...@@ -211,10 +211,16 @@ pub fn parseObject(self: Archive, offset: u32) !Object {
211211
212 log.warn("extracting object '{s}' from archive '{s}'", .{ object_name, self.name.? });212 log.warn("extracting object '{s}' from archive '{s}'", .{ object_name, self.name.? });
213213
214 const name = name: {
215 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
216 const path = try std.os.realpath(self.name.?, &buffer);
217 break :name try std.fmt.allocPrint(self.allocator, "{s}({s})", .{ path, object_name });
218 };
219
214 var object = Object.init(self.allocator);220 var object = Object.init(self.allocator);
215 object.arch = self.arch.?;221 object.arch = self.arch.?;
216 object.file = try fs.cwd().openFile(self.name.?, .{});222 object.file = try fs.cwd().openFile(self.name.?, .{});
217 object.name = try std.fmt.allocPrint(self.allocator, "{s}({s})", .{ self.name.?, object_name });223 object.name = name;
218 object.file_offset = @intCast(u32, try reader.context.getPos());224 object.file_offset = @intCast(u32, try reader.context.getPos());
219 try object.parse();225 try object.parse();
220226
src/link/MachO/Object.zig+4
...@@ -71,6 +71,7 @@ const Stab = struct {...@@ -71,6 +71,7 @@ const Stab = struct {
71 tag: Tag,71 tag: Tag,
72 symbol: u32,72 symbol: u32,
73 size: ?u64 = null,73 size: ?u64 = null,
74 source_sect_id: u16,
7475
75 const Tag = enum {76 const Tag = enum {
76 function,77 function,
...@@ -387,6 +388,8 @@ pub fn parseDebugInfo(self: *Object) !void {...@@ -387,6 +388,8 @@ pub fn parseDebugInfo(self: *Object) !void {
387 };388 };
388389
389 for (self.symtab.items) |sym, index| {390 for (self.symtab.items) |sym, index| {
391 if (sym.tag == .Undef) continue;
392
390 const sym_name = self.getString(sym.inner.n_strx);393 const sym_name = self.getString(sym.inner.n_strx);
391 const size = blk: for (debug_info.inner.func_list.items) |func| {394 const size = blk: for (debug_info.inner.func_list.items) |func| {
392 if (func.pc_range) |range| {395 if (func.pc_range) |range| {
...@@ -402,6 +405,7 @@ pub fn parseDebugInfo(self: *Object) !void {...@@ -402,6 +405,7 @@ pub fn parseDebugInfo(self: *Object) !void {
402 .tag = tag,405 .tag = tag,
403 .size = size,406 .size = size,
404 .symbol = @intCast(u32, index),407 .symbol = @intCast(u32, index),
408 .source_sect_id = sym.inner.n_sect - 1,
405 });409 });
406 }410 }
407}411}
src/link/MachO/Zld.zig+21-5
...@@ -236,6 +236,11 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {...@@ -236,6 +236,11 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
236 // First, classify input files as either object or archive.236 // First, classify input files as either object or archive.
237 for (files) |file_name| {237 for (files) |file_name| {
238 const file = try fs.cwd().openFile(file_name, .{});238 const file = try fs.cwd().openFile(file_name, .{});
239 const full_path = full_path: {
240 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
241 const path = try std.fs.realpath(file_name, &buffer);
242 break :full_path try self.allocator.dupe(u8, path);
243 };
239244
240 try_object: {245 try_object: {
241 const header = try file.reader().readStruct(macho.mach_header_64);246 const header = try file.reader().readStruct(macho.mach_header_64);
...@@ -248,7 +253,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {...@@ -248,7 +253,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
248 try classified.append(.{253 try classified.append(.{
249 .kind = .object,254 .kind = .object,
250 .file = file,255 .file = file,
251 .name = file_name,256 .name = full_path,
252 });257 });
253 continue;258 continue;
254 }259 }
...@@ -264,7 +269,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {...@@ -264,7 +269,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
264 try classified.append(.{269 try classified.append(.{
265 .kind = .archive,270 .kind = .archive,
266 .file = file,271 .file = file,
267 .name = file_name,272 .name = full_path,
268 });273 });
269 continue;274 continue;
270 }275 }
...@@ -2441,7 +2446,7 @@ fn writeDebugInfo(self: *Zld) !void {...@@ -2441,7 +2446,7 @@ fn writeDebugInfo(self: *Zld) !void {
2441 var stabs = std.ArrayList(macho.nlist_64).init(self.allocator);2446 var stabs = std.ArrayList(macho.nlist_64).init(self.allocator);
2442 defer stabs.deinit();2447 defer stabs.deinit();
24432448
2444 for (self.objects.items) |object| {2449 for (self.objects.items) |object, object_id| {
2445 const tu_path = object.tu_path orelse continue;2450 const tu_path = object.tu_path orelse continue;
2446 const tu_mtime = object.tu_mtime orelse continue;2451 const tu_mtime = object.tu_mtime orelse continue;
2447 const dirname = std.fs.path.dirname(tu_path) orelse "./";2452 const dirname = std.fs.path.dirname(tu_path) orelse "./";
...@@ -2472,6 +2477,15 @@ fn writeDebugInfo(self: *Zld) !void {...@@ -2472,6 +2477,15 @@ fn writeDebugInfo(self: *Zld) !void {
24722477
2473 for (object.stabs.items) |stab| {2478 for (object.stabs.items) |stab| {
2474 const sym = object.symtab.items[stab.symbol];2479 const sym = object.symtab.items[stab.symbol];
2480
2481 // TODO We should clean this up.
2482 if (self.unhandled_sections.contains(.{
2483 .object_id = @intCast(u16, object_id),
2484 .source_sect_id = stab.source_sect_id,
2485 })) {
2486 continue;
2487 }
2488
2475 switch (stab.tag) {2489 switch (stab.tag) {
2476 .function => {2490 .function => {
2477 try stabs.append(.{2491 try stabs.append(.{
...@@ -2549,8 +2563,8 @@ fn populateStringTable(self: *Zld) !void {...@@ -2549,8 +2563,8 @@ fn populateStringTable(self: *Zld) !void {
2549 for (self.objects.items) |*object| {2563 for (self.objects.items) |*object| {
2550 for (object.symtab.items) |*sym| {2564 for (object.symtab.items) |*sym| {
2551 switch (sym.tag) {2565 switch (sym.tag) {
2552 .Stab, .Local => {},2566 .Undef, .Import => continue,
2553 else => continue,2567 else => {},
2554 }2568 }
2555 const sym_name = object.getString(sym.inner.n_strx);2569 const sym_name = object.getString(sym.inner.n_strx);
2556 const n_strx = try self.makeString(sym_name);2570 const n_strx = try self.makeString(sym_name);
...@@ -2559,6 +2573,8 @@ fn populateStringTable(self: *Zld) !void {...@@ -2559,6 +2573,8 @@ fn populateStringTable(self: *Zld) !void {
2559 }2573 }
25602574
2561 for (self.symtab.items()) |*entry| {2575 for (self.symtab.items()) |*entry| {
2576 if (entry.value.tag != .Import) continue;
2577
2562 const n_strx = try self.makeString(entry.key);2578 const n_strx = try self.makeString(entry.key);
2563 entry.value.inner.n_strx = n_strx;2579 entry.value.inner.n_strx = n_strx;
2564 }2580 }