authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-22 09:37:32+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-22 12:06:02+02:00
log06a0da3e8a34d12de7adece6223d4235c4673aaf
treefc13aa129468878e74c8c0ce19c565dac78b65fb
parent79fefec599fd940adfd611c9da880c01e2aa842c

macho: cache string len


7 files changed, 93 insertions(+), 73 deletions(-)

src/link/MachO.zig+5
...@@ -4578,6 +4578,11 @@ pub const SymbolResolver = struct {...@@ -4578,6 +4578,11 @@ pub const SymbolResolver = struct {
4578 pub const Index = u32;4578 pub const Index = u32;
4579};4579};
45804580
4581pub const String = struct {
4582 pos: u32 = 0,
4583 len: u32 = 0,
4584};
4585
4581const MachO = @This();4586const MachO = @This();
45824587
4583const std = @import("std");4588const std = @import("std");
src/link/MachO/Atom.zig+2-2
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2value: u64 = 0,2value: u64 = 0,
33
4/// Name of this Atom.4/// Name of this Atom.
5name: u32 = 0,5name: MachO.String = .{},
66
7/// Index into linker's input file table.7/// Index into linker's input file table.
8file: File.Index = 0,8file: File.Index = 0,
...@@ -42,7 +42,7 @@ extra: u32 = 0,...@@ -42,7 +42,7 @@ extra: u32 = 0,
42pub fn getName(self: Atom, macho_file: *MachO) [:0]const u8 {42pub fn getName(self: Atom, macho_file: *MachO) [:0]const u8 {
43 return switch (self.getFile(macho_file)) {43 return switch (self.getFile(macho_file)) {
44 .dylib => unreachable,44 .dylib => unreachable,
45 .zig_object => |x| x.strtab.getAssumeExists(self.name),45 .zig_object => |x| x.strtab.buffer.items[self.name.pos..][0 .. self.name.len - 1 :0],
46 inline else => |x| x.getString(self.name),46 inline else => |x| x.getString(self.name),
47 };47 };
48}48}
src/link/MachO/Dylib.zig+10-7
...@@ -610,15 +610,18 @@ pub inline fn getUmbrella(self: Dylib, macho_file: *MachO) *Dylib {...@@ -610,15 +610,18 @@ pub inline fn getUmbrella(self: Dylib, macho_file: *MachO) *Dylib {
610 return macho_file.getFile(self.umbrella).?.dylib;610 return macho_file.getFile(self.umbrella).?.dylib;
611}611}
612612
613fn addString(self: *Dylib, allocator: Allocator, name: []const u8) !u32 {613fn addString(self: *Dylib, allocator: Allocator, name: []const u8) !MachO.String {
614 const off = @as(u32, @intCast(self.strtab.items.len));614 const off = @as(u32, @intCast(self.strtab.items.len));
615 try self.strtab.writer(allocator).print("{s}\x00", .{name});615 try self.strtab.ensureUnusedCapacity(allocator, name.len + 1);
616 return off;616 self.strtab.appendSliceAssumeCapacity(name);
617 self.strtab.appendAssumeCapacity(0);
618 return .{ .pos = off, .len = @intCast(name.len + 1) };
617}619}
618620
619pub fn getString(self: Dylib, off: u32) [:0]const u8 {621pub fn getString(self: Dylib, string: MachO.String) [:0]const u8 {
620 assert(off < self.strtab.items.len);622 assert(string.pos < self.strtab.items.len and string.pos + string.len <= self.strtab.items.len);
621 return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0);623 if (string.len == 0) return "";
624 return self.strtab.items[string.pos..][0 .. string.len - 1 :0];
622}625}
623626
624pub fn asFile(self: *Dylib) File {627pub fn asFile(self: *Dylib) File {
...@@ -932,7 +935,7 @@ pub const Id = struct {...@@ -932,7 +935,7 @@ pub const Id = struct {
932};935};
933936
934const Export = struct {937const Export = struct {
935 name: u32,938 name: MachO.String,
936 flags: Flags,939 flags: Flags,
937940
938 const Flags = packed struct {941 const Flags = packed struct {
src/link/MachO/InternalObject.zig+17-16
...@@ -53,7 +53,7 @@ pub fn init(self: *InternalObject, allocator: Allocator) !void {...@@ -53,7 +53,7 @@ pub fn init(self: *InternalObject, allocator: Allocator) !void {
5353
54pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {54pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
55 const newSymbolAssumeCapacity = struct {55 const newSymbolAssumeCapacity = struct {
56 fn newSymbolAssumeCapacity(obj: *InternalObject, name: u32, args: struct {56 fn newSymbolAssumeCapacity(obj: *InternalObject, name: MachO.String, args: struct {
57 type: u8 = macho.N_UNDF | macho.N_EXT,57 type: u8 = macho.N_UNDF | macho.N_EXT,
58 desc: u16 = 0,58 desc: u16 = 0,
59 }) Symbol.Index {59 }) Symbol.Index {
...@@ -69,7 +69,7 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {...@@ -69,7 +69,7 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
69 const nlist_idx: u32 = @intCast(obj.symtab.items.len);69 const nlist_idx: u32 = @intCast(obj.symtab.items.len);
70 const nlist = obj.symtab.addOneAssumeCapacity();70 const nlist = obj.symtab.addOneAssumeCapacity();
71 nlist.* = .{71 nlist.* = .{
72 .n_strx = name,72 .n_strx = name.pos,
73 .n_type = args.type,73 .n_type = args.type,
74 .n_sect = 0,74 .n_sect = 0,
75 .n_desc = args.desc,75 .n_desc = args.desc,
...@@ -197,16 +197,16 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void {...@@ -197,16 +197,16 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void {
197 try self.globals.ensureUnusedCapacity(gpa, nsyms);197 try self.globals.ensureUnusedCapacity(gpa, nsyms);
198198
199 for (boundary_symbols.keys(), boundary_symbols.values()) |name, ref| {199 for (boundary_symbols.keys(), boundary_symbols.values()) |name, ref| {
200 const name_off = try self.addString(gpa, name);200 const name_str = try self.addString(gpa, name);
201 const sym_index = self.addSymbolAssumeCapacity();201 const sym_index = self.addSymbolAssumeCapacity();
202 self.boundary_symbols.appendAssumeCapacity(sym_index);202 self.boundary_symbols.appendAssumeCapacity(sym_index);
203 const sym = &self.symbols.items[sym_index];203 const sym = &self.symbols.items[sym_index];
204 sym.name = name_off;204 sym.name = name_str;
205 sym.visibility = .local;205 sym.visibility = .local;
206 const nlist_idx: u32 = @intCast(self.symtab.items.len);206 const nlist_idx: u32 = @intCast(self.symtab.items.len);
207 const nlist = self.symtab.addOneAssumeCapacity();207 const nlist = self.symtab.addOneAssumeCapacity();
208 nlist.* = .{208 nlist.* = .{
209 .n_strx = name_off,209 .n_strx = name_str.pos,
210 .n_type = macho.N_SECT,210 .n_type = macho.N_SECT,
211 .n_sect = 0,211 .n_sect = 0,
212 .n_desc = 0,212 .n_desc = 0,
...@@ -273,7 +273,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil...@@ -273,7 +273,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
273 const nlist_idx: u32 = @intCast(self.symtab.items.len);273 const nlist_idx: u32 = @intCast(self.symtab.items.len);
274 const nlist = try self.symtab.addOne(gpa);274 const nlist = try self.symtab.addOne(gpa);
275 nlist.* = .{275 nlist.* = .{
276 .n_strx = name_str,276 .n_strx = name_str.pos,
277 .n_type = macho.N_SECT,277 .n_type = macho.N_SECT,
278 .n_sect = @intCast(n_sect + 1),278 .n_sect = @intCast(n_sect + 1),
279 .n_desc = 0,279 .n_desc = 0,
...@@ -373,15 +373,15 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi...@@ -373,15 +373,15 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi
373 const name = MachO.eatPrefix(sym_name, "_objc_msgSend$").?;373 const name = MachO.eatPrefix(sym_name, "_objc_msgSend$").?;
374 const selrefs_index = try self.addObjcMsgsendSections(name, macho_file);374 const selrefs_index = try self.addObjcMsgsendSections(name, macho_file);
375375
376 const name_off = try self.addString(gpa, sym_name);376 const name_str = try self.addString(gpa, sym_name);
377 const sym_index = try self.addSymbol(gpa);377 const sym_index = try self.addSymbol(gpa);
378 const sym = &self.symbols.items[sym_index];378 const sym = &self.symbols.items[sym_index];
379 sym.name = name_off;379 sym.name = name_str;
380 sym.visibility = .hidden;380 sym.visibility = .hidden;
381 const nlist_idx: u32 = @intCast(self.symtab.items.len);381 const nlist_idx: u32 = @intCast(self.symtab.items.len);
382 const nlist = try self.symtab.addOne(gpa);382 const nlist = try self.symtab.addOne(gpa);
383 nlist.* = .{383 nlist.* = .{
384 .n_strx = name_off,384 .n_strx = name_str.pos,
385 .n_type = macho.N_SECT | macho.N_EXT | macho.N_PEXT,385 .n_type = macho.N_SECT | macho.N_EXT | macho.N_PEXT,
386 .n_sect = 0,386 .n_sect = 0,
387 .n_desc = 0,387 .n_desc = 0,
...@@ -624,17 +624,18 @@ fn getSectionData(self: *const InternalObject, index: u32) error{Overflow}![]con...@@ -624,17 +624,18 @@ fn getSectionData(self: *const InternalObject, index: u32) error{Overflow}![]con
624 @panic("ref to non-existent section");624 @panic("ref to non-existent section");
625}625}
626626
627pub fn addString(self: *InternalObject, allocator: Allocator, name: []const u8) !u32 {627pub fn addString(self: *InternalObject, allocator: Allocator, string: []const u8) !MachO.String {
628 const off: u32 = @intCast(self.strtab.items.len);628 const off: u32 = @intCast(self.strtab.items.len);
629 try self.strtab.ensureUnusedCapacity(allocator, name.len + 1);629 try self.strtab.ensureUnusedCapacity(allocator, string.len + 1);
630 self.strtab.appendSliceAssumeCapacity(name);630 self.strtab.appendSliceAssumeCapacity(string);
631 self.strtab.appendAssumeCapacity(0);631 self.strtab.appendAssumeCapacity(0);
632 return off;632 return .{ .pos = off, .len = @intCast(string.len + 1) };
633}633}
634634
635pub fn getString(self: InternalObject, off: u32) [:0]const u8 {635pub fn getString(self: InternalObject, string: MachO.String) [:0]const u8 {
636 assert(off < self.strtab.items.len);636 assert(string.pos < self.strtab.items.len and string.pos + string.len <= self.strtab.items.len);
637 return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0);637 if (string.len == 0) return "";
638 return self.strtab.items[string.pos..][0 .. string.len - 1 :0];
638}639}
639640
640pub fn asFile(self: *InternalObject) File {641pub fn asFile(self: *InternalObject) File {
src/link/MachO/Object.zig+30-24
...@@ -178,7 +178,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -178,7 +178,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
178178
179 fn rank(ctx: *const Object, nl: macho.nlist_64) u8 {179 fn rank(ctx: *const Object, nl: macho.nlist_64) u8 {
180 if (!nl.ext()) {180 if (!nl.ext()) {
181 const name = ctx.getString(nl.n_strx);181 const name = ctx.getNStrx(nl.n_strx);
182 if (name.len == 0) return 5;182 if (name.len == 0) return 5;
183 if (name[0] == 'l' or name[0] == 'L') return 4;183 if (name[0] == 'l' or name[0] == 'L') return 4;
184 return 3;184 return 3;
...@@ -341,7 +341,7 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void {...@@ -341,7 +341,7 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void {
341 else341 else
342 sect.@"align";342 sect.@"align";
343 const atom_index = try self.addAtom(allocator, .{343 const atom_index = try self.addAtom(allocator, .{
344 .name = nlist.nlist.n_strx,344 .name = .{ .pos = nlist.nlist.n_strx, .len = @intCast(self.getNStrx(nlist.nlist.n_strx).len + 1) },
345 .n_sect = @intCast(n_sect),345 .n_sect = @intCast(n_sect),
346 .off = nlist.nlist.n_value - sect.addr,346 .off = nlist.nlist.n_value - sect.addr,
347 .size = size,347 .size = size,
...@@ -465,7 +465,7 @@ fn initCstringLiterals(self: *Object, allocator: Allocator, file: File.Handle, m...@@ -465,7 +465,7 @@ fn initCstringLiterals(self: *Object, allocator: Allocator, file: File.Handle, m
465 const nlist_index: u32 = @intCast(try self.symtab.addOne(allocator));465 const nlist_index: u32 = @intCast(try self.symtab.addOne(allocator));
466 self.symtab.set(nlist_index, .{466 self.symtab.set(nlist_index, .{
467 .nlist = .{467 .nlist = .{
468 .n_strx = name_str,468 .n_strx = name_str.pos,
469 .n_type = macho.N_SECT,469 .n_type = macho.N_SECT,
470 .n_sect = @intCast(atom.n_sect + 1),470 .n_sect = @intCast(atom.n_sect + 1),
471 .n_desc = 0,471 .n_desc = 0,
...@@ -532,7 +532,7 @@ fn initFixedSizeLiterals(self: *Object, allocator: Allocator, macho_file: *MachO...@@ -532,7 +532,7 @@ fn initFixedSizeLiterals(self: *Object, allocator: Allocator, macho_file: *MachO
532 const nlist_index: u32 = @intCast(try self.symtab.addOne(allocator));532 const nlist_index: u32 = @intCast(try self.symtab.addOne(allocator));
533 self.symtab.set(nlist_index, .{533 self.symtab.set(nlist_index, .{
534 .nlist = .{534 .nlist = .{
535 .n_strx = name_str,535 .n_strx = name_str.pos,
536 .n_type = macho.N_SECT,536 .n_type = macho.N_SECT,
537 .n_sect = @intCast(atom.n_sect + 1),537 .n_sect = @intCast(atom.n_sect + 1),
538 .n_desc = 0,538 .n_desc = 0,
...@@ -590,7 +590,7 @@ fn initPointerLiterals(self: *Object, allocator: Allocator, macho_file: *MachO)...@@ -590,7 +590,7 @@ fn initPointerLiterals(self: *Object, allocator: Allocator, macho_file: *MachO)
590 const nlist_index: u32 = @intCast(try self.symtab.addOne(allocator));590 const nlist_index: u32 = @intCast(try self.symtab.addOne(allocator));
591 self.symtab.set(nlist_index, .{591 self.symtab.set(nlist_index, .{
592 .nlist = .{592 .nlist = .{
593 .n_strx = name_str,593 .n_strx = name_str.pos,
594 .n_type = macho.N_SECT,594 .n_type = macho.N_SECT,
595 .n_sect = @intCast(atom.n_sect + 1),595 .n_sect = @intCast(atom.n_sect + 1),
596 .n_desc = 0,596 .n_desc = 0,
...@@ -796,7 +796,7 @@ fn linkNlistToAtom(self: *Object, macho_file: *MachO) !void {...@@ -796,7 +796,7 @@ fn linkNlistToAtom(self: *Object, macho_file: *MachO) !void {
796 atom.* = atom_index;796 atom.* = atom_index;
797 } else {797 } else {
798 try macho_file.reportParseError2(self.index, "symbol {s} not attached to any (sub)section", .{798 try macho_file.reportParseError2(self.index, "symbol {s} not attached to any (sub)section", .{
799 self.getString(nlist.n_strx),799 self.getNStrx(nlist.n_strx),
800 });800 });
801 return error.MalformedObject;801 return error.MalformedObject;
802 }802 }
...@@ -821,7 +821,7 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {...@@ -821,7 +821,7 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {
821 const index = self.addSymbolAssumeCapacity();821 const index = self.addSymbolAssumeCapacity();
822 const symbol = &self.symbols.items[index];822 const symbol = &self.symbols.items[index];
823 symbol.value = nlist.n_value;823 symbol.value = nlist.n_value;
824 symbol.name = nlist.n_strx;824 symbol.name = .{ .pos = nlist.n_strx, .len = @intCast(self.getNStrx(nlist.n_strx).len + 1) };
825 symbol.nlist_idx = @intCast(i);825 symbol.nlist_idx = @intCast(i);
826 symbol.extra = self.addSymbolExtraAssumeCapacity(.{});826 symbol.extra = self.addSymbolExtraAssumeCapacity(.{});
827827
...@@ -894,7 +894,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f...@@ -894,7 +894,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
894 defer addr_lookup.deinit();894 defer addr_lookup.deinit();
895 for (syms) |sym| {895 for (syms) |sym| {
896 if (sym.sect() and (sym.ext() or sym.pext())) {896 if (sym.sect() and (sym.ext() or sym.pext())) {
897 try addr_lookup.putNoClobber(self.getString(sym.n_strx), sym.n_value);897 try addr_lookup.putNoClobber(self.getNStrx(sym.n_strx), sym.n_value);
898 }898 }
899 }899 }
900900
...@@ -926,7 +926,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f...@@ -926,7 +926,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
926 },926 },
927 macho.N_GSYM => {927 macho.N_GSYM => {
928 stab.is_func = false;928 stab.is_func = false;
929 stab.index = sym_lookup.find(addr_lookup.get(self.getString(nlist.n_strx)).?);929 stab.index = sym_lookup.find(addr_lookup.get(self.getNStrx(nlist.n_strx)).?);
930 },930 },
931 macho.N_STSYM => {931 macho.N_STSYM => {
932 stab.is_func = false;932 stab.is_func = false;
...@@ -1708,7 +1708,7 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *M...@@ -1708,7 +1708,7 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *M
1708 const gpa = macho_file.base.comp.gpa;1708 const gpa = macho_file.base.comp.gpa;
1709 for (self.symtab.items(.nlist)) |nlist| {1709 for (self.symtab.items(.nlist)) |nlist| {
1710 if (!nlist.ext() or (nlist.undf() and !nlist.tentative())) continue;1710 if (!nlist.ext() or (nlist.undf() and !nlist.tentative())) continue;
1711 const off = try ar_symtab.strtab.insert(gpa, self.getString(nlist.n_strx));1711 const off = try ar_symtab.strtab.insert(gpa, self.getNStrx(nlist.n_strx));
1712 try ar_symtab.entries.append(gpa, .{ .off = off, .file = self.index });1712 try ar_symtab.entries.append(gpa, .{ .off = off, .file = self.index });
1713 }1713 }
1714}1714}
...@@ -2292,17 +2292,23 @@ pub fn getAtomRelocs(self: *const Object, atom: Atom, macho_file: *MachO) []cons...@@ -2292,17 +2292,23 @@ pub fn getAtomRelocs(self: *const Object, atom: Atom, macho_file: *MachO) []cons
2292 return relocs.items[extra.rel_index..][0..extra.rel_count];2292 return relocs.items[extra.rel_index..][0..extra.rel_count];
2293}2293}
22942294
2295fn addString(self: *Object, allocator: Allocator, name: [:0]const u8) error{OutOfMemory}!u32 {2295fn addString(self: *Object, allocator: Allocator, string: [:0]const u8) error{OutOfMemory}!MachO.String {
2296 const off: u32 = @intCast(self.strtab.items.len);2296 const off: u32 = @intCast(self.strtab.items.len);
2297 try self.strtab.ensureUnusedCapacity(allocator, name.len + 1);2297 try self.strtab.ensureUnusedCapacity(allocator, string.len + 1);
2298 self.strtab.appendSliceAssumeCapacity(name);2298 self.strtab.appendSliceAssumeCapacity(string);
2299 self.strtab.appendAssumeCapacity(0);2299 self.strtab.appendAssumeCapacity(0);
2300 return off;2300 return .{ .pos = off, .len = @intCast(string.len + 1) };
2301}2301}
23022302
2303pub fn getString(self: Object, off: u32) [:0]const u8 {2303pub fn getString(self: Object, string: MachO.String) [:0]const u8 {
2304 assert(off < self.strtab.items.len);2304 assert(string.pos < self.strtab.items.len and string.pos + string.len <= self.strtab.items.len);
2305 return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0);2305 if (string.len == 0) return "";
2306 return self.strtab.items[string.pos..][0 .. string.len - 1 :0];
2307}
2308
2309fn getNStrx(self: Object, n_strx: u32) [:0]const u8 {
2310 assert(n_strx < self.strtab.items.len);
2311 return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + n_strx)), 0);
2306}2312}
23072313
2308pub fn hasUnwindRecords(self: Object) bool {2314pub fn hasUnwindRecords(self: Object) bool {
...@@ -2323,7 +2329,7 @@ fn hasSymbolStabs(self: Object) bool {...@@ -2323,7 +2329,7 @@ fn hasSymbolStabs(self: Object) bool {
23232329
2324fn hasObjC(self: Object) bool {2330fn hasObjC(self: Object) bool {
2325 for (self.symtab.items(.nlist)) |nlist| {2331 for (self.symtab.items(.nlist)) |nlist| {
2326 const name = self.getString(nlist.n_strx);2332 const name = self.getNStrx(nlist.n_strx);
2327 if (mem.startsWith(u8, name, "_OBJC_CLASS_$_")) return true;2333 if (mem.startsWith(u8, name, "_OBJC_CLASS_$_")) return true;
2328 }2334 }
2329 for (self.sections.items(.header)) |sect| {2335 for (self.sections.items(.header)) |sect| {
...@@ -2346,7 +2352,7 @@ pub fn asFile(self: *Object) File {...@@ -2346,7 +2352,7 @@ pub fn asFile(self: *Object) File {
2346}2352}
23472353
2348const AddAtomArgs = struct {2354const AddAtomArgs = struct {
2349 name: u32,2355 name: MachO.String,
2350 n_sect: u8,2356 n_sect: u8,
2351 off: u64,2357 off: u64,
2352 size: u64,2358 size: u64,
...@@ -2690,17 +2696,17 @@ const StabFile = struct {...@@ -2690,17 +2696,17 @@ const StabFile = struct {
26902696
2691 fn getCompDir(sf: StabFile, object: Object) [:0]const u8 {2697 fn getCompDir(sf: StabFile, object: Object) [:0]const u8 {
2692 const nlist = object.symtab.items(.nlist)[sf.comp_dir];2698 const nlist = object.symtab.items(.nlist)[sf.comp_dir];
2693 return object.getString(nlist.n_strx);2699 return object.getNStrx(nlist.n_strx);
2694 }2700 }
26952701
2696 fn getTuName(sf: StabFile, object: Object) [:0]const u8 {2702 fn getTuName(sf: StabFile, object: Object) [:0]const u8 {
2697 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 1];2703 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 1];
2698 return object.getString(nlist.n_strx);2704 return object.getNStrx(nlist.n_strx);
2699 }2705 }
27002706
2701 fn getOsoPath(sf: StabFile, object: Object) [:0]const u8 {2707 fn getOsoPath(sf: StabFile, object: Object) [:0]const u8 {
2702 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];2708 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];
2703 return object.getString(nlist.n_strx);2709 return object.getNStrx(nlist.n_strx);
2704 }2710 }
27052711
2706 fn getOsoModTime(sf: StabFile, object: Object) u64 {2712 fn getOsoModTime(sf: StabFile, object: Object) u64 {
...@@ -2758,8 +2764,8 @@ const StabFile = struct {...@@ -2758,8 +2764,8 @@ const StabFile = struct {
2758};2764};
27592765
2760const CompileUnit = struct {2766const CompileUnit = struct {
2761 comp_dir: u32,2767 comp_dir: MachO.String,
2762 tu_name: u32,2768 tu_name: MachO.String,
27632769
2764 fn getCompDir(cu: CompileUnit, object: Object) [:0]const u8 {2770 fn getCompDir(cu: CompileUnit, object: Object) [:0]const u8 {
2765 return object.getString(cu.comp_dir);2771 return object.getString(cu.comp_dir);
src/link/MachO/Symbol.zig+2-2
...@@ -4,7 +4,7 @@...@@ -4,7 +4,7 @@
4value: u64 = 0,4value: u64 = 0,
55
6/// Offset into the linker's intern table.6/// Offset into the linker's intern table.
7name: u32 = 0,7name: MachO.String = .{},
88
9/// File where this symbol is defined.9/// File where this symbol is defined.
10file: File.Index = 0,10file: File.Index = 0,
...@@ -57,7 +57,7 @@ pub fn weakRef(symbol: Symbol, macho_file: *MachO) bool {...@@ -57,7 +57,7 @@ pub fn weakRef(symbol: Symbol, macho_file: *MachO) bool {
5757
58pub fn getName(symbol: Symbol, macho_file: *MachO) [:0]const u8 {58pub fn getName(symbol: Symbol, macho_file: *MachO) [:0]const u8 {
59 return switch (symbol.getFile(macho_file).?) {59 return switch (symbol.getFile(macho_file).?) {
60 .zig_object => |x| x.strtab.getAssumeExists(symbol.name),60 .zig_object => |x| x.strtab.buffer.items[symbol.name.pos..][0 .. symbol.name.len - 1 :0],
61 inline else => |x| x.getString(symbol.name),61 inline else => |x| x.getString(symbol.name),
62 };62 };
63}63}
src/link/MachO/ZigObject.zig+27-22
...@@ -141,7 +141,7 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -141,7 +141,7 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
141 }141 }
142}142}
143143
144fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct {144fn newSymbol(self: *ZigObject, allocator: Allocator, name: MachO.String, args: struct {
145 type: u8 = macho.N_UNDF | macho.N_EXT,145 type: u8 = macho.N_UNDF | macho.N_EXT,
146 desc: u16 = 0,146 desc: u16 = 0,
147}) !Symbol.Index {147}) !Symbol.Index {
...@@ -158,7 +158,7 @@ fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct {...@@ -158,7 +158,7 @@ fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct {
158 const nlist_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());158 const nlist_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());
159 self.symtab.set(nlist_idx, .{159 self.symtab.set(nlist_idx, .{
160 .nlist = .{160 .nlist = .{
161 .n_strx = name,161 .n_strx = name.pos,
162 .n_type = args.type,162 .n_type = args.type,
163 .n_sect = 0,163 .n_sect = 0,
164 .n_desc = args.desc,164 .n_desc = args.desc,
...@@ -174,7 +174,7 @@ fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct {...@@ -174,7 +174,7 @@ fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct {
174 return index;174 return index;
175}175}
176176
177fn newAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Atom.Index {177fn newAtom(self: *ZigObject, allocator: Allocator, name: MachO.String, macho_file: *MachO) !Atom.Index {
178 try self.atoms.ensureUnusedCapacity(allocator, 1);178 try self.atoms.ensureUnusedCapacity(allocator, 1);
179 try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra));179 try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra));
180 try self.atoms_indexes.ensureUnusedCapacity(allocator, 1);180 try self.atoms_indexes.ensureUnusedCapacity(allocator, 1);
...@@ -192,7 +192,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO...@@ -192,7 +192,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO
192 return index;192 return index;
193}193}
194194
195fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Symbol.Index {195fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name: MachO.String, macho_file: *MachO) !Symbol.Index {
196 const atom_index = try self.newAtom(allocator, name, macho_file);196 const atom_index = try self.newAtom(allocator, name, macho_file);
197 const sym_index = try self.newSymbol(allocator, name, .{ .type = macho.N_SECT });197 const sym_index = try self.newSymbol(allocator, name, .{ .type = macho.N_SECT });
198 const sym = &self.symbols.items[sym_index];198 const sym = &self.symbols.items[sym_index];
...@@ -992,10 +992,10 @@ fn updateDeclCode(...@@ -992,10 +992,10 @@ fn updateDeclCode(
992992
993 const sym_name = try std.fmt.allocPrintZ(gpa, "_{s}", .{decl.fqn.toSlice(ip)});993 const sym_name = try std.fmt.allocPrintZ(gpa, "_{s}", .{decl.fqn.toSlice(ip)});
994 defer gpa.free(sym_name);994 defer gpa.free(sym_name);
995 sym.name = try self.strtab.insert(gpa, sym_name);995 sym.name = try self.addString(gpa, sym_name);
996 atom.setAlive(true);996 atom.setAlive(true);
997 atom.name = sym.name;997 atom.name = sym.name;
998 nlist.n_strx = sym.name;998 nlist.n_strx = sym.name.pos;
999 nlist.n_type = macho.N_SECT;999 nlist.n_type = macho.N_SECT;
1000 nlist.n_sect = sect_index + 1;1000 nlist.n_sect = sect_index + 1;
1001 self.symtab.items(.size)[sym.nlist_idx] = code.len;1001 self.symtab.items(.size)[sym.nlist_idx] = code.len;
...@@ -1090,9 +1090,9 @@ fn createTlvInitializer(...@@ -1090,9 +1090,9 @@ fn createTlvInitializer(
1090 const gpa = macho_file.base.comp.gpa;1090 const gpa = macho_file.base.comp.gpa;
1091 const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name});1091 const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name});
1092 defer gpa.free(sym_name);1092 defer gpa.free(sym_name);
1093 const off = try self.strtab.insert(gpa, sym_name);1093 const string = try self.addString(gpa, sym_name);
10941094
1095 const sym_index = try self.newSymbolWithAtom(gpa, off, macho_file);1095 const sym_index = try self.newSymbolWithAtom(gpa, string, macho_file);
1096 const sym = &self.symbols.items[sym_index];1096 const sym = &self.symbols.items[sym_index];
1097 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];1097 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
1098 const atom = sym.getAtom(macho_file).?;1098 const atom = sym.getAtom(macho_file).?;
...@@ -1142,10 +1142,10 @@ fn createTlvDescriptor(...@@ -1142,10 +1142,10 @@ fn createTlvDescriptor(
1142 atom.out_n_sect = sect_index;1142 atom.out_n_sect = sect_index;
11431143
1144 sym.value = 0;1144 sym.value = 0;
1145 sym.name = try self.strtab.insert(gpa, name);1145 sym.name = try self.addString(gpa, name);
1146 atom.setAlive(true);1146 atom.setAlive(true);
1147 atom.name = sym.name;1147 atom.name = sym.name;
1148 nlist.n_strx = sym.name;1148 nlist.n_strx = sym.name.pos;
1149 nlist.n_sect = sect_index + 1;1149 nlist.n_sect = sect_index + 1;
1150 nlist.n_type = macho.N_SECT;1150 nlist.n_type = macho.N_SECT;
1151 nlist.n_value = 0;1151 nlist.n_value = 0;
...@@ -1296,8 +1296,8 @@ fn lowerConst(...@@ -1296,8 +1296,8 @@ fn lowerConst(
1296 var code_buffer = std.ArrayList(u8).init(gpa);1296 var code_buffer = std.ArrayList(u8).init(gpa);
1297 defer code_buffer.deinit();1297 defer code_buffer.deinit();
12981298
1299 const name_str_index = try self.strtab.insert(gpa, name);1299 const name_str = try self.addString(gpa, name);
1300 const sym_index = try self.newSymbolWithAtom(gpa, name_str_index, macho_file);1300 const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);
13011301
1302 const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{1302 const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{
1303 .none = {},1303 .none = {},
...@@ -1447,13 +1447,13 @@ fn updateLazySymbol(...@@ -1447,13 +1447,13 @@ fn updateLazySymbol(
1447 var code_buffer = std.ArrayList(u8).init(gpa);1447 var code_buffer = std.ArrayList(u8).init(gpa);
1448 defer code_buffer.deinit();1448 defer code_buffer.deinit();
14491449
1450 const name_str_index = blk: {1450 const name_str = blk: {
1451 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1451 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1452 @tagName(lazy_sym.kind),1452 @tagName(lazy_sym.kind),
1453 lazy_sym.ty.fmt(pt),1453 lazy_sym.ty.fmt(pt),
1454 });1454 });
1455 defer gpa.free(name);1455 defer gpa.free(name);
1456 break :blk try self.strtab.insert(gpa, name);1456 break :blk try self.addString(gpa, name);
1457 };1457 };
14581458
1459 const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;1459 const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
...@@ -1480,18 +1480,18 @@ fn updateLazySymbol(...@@ -1480,18 +1480,18 @@ fn updateLazySymbol(
1480 .const_data => macho_file.zig_const_sect_index.?,1480 .const_data => macho_file.zig_const_sect_index.?,
1481 };1481 };
1482 const sym = &self.symbols.items[symbol_index];1482 const sym = &self.symbols.items[symbol_index];
1483 sym.name = name_str_index;1483 sym.name = name_str;
1484 sym.out_n_sect = output_section_index;1484 sym.out_n_sect = output_section_index;
14851485
1486 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];1486 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
1487 nlist.n_strx = name_str_index;1487 nlist.n_strx = name_str.pos;
1488 nlist.n_type = macho.N_SECT;1488 nlist.n_type = macho.N_SECT;
1489 nlist.n_sect = output_section_index + 1;1489 nlist.n_sect = output_section_index + 1;
1490 self.symtab.items(.size)[sym.nlist_idx] = code.len;1490 self.symtab.items(.size)[sym.nlist_idx] = code.len;
14911491
1492 const atom = sym.getAtom(macho_file).?;1492 const atom = sym.getAtom(macho_file).?;
1493 atom.setAlive(true);1493 atom.setAlive(true);
1494 atom.name = name_str_index;1494 atom.name = name_str;
1495 atom.alignment = required_alignment;1495 atom.alignment = required_alignment;
1496 atom.size = code.len;1496 atom.size = code.len;
1497 atom.out_n_sect = output_section_index;1497 atom.out_n_sect = output_section_index;
...@@ -1553,10 +1553,10 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l...@@ -1553,10 +1553,10 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
1553 const gpa = macho_file.base.comp.gpa;1553 const gpa = macho_file.base.comp.gpa;
1554 const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});1554 const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
1555 defer gpa.free(sym_name);1555 defer gpa.free(sym_name);
1556 const off = try self.strtab.insert(gpa, sym_name);1556 const name_str = try self.addString(gpa, sym_name);
1557 const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);1557 const lookup_gop = try self.globals_lookup.getOrPut(gpa, name_str.pos);
1558 if (!lookup_gop.found_existing) {1558 if (!lookup_gop.found_existing) {
1559 const sym_index = try self.newSymbol(gpa, off, .{});1559 const sym_index = try self.newSymbol(gpa, name_str, .{});
1560 const sym = &self.symbols.items[sym_index];1560 const sym = &self.symbols.items[sym_index];
1561 lookup_gop.value_ptr.* = sym.nlist_idx;1561 lookup_gop.value_ptr.* = sym.nlist_idx;
1562 }1562 }
...@@ -1571,7 +1571,7 @@ pub fn getOrCreateMetadataForDecl(...@@ -1571,7 +1571,7 @@ pub fn getOrCreateMetadataForDecl(
1571 const gpa = macho_file.base.comp.gpa;1571 const gpa = macho_file.base.comp.gpa;
1572 const gop = try self.decls.getOrPut(gpa, decl_index);1572 const gop = try self.decls.getOrPut(gpa, decl_index);
1573 if (!gop.found_existing) {1573 if (!gop.found_existing) {
1574 const sym_index = try self.newSymbolWithAtom(gpa, 0, macho_file);1574 const sym_index = try self.newSymbolWithAtom(gpa, .{}, macho_file);
1575 const sym = &self.symbols.items[sym_index];1575 const sym = &self.symbols.items[sym_index];
1576 if (isThreadlocal(macho_file, decl_index)) {1576 if (isThreadlocal(macho_file, decl_index)) {
1577 sym.flags.tlv = true;1577 sym.flags.tlv = true;
...@@ -1609,7 +1609,7 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1609,7 +1609,7 @@ pub fn getOrCreateMetadataForLazySymbol(
1609 };1609 };
1610 switch (metadata.state.*) {1610 switch (metadata.state.*) {
1611 .unused => {1611 .unused => {
1612 const symbol_index = try self.newSymbolWithAtom(gpa, 0, macho_file);1612 const symbol_index = try self.newSymbolWithAtom(gpa, .{}, macho_file);
1613 const sym = &self.symbols.items[symbol_index];1613 const sym = &self.symbols.items[symbol_index];
1614 sym.setSectionFlags(.{ .needs_zig_got = true });1614 sym.setSectionFlags(.{ .needs_zig_got = true });
1615 metadata.symbol_index.* = symbol_index;1615 metadata.symbol_index.* = symbol_index;
...@@ -1762,6 +1762,11 @@ pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void {...@@ -1762,6 +1762,11 @@ pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void {
1762 }1762 }
1763}1763}
17641764
1765fn addString(self: *ZigObject, allocator: Allocator, string: []const u8) !MachO.String {
1766 const off = try self.strtab.insert(allocator, string);
1767 return .{ .pos = off, .len = @intCast(string.len + 1) };
1768}
1769
1765pub fn asFile(self: *ZigObject) File {1770pub fn asFile(self: *ZigObject) File {
1766 return .{ .zig_object = self };1771 return .{ .zig_object = self };
1767}1772}