| author | |
| committer | |
| log | 3e939e61538706f37abb76a97af0ee77c15b24fc |
| tree | 115e68db5a398834f7bf3034275ad5e54a27da04 |
| parent | f93a36c091a151ed02602d2f330f7206eb9f95a3 |
| parent | 78740e55406ebf82371f385bbbf54f224949b8cb |
| signature |
macho: reinstate DWARF in self-hosted x86_64-macho9 files changed, 278 insertions(+), 283 deletions(-)
src/link/Dwarf.zig-1| ... | @@ -1468,7 +1468,6 @@ pub fn commitDeclState( | ... | @@ -1468,7 +1468,6 @@ pub fn commitDeclState( |
| 1468 | .target = reloc.target, | 1468 | .target = reloc.target, |
| 1469 | .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off, | 1469 | .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off, |
| 1470 | .addend = 0, | 1470 | .addend = 0, |
| 1471 | .prev_vaddr = 0, | ||
| 1472 | }); | 1471 | }); |
| 1473 | }, | 1472 | }, |
| 1474 | .elf => {}, // TODO | 1473 | .elf => {}, // TODO |
src/link/MachO.zig+45-37| ... | @@ -256,32 +256,39 @@ pub fn createEmpty( | ... | @@ -256,32 +256,39 @@ pub fn createEmpty( |
| 256 | .program_code_size_hint = options.program_code_size_hint, | 256 | .program_code_size_hint = options.program_code_size_hint, |
| 257 | }); | 257 | }); |
| 258 | 258 | ||
| 259 | // TODO init dwarf | 259 | switch (comp.config.debug_format) { |
| 260 | 260 | .strip => {}, | |
| 261 | // if (comp.config.debug_format != .strip) { | 261 | .dwarf => if (!self.base.isRelocatable()) { |
| 262 | // // Create dSYM bundle. | 262 | // Create dSYM bundle. |
| 263 | // log.debug("creating {s}.dSYM bundle", .{emit.sub_path}); | 263 | log.debug("creating {s}.dSYM bundle", .{emit.sub_path}); |
| 264 | 264 | ||
| 265 | // const d_sym_path = try std.fmt.allocPrint( | 265 | const sep = fs.path.sep_str; |
| 266 | // arena, | 266 | const d_sym_path = try std.fmt.allocPrint( |
| 267 | // "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF", | 267 | arena, |
| 268 | // .{emit.sub_path}, | 268 | "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF", |
| 269 | // ); | 269 | .{emit.sub_path}, |
| 270 | 270 | ); | |
| 271 | // var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{}); | 271 | |
| 272 | // defer d_sym_bundle.close(); | 272 | var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{}); |
| 273 | 273 | defer d_sym_bundle.close(); | |
| 274 | // const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{ | 274 | |
| 275 | // .truncate = false, | 275 | const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{ |
| 276 | // .read = true, | 276 | .truncate = false, |
| 277 | // }); | 277 | .read = true, |
| 278 | 278 | }); | |
| 279 | // self.d_sym = .{ | 279 | |
| 280 | // .allocator = gpa, | 280 | self.d_sym = .{ |
| 281 | // .dwarf = link.File.Dwarf.init(&self.base, .dwarf32), | 281 | .allocator = gpa, |
| 282 | // .file = d_sym_file, | 282 | .dwarf = link.File.Dwarf.init(&self.base, .dwarf32), |
| 283 | // }; | 283 | .file = d_sym_file, |
| 284 | // } | 284 | }; |
| 285 | try self.d_sym.?.initMetadata(self); | ||
| 286 | } else { | ||
| 287 | try self.reportUnexpectedError("TODO: implement generating and emitting __DWARF in .o file", .{}); | ||
| 288 | return error.Unexpected; | ||
| 289 | }, | ||
| 290 | .code_view => unreachable, | ||
| 291 | } | ||
| 285 | } | 292 | } |
| 286 | } | 293 | } |
| 287 | 294 | ||
| ... | @@ -692,6 +699,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node | ... | @@ -692,6 +699,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 692 | const ncmds, const sizeofcmds, const uuid_cmd_offset = try self.writeLoadCommands(); | 699 | const ncmds, const sizeofcmds, const uuid_cmd_offset = try self.writeLoadCommands(); |
| 693 | try self.writeHeader(ncmds, sizeofcmds); | 700 | try self.writeHeader(ncmds, sizeofcmds); |
| 694 | try self.writeUuid(uuid_cmd_offset, self.requiresCodeSig()); | 701 | try self.writeUuid(uuid_cmd_offset, self.requiresCodeSig()); |
| 702 | if (self.getDebugSymbols()) |dsym| try dsym.flushModule(self); | ||
| 695 | 703 | ||
| 696 | if (codesig) |*csig| { | 704 | if (codesig) |*csig| { |
| 697 | try self.writeCodeSignature(csig); // code signing always comes last | 705 | try self.writeCodeSignature(csig); // code signing always comes last |
| ... | @@ -731,9 +739,6 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { | ... | @@ -731,9 +739,6 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { |
| 731 | try argv.append("-r"); | 739 | try argv.append("-r"); |
| 732 | } | 740 | } |
| 733 | 741 | ||
| 734 | try argv.append("-o"); | ||
| 735 | try argv.append(full_out_path); | ||
| 736 | |||
| 737 | if (self.base.isRelocatable()) { | 742 | if (self.base.isRelocatable()) { |
| 738 | for (comp.objects) |obj| { | 743 | for (comp.objects) |obj| { |
| 739 | try argv.append(obj.path); | 744 | try argv.append(obj.path); |
| ... | @@ -2047,7 +2052,11 @@ pub fn sortSections(self: *MachO) !void { | ... | @@ -2047,7 +2052,11 @@ pub fn sortSections(self: *MachO) !void { |
| 2047 | for (&[_]*?u8{ | 2052 | for (&[_]*?u8{ |
| 2048 | &self.data_sect_index, | 2053 | &self.data_sect_index, |
| 2049 | &self.got_sect_index, | 2054 | &self.got_sect_index, |
| 2055 | &self.zig_text_sect_index, | ||
| 2050 | &self.zig_got_sect_index, | 2056 | &self.zig_got_sect_index, |
| 2057 | &self.zig_const_sect_index, | ||
| 2058 | &self.zig_data_sect_index, | ||
| 2059 | &self.zig_bss_sect_index, | ||
| 2051 | &self.stubs_sect_index, | 2060 | &self.stubs_sect_index, |
| 2052 | &self.stubs_helper_sect_index, | 2061 | &self.stubs_helper_sect_index, |
| 2053 | &self.la_symbol_ptr_sect_index, | 2062 | &self.la_symbol_ptr_sect_index, |
| ... | @@ -2901,16 +2910,16 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 { | ... | @@ -2901,16 +2910,16 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 { |
| 2901 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); | 2910 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); |
| 2902 | 2911 | ||
| 2903 | if (self.getZigObject()) |zo| { | 2912 | if (self.getZigObject()) |zo| { |
| 2904 | zo.writeSymtab(self); | 2913 | zo.writeSymtab(self, self); |
| 2905 | } | 2914 | } |
| 2906 | for (self.objects.items) |index| { | 2915 | for (self.objects.items) |index| { |
| 2907 | try self.getFile(index).?.writeSymtab(self); | 2916 | try self.getFile(index).?.writeSymtab(self, self); |
| 2908 | } | 2917 | } |
| 2909 | for (self.dylibs.items) |index| { | 2918 | for (self.dylibs.items) |index| { |
| 2910 | try self.getFile(index).?.writeSymtab(self); | 2919 | try self.getFile(index).?.writeSymtab(self, self); |
| 2911 | } | 2920 | } |
| 2912 | if (self.getInternalObject()) |internal| { | 2921 | if (self.getInternalObject()) |internal| { |
| 2913 | internal.writeSymtab(self); | 2922 | internal.writeSymtab(self, self); |
| 2914 | } | 2923 | } |
| 2915 | 2924 | ||
| 2916 | assert(self.strtab.items.len == cmd.strsize); | 2925 | assert(self.strtab.items.len == cmd.strsize); |
| ... | @@ -3176,7 +3185,7 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) | ... | @@ -3176,7 +3185,7 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) |
| 3176 | 3185 | ||
| 3177 | pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void { | 3186 | pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void { |
| 3178 | if (self.llvm_object) |_| return; | 3187 | if (self.llvm_object) |_| return; |
| 3179 | return self.getZigObject().?.updateDeclLineNumber(module, decl_index); | 3188 | return self.getZigObject().?.updateDeclLineNumber(self, module, decl_index); |
| 3180 | } | 3189 | } |
| 3181 | 3190 | ||
| 3182 | pub fn updateExports( | 3191 | pub fn updateExports( |
| ... | @@ -3909,9 +3918,8 @@ fn reportDuplicates(self: *MachO, dupes: anytype) error{ HasDuplicates, OutOfMem | ... | @@ -3909,9 +3918,8 @@ fn reportDuplicates(self: *MachO, dupes: anytype) error{ HasDuplicates, OutOfMem |
| 3909 | } | 3918 | } |
| 3910 | 3919 | ||
| 3911 | pub fn getDebugSymbols(self: *MachO) ?*DebugSymbols { | 3920 | pub fn getDebugSymbols(self: *MachO) ?*DebugSymbols { |
| 3912 | if (self.d_sym) |*ds| { | 3921 | if (self.d_sym) |*ds| return ds; |
| 3913 | return ds; | 3922 | return null; |
| 3914 | } else return null; | ||
| 3915 | } | 3923 | } |
| 3916 | 3924 | ||
| 3917 | pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void { | 3925 | pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void { |
src/link/MachO/DebugSymbols.zig+117-153| ... | @@ -3,6 +3,7 @@ dwarf: Dwarf, | ... | @@ -3,6 +3,7 @@ dwarf: Dwarf, |
| 3 | file: fs.File, | 3 | file: fs.File, |
| 4 | 4 | ||
| 5 | symtab_cmd: macho.symtab_command = .{}, | 5 | symtab_cmd: macho.symtab_command = .{}, |
| 6 | uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 }, | ||
| 6 | 7 | ||
| 7 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, | 8 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, |
| 8 | sections: std.ArrayListUnmanaged(macho.section_64) = .{}, | 9 | sections: std.ArrayListUnmanaged(macho.section_64) = .{}, |
| ... | @@ -22,9 +23,12 @@ debug_aranges_section_dirty: bool = false, | ... | @@ -22,9 +23,12 @@ debug_aranges_section_dirty: bool = false, |
| 22 | debug_info_header_dirty: bool = false, | 23 | debug_info_header_dirty: bool = false, |
| 23 | debug_line_header_dirty: bool = false, | 24 | debug_line_header_dirty: bool = false, |
| 24 | 25 | ||
| 25 | strtab: StringTable = .{}, | ||
| 26 | relocs: std.ArrayListUnmanaged(Reloc) = .{}, | 26 | relocs: std.ArrayListUnmanaged(Reloc) = .{}, |
| 27 | 27 | ||
| 28 | /// Output synthetic sections | ||
| 29 | symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | ||
| 30 | strtab: std.ArrayListUnmanaged(u8) = .{}, | ||
| 31 | |||
| 28 | pub const Reloc = struct { | 32 | pub const Reloc = struct { |
| 29 | type: enum { | 33 | type: enum { |
| 30 | direct_load, | 34 | direct_load, |
| ... | @@ -33,18 +37,17 @@ pub const Reloc = struct { | ... | @@ -33,18 +37,17 @@ pub const Reloc = struct { |
| 33 | target: u32, | 37 | target: u32, |
| 34 | offset: u64, | 38 | offset: u64, |
| 35 | addend: u32, | 39 | addend: u32, |
| 36 | prev_vaddr: u64, | ||
| 37 | }; | 40 | }; |
| 38 | 41 | ||
| 39 | /// You must call this function *after* `MachO.populateMissingMetadata()` | 42 | /// You must call this function *after* `ZigObject.initMetadata()` |
| 40 | /// has been called to get a viable debug symbols output. | 43 | /// has been called to get a viable debug symbols output. |
| 41 | pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void { | 44 | pub fn initMetadata(self: *DebugSymbols, macho_file: *MachO) !void { |
| 42 | const target = macho_file.base.comp.root_mod.resolved_target.result; | 45 | try self.strtab.append(self.allocator, 0); |
| 43 | 46 | ||
| 44 | if (self.dwarf_segment_cmd_index == null) { | 47 | if (self.dwarf_segment_cmd_index == null) { |
| 45 | self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len)); | 48 | self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len)); |
| 46 | 49 | ||
| 47 | const page_size = MachO.getPageSize(target.cpu.arch); | 50 | const page_size = macho_file.getPageSize(); |
| 48 | const off = @as(u64, @intCast(page_size)); | 51 | const off = @as(u64, @intCast(page_size)); |
| 49 | const ideal_size: u16 = 200 + 128 + 160 + 250; | 52 | const ideal_size: u16 = 200 + 128 + 160 + 250; |
| 50 | const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size); | 53 | const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size); |
| ... | @@ -203,35 +206,24 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -203,35 +206,24 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 203 | // and it corresponds to the Zig source code. | 206 | // and it corresponds to the Zig source code. |
| 204 | const zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; | 207 | const zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| 205 | 208 | ||
| 209 | try self.dwarf.flushModule(zcu); | ||
| 210 | |||
| 206 | for (self.relocs.items) |*reloc| { | 211 | for (self.relocs.items) |*reloc| { |
| 207 | const sym = switch (reloc.type) { | 212 | const sym = macho_file.getSymbol(reloc.target); |
| 208 | .direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target }), | 213 | const sym_name = sym.getName(macho_file); |
| 209 | .got_load => blk: { | 214 | const addr = switch (reloc.type) { |
| 210 | const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?; | 215 | .direct_load => sym.getAddress(.{}, macho_file), |
| 211 | const got_entry = macho_file.got_table.entries.items[got_index]; | 216 | .got_load => sym.getGotAddress(macho_file), |
| 212 | break :blk macho_file.getSymbol(got_entry); | ||
| 213 | }, | ||
| 214 | }; | ||
| 215 | if (sym.n_value == reloc.prev_vaddr) continue; | ||
| 216 | |||
| 217 | const sym_name = switch (reloc.type) { | ||
| 218 | .direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target }), | ||
| 219 | .got_load => blk: { | ||
| 220 | const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?; | ||
| 221 | const got_entry = macho_file.got_table.entries.items[got_index]; | ||
| 222 | break :blk macho_file.getSymbolName(got_entry); | ||
| 223 | }, | ||
| 224 | }; | 217 | }; |
| 225 | const sect = &self.sections.items[self.debug_info_section_index.?]; | 218 | const sect = &self.sections.items[self.debug_info_section_index.?]; |
| 226 | const file_offset = sect.offset + reloc.offset; | 219 | const file_offset = sect.offset + reloc.offset; |
| 227 | log.debug("resolving relocation: {d}@{x} ('{s}') at offset {x}", .{ | 220 | log.debug("resolving relocation: {d}@{x} ('{s}') at offset {x}", .{ |
| 228 | reloc.target, | 221 | reloc.target, |
| 229 | sym.n_value, | 222 | addr, |
| 230 | sym_name, | 223 | sym_name, |
| 231 | file_offset, | 224 | file_offset, |
| 232 | }); | 225 | }); |
| 233 | try self.file.pwriteAll(mem.asBytes(&sym.n_value), file_offset); | 226 | try self.file.pwriteAll(mem.asBytes(&addr), file_offset); |
| 234 | reloc.prev_vaddr = sym.n_value; | ||
| 235 | } | 227 | } |
| 236 | 228 | ||
| 237 | if (self.debug_abbrev_section_dirty) { | 229 | if (self.debug_abbrev_section_dirty) { |
| ... | @@ -242,7 +234,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -242,7 +234,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 242 | if (self.debug_info_header_dirty) { | 234 | if (self.debug_info_header_dirty) { |
| 243 | // Currently only one compilation unit is supported, so the address range is simply | 235 | // Currently only one compilation unit is supported, so the address range is simply |
| 244 | // identical to the main program header virtual address and memory size. | 236 | // identical to the main program header virtual address and memory size. |
| 245 | const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?]; | 237 | const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?]; |
| 246 | const low_pc = text_section.addr; | 238 | const low_pc = text_section.addr; |
| 247 | const high_pc = text_section.addr + text_section.size; | 239 | const high_pc = text_section.addr + text_section.size; |
| 248 | try self.dwarf.writeDbgInfoHeader(zcu, low_pc, high_pc); | 240 | try self.dwarf.writeDbgInfoHeader(zcu, low_pc, high_pc); |
| ... | @@ -252,7 +244,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -252,7 +244,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 252 | if (self.debug_aranges_section_dirty) { | 244 | if (self.debug_aranges_section_dirty) { |
| 253 | // Currently only one compilation unit is supported, so the address range is simply | 245 | // Currently only one compilation unit is supported, so the address range is simply |
| 254 | // identical to the main program header virtual address and memory size. | 246 | // identical to the main program header virtual address and memory size. |
| 255 | const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?]; | 247 | const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?]; |
| 256 | try self.dwarf.writeDbgAranges(text_section.addr, text_section.size); | 248 | try self.dwarf.writeDbgAranges(text_section.addr, text_section.size); |
| 257 | self.debug_aranges_section_dirty = false; | 249 | self.debug_aranges_section_dirty = false; |
| 258 | } | 250 | } |
| ... | @@ -276,17 +268,8 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -276,17 +268,8 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 276 | try self.writeLinkeditSegmentData(macho_file); | 268 | try self.writeLinkeditSegmentData(macho_file); |
| 277 | 269 | ||
| 278 | // Write load commands | 270 | // Write load commands |
| 279 | var lc_buffer = std.ArrayList(u8).init(self.allocator); | 271 | const ncmds, const sizeofcmds = try self.writeLoadCommands(macho_file); |
| 280 | defer lc_buffer.deinit(); | 272 | try self.writeHeader(macho_file, ncmds, sizeofcmds); |
| 281 | const lc_writer = lc_buffer.writer(); | ||
| 282 | |||
| 283 | try self.writeSegmentHeaders(macho_file, lc_writer); | ||
| 284 | try lc_writer.writeStruct(self.symtab_cmd); | ||
| 285 | try lc_writer.writeStruct(macho_file.uuid_cmd); | ||
| 286 | |||
| 287 | const ncmds = load_commands.calcNumOfLCs(lc_buffer.items); | ||
| 288 | try self.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64)); | ||
| 289 | try self.writeHeader(macho_file, ncmds, @as(u32, @intCast(lc_buffer.items.len))); | ||
| 290 | 273 | ||
| 291 | assert(!self.debug_abbrev_section_dirty); | 274 | assert(!self.debug_abbrev_section_dirty); |
| 292 | assert(!self.debug_aranges_section_dirty); | 275 | assert(!self.debug_aranges_section_dirty); |
| ... | @@ -299,8 +282,9 @@ pub fn deinit(self: *DebugSymbols) void { | ... | @@ -299,8 +282,9 @@ pub fn deinit(self: *DebugSymbols) void { |
| 299 | self.segments.deinit(gpa); | 282 | self.segments.deinit(gpa); |
| 300 | self.sections.deinit(gpa); | 283 | self.sections.deinit(gpa); |
| 301 | self.dwarf.deinit(); | 284 | self.dwarf.deinit(); |
| 302 | self.strtab.deinit(gpa); | ||
| 303 | self.relocs.deinit(gpa); | 285 | self.relocs.deinit(gpa); |
| 286 | self.symtab.deinit(gpa); | ||
| 287 | self.strtab.deinit(gpa); | ||
| 304 | } | 288 | } |
| 305 | 289 | ||
| 306 | pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void { | 290 | pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void { |
| ... | @@ -324,7 +308,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { | ... | @@ -324,7 +308,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 324 | // however at the cost of having LINKEDIT preceed DWARF in dSYM binary which we | 308 | // however at the cost of having LINKEDIT preceed DWARF in dSYM binary which we |
| 325 | // do not want as we want to be able to incrementally move DWARF sections in the | 309 | // do not want as we want to be able to incrementally move DWARF sections in the |
| 326 | // file as we please. | 310 | // file as we please. |
| 327 | const last_seg = macho_file.getLinkeditSegmentPtr(); | 311 | const last_seg = macho_file.getLinkeditSegment(); |
| 328 | break :blk last_seg.vmaddr + last_seg.vmsize; | 312 | break :blk last_seg.vmaddr + last_seg.vmsize; |
| 329 | }; | 313 | }; |
| 330 | const dwarf_segment = self.getDwarfSegmentPtr(); | 314 | const dwarf_segment = self.getDwarfSegmentPtr(); |
| ... | @@ -334,8 +318,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { | ... | @@ -334,8 +318,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 334 | file_size = @max(file_size, header.offset + header.size); | 318 | file_size = @max(file_size, header.offset + header.size); |
| 335 | } | 319 | } |
| 336 | 320 | ||
| 337 | const target = macho_file.base.comp.root_mod.resolved_target.result; | 321 | const page_size = macho_file.getPageSize(); |
| 338 | const page_size = MachO.getPageSize(target.cpu.arch); | ||
| 339 | const aligned_size = mem.alignForward(u64, file_size, page_size); | 322 | const aligned_size = mem.alignForward(u64, file_size, page_size); |
| 340 | dwarf_segment.vmaddr = base_vmaddr; | 323 | dwarf_segment.vmaddr = base_vmaddr; |
| 341 | dwarf_segment.filesize = aligned_size; | 324 | dwarf_segment.filesize = aligned_size; |
| ... | @@ -355,54 +338,70 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { | ... | @@ -355,54 +338,70 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 355 | log.debug("found __LINKEDIT segment free space at 0x{x}", .{linkedit.fileoff}); | 338 | log.debug("found __LINKEDIT segment free space at 0x{x}", .{linkedit.fileoff}); |
| 356 | } | 339 | } |
| 357 | 340 | ||
| 358 | fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype) !void { | 341 | fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, usize } { |
| 359 | // Write segment/section headers from the binary file first. | 342 | const gpa = self.allocator; |
| 360 | const end = macho_file.linkedit_segment_cmd_index.?; | 343 | const needed_size = load_commands.calcLoadCommandsSizeDsym(macho_file, self); |
| 361 | for (macho_file.segments.items[0..end], 0..) |seg, i| { | 344 | const buffer = try gpa.alloc(u8, needed_size); |
| 362 | const indexes = macho_file.getSectionIndexes(@as(u8, @intCast(i))); | 345 | defer gpa.free(buffer); |
| 363 | var out_seg = seg; | 346 | |
| 364 | out_seg.fileoff = 0; | 347 | var stream = std.io.fixedBufferStream(buffer); |
| 365 | out_seg.filesize = 0; | 348 | var cwriter = std.io.countingWriter(stream.writer()); |
| 366 | out_seg.cmdsize = @sizeOf(macho.segment_command_64); | 349 | const writer = cwriter.writer(); |
| 367 | out_seg.nsects = 0; | ||
| 368 | |||
| 369 | // Update section headers count; any section with size of 0 is excluded | ||
| 370 | // since it doesn't have any data in the final binary file. | ||
| 371 | for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| { | ||
| 372 | if (header.size == 0) continue; | ||
| 373 | out_seg.cmdsize += @sizeOf(macho.section_64); | ||
| 374 | out_seg.nsects += 1; | ||
| 375 | } | ||
| 376 | 350 | ||
| 377 | if (out_seg.nsects == 0 and | 351 | var ncmds: usize = 0; |
| 378 | (mem.eql(u8, out_seg.segName(), "__DATA_CONST") or | ||
| 379 | mem.eql(u8, out_seg.segName(), "__DATA"))) continue; | ||
| 380 | 352 | ||
| 381 | try writer.writeStruct(out_seg); | 353 | // UUID comes first presumably to speed up lookup by the consumer like lldb. |
| 382 | for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| { | 354 | @memcpy(&self.uuid_cmd.uuid, &macho_file.uuid_cmd.uuid); |
| 383 | if (header.size == 0) continue; | 355 | try writer.writeStruct(self.uuid_cmd); |
| 384 | var out_header = header; | 356 | ncmds += 1; |
| 385 | out_header.offset = 0; | 357 | |
| 386 | try writer.writeStruct(out_header); | 358 | // Segment and section load commands |
| 359 | { | ||
| 360 | // Write segment/section headers from the binary file first. | ||
| 361 | const slice = macho_file.sections.slice(); | ||
| 362 | var sect_id: usize = 0; | ||
| 363 | for (macho_file.segments.items, 0..) |seg, seg_id| { | ||
| 364 | if (seg_id == macho_file.linkedit_seg_index.?) break; | ||
| 365 | var out_seg = seg; | ||
| 366 | out_seg.fileoff = 0; | ||
| 367 | out_seg.filesize = 0; | ||
| 368 | try writer.writeStruct(out_seg); | ||
| 369 | for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| { | ||
| 370 | var out_header = header; | ||
| 371 | out_header.offset = 0; | ||
| 372 | try writer.writeStruct(out_header); | ||
| 373 | } | ||
| 374 | sect_id += seg.nsects; | ||
| 387 | } | 375 | } |
| 388 | } | 376 | ncmds += macho_file.segments.items.len - 1; |
| 389 | // Next, commit DSYM's __LINKEDIT and __DWARF segments headers. | 377 | |
| 390 | for (self.segments.items, 0..) |seg, i| { | 378 | // Next, commit DSYM's __LINKEDIT and __DWARF segments headers. |
| 391 | const indexes = self.getSectionIndexes(@as(u8, @intCast(i))); | 379 | sect_id = 0; |
| 392 | try writer.writeStruct(seg); | 380 | for (self.segments.items) |seg| { |
| 393 | for (self.sections.items[indexes.start..indexes.end]) |header| { | 381 | try writer.writeStruct(seg); |
| 394 | try writer.writeStruct(header); | 382 | for (self.sections.items[sect_id..][0..seg.nsects]) |header| { |
| 383 | try writer.writeStruct(header); | ||
| 384 | } | ||
| 385 | sect_id += seg.nsects; | ||
| 395 | } | 386 | } |
| 387 | ncmds += self.segments.items.len; | ||
| 396 | } | 388 | } |
| 397 | } | ||
| 398 | 389 | ||
| 399 | fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void { | 390 | try writer.writeStruct(self.symtab_cmd); |
| 400 | const target = macho_file.base.comp.root_mod.resolved_target.result; | 391 | ncmds += 1; |
| 392 | |||
| 393 | assert(cwriter.bytes_written == needed_size); | ||
| 401 | 394 | ||
| 395 | try self.file.pwriteAll(buffer, @sizeOf(macho.mach_header_64)); | ||
| 396 | |||
| 397 | return .{ ncmds, buffer.len }; | ||
| 398 | } | ||
| 399 | |||
| 400 | fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void { | ||
| 402 | var header: macho.mach_header_64 = .{}; | 401 | var header: macho.mach_header_64 = .{}; |
| 403 | header.filetype = macho.MH_DSYM; | 402 | header.filetype = macho.MH_DSYM; |
| 404 | 403 | ||
| 405 | switch (target.cpu.arch) { | 404 | switch (macho_file.getTarget().cpu.arch) { |
| 406 | .aarch64 => { | 405 | .aarch64 => { |
| 407 | header.cputype = macho.CPU_TYPE_ARM64; | 406 | header.cputype = macho.CPU_TYPE_ARM64; |
| 408 | header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL; | 407 | header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL; |
| ... | @@ -414,8 +413,8 @@ fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: | ... | @@ -414,8 +413,8 @@ fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: |
| 414 | else => return error.UnsupportedCpuArchitecture, | 413 | else => return error.UnsupportedCpuArchitecture, |
| 415 | } | 414 | } |
| 416 | 415 | ||
| 417 | header.ncmds = ncmds; | 416 | header.ncmds = @intCast(ncmds); |
| 418 | header.sizeofcmds = sizeofcmds; | 417 | header.sizeofcmds = @intCast(sizeofcmds); |
| 419 | 418 | ||
| 420 | log.debug("writing Mach-O header {}", .{header}); | 419 | log.debug("writing Mach-O header {}", .{header}); |
| 421 | 420 | ||
| ... | @@ -437,91 +436,56 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -437,91 +436,56 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void { |
| 437 | const tracy = trace(@src()); | 436 | const tracy = trace(@src()); |
| 438 | defer tracy.end(); | 437 | defer tracy.end(); |
| 439 | 438 | ||
| 440 | try self.writeSymtab(macho_file); | 439 | const page_size = macho_file.getPageSize(); |
| 441 | try self.writeStrtab(); | ||
| 442 | |||
| 443 | const target = macho_file.base.comp.root_mod.resolved_target.result; | ||
| 444 | const page_size = MachO.getPageSize(target.cpu.arch); | ||
| 445 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; | 440 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; |
| 441 | |||
| 442 | var off = math.cast(u32, seg.fileoff) orelse return error.Overflow; | ||
| 443 | off = try self.writeSymtab(off, macho_file); | ||
| 444 | off = mem.alignForward(u32, off, @alignOf(u64)); | ||
| 445 | off = try self.writeStrtab(off); | ||
| 446 | seg.filesize = off - seg.fileoff; | ||
| 447 | |||
| 446 | const aligned_size = mem.alignForward(u64, seg.filesize, page_size); | 448 | const aligned_size = mem.alignForward(u64, seg.filesize, page_size); |
| 447 | seg.vmsize = aligned_size; | 449 | seg.vmsize = aligned_size; |
| 448 | } | 450 | } |
| 449 | 451 | ||
| 450 | fn writeSymtab(self: *DebugSymbols, macho_file: *MachO) !void { | 452 | pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 { |
| 451 | const tracy = trace(@src()); | 453 | const tracy = trace(@src()); |
| 452 | defer tracy.end(); | 454 | defer tracy.end(); |
| 453 | |||
| 454 | const gpa = self.allocator; | 455 | const gpa = self.allocator; |
| 456 | const cmd = &self.symtab_cmd; | ||
| 457 | cmd.nsyms = macho_file.symtab_cmd.nsyms; | ||
| 458 | cmd.strsize = macho_file.symtab_cmd.strsize; | ||
| 459 | cmd.symoff = off; | ||
| 455 | 460 | ||
| 456 | var locals = std.ArrayList(macho.nlist_64).init(gpa); | 461 | try self.symtab.resize(gpa, cmd.nsyms); |
| 457 | defer locals.deinit(); | 462 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); |
| 458 | |||
| 459 | for (macho_file.locals.items, 0..) |sym, sym_id| { | ||
| 460 | if (sym.n_strx == 0) continue; // no name, skip | ||
| 461 | const sym_loc = MachO.SymbolWithLoc{ .sym_index = @as(u32, @intCast(sym_id)) }; | ||
| 462 | if (macho_file.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip | ||
| 463 | if (macho_file.getGlobal(macho_file.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip | ||
| 464 | var out_sym = sym; | ||
| 465 | out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(sym_loc)); | ||
| 466 | try locals.append(out_sym); | ||
| 467 | } | ||
| 468 | 463 | ||
| 469 | var exports = std.ArrayList(macho.nlist_64).init(gpa); | 464 | if (macho_file.getZigObject()) |zo| { |
| 470 | defer exports.deinit(); | 465 | zo.writeSymtab(macho_file, self); |
| 471 | 466 | } | |
| 472 | for (macho_file.globals.items) |global| { | 467 | for (macho_file.objects.items) |index| { |
| 473 | const sym = macho_file.getSymbol(global); | 468 | try macho_file.getFile(index).?.writeSymtab(macho_file, self); |
| 474 | if (sym.undf()) continue; // import, skip | 469 | } |
| 475 | var out_sym = sym; | 470 | for (macho_file.dylibs.items) |index| { |
| 476 | out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(global)); | 471 | try macho_file.getFile(index).?.writeSymtab(macho_file, self); |
| 477 | try exports.append(out_sym); | 472 | } |
| 473 | if (macho_file.getInternalObject()) |internal| { | ||
| 474 | internal.writeSymtab(macho_file, self); | ||
| 478 | } | 475 | } |
| 479 | 476 | ||
| 480 | const nlocals = locals.items.len; | 477 | assert(self.strtab.items.len == cmd.strsize); |
| 481 | const nexports = exports.items.len; | ||
| 482 | const nsyms = nlocals + nexports; | ||
| 483 | |||
| 484 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; | ||
| 485 | const offset = mem.alignForward(u64, seg.fileoff, @alignOf(macho.nlist_64)); | ||
| 486 | const needed_size = nsyms * @sizeOf(macho.nlist_64); | ||
| 487 | seg.filesize = offset + needed_size - seg.fileoff; | ||
| 488 | |||
| 489 | self.symtab_cmd.symoff = @as(u32, @intCast(offset)); | ||
| 490 | self.symtab_cmd.nsyms = @as(u32, @intCast(nsyms)); | ||
| 491 | |||
| 492 | const locals_off = @as(u32, @intCast(offset)); | ||
| 493 | const locals_size = nlocals * @sizeOf(macho.nlist_64); | ||
| 494 | const exports_off = locals_off + locals_size; | ||
| 495 | const exports_size = nexports * @sizeOf(macho.nlist_64); | ||
| 496 | 478 | ||
| 497 | log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); | 479 | try self.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff); |
| 498 | try self.file.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); | ||
| 499 | 480 | ||
| 500 | log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); | 481 | return off + cmd.nsyms * @sizeOf(macho.nlist_64); |
| 501 | try self.file.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); | ||
| 502 | } | 482 | } |
| 503 | 483 | ||
| 504 | fn writeStrtab(self: *DebugSymbols) !void { | 484 | pub fn writeStrtab(self: *DebugSymbols, off: u32) !u32 { |
| 505 | const tracy = trace(@src()); | 485 | const cmd = &self.symtab_cmd; |
| 506 | defer tracy.end(); | 486 | cmd.stroff = off; |
| 507 | 487 | try self.file.pwriteAll(self.strtab.items, cmd.stroff); | |
| 508 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; | 488 | return off + cmd.strsize; |
| 509 | const symtab_size = @as(u32, @intCast(self.symtab_cmd.nsyms * @sizeOf(macho.nlist_64))); | ||
| 510 | const offset = mem.alignForward(u64, self.symtab_cmd.symoff + symtab_size, @alignOf(u64)); | ||
| 511 | const needed_size = mem.alignForward(u64, self.strtab.buffer.items.len, @alignOf(u64)); | ||
| 512 | |||
| 513 | seg.filesize = offset + needed_size - seg.fileoff; | ||
| 514 | self.symtab_cmd.stroff = @as(u32, @intCast(offset)); | ||
| 515 | self.symtab_cmd.strsize = @as(u32, @intCast(needed_size)); | ||
| 516 | |||
| 517 | log.debug("writing string table from 0x{x} to 0x{x}", .{ offset, offset + needed_size }); | ||
| 518 | |||
| 519 | try self.file.pwriteAll(self.strtab.buffer.items, offset); | ||
| 520 | |||
| 521 | if (self.strtab.buffer.items.len < needed_size) { | ||
| 522 | // Ensure we are always padded to the actual length of the file. | ||
| 523 | try self.file.pwriteAll(&[_]u8{0}, offset + needed_size); | ||
| 524 | } | ||
| 525 | } | 489 | } |
| 526 | 490 | ||
| 527 | pub fn getSectionIndexes(self: *DebugSymbols, segment_index: u8) struct { start: u8, end: u8 } { | 491 | pub fn getSectionIndexes(self: *DebugSymbols, segment_index: u8) struct { start: u8, end: u8 } { |
| ... | @@ -561,7 +525,7 @@ const assert = std.debug.assert; | ... | @@ -561,7 +525,7 @@ const assert = std.debug.assert; |
| 561 | const fs = std.fs; | 525 | const fs = std.fs; |
| 562 | const link = @import("../../link.zig"); | 526 | const link = @import("../../link.zig"); |
| 563 | const load_commands = @import("load_commands.zig"); | 527 | const load_commands = @import("load_commands.zig"); |
| 564 | const log = std.log.scoped(.dsym); | 528 | const log = std.log.scoped(.link_dsym); |
| 565 | const macho = std.macho; | 529 | const macho = std.macho; |
| 566 | const makeStaticString = MachO.makeStaticString; | 530 | const makeStaticString = MachO.makeStaticString; |
| 567 | const math = std.math; | 531 | const math = std.math; |
src/link/MachO/Dylib.zig+5-5| ... | @@ -576,7 +576,7 @@ pub fn calcSymtabSize(self: *Dylib, macho_file: *MachO) !void { | ... | @@ -576,7 +576,7 @@ pub fn calcSymtabSize(self: *Dylib, macho_file: *MachO) !void { |
| 576 | } | 576 | } |
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | pub fn writeSymtab(self: Dylib, macho_file: *MachO) void { | 579 | pub fn writeSymtab(self: Dylib, macho_file: *MachO, ctx: anytype) void { |
| 580 | const tracy = trace(@src()); | 580 | const tracy = trace(@src()); |
| 581 | defer tracy.end(); | 581 | defer tracy.end(); |
| 582 | 582 | ||
| ... | @@ -585,10 +585,10 @@ pub fn writeSymtab(self: Dylib, macho_file: *MachO) void { | ... | @@ -585,10 +585,10 @@ pub fn writeSymtab(self: Dylib, macho_file: *MachO) void { |
| 585 | const file = global.getFile(macho_file) orelse continue; | 585 | const file = global.getFile(macho_file) orelse continue; |
| 586 | if (file.getIndex() != self.index) continue; | 586 | if (file.getIndex() != self.index) continue; |
| 587 | const idx = global.getOutputSymtabIndex(macho_file) orelse continue; | 587 | const idx = global.getOutputSymtabIndex(macho_file) orelse continue; |
| 588 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 588 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 589 | macho_file.strtab.appendSliceAssumeCapacity(global.getName(macho_file)); | 589 | ctx.strtab.appendSliceAssumeCapacity(global.getName(macho_file)); |
| 590 | macho_file.strtab.appendAssumeCapacity(0); | 590 | ctx.strtab.appendAssumeCapacity(0); |
| 591 | const out_sym = &macho_file.symtab.items[idx]; | 591 | const out_sym = &ctx.symtab.items[idx]; |
| 592 | out_sym.n_strx = n_strx; | 592 | out_sym.n_strx = n_strx; |
| 593 | global.setOutputSym(macho_file, out_sym); | 593 | global.setOutputSym(macho_file, out_sym); |
| 594 | } | 594 | } |
src/link/MachO/InternalObject.zig+5-5| ... | @@ -139,15 +139,15 @@ pub fn calcSymtabSize(self: *InternalObject, macho_file: *MachO) !void { | ... | @@ -139,15 +139,15 @@ pub fn calcSymtabSize(self: *InternalObject, macho_file: *MachO) !void { |
| 139 | } | 139 | } |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | pub fn writeSymtab(self: InternalObject, macho_file: *MachO) void { | 142 | pub fn writeSymtab(self: InternalObject, macho_file: *MachO, ctx: anytype) void { |
| 143 | for (self.symbols.items) |sym_index| { | 143 | for (self.symbols.items) |sym_index| { |
| 144 | const sym = macho_file.getSymbol(sym_index); | 144 | const sym = macho_file.getSymbol(sym_index); |
| 145 | if (sym.getFile(macho_file)) |file| if (file.getIndex() != self.index) continue; | 145 | if (sym.getFile(macho_file)) |file| if (file.getIndex() != self.index) continue; |
| 146 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; | 146 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 147 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 147 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 148 | macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | 148 | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); |
| 149 | macho_file.strtab.appendAssumeCapacity(0); | 149 | ctx.strtab.appendAssumeCapacity(0); |
| 150 | const out_sym = &macho_file.symtab.items[idx]; | 150 | const out_sym = &ctx.symtab.items[idx]; |
| 151 | out_sym.n_strx = n_strx; | 151 | out_sym.n_strx = n_strx; |
| 152 | sym.setOutputSym(macho_file, out_sym); | 152 | sym.setOutputSym(macho_file, out_sym); |
| 153 | } | 153 | } |
src/link/MachO/Object.zig+51-51| ... | @@ -1320,7 +1320,7 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void { | ... | @@ -1320,7 +1320,7 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void { |
| 1320 | } | 1320 | } |
| 1321 | } | 1321 | } |
| 1322 | 1322 | ||
| 1323 | pub fn writeSymtab(self: Object, macho_file: *MachO) error{Overflow}!void { | 1323 | pub fn writeSymtab(self: Object, macho_file: *MachO, ctx: anytype) error{Overflow}!void { |
| 1324 | const tracy = trace(@src()); | 1324 | const tracy = trace(@src()); |
| 1325 | defer tracy.end(); | 1325 | defer tracy.end(); |
| 1326 | 1326 | ||
| ... | @@ -1329,19 +1329,19 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) error{Overflow}!void { | ... | @@ -1329,19 +1329,19 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) error{Overflow}!void { |
| 1329 | const file = sym.getFile(macho_file) orelse continue; | 1329 | const file = sym.getFile(macho_file) orelse continue; |
| 1330 | if (file.getIndex() != self.index) continue; | 1330 | if (file.getIndex() != self.index) continue; |
| 1331 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; | 1331 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 1332 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 1332 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 1333 | macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | 1333 | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); |
| 1334 | macho_file.strtab.appendAssumeCapacity(0); | 1334 | ctx.strtab.appendAssumeCapacity(0); |
| 1335 | const out_sym = &macho_file.symtab.items[idx]; | 1335 | const out_sym = &ctx.symtab.items[idx]; |
| 1336 | out_sym.n_strx = n_strx; | 1336 | out_sym.n_strx = n_strx; |
| 1337 | sym.setOutputSym(macho_file, out_sym); | 1337 | sym.setOutputSym(macho_file, out_sym); |
| 1338 | } | 1338 | } |
| 1339 | 1339 | ||
| 1340 | if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo()) | 1340 | if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo()) |
| 1341 | try self.writeStabs(macho_file); | 1341 | try self.writeStabs(macho_file, ctx); |
| 1342 | } | 1342 | } |
| 1343 | 1343 | ||
| 1344 | pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void { | 1344 | pub fn writeStabs(self: *const Object, macho_file: *MachO, ctx: anytype) error{Overflow}!void { |
| 1345 | const writeFuncStab = struct { | 1345 | const writeFuncStab = struct { |
| 1346 | inline fn writeFuncStab( | 1346 | inline fn writeFuncStab( |
| 1347 | n_strx: u32, | 1347 | n_strx: u32, |
| ... | @@ -1349,30 +1349,30 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1349,30 +1349,30 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1349 | n_value: u64, | 1349 | n_value: u64, |
| 1350 | size: u64, | 1350 | size: u64, |
| 1351 | index: u32, | 1351 | index: u32, |
| 1352 | ctx: *MachO, | 1352 | context: anytype, |
| 1353 | ) void { | 1353 | ) void { |
| 1354 | ctx.symtab.items[index] = .{ | 1354 | context.symtab.items[index] = .{ |
| 1355 | .n_strx = 0, | 1355 | .n_strx = 0, |
| 1356 | .n_type = macho.N_BNSYM, | 1356 | .n_type = macho.N_BNSYM, |
| 1357 | .n_sect = n_sect, | 1357 | .n_sect = n_sect, |
| 1358 | .n_desc = 0, | 1358 | .n_desc = 0, |
| 1359 | .n_value = n_value, | 1359 | .n_value = n_value, |
| 1360 | }; | 1360 | }; |
| 1361 | ctx.symtab.items[index + 1] = .{ | 1361 | context.symtab.items[index + 1] = .{ |
| 1362 | .n_strx = n_strx, | 1362 | .n_strx = n_strx, |
| 1363 | .n_type = macho.N_FUN, | 1363 | .n_type = macho.N_FUN, |
| 1364 | .n_sect = n_sect, | 1364 | .n_sect = n_sect, |
| 1365 | .n_desc = 0, | 1365 | .n_desc = 0, |
| 1366 | .n_value = n_value, | 1366 | .n_value = n_value, |
| 1367 | }; | 1367 | }; |
| 1368 | ctx.symtab.items[index + 2] = .{ | 1368 | context.symtab.items[index + 2] = .{ |
| 1369 | .n_strx = 0, | 1369 | .n_strx = 0, |
| 1370 | .n_type = macho.N_FUN, | 1370 | .n_type = macho.N_FUN, |
| 1371 | .n_sect = 0, | 1371 | .n_sect = 0, |
| 1372 | .n_desc = 0, | 1372 | .n_desc = 0, |
| 1373 | .n_value = size, | 1373 | .n_value = size, |
| 1374 | }; | 1374 | }; |
| 1375 | ctx.symtab.items[index + 3] = .{ | 1375 | context.symtab.items[index + 3] = .{ |
| 1376 | .n_strx = 0, | 1376 | .n_strx = 0, |
| 1377 | .n_type = macho.N_ENSYM, | 1377 | .n_type = macho.N_ENSYM, |
| 1378 | .n_sect = n_sect, | 1378 | .n_sect = n_sect, |
| ... | @@ -1392,10 +1392,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1392,10 +1392,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1392 | 1392 | ||
| 1393 | // Open scope | 1393 | // Open scope |
| 1394 | // N_SO comp_dir | 1394 | // N_SO comp_dir |
| 1395 | var n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 1395 | var n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 1396 | macho_file.strtab.appendSliceAssumeCapacity(comp_dir); | 1396 | ctx.strtab.appendSliceAssumeCapacity(comp_dir); |
| 1397 | macho_file.strtab.appendAssumeCapacity(0); | 1397 | ctx.strtab.appendAssumeCapacity(0); |
| 1398 | macho_file.symtab.items[index] = .{ | 1398 | ctx.symtab.items[index] = .{ |
| 1399 | .n_strx = n_strx, | 1399 | .n_strx = n_strx, |
| 1400 | .n_type = macho.N_SO, | 1400 | .n_type = macho.N_SO, |
| 1401 | .n_sect = 0, | 1401 | .n_sect = 0, |
| ... | @@ -1404,10 +1404,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1404,10 +1404,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1404 | }; | 1404 | }; |
| 1405 | index += 1; | 1405 | index += 1; |
| 1406 | // N_SO tu_name | 1406 | // N_SO tu_name |
| 1407 | n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 1407 | n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 1408 | macho_file.strtab.appendSliceAssumeCapacity(tu_name); | 1408 | ctx.strtab.appendSliceAssumeCapacity(tu_name); |
| 1409 | macho_file.strtab.appendAssumeCapacity(0); | 1409 | ctx.strtab.appendAssumeCapacity(0); |
| 1410 | macho_file.symtab.items[index] = .{ | 1410 | ctx.symtab.items[index] = .{ |
| 1411 | .n_strx = n_strx, | 1411 | .n_strx = n_strx, |
| 1412 | .n_type = macho.N_SO, | 1412 | .n_type = macho.N_SO, |
| 1413 | .n_sect = 0, | 1413 | .n_sect = 0, |
| ... | @@ -1416,18 +1416,18 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1416,18 +1416,18 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1416 | }; | 1416 | }; |
| 1417 | index += 1; | 1417 | index += 1; |
| 1418 | // N_OSO path | 1418 | // N_OSO path |
| 1419 | n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 1419 | n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 1420 | if (self.archive) |ar| { | 1420 | if (self.archive) |ar| { |
| 1421 | macho_file.strtab.appendSliceAssumeCapacity(ar.path); | 1421 | ctx.strtab.appendSliceAssumeCapacity(ar.path); |
| 1422 | macho_file.strtab.appendAssumeCapacity('('); | 1422 | ctx.strtab.appendAssumeCapacity('('); |
| 1423 | macho_file.strtab.appendSliceAssumeCapacity(self.path); | 1423 | ctx.strtab.appendSliceAssumeCapacity(self.path); |
| 1424 | macho_file.strtab.appendAssumeCapacity(')'); | 1424 | ctx.strtab.appendAssumeCapacity(')'); |
| 1425 | macho_file.strtab.appendAssumeCapacity(0); | 1425 | ctx.strtab.appendAssumeCapacity(0); |
| 1426 | } else { | 1426 | } else { |
| 1427 | macho_file.strtab.appendSliceAssumeCapacity(self.path); | 1427 | ctx.strtab.appendSliceAssumeCapacity(self.path); |
| 1428 | macho_file.strtab.appendAssumeCapacity(0); | 1428 | ctx.strtab.appendAssumeCapacity(0); |
| 1429 | } | 1429 | } |
| 1430 | macho_file.symtab.items[index] = .{ | 1430 | ctx.symtab.items[index] = .{ |
| 1431 | .n_strx = n_strx, | 1431 | .n_strx = n_strx, |
| 1432 | .n_type = macho.N_OSO, | 1432 | .n_type = macho.N_OSO, |
| 1433 | .n_sect = 0, | 1433 | .n_sect = 0, |
| ... | @@ -1448,17 +1448,17 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1448,17 +1448,17 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1448 | const sect = macho_file.sections.items(.header)[sym.out_n_sect]; | 1448 | const sect = macho_file.sections.items(.header)[sym.out_n_sect]; |
| 1449 | const sym_n_strx = n_strx: { | 1449 | const sym_n_strx = n_strx: { |
| 1450 | const symtab_index = sym.getOutputSymtabIndex(macho_file).?; | 1450 | const symtab_index = sym.getOutputSymtabIndex(macho_file).?; |
| 1451 | const osym = macho_file.symtab.items[symtab_index]; | 1451 | const osym = ctx.symtab.items[symtab_index]; |
| 1452 | break :n_strx osym.n_strx; | 1452 | break :n_strx osym.n_strx; |
| 1453 | }; | 1453 | }; |
| 1454 | const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0; | 1454 | const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0; |
| 1455 | const sym_n_value = sym.getAddress(.{}, macho_file); | 1455 | const sym_n_value = sym.getAddress(.{}, macho_file); |
| 1456 | const sym_size = sym.getSize(macho_file); | 1456 | const sym_size = sym.getSize(macho_file); |
| 1457 | if (sect.isCode()) { | 1457 | if (sect.isCode()) { |
| 1458 | writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file); | 1458 | writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx); |
| 1459 | index += 4; | 1459 | index += 4; |
| 1460 | } else if (sym.visibility == .global) { | 1460 | } else if (sym.visibility == .global) { |
| 1461 | macho_file.symtab.items[index] = .{ | 1461 | ctx.symtab.items[index] = .{ |
| 1462 | .n_strx = sym_n_strx, | 1462 | .n_strx = sym_n_strx, |
| 1463 | .n_type = macho.N_GSYM, | 1463 | .n_type = macho.N_GSYM, |
| 1464 | .n_sect = sym_n_sect, | 1464 | .n_sect = sym_n_sect, |
| ... | @@ -1467,7 +1467,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1467,7 +1467,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1467 | }; | 1467 | }; |
| 1468 | index += 1; | 1468 | index += 1; |
| 1469 | } else { | 1469 | } else { |
| 1470 | macho_file.symtab.items[index] = .{ | 1470 | ctx.symtab.items[index] = .{ |
| 1471 | .n_strx = sym_n_strx, | 1471 | .n_strx = sym_n_strx, |
| 1472 | .n_type = macho.N_STSYM, | 1472 | .n_type = macho.N_STSYM, |
| 1473 | .n_sect = sym_n_sect, | 1473 | .n_sect = sym_n_sect, |
| ... | @@ -1480,7 +1480,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1480,7 +1480,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1480 | 1480 | ||
| 1481 | // Close scope | 1481 | // Close scope |
| 1482 | // N_SO | 1482 | // N_SO |
| 1483 | macho_file.symtab.items[index] = .{ | 1483 | ctx.symtab.items[index] = .{ |
| 1484 | .n_strx = 0, | 1484 | .n_strx = 0, |
| 1485 | .n_type = macho.N_SO, | 1485 | .n_type = macho.N_SO, |
| 1486 | .n_sect = 0, | 1486 | .n_sect = 0, |
| ... | @@ -1493,10 +1493,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1493,10 +1493,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1493 | for (self.stab_files.items) |sf| { | 1493 | for (self.stab_files.items) |sf| { |
| 1494 | // Open scope | 1494 | // Open scope |
| 1495 | // N_SO comp_dir | 1495 | // N_SO comp_dir |
| 1496 | var n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 1496 | var n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 1497 | macho_file.strtab.appendSliceAssumeCapacity(sf.getCompDir(self)); | 1497 | ctx.strtab.appendSliceAssumeCapacity(sf.getCompDir(self)); |
| 1498 | macho_file.strtab.appendAssumeCapacity(0); | 1498 | ctx.strtab.appendAssumeCapacity(0); |
| 1499 | macho_file.symtab.items[index] = .{ | 1499 | ctx.symtab.items[index] = .{ |
| 1500 | .n_strx = n_strx, | 1500 | .n_strx = n_strx, |
| 1501 | .n_type = macho.N_SO, | 1501 | .n_type = macho.N_SO, |
| 1502 | .n_sect = 0, | 1502 | .n_sect = 0, |
| ... | @@ -1505,10 +1505,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1505,10 +1505,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1505 | }; | 1505 | }; |
| 1506 | index += 1; | 1506 | index += 1; |
| 1507 | // N_SO tu_name | 1507 | // N_SO tu_name |
| 1508 | n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 1508 | n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 1509 | macho_file.strtab.appendSliceAssumeCapacity(sf.getTuName(self)); | 1509 | ctx.strtab.appendSliceAssumeCapacity(sf.getTuName(self)); |
| 1510 | macho_file.strtab.appendAssumeCapacity(0); | 1510 | ctx.strtab.appendAssumeCapacity(0); |
| 1511 | macho_file.symtab.items[index] = .{ | 1511 | ctx.symtab.items[index] = .{ |
| 1512 | .n_strx = n_strx, | 1512 | .n_strx = n_strx, |
| 1513 | .n_type = macho.N_SO, | 1513 | .n_type = macho.N_SO, |
| 1514 | .n_sect = 0, | 1514 | .n_sect = 0, |
| ... | @@ -1517,10 +1517,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1517,10 +1517,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1517 | }; | 1517 | }; |
| 1518 | index += 1; | 1518 | index += 1; |
| 1519 | // N_OSO path | 1519 | // N_OSO path |
| 1520 | n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 1520 | n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 1521 | macho_file.strtab.appendSliceAssumeCapacity(sf.getOsoPath(self)); | 1521 | ctx.strtab.appendSliceAssumeCapacity(sf.getOsoPath(self)); |
| 1522 | macho_file.strtab.appendAssumeCapacity(0); | 1522 | ctx.strtab.appendAssumeCapacity(0); |
| 1523 | macho_file.symtab.items[index] = .{ | 1523 | ctx.symtab.items[index] = .{ |
| 1524 | .n_strx = n_strx, | 1524 | .n_strx = n_strx, |
| 1525 | .n_type = macho.N_OSO, | 1525 | .n_type = macho.N_OSO, |
| 1526 | .n_sect = 0, | 1526 | .n_sect = 0, |
| ... | @@ -1536,7 +1536,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1536,7 +1536,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1536 | if (!sym.flags.output_symtab) continue; | 1536 | if (!sym.flags.output_symtab) continue; |
| 1537 | const sym_n_strx = n_strx: { | 1537 | const sym_n_strx = n_strx: { |
| 1538 | const symtab_index = sym.getOutputSymtabIndex(macho_file).?; | 1538 | const symtab_index = sym.getOutputSymtabIndex(macho_file).?; |
| 1539 | const osym = macho_file.symtab.items[symtab_index]; | 1539 | const osym = ctx.symtab.items[symtab_index]; |
| 1540 | break :n_strx osym.n_strx; | 1540 | break :n_strx osym.n_strx; |
| 1541 | }; | 1541 | }; |
| 1542 | const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0; | 1542 | const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0; |
| ... | @@ -1544,11 +1544,11 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1544,11 +1544,11 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1544 | const sym_size = sym.getSize(macho_file); | 1544 | const sym_size = sym.getSize(macho_file); |
| 1545 | switch (stab.tag) { | 1545 | switch (stab.tag) { |
| 1546 | .func => { | 1546 | .func => { |
| 1547 | writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file); | 1547 | writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx); |
| 1548 | index += 4; | 1548 | index += 4; |
| 1549 | }, | 1549 | }, |
| 1550 | .global => { | 1550 | .global => { |
| 1551 | macho_file.symtab.items[index] = .{ | 1551 | ctx.symtab.items[index] = .{ |
| 1552 | .n_strx = sym_n_strx, | 1552 | .n_strx = sym_n_strx, |
| 1553 | .n_type = macho.N_GSYM, | 1553 | .n_type = macho.N_GSYM, |
| 1554 | .n_sect = sym_n_sect, | 1554 | .n_sect = sym_n_sect, |
| ... | @@ -1558,7 +1558,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1558,7 +1558,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1558 | index += 1; | 1558 | index += 1; |
| 1559 | }, | 1559 | }, |
| 1560 | .static => { | 1560 | .static => { |
| 1561 | macho_file.symtab.items[index] = .{ | 1561 | ctx.symtab.items[index] = .{ |
| 1562 | .n_strx = sym_n_strx, | 1562 | .n_strx = sym_n_strx, |
| 1563 | .n_type = macho.N_STSYM, | 1563 | .n_type = macho.N_STSYM, |
| 1564 | .n_sect = sym_n_sect, | 1564 | .n_sect = sym_n_sect, |
| ... | @@ -1572,7 +1572,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void | ... | @@ -1572,7 +1572,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1572 | 1572 | ||
| 1573 | // Close scope | 1573 | // Close scope |
| 1574 | // N_SO | 1574 | // N_SO |
| 1575 | macho_file.symtab.items[index] = .{ | 1575 | ctx.symtab.items[index] = .{ |
| 1576 | .n_strx = 0, | 1576 | .n_strx = 0, |
| 1577 | .n_type = macho.N_SO, | 1577 | .n_type = macho.N_SO, |
| 1578 | .n_sect = 0, | 1578 | .n_sect = 0, |
src/link/MachO/ZigObject.zig+31-29| ... | @@ -310,7 +310,7 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void { | ... | @@ -310,7 +310,7 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void { |
| 310 | } | 310 | } |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void { | 313 | pub fn writeSymtab(self: ZigObject, macho_file: *MachO, ctx: anytype) void { |
| 314 | const tracy = trace(@src()); | 314 | const tracy = trace(@src()); |
| 315 | defer tracy.end(); | 315 | defer tracy.end(); |
| 316 | 316 | ||
| ... | @@ -319,10 +319,10 @@ pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void { | ... | @@ -319,10 +319,10 @@ pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void { |
| 319 | const file = sym.getFile(macho_file) orelse continue; | 319 | const file = sym.getFile(macho_file) orelse continue; |
| 320 | if (file.getIndex() != self.index) continue; | 320 | if (file.getIndex() != self.index) continue; |
| 321 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; | 321 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 322 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | 322 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 323 | macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | 323 | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); |
| 324 | macho_file.strtab.appendAssumeCapacity(0); | 324 | ctx.strtab.appendAssumeCapacity(0); |
| 325 | const out_sym = &macho_file.symtab.items[idx]; | 325 | const out_sym = &ctx.symtab.items[idx]; |
| 326 | out_sym.n_strx = n_strx; | 326 | out_sym.n_strx = n_strx; |
| 327 | sym.setOutputSym(macho_file, out_sym); | 327 | sym.setOutputSym(macho_file, out_sym); |
| 328 | } | 328 | } |
| ... | @@ -531,7 +531,7 @@ pub fn updateFunc( | ... | @@ -531,7 +531,7 @@ pub fn updateFunc( |
| 531 | var code_buffer = std.ArrayList(u8).init(gpa); | 531 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 532 | defer code_buffer.deinit(); | 532 | defer code_buffer.deinit(); |
| 533 | 533 | ||
| 534 | var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf | 534 | var decl_state: ?Dwarf.DeclState = if (macho_file.getDebugSymbols()) |d_sym| try d_sym.dwarf.initDeclState(mod, decl_index) else null; |
| 535 | defer if (decl_state) |*ds| ds.deinit(); | 535 | defer if (decl_state) |*ds| ds.deinit(); |
| 536 | 536 | ||
| 537 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; | 537 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; |
| ... | @@ -557,16 +557,16 @@ pub fn updateFunc( | ... | @@ -557,16 +557,16 @@ pub fn updateFunc( |
| 557 | const sect_index = try self.getDeclOutputSection(macho_file, decl, code); | 557 | const sect_index = try self.getDeclOutputSection(macho_file, decl, code); |
| 558 | try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); | 558 | try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); |
| 559 | 559 | ||
| 560 | // if (decl_state) |*ds| { | 560 | if (decl_state) |*ds| { |
| 561 | // const sym = elf_file.symbol(sym_index); | 561 | const sym = macho_file.getSymbol(sym_index); |
| 562 | // try self.dwarf.?.commitDeclState( | 562 | try macho_file.getDebugSymbols().?.dwarf.commitDeclState( |
| 563 | // mod, | 563 | mod, |
| 564 | // decl_index, | 564 | decl_index, |
| 565 | // sym.value, | 565 | sym.getAddress(.{}, macho_file), |
| 566 | // sym.atom(elf_file).?.size, | 566 | sym.getAtom(macho_file).?.size, |
| 567 | // ds, | 567 | ds, |
| 568 | // ); | 568 | ); |
| 569 | // } | 569 | } |
| 570 | 570 | ||
| 571 | // Since we updated the vaddr and the size, each corresponding export | 571 | // Since we updated the vaddr and the size, each corresponding export |
| 572 | // symbol also needs to be updated. | 572 | // symbol also needs to be updated. |
| ... | @@ -606,7 +606,7 @@ pub fn updateDecl( | ... | @@ -606,7 +606,7 @@ pub fn updateDecl( |
| 606 | var code_buffer = std.ArrayList(u8).init(gpa); | 606 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 607 | defer code_buffer.deinit(); | 607 | defer code_buffer.deinit(); |
| 608 | 608 | ||
| 609 | var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf | 609 | var decl_state: ?Dwarf.DeclState = if (macho_file.getDebugSymbols()) |d_sym| try d_sym.dwarf.initDeclState(mod, decl_index) else null; |
| 610 | defer if (decl_state) |*ds| ds.deinit(); | 610 | defer if (decl_state) |*ds| ds.deinit(); |
| 611 | 611 | ||
| 612 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 612 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| ... | @@ -638,15 +638,16 @@ pub fn updateDecl( | ... | @@ -638,15 +638,16 @@ pub fn updateDecl( |
| 638 | try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); | 638 | try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | // if (decl_state) |*ds| { | 641 | if (decl_state) |*ds| { |
| 642 | // try self.d_sym.?.dwarf.commitDeclState( | 642 | const sym = macho_file.getSymbol(sym_index); |
| 643 | // mod, | 643 | try macho_file.getDebugSymbols().?.dwarf.commitDeclState( |
| 644 | // decl_index, | 644 | mod, |
| 645 | // addr, | 645 | decl_index, |
| 646 | // self.getAtom(atom_index).size, | 646 | sym.getAddress(.{}, macho_file), |
| 647 | // ds, | 647 | sym.getAtom(macho_file).?.size, |
| 648 | // ); | 648 | ds, |
| 649 | // } | 649 | ); |
| 650 | } | ||
| 650 | 651 | ||
| 651 | // Since we updated the vaddr and the size, each corresponding export symbol also | 652 | // Since we updated the vaddr and the size, each corresponding export symbol also |
| 652 | // needs to be updated. | 653 | // needs to be updated. |
| ... | @@ -1220,13 +1221,14 @@ fn updateLazySymbol( | ... | @@ -1220,13 +1221,14 @@ fn updateLazySymbol( |
| 1220 | /// Must be called only after a successful call to `updateDecl`. | 1221 | /// Must be called only after a successful call to `updateDecl`. |
| 1221 | pub fn updateDeclLineNumber( | 1222 | pub fn updateDeclLineNumber( |
| 1222 | self: *ZigObject, | 1223 | self: *ZigObject, |
| 1224 | macho_file: *MachO, | ||
| 1223 | mod: *Module, | 1225 | mod: *Module, |
| 1224 | decl_index: InternPool.DeclIndex, | 1226 | decl_index: InternPool.DeclIndex, |
| 1225 | ) !void { | 1227 | ) !void { |
| 1226 | _ = self; | 1228 | _ = self; |
| 1227 | _ = mod; | 1229 | if (macho_file.getDebugSymbols()) |d_sym| { |
| 1228 | _ = decl_index; | 1230 | try d_sym.dwarf.updateDeclLineNumber(mod, decl_index); |
| 1229 | // TODO: Dwarf | 1231 | } |
| 1230 | } | 1232 | } |
| 1231 | 1233 | ||
| 1232 | pub fn deleteDeclExport( | 1234 | pub fn deleteDeclExport( |
src/link/MachO/file.zig+2-2| ... | @@ -90,9 +90,9 @@ pub const File = union(enum) { | ... | @@ -90,9 +90,9 @@ pub const File = union(enum) { |
| 90 | }; | 90 | }; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | pub fn writeSymtab(file: File, macho_file: *MachO) !void { | 93 | pub fn writeSymtab(file: File, macho_file: *MachO, ctx: anytype) !void { |
| 94 | return switch (file) { | 94 | return switch (file) { |
| 95 | inline else => |x| x.writeSymtab(macho_file), | 95 | inline else => |x| x.writeSymtab(macho_file, ctx), |
| 96 | }; | 96 | }; |
| 97 | } | 97 | } |
| 98 | 98 |
src/link/MachO/load_commands.zig+22| ... | @@ -5,6 +5,7 @@ const macho = std.macho; | ... | @@ -5,6 +5,7 @@ const macho = std.macho; |
| 5 | const mem = std.mem; | 5 | const mem = std.mem; |
| 6 | 6 | ||
| 7 | const Allocator = mem.Allocator; | 7 | const Allocator = mem.Allocator; |
| 8 | const DebugSymbols = @import("DebugSymbols.zig"); | ||
| 8 | const Dylib = @import("Dylib.zig"); | 9 | const Dylib = @import("Dylib.zig"); |
| 9 | const MachO = @import("../MachO.zig"); | 10 | const MachO = @import("../MachO.zig"); |
| 10 | 11 | ||
| ... | @@ -97,6 +98,27 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 { | ... | @@ -97,6 +98,27 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 { |
| 97 | return @as(u32, @intCast(sizeofcmds)); | 98 | return @as(u32, @intCast(sizeofcmds)); |
| 98 | } | 99 | } |
| 99 | 100 | ||
| 101 | pub fn calcLoadCommandsSizeDsym(macho_file: *MachO, dsym: *const DebugSymbols) u32 { | ||
| 102 | var sizeofcmds: u64 = 0; | ||
| 103 | |||
| 104 | // LC_SEGMENT_64 | ||
| 105 | sizeofcmds += @sizeOf(macho.segment_command_64) * (macho_file.segments.items.len - 1); | ||
| 106 | for (macho_file.segments.items) |seg| { | ||
| 107 | sizeofcmds += seg.nsects * @sizeOf(macho.section_64); | ||
| 108 | } | ||
| 109 | sizeofcmds += @sizeOf(macho.segment_command_64) * dsym.segments.items.len; | ||
| 110 | for (dsym.segments.items) |seg| { | ||
| 111 | sizeofcmds += seg.nsects * @sizeOf(macho.section_64); | ||
| 112 | } | ||
| 113 | |||
| 114 | // LC_SYMTAB | ||
| 115 | sizeofcmds += @sizeOf(macho.symtab_command); | ||
| 116 | // LC_UUID | ||
| 117 | sizeofcmds += @sizeOf(macho.uuid_command); | ||
| 118 | |||
| 119 | return @as(u32, @intCast(sizeofcmds)); | ||
| 120 | } | ||
| 121 | |||
| 100 | pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 { | 122 | pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 { |
| 101 | var sizeofcmds: u64 = 0; | 123 | var sizeofcmds: u64 = 0; |
| 102 | 124 |