| author | |
| committer | |
| log | f2214e43715d1094a2d933c3fe1b6f461391915b |
| tree | fef3b2025f353c4be81eeda7d87fbcc314019525 |
| parent | d53cb284de0486fbb31f6377d3b86d8de5f93cd0 |
9 files changed, 212 insertions(+), 223 deletions(-)
src/link/Dwarf.zig-1| ... | ... | @@ -1468,7 +1468,6 @@ pub fn commitDeclState( |
| 1468 | 1468 | .target = reloc.target, |
| 1469 | 1469 | .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off, |
| 1470 | 1470 | .addend = 0, |
| 1471 | .prev_vaddr = 0, | |
| 1472 | 1471 | }); |
| 1473 | 1472 | }, |
| 1474 | 1473 | .elf => {}, // TODO |
src/link/MachO.zig+9-5| ... | ... | @@ -258,7 +258,7 @@ pub fn createEmpty( |
| 258 | 258 | |
| 259 | 259 | switch (comp.config.debug_format) { |
| 260 | 260 | .strip => {}, |
| 261 | .dwarf => { | |
| 261 | .dwarf => if (!self.base.isRelocatable()) { | |
| 262 | 262 | // Create dSYM bundle. |
| 263 | 263 | log.debug("creating {s}.dSYM bundle", .{emit.sub_path}); |
| 264 | 264 | |
| ... | ... | @@ -283,6 +283,9 @@ pub fn createEmpty( |
| 283 | 283 | .file = d_sym_file, |
| 284 | 284 | }; |
| 285 | 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; | |
| 286 | 289 | }, |
| 287 | 290 | .code_view => unreachable, |
| 288 | 291 | } |
| ... | ... | @@ -696,6 +699,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 696 | 699 | const ncmds, const sizeofcmds, const uuid_cmd_offset = try self.writeLoadCommands(); |
| 697 | 700 | try self.writeHeader(ncmds, sizeofcmds); |
| 698 | 701 | try self.writeUuid(uuid_cmd_offset, self.requiresCodeSig()); |
| 702 | if (self.getDebugSymbols()) |dsym| try dsym.flushModule(self); | |
| 699 | 703 | |
| 700 | 704 | if (codesig) |*csig| { |
| 701 | 705 | try self.writeCodeSignature(csig); // code signing always comes last |
| ... | ... | @@ -2902,16 +2906,16 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 { |
| 2902 | 2906 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); |
| 2903 | 2907 | |
| 2904 | 2908 | if (self.getZigObject()) |zo| { |
| 2905 | zo.writeSymtab(self); | |
| 2909 | zo.writeSymtab(self, self); | |
| 2906 | 2910 | } |
| 2907 | 2911 | for (self.objects.items) |index| { |
| 2908 | try self.getFile(index).?.writeSymtab(self); | |
| 2912 | try self.getFile(index).?.writeSymtab(self, self); | |
| 2909 | 2913 | } |
| 2910 | 2914 | for (self.dylibs.items) |index| { |
| 2911 | try self.getFile(index).?.writeSymtab(self); | |
| 2915 | try self.getFile(index).?.writeSymtab(self, self); | |
| 2912 | 2916 | } |
| 2913 | 2917 | if (self.getInternalObject()) |internal| { |
| 2914 | internal.writeSymtab(self); | |
| 2918 | internal.writeSymtab(self, self); | |
| 2915 | 2919 | } |
| 2916 | 2920 | |
| 2917 | 2921 | assert(self.strtab.items.len == cmd.strsize); |
src/link/MachO/DebugSymbols.zig+113-149| ... | ... | @@ -3,6 +3,7 @@ dwarf: Dwarf, |
| 3 | 3 | file: fs.File, |
| 4 | 4 | |
| 5 | 5 | symtab_cmd: macho.symtab_command = .{}, |
| 6 | uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 }, | |
| 6 | 7 | |
| 7 | 8 | segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{}, |
| 8 | 9 | sections: std.ArrayListUnmanaged(macho.section_64) = .{}, |
| ... | ... | @@ -22,9 +23,12 @@ debug_aranges_section_dirty: bool = false, |
| 22 | 23 | debug_info_header_dirty: bool = false, |
| 23 | 24 | debug_line_header_dirty: bool = false, |
| 24 | 25 | |
| 25 | strtab: StringTable = .{}, | |
| 26 | 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 | 32 | pub const Reloc = struct { |
| 29 | 33 | type: enum { |
| 30 | 34 | direct_load, |
| ... | ... | @@ -33,12 +37,13 @@ pub const Reloc = struct { |
| 33 | 37 | target: u32, |
| 34 | 38 | offset: u64, |
| 35 | 39 | addend: u32, |
| 36 | prev_vaddr: u64, | |
| 37 | 40 | }; |
| 38 | 41 | |
| 39 | 42 | /// You must call this function *after* `ZigObject.initMetadata()` |
| 40 | 43 | /// has been called to get a viable debug symbols output. |
| 41 | 44 | pub fn initMetadata(self: *DebugSymbols, macho_file: *MachO) !void { |
| 45 | try self.strtab.append(self.allocator, 0); | |
| 46 | ||
| 42 | 47 | if (self.dwarf_segment_cmd_index == null) { |
| 43 | 48 | self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len)); |
| 44 | 49 | |
| ... | ... | @@ -202,34 +207,21 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 202 | 207 | const zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| 203 | 208 | |
| 204 | 209 | for (self.relocs.items) |*reloc| { |
| 205 | const sym = switch (reloc.type) { | |
| 206 | .direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target }), | |
| 207 | .got_load => blk: { | |
| 208 | const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?; | |
| 209 | const got_entry = macho_file.got_table.entries.items[got_index]; | |
| 210 | break :blk macho_file.getSymbol(got_entry); | |
| 211 | }, | |
| 212 | }; | |
| 213 | if (sym.n_value == reloc.prev_vaddr) continue; | |
| 214 | ||
| 215 | const sym_name = switch (reloc.type) { | |
| 216 | .direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target }), | |
| 217 | .got_load => blk: { | |
| 218 | const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?; | |
| 219 | const got_entry = macho_file.got_table.entries.items[got_index]; | |
| 220 | break :blk macho_file.getSymbolName(got_entry); | |
| 221 | }, | |
| 210 | const sym = macho_file.getSymbol(reloc.target); | |
| 211 | const sym_name = sym.getName(macho_file); | |
| 212 | const addr = switch (reloc.type) { | |
| 213 | .direct_load => sym.getAddress(.{}, macho_file), | |
| 214 | .got_load => sym.getGotAddress(macho_file), | |
| 222 | 215 | }; |
| 223 | 216 | const sect = &self.sections.items[self.debug_info_section_index.?]; |
| 224 | 217 | const file_offset = sect.offset + reloc.offset; |
| 225 | 218 | log.debug("resolving relocation: {d}@{x} ('{s}') at offset {x}", .{ |
| 226 | 219 | reloc.target, |
| 227 | sym.n_value, | |
| 220 | addr, | |
| 228 | 221 | sym_name, |
| 229 | 222 | file_offset, |
| 230 | 223 | }); |
| 231 | try self.file.pwriteAll(mem.asBytes(&sym.n_value), file_offset); | |
| 232 | reloc.prev_vaddr = sym.n_value; | |
| 224 | try self.file.pwriteAll(mem.asBytes(&addr), file_offset); | |
| 233 | 225 | } |
| 234 | 226 | |
| 235 | 227 | if (self.debug_abbrev_section_dirty) { |
| ... | ... | @@ -240,7 +232,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 240 | 232 | if (self.debug_info_header_dirty) { |
| 241 | 233 | // Currently only one compilation unit is supported, so the address range is simply |
| 242 | 234 | // identical to the main program header virtual address and memory size. |
| 243 | const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?]; | |
| 235 | const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?]; | |
| 244 | 236 | const low_pc = text_section.addr; |
| 245 | 237 | const high_pc = text_section.addr + text_section.size; |
| 246 | 238 | try self.dwarf.writeDbgInfoHeader(zcu, low_pc, high_pc); |
| ... | ... | @@ -250,7 +242,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 250 | 242 | if (self.debug_aranges_section_dirty) { |
| 251 | 243 | // Currently only one compilation unit is supported, so the address range is simply |
| 252 | 244 | // identical to the main program header virtual address and memory size. |
| 253 | const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?]; | |
| 245 | const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?]; | |
| 254 | 246 | try self.dwarf.writeDbgAranges(text_section.addr, text_section.size); |
| 255 | 247 | self.debug_aranges_section_dirty = false; |
| 256 | 248 | } |
| ... | ... | @@ -274,17 +266,8 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 274 | 266 | try self.writeLinkeditSegmentData(macho_file); |
| 275 | 267 | |
| 276 | 268 | // Write load commands |
| 277 | var lc_buffer = std.ArrayList(u8).init(self.allocator); | |
| 278 | defer lc_buffer.deinit(); | |
| 279 | const lc_writer = lc_buffer.writer(); | |
| 280 | ||
| 281 | try self.writeSegmentHeaders(macho_file, lc_writer); | |
| 282 | try lc_writer.writeStruct(self.symtab_cmd); | |
| 283 | try lc_writer.writeStruct(macho_file.uuid_cmd); | |
| 284 | ||
| 285 | const ncmds = load_commands.calcNumOfLCs(lc_buffer.items); | |
| 286 | try self.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64)); | |
| 287 | try self.writeHeader(macho_file, ncmds, @as(u32, @intCast(lc_buffer.items.len))); | |
| 269 | const ncmds, const sizeofcmds = try self.writeLoadCommands(macho_file); | |
| 270 | try self.writeHeader(macho_file, ncmds, sizeofcmds); | |
| 288 | 271 | |
| 289 | 272 | assert(!self.debug_abbrev_section_dirty); |
| 290 | 273 | assert(!self.debug_aranges_section_dirty); |
| ... | ... | @@ -297,8 +280,9 @@ pub fn deinit(self: *DebugSymbols) void { |
| 297 | 280 | self.segments.deinit(gpa); |
| 298 | 281 | self.sections.deinit(gpa); |
| 299 | 282 | self.dwarf.deinit(); |
| 300 | self.strtab.deinit(gpa); | |
| 301 | 283 | self.relocs.deinit(gpa); |
| 284 | self.symtab.deinit(gpa); | |
| 285 | self.strtab.deinit(gpa); | |
| 302 | 286 | } |
| 303 | 287 | |
| 304 | 288 | pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void { |
| ... | ... | @@ -322,7 +306,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 322 | 306 | // however at the cost of having LINKEDIT preceed DWARF in dSYM binary which we |
| 323 | 307 | // do not want as we want to be able to incrementally move DWARF sections in the |
| 324 | 308 | // file as we please. |
| 325 | const last_seg = macho_file.getLinkeditSegmentPtr(); | |
| 309 | const last_seg = macho_file.getLinkeditSegment(); | |
| 326 | 310 | break :blk last_seg.vmaddr + last_seg.vmsize; |
| 327 | 311 | }; |
| 328 | 312 | const dwarf_segment = self.getDwarfSegmentPtr(); |
| ... | ... | @@ -332,8 +316,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 332 | 316 | file_size = @max(file_size, header.offset + header.size); |
| 333 | 317 | } |
| 334 | 318 | |
| 335 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 336 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 319 | const page_size = macho_file.getPageSize(); | |
| 337 | 320 | const aligned_size = mem.alignForward(u64, file_size, page_size); |
| 338 | 321 | dwarf_segment.vmaddr = base_vmaddr; |
| 339 | 322 | dwarf_segment.filesize = aligned_size; |
| ... | ... | @@ -353,54 +336,70 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 353 | 336 | log.debug("found __LINKEDIT segment free space at 0x{x}", .{linkedit.fileoff}); |
| 354 | 337 | } |
| 355 | 338 | |
| 356 | fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype) !void { | |
| 357 | // Write segment/section headers from the binary file first. | |
| 358 | const end = macho_file.linkedit_segment_cmd_index.?; | |
| 359 | for (macho_file.segments.items[0..end], 0..) |seg, i| { | |
| 360 | const indexes = macho_file.getSectionIndexes(@as(u8, @intCast(i))); | |
| 361 | var out_seg = seg; | |
| 362 | out_seg.fileoff = 0; | |
| 363 | out_seg.filesize = 0; | |
| 364 | out_seg.cmdsize = @sizeOf(macho.segment_command_64); | |
| 365 | out_seg.nsects = 0; | |
| 366 | ||
| 367 | // Update section headers count; any section with size of 0 is excluded | |
| 368 | // since it doesn't have any data in the final binary file. | |
| 369 | for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| { | |
| 370 | if (header.size == 0) continue; | |
| 371 | out_seg.cmdsize += @sizeOf(macho.section_64); | |
| 372 | out_seg.nsects += 1; | |
| 373 | } | |
| 339 | fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, usize } { | |
| 340 | const gpa = self.allocator; | |
| 341 | const needed_size = load_commands.calcLoadCommandsSizeDsym(macho_file, self); | |
| 342 | const buffer = try gpa.alloc(u8, needed_size); | |
| 343 | defer gpa.free(buffer); | |
| 344 | ||
| 345 | var stream = std.io.fixedBufferStream(buffer); | |
| 346 | var cwriter = std.io.countingWriter(stream.writer()); | |
| 347 | const writer = cwriter.writer(); | |
| 374 | 348 | |
| 375 | if (out_seg.nsects == 0 and | |
| 376 | (mem.eql(u8, out_seg.segName(), "__DATA_CONST") or | |
| 377 | mem.eql(u8, out_seg.segName(), "__DATA"))) continue; | |
| 349 | var ncmds: usize = 0; | |
| 378 | 350 | |
| 379 | try writer.writeStruct(out_seg); | |
| 380 | for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| { | |
| 381 | if (header.size == 0) continue; | |
| 382 | var out_header = header; | |
| 383 | out_header.offset = 0; | |
| 384 | try writer.writeStruct(out_header); | |
| 351 | // UUID comes first presumably to speed up lookup by the consumer like lldb. | |
| 352 | @memcpy(&self.uuid_cmd.uuid, &macho_file.uuid_cmd.uuid); | |
| 353 | try writer.writeStruct(self.uuid_cmd); | |
| 354 | ncmds += 1; | |
| 355 | ||
| 356 | // Segment and section load commands | |
| 357 | { | |
| 358 | // Write segment/section headers from the binary file first. | |
| 359 | const slice = macho_file.sections.slice(); | |
| 360 | var sect_id: usize = 0; | |
| 361 | for (macho_file.segments.items, 0..) |seg, seg_id| { | |
| 362 | if (seg_id == macho_file.linkedit_seg_index.?) break; | |
| 363 | var out_seg = seg; | |
| 364 | out_seg.fileoff = 0; | |
| 365 | out_seg.filesize = 0; | |
| 366 | try writer.writeStruct(out_seg); | |
| 367 | for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| { | |
| 368 | var out_header = header; | |
| 369 | out_header.offset = 0; | |
| 370 | try writer.writeStruct(out_header); | |
| 371 | } | |
| 372 | sect_id += seg.nsects; | |
| 385 | 373 | } |
| 386 | } | |
| 387 | // Next, commit DSYM's __LINKEDIT and __DWARF segments headers. | |
| 388 | for (self.segments.items, 0..) |seg, i| { | |
| 389 | const indexes = self.getSectionIndexes(@as(u8, @intCast(i))); | |
| 390 | try writer.writeStruct(seg); | |
| 391 | for (self.sections.items[indexes.start..indexes.end]) |header| { | |
| 392 | try writer.writeStruct(header); | |
| 374 | ncmds += macho_file.segments.items.len - 1; | |
| 375 | ||
| 376 | // Next, commit DSYM's __LINKEDIT and __DWARF segments headers. | |
| 377 | sect_id = 0; | |
| 378 | for (self.segments.items) |seg| { | |
| 379 | try writer.writeStruct(seg); | |
| 380 | for (self.sections.items[sect_id..][0..seg.nsects]) |header| { | |
| 381 | try writer.writeStruct(header); | |
| 382 | } | |
| 383 | sect_id += seg.nsects; | |
| 393 | 384 | } |
| 385 | ncmds += self.segments.items.len; | |
| 394 | 386 | } |
| 395 | } | |
| 396 | 387 | |
| 397 | fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void { | |
| 398 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 388 | try writer.writeStruct(self.symtab_cmd); | |
| 389 | ncmds += 1; | |
| 390 | ||
| 391 | assert(cwriter.bytes_written == needed_size); | |
| 399 | 392 | |
| 393 | try self.file.pwriteAll(buffer, @sizeOf(macho.mach_header_64)); | |
| 394 | ||
| 395 | return .{ ncmds, buffer.len }; | |
| 396 | } | |
| 397 | ||
| 398 | fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void { | |
| 400 | 399 | var header: macho.mach_header_64 = .{}; |
| 401 | 400 | header.filetype = macho.MH_DSYM; |
| 402 | 401 | |
| 403 | switch (target.cpu.arch) { | |
| 402 | switch (macho_file.getTarget().cpu.arch) { | |
| 404 | 403 | .aarch64 => { |
| 405 | 404 | header.cputype = macho.CPU_TYPE_ARM64; |
| 406 | 405 | header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL; |
| ... | ... | @@ -412,8 +411,8 @@ fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: |
| 412 | 411 | else => return error.UnsupportedCpuArchitecture, |
| 413 | 412 | } |
| 414 | 413 | |
| 415 | header.ncmds = ncmds; | |
| 416 | header.sizeofcmds = sizeofcmds; | |
| 414 | header.ncmds = @intCast(ncmds); | |
| 415 | header.sizeofcmds = @intCast(sizeofcmds); | |
| 417 | 416 | |
| 418 | 417 | log.debug("writing Mach-O header {}", .{header}); |
| 419 | 418 | |
| ... | ... | @@ -435,91 +434,56 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void { |
| 435 | 434 | const tracy = trace(@src()); |
| 436 | 435 | defer tracy.end(); |
| 437 | 436 | |
| 438 | try self.writeSymtab(macho_file); | |
| 439 | try self.writeStrtab(); | |
| 440 | ||
| 441 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 442 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 437 | const page_size = macho_file.getPageSize(); | |
| 443 | 438 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; |
| 439 | ||
| 440 | var off = math.cast(u32, seg.fileoff) orelse return error.Overflow; | |
| 441 | off = try self.writeSymtab(off, macho_file); | |
| 442 | off = mem.alignForward(u32, off, @alignOf(u64)); | |
| 443 | off = try self.writeStrtab(off); | |
| 444 | seg.filesize = off - seg.fileoff; | |
| 445 | ||
| 444 | 446 | const aligned_size = mem.alignForward(u64, seg.filesize, page_size); |
| 445 | 447 | seg.vmsize = aligned_size; |
| 446 | 448 | } |
| 447 | 449 | |
| 448 | fn writeSymtab(self: *DebugSymbols, macho_file: *MachO) !void { | |
| 450 | pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 { | |
| 449 | 451 | const tracy = trace(@src()); |
| 450 | 452 | defer tracy.end(); |
| 451 | ||
| 452 | 453 | const gpa = self.allocator; |
| 454 | const cmd = &self.symtab_cmd; | |
| 455 | cmd.nsyms = macho_file.symtab_cmd.nsyms; | |
| 456 | cmd.strsize = macho_file.symtab_cmd.strsize; | |
| 457 | cmd.symoff = off; | |
| 453 | 458 | |
| 454 | var locals = std.ArrayList(macho.nlist_64).init(gpa); | |
| 455 | defer locals.deinit(); | |
| 456 | ||
| 457 | for (macho_file.locals.items, 0..) |sym, sym_id| { | |
| 458 | if (sym.n_strx == 0) continue; // no name, skip | |
| 459 | const sym_loc = MachO.SymbolWithLoc{ .sym_index = @as(u32, @intCast(sym_id)) }; | |
| 460 | if (macho_file.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip | |
| 461 | if (macho_file.getGlobal(macho_file.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip | |
| 462 | var out_sym = sym; | |
| 463 | out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(sym_loc)); | |
| 464 | try locals.append(out_sym); | |
| 465 | } | |
| 459 | try self.symtab.resize(gpa, cmd.nsyms); | |
| 460 | try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1); | |
| 466 | 461 | |
| 467 | var exports = std.ArrayList(macho.nlist_64).init(gpa); | |
| 468 | defer exports.deinit(); | |
| 469 | ||
| 470 | for (macho_file.globals.items) |global| { | |
| 471 | const sym = macho_file.getSymbol(global); | |
| 472 | if (sym.undf()) continue; // import, skip | |
| 473 | var out_sym = sym; | |
| 474 | out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(global)); | |
| 475 | try exports.append(out_sym); | |
| 462 | if (macho_file.getZigObject()) |zo| { | |
| 463 | zo.writeSymtab(macho_file, self); | |
| 464 | } | |
| 465 | for (macho_file.objects.items) |index| { | |
| 466 | try macho_file.getFile(index).?.writeSymtab(macho_file, self); | |
| 467 | } | |
| 468 | for (macho_file.dylibs.items) |index| { | |
| 469 | try macho_file.getFile(index).?.writeSymtab(macho_file, self); | |
| 470 | } | |
| 471 | if (macho_file.getInternalObject()) |internal| { | |
| 472 | internal.writeSymtab(macho_file, self); | |
| 476 | 473 | } |
| 477 | 474 | |
| 478 | const nlocals = locals.items.len; | |
| 479 | const nexports = exports.items.len; | |
| 480 | const nsyms = nlocals + nexports; | |
| 481 | ||
| 482 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; | |
| 483 | const offset = mem.alignForward(u64, seg.fileoff, @alignOf(macho.nlist_64)); | |
| 484 | const needed_size = nsyms * @sizeOf(macho.nlist_64); | |
| 485 | seg.filesize = offset + needed_size - seg.fileoff; | |
| 486 | ||
| 487 | self.symtab_cmd.symoff = @as(u32, @intCast(offset)); | |
| 488 | self.symtab_cmd.nsyms = @as(u32, @intCast(nsyms)); | |
| 489 | ||
| 490 | const locals_off = @as(u32, @intCast(offset)); | |
| 491 | const locals_size = nlocals * @sizeOf(macho.nlist_64); | |
| 492 | const exports_off = locals_off + locals_size; | |
| 493 | const exports_size = nexports * @sizeOf(macho.nlist_64); | |
| 475 | assert(self.strtab.items.len == cmd.strsize); | |
| 494 | 476 | |
| 495 | log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); | |
| 496 | try self.file.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); | |
| 477 | try self.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff); | |
| 497 | 478 | |
| 498 | log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); | |
| 499 | try self.file.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); | |
| 479 | return off + cmd.nsyms * @sizeOf(macho.nlist_64); | |
| 500 | 480 | } |
| 501 | 481 | |
| 502 | fn writeStrtab(self: *DebugSymbols) !void { | |
| 503 | const tracy = trace(@src()); | |
| 504 | defer tracy.end(); | |
| 505 | ||
| 506 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; | |
| 507 | const symtab_size = @as(u32, @intCast(self.symtab_cmd.nsyms * @sizeOf(macho.nlist_64))); | |
| 508 | const offset = mem.alignForward(u64, self.symtab_cmd.symoff + symtab_size, @alignOf(u64)); | |
| 509 | const needed_size = mem.alignForward(u64, self.strtab.buffer.items.len, @alignOf(u64)); | |
| 510 | ||
| 511 | seg.filesize = offset + needed_size - seg.fileoff; | |
| 512 | self.symtab_cmd.stroff = @as(u32, @intCast(offset)); | |
| 513 | self.symtab_cmd.strsize = @as(u32, @intCast(needed_size)); | |
| 514 | ||
| 515 | log.debug("writing string table from 0x{x} to 0x{x}", .{ offset, offset + needed_size }); | |
| 516 | ||
| 517 | try self.file.pwriteAll(self.strtab.buffer.items, offset); | |
| 518 | ||
| 519 | if (self.strtab.buffer.items.len < needed_size) { | |
| 520 | // Ensure we are always padded to the actual length of the file. | |
| 521 | try self.file.pwriteAll(&[_]u8{0}, offset + needed_size); | |
| 522 | } | |
| 482 | pub fn writeStrtab(self: *DebugSymbols, off: u32) !u32 { | |
| 483 | const cmd = &self.symtab_cmd; | |
| 484 | cmd.stroff = off; | |
| 485 | try self.file.pwriteAll(self.strtab.items, cmd.stroff); | |
| 486 | return off + cmd.strsize; | |
| 523 | 487 | } |
| 524 | 488 | |
| 525 | 489 | pub fn getSectionIndexes(self: *DebugSymbols, segment_index: u8) struct { start: u8, end: u8 } { |
| ... | ... | @@ -559,7 +523,7 @@ const assert = std.debug.assert; |
| 559 | 523 | const fs = std.fs; |
| 560 | 524 | const link = @import("../../link.zig"); |
| 561 | 525 | const load_commands = @import("load_commands.zig"); |
| 562 | const log = std.log.scoped(.dsym); | |
| 526 | const log = std.log.scoped(.link_dsym); | |
| 563 | 527 | const macho = std.macho; |
| 564 | 528 | const makeStaticString = MachO.makeStaticString; |
| 565 | 529 | 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 | 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 | 580 | const tracy = trace(@src()); |
| 581 | 581 | defer tracy.end(); |
| 582 | 582 | |
| ... | ... | @@ -585,10 +585,10 @@ pub fn writeSymtab(self: Dylib, macho_file: *MachO) void { |
| 585 | 585 | const file = global.getFile(macho_file) orelse continue; |
| 586 | 586 | if (file.getIndex() != self.index) continue; |
| 587 | 587 | const idx = global.getOutputSymtabIndex(macho_file) orelse continue; |
| 588 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 589 | macho_file.strtab.appendSliceAssumeCapacity(global.getName(macho_file)); | |
| 590 | macho_file.strtab.appendAssumeCapacity(0); | |
| 591 | const out_sym = &macho_file.symtab.items[idx]; | |
| 588 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 589 | ctx.strtab.appendSliceAssumeCapacity(global.getName(macho_file)); | |
| 590 | ctx.strtab.appendAssumeCapacity(0); | |
| 591 | const out_sym = &ctx.symtab.items[idx]; | |
| 592 | 592 | out_sym.n_strx = n_strx; |
| 593 | 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 | 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 | 143 | for (self.symbols.items) |sym_index| { |
| 144 | 144 | const sym = macho_file.getSymbol(sym_index); |
| 145 | 145 | if (sym.getFile(macho_file)) |file| if (file.getIndex() != self.index) continue; |
| 146 | 146 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 147 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 148 | macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | |
| 149 | macho_file.strtab.appendAssumeCapacity(0); | |
| 150 | const out_sym = &macho_file.symtab.items[idx]; | |
| 147 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 148 | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | |
| 149 | ctx.strtab.appendAssumeCapacity(0); | |
| 150 | const out_sym = &ctx.symtab.items[idx]; | |
| 151 | 151 | out_sym.n_strx = n_strx; |
| 152 | 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 | 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 | 1324 | const tracy = trace(@src()); |
| 1325 | 1325 | defer tracy.end(); |
| 1326 | 1326 | |
| ... | ... | @@ -1329,19 +1329,19 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) error{Overflow}!void { |
| 1329 | 1329 | const file = sym.getFile(macho_file) orelse continue; |
| 1330 | 1330 | if (file.getIndex() != self.index) continue; |
| 1331 | 1331 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 1332 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 1333 | macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | |
| 1334 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1335 | const out_sym = &macho_file.symtab.items[idx]; | |
| 1332 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 1333 | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | |
| 1334 | ctx.strtab.appendAssumeCapacity(0); | |
| 1335 | const out_sym = &ctx.symtab.items[idx]; | |
| 1336 | 1336 | out_sym.n_strx = n_strx; |
| 1337 | 1337 | sym.setOutputSym(macho_file, out_sym); |
| 1338 | 1338 | } |
| 1339 | 1339 | |
| 1340 | 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 | 1345 | const writeFuncStab = struct { |
| 1346 | 1346 | inline fn writeFuncStab( |
| 1347 | 1347 | n_strx: u32, |
| ... | ... | @@ -1349,30 +1349,30 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1349 | 1349 | n_value: u64, |
| 1350 | 1350 | size: u64, |
| 1351 | 1351 | index: u32, |
| 1352 | ctx: *MachO, | |
| 1352 | context: anytype, | |
| 1353 | 1353 | ) void { |
| 1354 | ctx.symtab.items[index] = .{ | |
| 1354 | context.symtab.items[index] = .{ | |
| 1355 | 1355 | .n_strx = 0, |
| 1356 | 1356 | .n_type = macho.N_BNSYM, |
| 1357 | 1357 | .n_sect = n_sect, |
| 1358 | 1358 | .n_desc = 0, |
| 1359 | 1359 | .n_value = n_value, |
| 1360 | 1360 | }; |
| 1361 | ctx.symtab.items[index + 1] = .{ | |
| 1361 | context.symtab.items[index + 1] = .{ | |
| 1362 | 1362 | .n_strx = n_strx, |
| 1363 | 1363 | .n_type = macho.N_FUN, |
| 1364 | 1364 | .n_sect = n_sect, |
| 1365 | 1365 | .n_desc = 0, |
| 1366 | 1366 | .n_value = n_value, |
| 1367 | 1367 | }; |
| 1368 | ctx.symtab.items[index + 2] = .{ | |
| 1368 | context.symtab.items[index + 2] = .{ | |
| 1369 | 1369 | .n_strx = 0, |
| 1370 | 1370 | .n_type = macho.N_FUN, |
| 1371 | 1371 | .n_sect = 0, |
| 1372 | 1372 | .n_desc = 0, |
| 1373 | 1373 | .n_value = size, |
| 1374 | 1374 | }; |
| 1375 | ctx.symtab.items[index + 3] = .{ | |
| 1375 | context.symtab.items[index + 3] = .{ | |
| 1376 | 1376 | .n_strx = 0, |
| 1377 | 1377 | .n_type = macho.N_ENSYM, |
| 1378 | 1378 | .n_sect = n_sect, |
| ... | ... | @@ -1392,10 +1392,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1392 | 1392 | |
| 1393 | 1393 | // Open scope |
| 1394 | 1394 | // N_SO comp_dir |
| 1395 | var n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 1396 | macho_file.strtab.appendSliceAssumeCapacity(comp_dir); | |
| 1397 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1398 | macho_file.symtab.items[index] = .{ | |
| 1395 | var n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 1396 | ctx.strtab.appendSliceAssumeCapacity(comp_dir); | |
| 1397 | ctx.strtab.appendAssumeCapacity(0); | |
| 1398 | ctx.symtab.items[index] = .{ | |
| 1399 | 1399 | .n_strx = n_strx, |
| 1400 | 1400 | .n_type = macho.N_SO, |
| 1401 | 1401 | .n_sect = 0, |
| ... | ... | @@ -1404,10 +1404,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1404 | 1404 | }; |
| 1405 | 1405 | index += 1; |
| 1406 | 1406 | // N_SO tu_name |
| 1407 | n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 1408 | macho_file.strtab.appendSliceAssumeCapacity(tu_name); | |
| 1409 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1410 | macho_file.symtab.items[index] = .{ | |
| 1407 | n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 1408 | ctx.strtab.appendSliceAssumeCapacity(tu_name); | |
| 1409 | ctx.strtab.appendAssumeCapacity(0); | |
| 1410 | ctx.symtab.items[index] = .{ | |
| 1411 | 1411 | .n_strx = n_strx, |
| 1412 | 1412 | .n_type = macho.N_SO, |
| 1413 | 1413 | .n_sect = 0, |
| ... | ... | @@ -1416,18 +1416,18 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1416 | 1416 | }; |
| 1417 | 1417 | index += 1; |
| 1418 | 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 | 1420 | if (self.archive) |ar| { |
| 1421 | macho_file.strtab.appendSliceAssumeCapacity(ar.path); | |
| 1422 | macho_file.strtab.appendAssumeCapacity('('); | |
| 1423 | macho_file.strtab.appendSliceAssumeCapacity(self.path); | |
| 1424 | macho_file.strtab.appendAssumeCapacity(')'); | |
| 1425 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1421 | ctx.strtab.appendSliceAssumeCapacity(ar.path); | |
| 1422 | ctx.strtab.appendAssumeCapacity('('); | |
| 1423 | ctx.strtab.appendSliceAssumeCapacity(self.path); | |
| 1424 | ctx.strtab.appendAssumeCapacity(')'); | |
| 1425 | ctx.strtab.appendAssumeCapacity(0); | |
| 1426 | 1426 | } else { |
| 1427 | macho_file.strtab.appendSliceAssumeCapacity(self.path); | |
| 1428 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1427 | ctx.strtab.appendSliceAssumeCapacity(self.path); | |
| 1428 | ctx.strtab.appendAssumeCapacity(0); | |
| 1429 | 1429 | } |
| 1430 | macho_file.symtab.items[index] = .{ | |
| 1430 | ctx.symtab.items[index] = .{ | |
| 1431 | 1431 | .n_strx = n_strx, |
| 1432 | 1432 | .n_type = macho.N_OSO, |
| 1433 | 1433 | .n_sect = 0, |
| ... | ... | @@ -1448,17 +1448,17 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1448 | 1448 | const sect = macho_file.sections.items(.header)[sym.out_n_sect]; |
| 1449 | 1449 | const sym_n_strx = n_strx: { |
| 1450 | 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 | 1452 | break :n_strx osym.n_strx; |
| 1453 | 1453 | }; |
| 1454 | 1454 | const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0; |
| 1455 | 1455 | const sym_n_value = sym.getAddress(.{}, macho_file); |
| 1456 | 1456 | const sym_size = sym.getSize(macho_file); |
| 1457 | 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 | 1459 | index += 4; |
| 1460 | 1460 | } else if (sym.visibility == .global) { |
| 1461 | macho_file.symtab.items[index] = .{ | |
| 1461 | ctx.symtab.items[index] = .{ | |
| 1462 | 1462 | .n_strx = sym_n_strx, |
| 1463 | 1463 | .n_type = macho.N_GSYM, |
| 1464 | 1464 | .n_sect = sym_n_sect, |
| ... | ... | @@ -1467,7 +1467,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1467 | 1467 | }; |
| 1468 | 1468 | index += 1; |
| 1469 | 1469 | } else { |
| 1470 | macho_file.symtab.items[index] = .{ | |
| 1470 | ctx.symtab.items[index] = .{ | |
| 1471 | 1471 | .n_strx = sym_n_strx, |
| 1472 | 1472 | .n_type = macho.N_STSYM, |
| 1473 | 1473 | .n_sect = sym_n_sect, |
| ... | ... | @@ -1480,7 +1480,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1480 | 1480 | |
| 1481 | 1481 | // Close scope |
| 1482 | 1482 | // N_SO |
| 1483 | macho_file.symtab.items[index] = .{ | |
| 1483 | ctx.symtab.items[index] = .{ | |
| 1484 | 1484 | .n_strx = 0, |
| 1485 | 1485 | .n_type = macho.N_SO, |
| 1486 | 1486 | .n_sect = 0, |
| ... | ... | @@ -1493,10 +1493,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1493 | 1493 | for (self.stab_files.items) |sf| { |
| 1494 | 1494 | // Open scope |
| 1495 | 1495 | // N_SO comp_dir |
| 1496 | var n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 1497 | macho_file.strtab.appendSliceAssumeCapacity(sf.getCompDir(self)); | |
| 1498 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1499 | macho_file.symtab.items[index] = .{ | |
| 1496 | var n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 1497 | ctx.strtab.appendSliceAssumeCapacity(sf.getCompDir(self)); | |
| 1498 | ctx.strtab.appendAssumeCapacity(0); | |
| 1499 | ctx.symtab.items[index] = .{ | |
| 1500 | 1500 | .n_strx = n_strx, |
| 1501 | 1501 | .n_type = macho.N_SO, |
| 1502 | 1502 | .n_sect = 0, |
| ... | ... | @@ -1505,10 +1505,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1505 | 1505 | }; |
| 1506 | 1506 | index += 1; |
| 1507 | 1507 | // N_SO tu_name |
| 1508 | n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 1509 | macho_file.strtab.appendSliceAssumeCapacity(sf.getTuName(self)); | |
| 1510 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1511 | macho_file.symtab.items[index] = .{ | |
| 1508 | n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 1509 | ctx.strtab.appendSliceAssumeCapacity(sf.getTuName(self)); | |
| 1510 | ctx.strtab.appendAssumeCapacity(0); | |
| 1511 | ctx.symtab.items[index] = .{ | |
| 1512 | 1512 | .n_strx = n_strx, |
| 1513 | 1513 | .n_type = macho.N_SO, |
| 1514 | 1514 | .n_sect = 0, |
| ... | ... | @@ -1517,10 +1517,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1517 | 1517 | }; |
| 1518 | 1518 | index += 1; |
| 1519 | 1519 | // N_OSO path |
| 1520 | n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 1521 | macho_file.strtab.appendSliceAssumeCapacity(sf.getOsoPath(self)); | |
| 1522 | macho_file.strtab.appendAssumeCapacity(0); | |
| 1523 | macho_file.symtab.items[index] = .{ | |
| 1520 | n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 1521 | ctx.strtab.appendSliceAssumeCapacity(sf.getOsoPath(self)); | |
| 1522 | ctx.strtab.appendAssumeCapacity(0); | |
| 1523 | ctx.symtab.items[index] = .{ | |
| 1524 | 1524 | .n_strx = n_strx, |
| 1525 | 1525 | .n_type = macho.N_OSO, |
| 1526 | 1526 | .n_sect = 0, |
| ... | ... | @@ -1536,7 +1536,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1536 | 1536 | if (!sym.flags.output_symtab) continue; |
| 1537 | 1537 | const sym_n_strx = n_strx: { |
| 1538 | 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 | 1540 | break :n_strx osym.n_strx; |
| 1541 | 1541 | }; |
| 1542 | 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 | 1544 | const sym_size = sym.getSize(macho_file); |
| 1545 | 1545 | switch (stab.tag) { |
| 1546 | 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 | 1548 | index += 4; |
| 1549 | 1549 | }, |
| 1550 | 1550 | .global => { |
| 1551 | macho_file.symtab.items[index] = .{ | |
| 1551 | ctx.symtab.items[index] = .{ | |
| 1552 | 1552 | .n_strx = sym_n_strx, |
| 1553 | 1553 | .n_type = macho.N_GSYM, |
| 1554 | 1554 | .n_sect = sym_n_sect, |
| ... | ... | @@ -1558,7 +1558,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1558 | 1558 | index += 1; |
| 1559 | 1559 | }, |
| 1560 | 1560 | .static => { |
| 1561 | macho_file.symtab.items[index] = .{ | |
| 1561 | ctx.symtab.items[index] = .{ | |
| 1562 | 1562 | .n_strx = sym_n_strx, |
| 1563 | 1563 | .n_type = macho.N_STSYM, |
| 1564 | 1564 | .n_sect = sym_n_sect, |
| ... | ... | @@ -1572,7 +1572,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void |
| 1572 | 1572 | |
| 1573 | 1573 | // Close scope |
| 1574 | 1574 | // N_SO |
| 1575 | macho_file.symtab.items[index] = .{ | |
| 1575 | ctx.symtab.items[index] = .{ | |
| 1576 | 1576 | .n_strx = 0, |
| 1577 | 1577 | .n_type = macho.N_SO, |
| 1578 | 1578 | .n_sect = 0, |
src/link/MachO/ZigObject.zig+5-5| ... | ... | @@ -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 | 314 | const tracy = trace(@src()); |
| 315 | 315 | defer tracy.end(); |
| 316 | 316 | |
| ... | ... | @@ -319,10 +319,10 @@ pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void { |
| 319 | 319 | const file = sym.getFile(macho_file) orelse continue; |
| 320 | 320 | if (file.getIndex() != self.index) continue; |
| 321 | 321 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 322 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | |
| 323 | macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | |
| 324 | macho_file.strtab.appendAssumeCapacity(0); | |
| 325 | const out_sym = &macho_file.symtab.items[idx]; | |
| 322 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | |
| 323 | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | |
| 324 | ctx.strtab.appendAssumeCapacity(0); | |
| 325 | const out_sym = &ctx.symtab.items[idx]; | |
| 326 | 326 | out_sym.n_strx = n_strx; |
| 327 | 327 | sym.setOutputSym(macho_file, out_sym); |
| 328 | 328 | } |
src/link/MachO/file.zig+2-2| ... | ... | @@ -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 | 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 | 5 | const mem = std.mem; |
| 6 | 6 | |
| 7 | 7 | const Allocator = mem.Allocator; |
| 8 | const DebugSymbols = @import("DebugSymbols.zig"); | |
| 8 | 9 | const Dylib = @import("Dylib.zig"); |
| 9 | 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 | 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 | 122 | pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 { |
| 101 | 123 | var sizeofcmds: u64 = 0; |
| 102 | 124 |