zld: fix parsing debug info

This commit is contained in:
Jakub Konka 2021-04-09 00:00:35 +02:00
parent 65c27d51f6
commit 6e3f82ef28
3 changed files with 32 additions and 6 deletions

View File

@ -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();

View File

@ -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,
});
}
}

View File

@ -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;
}