aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig2
-rw-r--r--src/link/MachO/Dylib.zig22
-rw-r--r--src/link/MachO/Object.zig35
-rw-r--r--src/link/MachO/StringTable.zig34
-rw-r--r--src/link/MachO/Symbol.zig189
-rw-r--r--src/link/MachO/Zld.zig133
6 files changed, 231 insertions, 184 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 59cfab4292..8095366c15 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -724,7 +724,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
try fs.cwd().copyFile(the_object_path, fs.cwd(), full_out_path, .{});
}
} else {
- var zld = Zld.init(self.base.allocator);
+ var zld = try Zld.init(self.base.allocator);
defer {
zld.closeFiles();
zld.deinit();
diff --git a/src/link/MachO/Dylib.zig b/src/link/MachO/Dylib.zig
index 324c54d362..cfd5ae18d3 100644
--- a/src/link/MachO/Dylib.zig
+++ b/src/link/MachO/Dylib.zig
@@ -146,7 +146,12 @@ pub const CreateOpts = struct {
id: ?Id = null,
};
-pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u8, opts: CreateOpts) Error!?[]*Dylib {
+pub fn createAndParseFromPath(
+ allocator: *Allocator,
+ arch: Arch,
+ path: []const u8,
+ opts: CreateOpts,
+) Error!?[]*Dylib {
const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) {
error.FileNotFound => return null,
else => |e| return e,
@@ -505,18 +510,7 @@ pub fn parseDependentLibs(self: *Dylib, out: *std.ArrayList(*Dylib)) !void {
pub fn createProxy(self: *Dylib, sym_name: []const u8) !?*Symbol {
if (!self.symbols.contains(sym_name)) return null;
-
- const name = try self.allocator.dupe(u8, sym_name);
- const proxy = try self.allocator.create(Symbol.Proxy);
- errdefer self.allocator.destroy(proxy);
-
- proxy.* = .{
- .base = .{
- .@"type" = .proxy,
- .name = name,
- },
+ return Symbol.Proxy.new(self.allocator, sym_name, .{
.file = self,
- };
-
- return &proxy.base;
+ });
}
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig
index cb55dd1fd8..197c302316 100644
--- a/src/link/MachO/Object.zig
+++ b/src/link/MachO/Object.zig
@@ -9,12 +9,12 @@ const log = std.log.scoped(.object);
const macho = std.macho;
const mem = std.mem;
const reloc = @import("reloc.zig");
+const parseName = @import("Zld.zig").parseName;
const Allocator = mem.Allocator;
const Arch = std.Target.Cpu.Arch;
const Relocation = reloc.Relocation;
const Symbol = @import("Symbol.zig");
-const parseName = @import("Zld.zig").parseName;
usingnamespace @import("commands.zig");
@@ -437,47 +437,26 @@ pub fn parseSymbols(self: *Object) !void {
if (Symbol.isWeakDef(sym) or Symbol.isPext(sym)) break :linkage .linkage_unit;
break :linkage .global;
};
- const regular = try self.allocator.create(Symbol.Regular);
- errdefer self.allocator.destroy(regular);
- regular.* = .{
- .base = .{
- .@"type" = .regular,
- .name = name,
- },
+ break :symbol try Symbol.Regular.new(self.allocator, name, .{
.linkage = linkage,
.address = sym.n_value,
.section = sym.n_sect - 1,
.weak_ref = Symbol.isWeakRef(sym),
.file = self,
- };
- break :symbol &regular.base;
+ });
}
if (sym.n_value != 0) {
- const tentative = try self.allocator.create(Symbol.Tentative);
- errdefer self.allocator.destroy(tentative);
- tentative.* = .{
- .base = .{
- .@"type" = .tentative,
- .name = name,
- },
+ break :symbol try Symbol.Tentative.new(self.allocator, name, .{
.size = sym.n_value,
.alignment = (sym.n_desc >> 8) & 0x0f,
.file = self,
- };
- break :symbol &tentative.base;
+ });
}
- const undef = try self.allocator.create(Symbol.Unresolved);
- errdefer self.allocator.destroy(undef);
- undef.* = .{
- .base = .{
- .@"type" = .unresolved,
- .name = name,
- },
+ break :symbol try Symbol.Unresolved.new(self.allocator, name, .{
.file = self,
- };
- break :symbol &undef.base;
+ });
};
try self.symbols.append(self.allocator, symbol);
diff --git a/src/link/MachO/StringTable.zig b/src/link/MachO/StringTable.zig
index 5437c70476..43770afdc1 100644
--- a/src/link/MachO/StringTable.zig
+++ b/src/link/MachO/StringTable.zig
@@ -8,7 +8,6 @@ const Allocator = mem.Allocator;
allocator: *Allocator,
buffer: std.ArrayListUnmanaged(u8) = .{},
-used_offsets: std.ArrayListUnmanaged(u32) = .{},
cache: std.StringHashMapUnmanaged(u32) = .{},
pub const Error = error{OutOfMemory};
@@ -22,8 +21,13 @@ pub fn init(allocator: *Allocator) Error!StringTable {
}
pub fn deinit(self: *StringTable) void {
+ {
+ var it = self.cache.keyIterator();
+ while (it.next()) |key| {
+ self.allocator.free(key.*);
+ }
+ }
self.cache.deinit(self.allocator);
- self.used_offsets.deinit(self.allocator);
self.buffer.deinit(self.allocator);
}
@@ -33,8 +37,6 @@ pub fn getOrPut(self: *StringTable, string: []const u8) Error!u32 {
return off;
}
- const invalidate_cache = self.needsToGrow(string.len + 1);
-
try self.buffer.ensureUnusedCapacity(self.allocator, string.len + 1);
const new_off = @intCast(u32, self.buffer.items.len);
@@ -43,25 +45,7 @@ pub fn getOrPut(self: *StringTable, string: []const u8) Error!u32 {
self.buffer.appendSliceAssumeCapacity(string);
self.buffer.appendAssumeCapacity(0);
- if (invalidate_cache) {
- log.debug("invalidating cache", .{});
- // Re-create the cache.
- self.cache.clearRetainingCapacity();
- for (self.used_offsets.items) |off| {
- try self.cache.putNoClobber(self.allocator, self.get(off).?, off);
- }
- }
-
- {
- log.debug("cache:", .{});
- var it = self.cache.iterator();
- while (it.next()) |entry| {
- log.debug(" | {s} => {}", .{ entry.key_ptr.*, entry.value_ptr.* });
- }
- }
-
- try self.cache.putNoClobber(self.allocator, self.get(new_off).?, new_off);
- try self.used_offsets.append(self.allocator, new_off);
+ try self.cache.putNoClobber(self.allocator, try self.allocator.dupe(u8, string), new_off);
return new_off;
}
@@ -78,7 +62,3 @@ pub fn asSlice(self: StringTable) []const u8 {
pub fn size(self: StringTable) u64 {
return self.buffer.items.len;
}
-
-fn needsToGrow(self: StringTable, needed_space: u64) bool {
- return self.buffer.capacity < needed_space + self.size();
-}
diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig
index 8da4704909..59a6f3d836 100644
--- a/src/link/MachO/Symbol.zig
+++ b/src/link/MachO/Symbol.zig
@@ -7,6 +7,7 @@ const mem = std.mem;
const Allocator = mem.Allocator;
const Dylib = @import("Dylib.zig");
const Object = @import("Object.zig");
+const StringTable = @import("StringTable.zig");
pub const Type = enum {
regular,
@@ -19,7 +20,7 @@ pub const Type = enum {
@"type": Type,
/// Symbol name. Owned slice.
-name: []u8,
+name: []const u8,
/// Alias of.
alias: ?*Symbol = null,
@@ -43,23 +44,14 @@ pub const Regular = struct {
section: u8,
/// Whether the symbol is a weak ref.
- weak_ref: bool,
+ weak_ref: bool = false,
/// Object file where to locate this symbol.
- file: *Object,
+ /// null means self-reference.
+ file: ?*Object = null,
/// Debug stab if defined.
- stab: ?struct {
- /// Stab kind
- kind: enum {
- function,
- global,
- static,
- },
-
- /// Size of the stab.
- size: u64,
- } = null,
+ stab: ?Stab = null,
/// True if symbol was already committed into the final
/// symbol table.
@@ -73,6 +65,68 @@ pub const Regular = struct {
global,
};
+ pub const Stab = struct {
+ /// Stab kind
+ kind: enum {
+ function,
+ global,
+ static,
+ },
+
+ /// Size of the stab.
+ size: u64,
+ };
+
+ const Opts = struct {
+ linkage: Linkage = .translation_unit,
+ address: u64 = 0,
+ section: u8 = 0,
+ weak_ref: bool = false,
+ file: ?*Object = null,
+ stab: ?Stab = null,
+ };
+
+ pub fn new(allocator: *Allocator, name: []const u8, opts: Opts) !*Symbol {
+ const reg = try allocator.create(Regular);
+ errdefer allocator.destroy(reg);
+
+ reg.* = .{
+ .base = .{
+ .@"type" = .regular,
+ .name = try allocator.dupe(u8, name),
+ },
+ .linkage = opts.linkage,
+ .address = opts.address,
+ .section = opts.section,
+ .weak_ref = opts.weak_ref,
+ .file = opts.file,
+ .stab = opts.stab,
+ };
+
+ return &reg.base;
+ }
+
+ pub fn asNlist(regular: *Regular, strtab: *StringTable) !macho.nlist_64 {
+ const n_strx = try strtab.getOrPut(regular.base.name);
+ var nlist = macho.nlist_64{
+ .n_strx = n_strx,
+ .n_type = macho.N_SECT,
+ .n_sect = regular.section,
+ .n_desc = 0,
+ .n_value = regular.address,
+ };
+
+ if (regular.linkage != .translation_unit) {
+ nlist.n_type |= macho.N_EXT;
+ }
+ if (regular.linkage == .linkage_unit) {
+ nlist.n_type |= macho.N_PEXT;
+ nlist.n_desc |= macho.N_WEAK_DEF;
+ }
+
+ return nlist;
+ }
+
pub fn isTemp(regular: *Regular) bool {
if (regular.linkage == .translation_unit) {
return mem.startsWith(u8, regular.base.name, "l") or mem.startsWith(u8, regular.base.name, "L");
@@ -97,6 +151,36 @@ pub const Proxy = struct {
pub const base_type: Symbol.Type = .proxy;
+ const Opts = struct {
+ file: ?*Dylib = null,
+ };
+
+ pub fn new(allocator: *Allocator, name: []const u8, opts: Opts) !*Symbol {
+ const proxy = try allocator.create(Proxy);
+ errdefer allocator.destroy(proxy);
+
+ proxy.* = .{
+ .base = .{
+ .@"type" = .proxy,
+ .name = try allocator.dupe(u8, name),
+ },
+ .file = opts.file,
+ };
+
+ return &proxy.base;
+ }
+
+ pub fn asNlist(proxy: *Proxy, strtab: *StringTable) !macho.nlist_64 {
+ const n_strx = try strtab.getOrPut(proxy.base.name);
+ return macho.nlist_64{
+ .n_strx = n_strx,
+ .n_type = macho.N_UNDF | macho.N_EXT,
+ .n_sect = 0,
+ .n_desc = (proxy.dylibOrdinal() * macho.N_SYMBOL_RESOLVER) | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY,
+ .n_value = 0,
+ };
+ }
+
pub fn deinit(proxy: *Proxy, allocator: *Allocator) void {
proxy.bind_info.deinit(allocator);
}
@@ -115,6 +199,36 @@ pub const Unresolved = struct {
file: ?*Object = null,
pub const base_type: Symbol.Type = .unresolved;
+
+ const Opts = struct {
+ file: ?*Object = null,
+ };
+
+ pub fn new(allocator: *Allocator, name: []const u8, opts: Opts) !*Symbol {
+ const undef = try allocator.create(Unresolved);
+ errdefer allocator.destroy(undef);
+
+ undef.* = .{
+ .base = .{
+ .@"type" = .unresolved,
+ .name = try allocator.dupe(u8, name),
+ },
+ .file = opts.file,
+ };
+
+ return &undef.base;
+ }
+
+ pub fn asNlist(undef: *Unresolved, strtab: *StringTable) !macho.nlist_64 {
+ const n_strx = try strtab.getOrPut(undef.base.name);
+ return macho.nlist_64{
+ .n_strx = n_strx,
+ .n_type = macho.N_UNDF,
+ .n_sect = 0,
+ .n_desc = 0,
+ .n_value = 0,
+ };
+ }
};
pub const Tentative = struct {
@@ -127,13 +241,49 @@ pub const Tentative = struct {
alignment: u16,
/// File where this symbol was referenced.
- file: *Object,
+ file: ?*Object = null,
pub const base_type: Symbol.Type = .tentative;
+
+ const Opts = struct {
+ size: u64 = 0,
+ alignment: u16 = 0,
+ file: ?*Object = null,
+ };
+
+ pub fn new(allocator: *Allocator, name: []const u8, opts: Opts) !*Symbol {
+ const tent = try allocator.create(Tentative);
+ errdefer allocator.destroy(tent);
+
+ tent.* = .{
+ .base = .{
+ .@"type" = .tentative,
+ .name = try allocator.dupe(u8, name),
+ },
+ .size = opts.size,
+ .alignment = opts.alignment,
+ .file = opts.file,
+ };
+
+ return &tent.base;
+ }
+
+ pub fn asNlist(tent: *Tentative, strtab: *StringTable) !macho.nlist_64 {
+ // TODO
+ const n_strx = try strtab.getOrPut(tent.base.name);
+ return macho.nlist_64{
+ .n_strx = n_strx,
+ .n_type = macho.N_UNDF,
+ .n_sect = 0,
+ .n_desc = 0,
+ .n_value = 0,
+ };
+ }
};
pub fn deinit(base: *Symbol, allocator: *Allocator) void {
allocator.free(base.name);
+
switch (base.@"type") {
.proxy => @fieldParentPtr(Proxy, "base", base).deinit(allocator),
else => {},
@@ -154,6 +304,15 @@ pub fn getTopmostAlias(base: *Symbol) *Symbol {
return base;
}
+pub fn asNlist(base: *Symbol, strtab: *StringTable) !macho.nlist_64 {
+ return switch (base.tag) {
+ .regular => @fieldParentPtr(Regular, "base", base).asNlist(strtab),
+ .proxy => @fieldParentPtr(Proxy, "base", base).asNlist(strtab),
+ .unresolved => @fieldParentPtr(Unresolved, "base", base).asNlist(strtab),
+ .tentative => @fieldParentPtr(Tentative, "base", base).asNlist(strtab),
+ };
+}
+
pub fn isStab(sym: macho.nlist_64) bool {
return (macho.N_STAB & sym.n_type) != 0;
}
diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig
index d223e04fd7..a20879f856 100644
--- a/src/link/MachO/Zld.zig
+++ b/src/link/MachO/Zld.zig
@@ -17,6 +17,7 @@ const Archive = @import("Archive.zig");
const CodeSignature = @import("CodeSignature.zig");
const Dylib = @import("Dylib.zig");
const Object = @import("Object.zig");
+const StringTable = @import("StringTable.zig");
const Symbol = @import("Symbol.zig");
const Trie = @import("Trie.zig");
@@ -24,6 +25,7 @@ usingnamespace @import("commands.zig");
usingnamespace @import("bind.zig");
allocator: *Allocator,
+strtab: StringTable,
target: ?std.Target = null,
page_size: ?u16 = null,
@@ -109,9 +111,6 @@ tentatives: std.StringArrayHashMapUnmanaged(*Symbol) = .{},
/// Set if the linker found tentative definitions in any of the objects.
tentative_defs_offset: u64 = 0,
-strtab: std.ArrayListUnmanaged(u8) = .{},
-strtab_dir: std.StringHashMapUnmanaged(u32) = .{},
-
threadlocal_offsets: std.ArrayListUnmanaged(TlvOffset) = .{}, // TODO merge with Symbol abstraction
local_rebases: std.ArrayListUnmanaged(Pointer) = .{},
stubs: std.ArrayListUnmanaged(*Symbol) = .{},
@@ -138,8 +137,11 @@ const TlvOffset = struct {
/// Default path to dyld
const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld";
-pub fn init(allocator: *Allocator) Zld {
- return .{ .allocator = allocator };
+pub fn init(allocator: *Allocator) !Zld {
+ return Zld{
+ .allocator = allocator,
+ .strtab = try StringTable.init(allocator),
+ };
}
pub fn deinit(self: *Zld) void {
@@ -180,15 +182,7 @@ pub fn deinit(self: *Zld) void {
self.tentatives.deinit(self.allocator);
self.globals.deinit(self.allocator);
self.unresolved.deinit(self.allocator);
- self.strtab.deinit(self.allocator);
-
- {
- var it = self.strtab_dir.keyIterator();
- while (it.next()) |key| {
- self.allocator.free(key.*);
- }
- }
- self.strtab_dir.deinit(self.allocator);
+ self.strtab.deinit();
}
pub fn closeFiles(self: Zld) void {
@@ -1137,16 +1131,7 @@ fn allocateTentativeSymbols(self: *Zld) !void {
// Convert tentative definitions into regular symbols.
for (self.tentatives.values()) |sym| {
const tent = sym.cast(Symbol.Tentative) orelse unreachable;
- const reg = try self.allocator.create(Symbol.Regular);
- errdefer self.allocator.destroy(reg);
-
- reg.* = .{
- .base = .{
- .@"type" = .regular,
- .name = try self.allocator.dupe(u8, tent.base.name),
- .got_index = tent.base.got_index,
- .stubs_index = tent.base.stubs_index,
- },
+ const reg = try Symbol.Regular.new(self.allocator, tent.base.name, .{
.linkage = .global,
.address = base_address,
.section = section,
@@ -1156,16 +1141,18 @@ fn allocateTentativeSymbols(self: *Zld) !void {
.kind = .global,
.size = 0,
},
- };
+ });
+ reg.got_index = tent.base.got_index;
+ reg.stubs_index = tent.base.stubs_index;
- try self.globals.putNoClobber(self.allocator, reg.base.name, &reg.base);
- tent.base.alias = &reg.base;
+ try self.globals.putNoClobber(self.allocator, reg.name, reg);
+ tent.base.alias = reg;
if (tent.base.got_index) |idx| {
- self.got_entries.items[idx] = &reg.base;
+ self.got_entries.items[idx] = reg;
}
if (tent.base.stubs_index) |idx| {
- self.stubs.items[idx] = &reg.base;
+ self.stubs.items[idx] = reg;
}
const address = mem.alignForwardGeneric(u64, base_address + tent.size, alignment);
@@ -1615,15 +1602,8 @@ fn resolveSymbols(self: *Zld) !void {
{
const name = try self.allocator.dupe(u8, "dyld_stub_binder");
errdefer self.allocator.free(name);
- const undef = try self.allocator.create(Symbol.Unresolved);
- errdefer self.allocator.destroy(undef);
- undef.* = .{
- .base = .{
- .@"type" = .unresolved,
- .name = name,
- },
- };
- try unresolved.append(&undef.base);
+ const undef = try Symbol.Unresolved.new(self.allocator, name, .{});
+ try unresolved.append(undef);
}
var referenced = std.AutoHashMap(*Dylib, void).init(self.allocator);
@@ -1641,16 +1621,7 @@ fn resolveSymbols(self: *Zld) !void {
// TODO this is just a temp patch until I work out what to actually
// do with ___dso_handle and __mh_execute_header symbols which are
// synthetically created by the linker on macOS.
- const name = try self.allocator.dupe(u8, undef.name);
- const proxy = try self.allocator.create(Symbol.Proxy);
- errdefer self.allocator.destroy(proxy);
- proxy.* = .{
- .base = .{
- .@"type" = .proxy,
- .name = name,
- },
- };
- break :inner &proxy.base;
+ break :inner try Symbol.Proxy.new(self.allocator, undef.name, .{});
}
self.unresolved.putAssumeCapacityNoClobber(undef.name, undef);
@@ -2126,7 +2097,6 @@ fn populateMetadata(self: *Zld) !void {
.strsize = 0,
},
});
- try self.strtab.append(self.allocator, 0);
}
if (self.dysymtab_cmd_index == null) {
@@ -2752,7 +2722,7 @@ fn writeDebugInfo(self: *Zld) !void {
const dirname = std.fs.path.dirname(tu_path) orelse "./";
// Current dir
try stabs.append(.{
- .n_strx = try self.makeString(tu_path[0 .. dirname.len + 1]),
+ .n_strx = try self.strtab.getOrPut(tu_path[0 .. dirname.len + 1]),
.n_type = macho.N_SO,
.n_sect = 0,
.n_desc = 0,
@@ -2760,7 +2730,7 @@ fn writeDebugInfo(self: *Zld) !void {
});
// Artifact name
try stabs.append(.{
- .n_strx = try self.makeString(tu_path[dirname.len + 1 ..]),
+ .n_strx = try self.strtab.getOrPut(tu_path[dirname.len + 1 ..]),
.n_type = macho.N_SO,
.n_sect = 0,
.n_desc = 0,
@@ -2768,7 +2738,7 @@ fn writeDebugInfo(self: *Zld) !void {
});
// Path to object file with debug info
try stabs.append(.{
- .n_strx = try self.makeString(object.name.?),
+ .n_strx = try self.strtab.getOrPut(object.name.?),
.n_type = macho.N_OSO,
.n_sect = 0,
.n_desc = 1,
@@ -2801,7 +2771,7 @@ fn writeDebugInfo(self: *Zld) !void {
.n_value = reg.address,
});
try stabs.append(.{
- .n_strx = try self.makeString(sym.name),
+ .n_strx = try self.strtab.getOrPut(sym.name),
.n_type = macho.N_FUN,
.n_sect = reg.section,
.n_desc = 0,
@@ -2824,7 +2794,7 @@ fn writeDebugInfo(self: *Zld) !void {
},
.global => {
try stabs.append(.{
- .n_strx = try self.makeString(sym.name),
+ .n_strx = try self.strtab.getOrPut(sym.name),
.n_type = macho.N_GSYM,
.n_sect = 0,
.n_desc = 0,
@@ -2833,7 +2803,7 @@ fn writeDebugInfo(self: *Zld) !void {
},
.static => {
try stabs.append(.{
- .n_strx = try self.makeString(sym.name),
+ .n_strx = try self.strtab.getOrPut(sym.name),
.n_type = macho.N_STSYM,
.n_sect = reg.section,
.n_desc = 0,
@@ -2892,24 +2862,14 @@ fn writeSymbolTable(self: *Zld) !void {
if (reg.isTemp()) continue;
if (reg.visited) continue;
+ const nlist = try reg.asNlist(&self.strtab);
+
switch (reg.linkage) {
.translation_unit => {
- try locals.append(.{
- .n_strx = try self.makeString(sym.name),
- .n_type = macho.N_SECT,
- .n_sect = reg.section,
- .n_desc = 0,
- .n_value = reg.address,
- });
+ try locals.append(nlist);
},
else => {
- try exports.append(.{
- .n_strx = try self.makeString(sym.name),
- .n_type = macho.N_SECT | macho.N_EXT,
- .n_sect = reg.section,
- .n_desc = 0,
- .n_value = reg.address,
- });
+ try exports.append(nlist);
},
}
@@ -2922,13 +2882,8 @@ fn writeSymbolTable(self: *Zld) !void {
for (self.imports.values()) |sym| {
const proxy = sym.cast(Symbol.Proxy) orelse unreachable;
- try undefs.append(.{
- .n_strx = try self.makeString(sym.name),
- .n_type = macho.N_UNDF | macho.N_EXT,
- .n_sect = 0,
- .n_desc = (proxy.dylibOrdinal() * macho.N_SYMBOL_RESOLVER) | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY,
- .n_value = 0,
- });
+ const nlist = try proxy.asNlist(&self.strtab);
+ try undefs.append(nlist);
}
const nlocals = locals.items.len;
@@ -3017,14 +2972,14 @@ fn writeStringTable(self: *Zld) !void {
const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
symtab.stroff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize);
- symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64)));
+ symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.size(), @alignOf(u64)));
seg.inner.filesize += symtab.strsize;
log.debug("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize });
- try self.file.?.pwriteAll(self.strtab.items, symtab.stroff);
+ try self.file.?.pwriteAll(self.strtab.asSlice(), symtab.stroff);
- if (symtab.strsize > self.strtab.items.len and self.target.?.cpu.arch == .x86_64) {
+ if (symtab.strsize > self.strtab.size() and self.target.?.cpu.arch == .x86_64) {
// This is the last section, so we need to pad it out.
try self.file.?.pwriteAll(&[_]u8{0}, seg.inner.fileoff + seg.inner.filesize - 1);
}
@@ -3173,26 +3128,6 @@ fn writeHeader(self: *Zld) !void {
try self.file.?.pwriteAll(mem.asBytes(&header), 0);
}
-fn makeString(self: *Zld, bytes: []const u8) !u32 {
- if (self.strtab_dir.get(bytes)) |offset| {
- log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset });
- return offset;
- }
-
- try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1);
- const offset = @intCast(u32, self.strtab.items.len);
- log.debug("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset });
- self.strtab.appendSliceAssumeCapacity(bytes);
- self.strtab.appendAssumeCapacity(0);
- try self.strtab_dir.putNoClobber(self.allocator, try self.allocator.dupe(u8, bytes), offset);
- return offset;
-}
-
-fn getString(self: *const Zld, str_off: u32) []const u8 {
- assert(str_off < self.strtab.items.len);
- return mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr + str_off));
-}
-
pub fn parseName(name: *const [16]u8) []const u8 {
const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len;
return name[0..len];