Skip to content

macho: fix DWARF in dSYM and sym naming more consistent #8784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions src/link/MachO.zig
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,8 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio

self.base.file = file;

// Create dSYM bundle.
if (!options.strip and options.module != null) {
// Create dSYM bundle.
const dir = options.module.?.zig_cache_artifact_directory;
log.debug("creating {s}.dSYM bundle in {s}", .{ sub_path, dir.path });

Expand Down Expand Up @@ -1223,7 +1223,11 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
self.shrinkTextBlock(&decl.link.macho, code.len);
}
decl.link.macho.size = code.len;
symbol.n_strx = try self.updateString(symbol.n_strx, mem.spanZ(decl.name));

const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
defer self.base.allocator.free(new_name);

symbol.n_strx = try self.updateString(symbol.n_strx, new_name);
symbol.n_type = macho.N_SECT;
symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
symbol.n_desc = 0;
Expand All @@ -1232,7 +1236,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
if (self.d_sym) |*ds|
try ds.writeLocalSymbol(decl.link.macho.local_sym_index);
} else {
const decl_name = mem.spanZ(decl.name);
const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
defer self.base.allocator.free(decl_name);

const name_str_index = try self.makeString(decl_name);
const addr = try self.allocateTextBlock(&decl.link.macho, code.len, required_alignment);

Expand Down Expand Up @@ -1371,6 +1377,9 @@ pub fn updateDeclExports(
const decl_sym = &self.locals.items[decl.link.macho.local_sym_index];

for (exports) |exp| {
const exp_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{exp.options.name});
defer self.base.allocator.free(exp_name);

if (exp.options.section) |section_name| {
if (!mem.eql(u8, section_name, "__text")) {
try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);
Expand Down Expand Up @@ -1398,7 +1407,7 @@ pub fn updateDeclExports(
// Otherwise, don't do anything since we already have all the flags
// set that we need for global (strong) linkage.
// n_type == N_SECT | N_EXT
if (mem.eql(u8, exp.options.name, "_main")) {
if (mem.eql(u8, exp_name, "_main")) {
self.entry_addr = decl_sym.n_value;
}
},
Expand All @@ -1420,14 +1429,14 @@ pub fn updateDeclExports(
if (exp.link.macho.sym_index) |i| {
const sym = &self.globals.items[i];
sym.* = .{
.n_strx = try self.updateString(sym.n_strx, exp.options.name),
.n_strx = try self.updateString(sym.n_strx, exp_name),
.n_type = n_type,
.n_sect = @intCast(u8, self.text_section_index.?) + 1,
.n_desc = n_desc,
.n_value = decl_sym.n_value,
};
} else {
const name_str_index = try self.makeString(exp.options.name);
const name_str_index = try self.makeString(exp_name);
const i = if (self.globals_free_list.popOrNull()) |i| i else blk: {
_ = self.globals.addOneAssumeCapacity();
self.export_info_dirty = true;
Expand Down Expand Up @@ -2230,9 +2239,12 @@ fn makeString(self: *MachO, bytes: []const u8) !u32 {

try self.string_table.ensureCapacity(self.base.allocator, self.string_table.items.len + bytes.len + 1);
const offset = @intCast(u32, self.string_table.items.len);

log.debug("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset });

self.string_table.appendSliceAssumeCapacity(bytes);
self.string_table.appendAssumeCapacity(0);

try self.string_table_directory.putNoClobber(
self.base.allocator,
try self.base.allocator.dupe(u8, bytes),
Expand Down
30 changes: 28 additions & 2 deletions src/link/MachO/DebugSymbols.zig
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,8 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), text_section.size);

// Sentinel.
mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0);
mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0);
mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), 0);
mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), 0);

// Go back and populate the initial length.
const init_len = di_buf.items.len - after_init_len;
Expand Down Expand Up @@ -1075,6 +1075,32 @@ pub fn commitDeclDebugInfo(
mem.writeIntLittle(u32, ptr, @intCast(u32, text_block.size));
}

{
// Advance line and PC.
// TODO encapsulate logic in a helper function.
try dbg_line_buffer.append(DW.LNS_advance_pc);
try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size);

try dbg_line_buffer.append(DW.LNS_advance_line);
const line_off: u28 = blk: {
const tree = decl.container.file_scope.tree;
const node_tags = tree.nodes.items(.tag);
const node_datas = tree.nodes.items(.data);
const token_starts = tree.tokens.items(.start);

// TODO Look into improving the performance here by adding a token-index-to-line
// lookup table. Currently this involves scanning over the source code for newlines.
const fn_decl = decl.src_node;
assert(node_tags[fn_decl] == .fn_decl);
const block = node_datas[fn_decl].rhs;
const lbrace = tree.firstToken(block);
const rbrace = tree.lastToken(block);
const line_delta = std.zig.lineDelta(tree.source, token_starts[lbrace], token_starts[rbrace]);
break :blk @intCast(u28, line_delta);
};
try leb.writeULEB128(dbg_line_buffer.writer(), line_off);
}

try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS_extended_op, 1, DW.LNE_end_sequence });

// Now we have the full contents and may allocate a region to store it.
Expand Down
14 changes: 7 additions & 7 deletions test/stage2/darwin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn addCases(ctx: *TestContext) !void {

// Incorrect return type
case.addError(
\\export fn _main() noreturn {
\\export fn main() noreturn {
\\}
, &[_][]const u8{":2:1: error: expected noreturn, found void"});

Expand All @@ -26,7 +26,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\extern "c" fn write(usize, usize, usize) usize;
\\extern "c" fn exit(usize) noreturn;
\\
\\export fn _main() noreturn {
\\export fn main() noreturn {
\\ print();
\\
\\ exit(0);
Expand All @@ -46,7 +46,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\extern "c" fn write(usize, usize, usize) usize;
\\extern "c" fn exit(usize) noreturn;
\\
\\export fn _main() noreturn {
\\export fn main() noreturn {
\\ print();
\\ print();
\\ print();
Expand All @@ -73,7 +73,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\extern "c" fn write(usize, usize, usize) usize;
\\extern "c" fn exit(usize) noreturn;
\\
\\export fn _main() noreturn {
\\export fn main() noreturn {
\\ print();
\\
\\ exit(0);
Expand All @@ -93,7 +93,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\extern "c" fn write(usize, usize, usize) usize;
\\extern "c" fn exit(usize) noreturn;
\\
\\export fn _main() noreturn {
\\export fn main() noreturn {
\\ print();
\\ print();
\\
Expand All @@ -119,7 +119,7 @@ pub fn addCases(ctx: *TestContext) !void {
case.addCompareOutput(
\\extern "c" fn exit(usize) noreturn;
\\
\\export fn _main() noreturn {
\\export fn main() noreturn {
\\ exit(0);
\\}
,
Expand All @@ -130,7 +130,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\extern "c" fn exit(usize) noreturn;
\\extern "c" fn write(usize, usize, usize) usize;
\\
\\export fn _main() noreturn {
\\export fn main() noreturn {
\\ _ = write(1, @ptrToInt("Hey!\n"), 5);
\\ exit(0);
\\}
Expand Down