mirror of
https://github.com/ziglang/zig.git
synced 2026-01-19 05:45:12 +00:00
macho: do not store stabs; generate on-the-fly instead
This commit is contained in:
parent
41b91442f4
commit
0da8ba816a
@ -4,6 +4,7 @@ const std = @import("std");
|
||||
const build_options = @import("build_options");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const dwarf = std.dwarf;
|
||||
const fmt = std.fmt;
|
||||
const fs = std.fs;
|
||||
const log = std.log.scoped(.link);
|
||||
@ -187,7 +188,6 @@ error_flags: File.ErrorFlags = File.ErrorFlags{},
|
||||
load_commands_dirty: bool = false,
|
||||
sections_order_dirty: bool = false,
|
||||
has_dices: bool = false,
|
||||
has_stabs: bool = false,
|
||||
|
||||
/// A helper var to indicate if we are at the start of the incremental updates, or
|
||||
/// already somewhere further along the update-and-run chain.
|
||||
@ -725,6 +725,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node)
|
||||
man.hash.add(self.base.options.headerpad_max_install_names);
|
||||
man.hash.add(dead_strip);
|
||||
man.hash.add(self.base.options.dead_strip_dylibs);
|
||||
man.hash.add(self.base.options.strip);
|
||||
man.hash.addListOfBytes(self.base.options.lib_dirs);
|
||||
man.hash.addListOfBytes(self.base.options.framework_dirs);
|
||||
link.hashAddSystemLibs(&man.hash, self.base.options.frameworks);
|
||||
@ -1388,9 +1389,15 @@ fn parseObject(self: *MachO, path: []const u8) !bool {
|
||||
const name = try self.base.allocator.dupe(u8, path);
|
||||
errdefer self.base.allocator.free(name);
|
||||
|
||||
const mtime: u64 = mtime: {
|
||||
const stat = file.stat() catch break :mtime 0;
|
||||
break :mtime @intCast(u64, @divFloor(stat.mtime, 1_000_000_000));
|
||||
};
|
||||
|
||||
var object = Object{
|
||||
.name = name,
|
||||
.file = file,
|
||||
.mtime = mtime,
|
||||
};
|
||||
|
||||
object.parse(self.base.allocator, self.base.options.target) catch |err| switch (err) {
|
||||
@ -2910,7 +2917,6 @@ fn createTentativeDefAtoms(self: *MachO) !void {
|
||||
try atom.contained.append(gpa, .{
|
||||
.sym_index = global.sym_index,
|
||||
.offset = 0,
|
||||
.stab = if (object.debug_info) |_| .static else null,
|
||||
});
|
||||
|
||||
try object.managed_atoms.append(gpa, atom);
|
||||
@ -6188,64 +6194,6 @@ fn writeSymtab(self: *MachO) !void {
|
||||
}
|
||||
|
||||
for (self.objects.items) |object, object_id| {
|
||||
if (self.has_stabs) {
|
||||
if (object.debug_info) |_| {
|
||||
// Open scope
|
||||
try locals.ensureUnusedCapacity(3);
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = try self.strtab.insert(gpa, object.tu_comp_dir.?),
|
||||
.n_type = macho.N_SO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = 0,
|
||||
});
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = try self.strtab.insert(gpa, object.tu_name.?),
|
||||
.n_type = macho.N_SO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = 0,
|
||||
});
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = try self.strtab.insert(gpa, object.name),
|
||||
.n_type = macho.N_OSO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 1,
|
||||
.n_value = object.mtime orelse 0,
|
||||
});
|
||||
|
||||
for (object.managed_atoms.items) |atom| {
|
||||
for (atom.contained.items) |sym_at_off| {
|
||||
const stab = sym_at_off.stab orelse continue;
|
||||
const sym_loc = SymbolWithLoc{
|
||||
.sym_index = sym_at_off.sym_index,
|
||||
.file = atom.file,
|
||||
};
|
||||
const sym = self.getSymbol(sym_loc);
|
||||
if (sym.n_strx == 0) continue;
|
||||
if (sym.n_desc == N_DESC_GCED) continue;
|
||||
if (self.symbolIsTemp(sym_loc)) continue;
|
||||
|
||||
const nlists = try stab.asNlists(.{
|
||||
.sym_index = sym_at_off.sym_index,
|
||||
.file = atom.file,
|
||||
}, self);
|
||||
defer gpa.free(nlists);
|
||||
|
||||
try locals.appendSlice(nlists);
|
||||
}
|
||||
}
|
||||
|
||||
// Close scope
|
||||
try locals.append(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_SO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
for (object.symtab.items) |sym, sym_id| {
|
||||
if (sym.n_strx == 0) continue; // no name, skip
|
||||
if (sym.n_desc == N_DESC_GCED) continue; // GCed, skip
|
||||
@ -6256,6 +6204,10 @@ fn writeSymtab(self: *MachO) !void {
|
||||
out_sym.n_strx = try self.strtab.insert(gpa, self.getSymbolName(sym_loc));
|
||||
try locals.append(out_sym);
|
||||
}
|
||||
|
||||
if (!self.base.options.strip) {
|
||||
try self.generateSymbolStabs(object, &locals);
|
||||
}
|
||||
}
|
||||
|
||||
var exports = std.ArrayList(macho.nlist_64).init(gpa);
|
||||
@ -6663,6 +6615,200 @@ pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate:
|
||||
return i;
|
||||
}
|
||||
|
||||
const DebugInfo = struct {
|
||||
inner: dwarf.DwarfInfo,
|
||||
debug_info: []const u8,
|
||||
debug_abbrev: []const u8,
|
||||
debug_str: []const u8,
|
||||
debug_line: []const u8,
|
||||
debug_line_str: []const u8,
|
||||
debug_ranges: []const u8,
|
||||
|
||||
pub fn parse(allocator: Allocator, object: Object) !?DebugInfo {
|
||||
var debug_info = blk: {
|
||||
const index = object.dwarf_debug_info_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_abbrev = blk: {
|
||||
const index = object.dwarf_debug_abbrev_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_str = blk: {
|
||||
const index = object.dwarf_debug_str_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_line = blk: {
|
||||
const index = object.dwarf_debug_line_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_line_str = blk: {
|
||||
if (object.dwarf_debug_line_str_index) |ind| {
|
||||
break :blk try object.getSectionContents(ind);
|
||||
}
|
||||
break :blk &[0]u8{};
|
||||
};
|
||||
var debug_ranges = blk: {
|
||||
if (object.dwarf_debug_ranges_index) |ind| {
|
||||
break :blk try object.getSectionContents(ind);
|
||||
}
|
||||
break :blk &[0]u8{};
|
||||
};
|
||||
|
||||
var inner: dwarf.DwarfInfo = .{
|
||||
.endian = .Little,
|
||||
.debug_info = debug_info,
|
||||
.debug_abbrev = debug_abbrev,
|
||||
.debug_str = debug_str,
|
||||
.debug_line = debug_line,
|
||||
.debug_line_str = debug_line_str,
|
||||
.debug_ranges = debug_ranges,
|
||||
};
|
||||
try dwarf.openDwarfDebugInfo(&inner, allocator);
|
||||
|
||||
return DebugInfo{
|
||||
.inner = inner,
|
||||
.debug_info = debug_info,
|
||||
.debug_abbrev = debug_abbrev,
|
||||
.debug_str = debug_str,
|
||||
.debug_line = debug_line,
|
||||
.debug_line_str = debug_line_str,
|
||||
.debug_ranges = debug_ranges,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *DebugInfo, allocator: Allocator) void {
|
||||
self.inner.deinit(allocator);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn generateSymbolStabs(
|
||||
self: *MachO,
|
||||
object: Object,
|
||||
locals: *std.ArrayList(macho.nlist_64),
|
||||
) !void {
|
||||
assert(!self.base.options.strip);
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
log.debug("parsing debug info in '{s}'", .{object.name});
|
||||
|
||||
var debug_info = (try DebugInfo.parse(gpa, object)) orelse return;
|
||||
|
||||
// We assume there is only one CU.
|
||||
const compile_unit = debug_info.inner.findCompileUnit(0x0) catch |err| switch (err) {
|
||||
error.MissingDebugInfo => {
|
||||
// TODO audit cases with missing debug info and audit our dwarf.zig module.
|
||||
log.debug("invalid or missing debug info in {s}; skipping", .{object.name});
|
||||
return;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
const tu_name = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.name);
|
||||
const tu_comp_dir = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.comp_dir);
|
||||
const source_symtab = object.getSourceSymtab();
|
||||
|
||||
// Open scope
|
||||
try locals.ensureUnusedCapacity(3);
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = try self.strtab.insert(gpa, tu_comp_dir),
|
||||
.n_type = macho.N_SO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = 0,
|
||||
});
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = try self.strtab.insert(gpa, tu_name),
|
||||
.n_type = macho.N_SO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = 0,
|
||||
});
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = try self.strtab.insert(gpa, object.name),
|
||||
.n_type = macho.N_OSO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 1,
|
||||
.n_value = object.mtime,
|
||||
});
|
||||
|
||||
for (object.managed_atoms.items) |atom| {
|
||||
for (atom.contained.items) |sym_at_off| {
|
||||
const sym_loc = SymbolWithLoc{
|
||||
.sym_index = sym_at_off.sym_index,
|
||||
.file = atom.file,
|
||||
};
|
||||
const sym = self.getSymbol(sym_loc);
|
||||
const sym_name = self.getSymbolName(sym_loc);
|
||||
if (sym.n_strx == 0) continue;
|
||||
if (sym.n_desc == N_DESC_GCED) continue;
|
||||
if (self.symbolIsTemp(sym_loc)) continue;
|
||||
if (sym_at_off.sym_index >= source_symtab.len) continue; // synthetic, linker generated
|
||||
|
||||
const source_sym = source_symtab[sym_at_off.sym_index];
|
||||
const size: ?u64 = size: {
|
||||
if (source_sym.tentative()) break :size null;
|
||||
for (debug_info.inner.func_list.items) |func| {
|
||||
if (func.pc_range) |range| {
|
||||
if (source_sym.n_value >= range.start and source_sym.n_value < range.end) {
|
||||
break :size range.end - range.start;
|
||||
}
|
||||
}
|
||||
}
|
||||
break :size null;
|
||||
};
|
||||
|
||||
if (size) |ss| {
|
||||
try locals.ensureUnusedCapacity(4);
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_BNSYM,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = sym.n_value,
|
||||
});
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = try self.strtab.insert(gpa, sym_name),
|
||||
.n_type = macho.N_FUN,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = sym.n_value,
|
||||
});
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_FUN,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = ss,
|
||||
});
|
||||
locals.appendAssumeCapacity(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_ENSYM,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = ss,
|
||||
});
|
||||
} else {
|
||||
try locals.append(.{
|
||||
.n_strx = try self.strtab.insert(gpa, sym_name),
|
||||
.n_type = macho.N_STSYM,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = sym.n_value,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close scope
|
||||
try locals.append(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_SO,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = 0,
|
||||
});
|
||||
}
|
||||
|
||||
fn snapshotState(self: *MachO) !void {
|
||||
const emit = self.base.options.emit orelse {
|
||||
log.debug("no emit directory found; skipping snapshot...", .{});
|
||||
|
||||
@ -78,76 +78,6 @@ pub const Binding = struct {
|
||||
pub const SymbolAtOffset = struct {
|
||||
sym_index: u32,
|
||||
offset: u64,
|
||||
stab: ?Stab = null,
|
||||
};
|
||||
|
||||
pub const Stab = union(enum) {
|
||||
function: u64,
|
||||
static,
|
||||
global,
|
||||
|
||||
pub fn asNlists(stab: Stab, sym_loc: SymbolWithLoc, macho_file: *MachO) ![]macho.nlist_64 {
|
||||
const gpa = macho_file.base.allocator;
|
||||
|
||||
var nlists = std.ArrayList(macho.nlist_64).init(gpa);
|
||||
defer nlists.deinit();
|
||||
|
||||
const sym = macho_file.getSymbol(sym_loc);
|
||||
const sym_name = macho_file.getSymbolName(sym_loc);
|
||||
switch (stab) {
|
||||
.function => |size| {
|
||||
try nlists.ensureUnusedCapacity(4);
|
||||
nlists.appendAssumeCapacity(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_BNSYM,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = sym.n_value,
|
||||
});
|
||||
nlists.appendAssumeCapacity(.{
|
||||
.n_strx = try macho_file.strtab.insert(gpa, sym_name),
|
||||
.n_type = macho.N_FUN,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = sym.n_value,
|
||||
});
|
||||
nlists.appendAssumeCapacity(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_FUN,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = size,
|
||||
});
|
||||
nlists.appendAssumeCapacity(.{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_ENSYM,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = size,
|
||||
});
|
||||
},
|
||||
.global => {
|
||||
try nlists.append(.{
|
||||
.n_strx = try macho_file.strtab.insert(gpa, sym_name),
|
||||
.n_type = macho.N_GSYM,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
.n_value = 0,
|
||||
});
|
||||
},
|
||||
.static => {
|
||||
try nlists.append(.{
|
||||
.n_strx = try macho_file.strtab.insert(gpa, sym_name),
|
||||
.n_type = macho.N_STSYM,
|
||||
.n_sect = sym.n_sect,
|
||||
.n_desc = 0,
|
||||
.n_value = sym.n_value,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
return nlists.toOwnedSlice();
|
||||
}
|
||||
};
|
||||
|
||||
pub const Relocation = struct {
|
||||
|
||||
@ -3,7 +3,6 @@ const Object = @This();
|
||||
const std = @import("std");
|
||||
const build_options = @import("build_options");
|
||||
const assert = std.debug.assert;
|
||||
const dwarf = std.dwarf;
|
||||
const fs = std.fs;
|
||||
const io = std.io;
|
||||
const log = std.log.scoped(.link);
|
||||
@ -17,9 +16,11 @@ const Allocator = mem.Allocator;
|
||||
const Atom = @import("Atom.zig");
|
||||
const MachO = @import("../MachO.zig");
|
||||
const MatchingSection = MachO.MatchingSection;
|
||||
const SymbolWithLoc = MachO.SymbolWithLoc;
|
||||
|
||||
file: fs.File,
|
||||
name: []const u8,
|
||||
mtime: u64,
|
||||
|
||||
/// Data contents of the file. Includes sections, and data of load commands.
|
||||
/// Excludes the backing memory for the header and load commands.
|
||||
@ -51,12 +52,6 @@ symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{},
|
||||
strtab: []const u8 = &.{},
|
||||
data_in_code_entries: []const macho.data_in_code_entry = &.{},
|
||||
|
||||
// Debug info
|
||||
debug_info: ?DebugInfo = null,
|
||||
tu_name: ?[]const u8 = null,
|
||||
tu_comp_dir: ?[]const u8 = null,
|
||||
mtime: ?u64 = null,
|
||||
|
||||
sections_as_symbols: std.AutoHashMapUnmanaged(u16, u32) = .{},
|
||||
|
||||
/// List of atoms that map to the symbols parsed from this object file.
|
||||
@ -65,72 +60,6 @@ managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},
|
||||
/// Table of atoms belonging to this object file indexed by the symbol index.
|
||||
atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{},
|
||||
|
||||
const DebugInfo = struct {
|
||||
inner: dwarf.DwarfInfo,
|
||||
debug_info: []const u8,
|
||||
debug_abbrev: []const u8,
|
||||
debug_str: []const u8,
|
||||
debug_line: []const u8,
|
||||
debug_line_str: []const u8,
|
||||
debug_ranges: []const u8,
|
||||
|
||||
pub fn parseFromObject(allocator: Allocator, object: *const Object) !?DebugInfo {
|
||||
var debug_info = blk: {
|
||||
const index = object.dwarf_debug_info_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_abbrev = blk: {
|
||||
const index = object.dwarf_debug_abbrev_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_str = blk: {
|
||||
const index = object.dwarf_debug_str_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_line = blk: {
|
||||
const index = object.dwarf_debug_line_index orelse return null;
|
||||
break :blk try object.getSectionContents(index);
|
||||
};
|
||||
var debug_line_str = blk: {
|
||||
if (object.dwarf_debug_line_str_index) |ind| {
|
||||
break :blk try object.getSectionContents(ind);
|
||||
}
|
||||
break :blk &[0]u8{};
|
||||
};
|
||||
var debug_ranges = blk: {
|
||||
if (object.dwarf_debug_ranges_index) |ind| {
|
||||
break :blk try object.getSectionContents(ind);
|
||||
}
|
||||
break :blk &[0]u8{};
|
||||
};
|
||||
|
||||
var inner: dwarf.DwarfInfo = .{
|
||||
.endian = .Little,
|
||||
.debug_info = debug_info,
|
||||
.debug_abbrev = debug_abbrev,
|
||||
.debug_str = debug_str,
|
||||
.debug_line = debug_line,
|
||||
.debug_line_str = debug_line_str,
|
||||
.debug_ranges = debug_ranges,
|
||||
};
|
||||
try dwarf.openDwarfDebugInfo(&inner, allocator);
|
||||
|
||||
return DebugInfo{
|
||||
.inner = inner,
|
||||
.debug_info = debug_info,
|
||||
.debug_abbrev = debug_abbrev,
|
||||
.debug_str = debug_str,
|
||||
.debug_line = debug_line,
|
||||
.debug_line_str = debug_line_str,
|
||||
.debug_ranges = debug_ranges,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *DebugInfo, allocator: Allocator) void {
|
||||
self.inner.deinit(allocator);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn deinit(self: *Object, gpa: Allocator) void {
|
||||
for (self.load_commands.items) |*lc| {
|
||||
lc.deinit(gpa);
|
||||
@ -147,10 +76,6 @@ pub fn deinit(self: *Object, gpa: Allocator) void {
|
||||
self.managed_atoms.deinit(gpa);
|
||||
|
||||
gpa.free(self.name);
|
||||
|
||||
if (self.debug_info) |*db| {
|
||||
db.deinit(gpa);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(self: *Object, allocator: Allocator, target: std.Target) !void {
|
||||
@ -253,7 +178,6 @@ pub fn parse(self: *Object, allocator: Allocator, target: std.Target) !void {
|
||||
|
||||
try self.parseSymtab(allocator);
|
||||
self.parseDataInCode();
|
||||
try self.parseDebugInfo(allocator);
|
||||
}
|
||||
|
||||
const Context = struct {
|
||||
@ -462,7 +386,6 @@ pub fn splitIntoAtomsOneShot(
|
||||
}
|
||||
break :blk false;
|
||||
};
|
||||
macho_file.has_stabs = macho_file.has_stabs or self.debug_info != null;
|
||||
|
||||
if (subsections_via_symbols and filtered_syms.len > 0) {
|
||||
// If the first nlist does not match the start of the section,
|
||||
@ -566,7 +489,6 @@ pub fn splitIntoAtomsOneShot(
|
||||
try atom.contained.append(gpa, .{
|
||||
.sym_index = alias,
|
||||
.offset = 0,
|
||||
.stab = null,
|
||||
});
|
||||
try self.atom_by_index_table.put(gpa, alias, atom);
|
||||
}
|
||||
@ -671,54 +593,17 @@ fn createAtomFromSubsection(
|
||||
// we can properly allocate addresses down the line.
|
||||
// While we're at it, we need to update segment,section mapping of each symbol too.
|
||||
try atom.contained.ensureTotalCapacity(gpa, indexes.len + 1);
|
||||
|
||||
{
|
||||
const stab: ?Atom.Stab = if (self.debug_info) |di| blk: {
|
||||
// TODO there has to be a better to handle this.
|
||||
for (di.inner.func_list.items) |func| {
|
||||
if (func.pc_range) |range| {
|
||||
if (sym.n_value >= range.start and sym.n_value < range.end) {
|
||||
break :blk Atom.Stab{
|
||||
.function = range.end - range.start,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
// if (zld.globals.contains(zld.getString(sym.strx))) break :blk .global;
|
||||
break :blk .static;
|
||||
} else null;
|
||||
|
||||
atom.contained.appendAssumeCapacity(.{
|
||||
.sym_index = sym_index,
|
||||
.offset = 0,
|
||||
.stab = stab,
|
||||
});
|
||||
}
|
||||
atom.contained.appendAssumeCapacity(.{
|
||||
.sym_index = sym_index,
|
||||
.offset = 0,
|
||||
});
|
||||
|
||||
for (indexes) |inner_sym_index| {
|
||||
const inner_sym = &self.symtab.items[inner_sym_index.index];
|
||||
inner_sym.n_sect = macho_file.getSectionOrdinal(match);
|
||||
|
||||
const stab: ?Atom.Stab = if (self.debug_info) |di| blk: {
|
||||
// TODO there has to be a better to handle this.
|
||||
for (di.inner.func_list.items) |func| {
|
||||
if (func.pc_range) |range| {
|
||||
if (inner_sym.n_value >= range.start and inner_sym.n_value < range.end) {
|
||||
break :blk Atom.Stab{
|
||||
.function = range.end - range.start,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
// if (zld.globals.contains(zld.getString(sym.strx))) break :blk .global;
|
||||
break :blk .static;
|
||||
} else null;
|
||||
atom.contained.appendAssumeCapacity(.{
|
||||
.sym_index = inner_sym_index.index,
|
||||
.offset = inner_sym.n_value - sym.n_value,
|
||||
.stab = stab,
|
||||
});
|
||||
|
||||
try self.atom_by_index_table.putNoClobber(gpa, inner_sym_index.index, atom);
|
||||
@ -755,7 +640,7 @@ fn parseSymtab(self: *Object, allocator: Allocator) !void {
|
||||
self.strtab = self.contents[symtab.stroff..][0..symtab.strsize];
|
||||
}
|
||||
|
||||
fn getSourceSymtab(self: *Object) []const macho.nlist_64 {
|
||||
pub fn getSourceSymtab(self: Object) []const macho.nlist_64 {
|
||||
const index = self.symtab_cmd_index orelse return &[0]macho.nlist_64{};
|
||||
const symtab = self.load_commands.items[index].symtab;
|
||||
const symtab_size = @sizeOf(macho.nlist_64) * symtab.nsyms;
|
||||
@ -766,38 +651,6 @@ fn getSourceSymtab(self: *Object) []const macho.nlist_64 {
|
||||
);
|
||||
}
|
||||
|
||||
fn parseDebugInfo(self: *Object, allocator: Allocator) !void {
|
||||
log.debug("parsing debug info in '{s}'", .{self.name});
|
||||
|
||||
var debug_info = blk: {
|
||||
var di = try DebugInfo.parseFromObject(allocator, self);
|
||||
break :blk di orelse return;
|
||||
};
|
||||
|
||||
// We assume there is only one CU.
|
||||
const compile_unit = debug_info.inner.findCompileUnit(0x0) catch |err| switch (err) {
|
||||
error.MissingDebugInfo => {
|
||||
// TODO audit cases with missing debug info and audit our dwarf.zig module.
|
||||
log.debug("invalid or missing debug info in {s}; skipping", .{self.name});
|
||||
return;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
const name = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.name);
|
||||
const comp_dir = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.comp_dir);
|
||||
|
||||
self.debug_info = debug_info;
|
||||
self.tu_name = name;
|
||||
self.tu_comp_dir = comp_dir;
|
||||
|
||||
if (self.mtime == null) {
|
||||
self.mtime = mtime: {
|
||||
const stat = self.file.stat() catch break :mtime 0;
|
||||
break :mtime @intCast(u64, @divFloor(stat.mtime, 1_000_000_000));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn parseDataInCode(self: *Object) void {
|
||||
const index = self.data_in_code_cmd_index orelse return;
|
||||
const data_in_code = self.load_commands.items[index].linkedit_data;
|
||||
@ -808,7 +661,7 @@ fn parseDataInCode(self: *Object) void {
|
||||
);
|
||||
}
|
||||
|
||||
fn getSectionContents(self: Object, sect_id: u16) error{Overflow}![]const u8 {
|
||||
pub fn getSectionContents(self: Object, sect_id: u16) error{Overflow}![]const u8 {
|
||||
const sect = self.getSection(sect_id);
|
||||
const size = math.cast(usize, sect.size) orelse return error.Overflow;
|
||||
log.debug("getting {s},{s} data at 0x{x} - 0x{x}", .{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user