Commit 6e3f82ef28

Jakub Konka <kubkon@jakubkonka.com>
2021-04-09 00:00:35
zld: fix parsing debug info
1 parent 65c27d5
Changed files (3)
src/link/MachO/Archive.zig
@@ -211,10 +211,16 @@ pub fn parseObject(self: Archive, offset: u32) !Object {
 
     log.warn("extracting object '{s}' from archive '{s}'", .{ object_name, self.name.? });
 
+    const name = name: {
+        var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+        const path = try std.os.realpath(self.name.?, &buffer);
+        break :name try std.fmt.allocPrint(self.allocator, "{s}({s})", .{ path, object_name });
+    };
+
     var object = Object.init(self.allocator);
     object.arch = self.arch.?;
     object.file = try fs.cwd().openFile(self.name.?, .{});
-    object.name = try std.fmt.allocPrint(self.allocator, "{s}({s})", .{ self.name.?, object_name });
+    object.name = name;
     object.file_offset = @intCast(u32, try reader.context.getPos());
     try object.parse();
 
src/link/MachO/Object.zig
@@ -71,6 +71,7 @@ const Stab = struct {
     tag: Tag,
     symbol: u32,
     size: ?u64 = null,
+    source_sect_id: u16,
 
     const Tag = enum {
         function,
@@ -387,6 +388,8 @@ pub fn parseDebugInfo(self: *Object) !void {
     };
 
     for (self.symtab.items) |sym, index| {
+        if (sym.tag == .Undef) continue;
+
         const sym_name = self.getString(sym.inner.n_strx);
         const size = blk: for (debug_info.inner.func_list.items) |func| {
             if (func.pc_range) |range| {
@@ -402,6 +405,7 @@ pub fn parseDebugInfo(self: *Object) !void {
             .tag = tag,
             .size = size,
             .symbol = @intCast(u32, index),
+            .source_sect_id = sym.inner.n_sect - 1,
         });
     }
 }
src/link/MachO/Zld.zig
@@ -236,6 +236,11 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
     // First, classify input files as either object or archive.
     for (files) |file_name| {
         const file = try fs.cwd().openFile(file_name, .{});
+        const full_path = full_path: {
+            var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+            const path = try std.fs.realpath(file_name, &buffer);
+            break :full_path try self.allocator.dupe(u8, path);
+        };
 
         try_object: {
             const header = try file.reader().readStruct(macho.mach_header_64);
@@ -248,7 +253,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
             try classified.append(.{
                 .kind = .object,
                 .file = file,
-                .name = file_name,
+                .name = full_path,
             });
             continue;
         }
@@ -264,7 +269,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void {
             try classified.append(.{
                 .kind = .archive,
                 .file = file,
-                .name = file_name,
+                .name = full_path,
             });
             continue;
         }
@@ -2441,7 +2446,7 @@ fn writeDebugInfo(self: *Zld) !void {
     var stabs = std.ArrayList(macho.nlist_64).init(self.allocator);
     defer stabs.deinit();
 
-    for (self.objects.items) |object| {
+    for (self.objects.items) |object, object_id| {
         const tu_path = object.tu_path orelse continue;
         const tu_mtime = object.tu_mtime orelse continue;
         const dirname = std.fs.path.dirname(tu_path) orelse "./";
@@ -2472,6 +2477,15 @@ fn writeDebugInfo(self: *Zld) !void {
 
         for (object.stabs.items) |stab| {
             const sym = object.symtab.items[stab.symbol];
+
+            // TODO We should clean this up.
+            if (self.unhandled_sections.contains(.{
+                .object_id = @intCast(u16, object_id),
+                .source_sect_id = stab.source_sect_id,
+            })) {
+                continue;
+            }
+
             switch (stab.tag) {
                 .function => {
                     try stabs.append(.{
@@ -2549,8 +2563,8 @@ fn populateStringTable(self: *Zld) !void {
     for (self.objects.items) |*object| {
         for (object.symtab.items) |*sym| {
             switch (sym.tag) {
-                .Stab, .Local => {},
-                else => continue,
+                .Undef, .Import => continue,
+                else => {},
             }
             const sym_name = object.getString(sym.inner.n_strx);
             const n_strx = try self.makeString(sym_name);
@@ -2559,6 +2573,8 @@ fn populateStringTable(self: *Zld) !void {
     }
 
     for (self.symtab.items()) |*entry| {
+        if (entry.value.tag != .Import) continue;
+
         const n_strx = try self.makeString(entry.key);
         entry.value.inner.n_strx = n_strx;
     }