aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-12-01 17:49:38 +0100
committerJakub Konka <kubkon@jakubkonka.com>2020-12-01 18:03:04 +0100
commitabb697e751cb0febf4e5e26f0190c01d7c5fd922 (patch)
tree90e863418f37e9333b11cc9bdd788b36f4db06ba /src/link/MachO
parent1f7fb560ab5a3a82af24ab7abe11dce8f877c7fe (diff)
downloadzig-abb697e751cb0febf4e5e26f0190c01d7c5fd922.tar.gz
zig-abb697e751cb0febf4e5e26f0190c01d7c5fd922.zip
macho: unify code signature between stage1 and stage2
Diffstat (limited to 'src/link/MachO')
-rw-r--r--src/link/MachO/CodeSignature.zig94
-rw-r--r--src/link/MachO/Parser.zig16
2 files changed, 17 insertions, 93 deletions
diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig
index 98189ae219..c7cfdfcb44 100644
--- a/src/link/MachO/CodeSignature.zig
+++ b/src/link/MachO/CodeSignature.zig
@@ -10,8 +10,6 @@ const testing = std.testing;
const Allocator = mem.Allocator;
const Sha256 = std.crypto.hash.sha2.Sha256;
-const MachO = @import("../MachO.zig");
-
const hash_size: u8 = 32;
const page_size: u16 = 0x1000;
@@ -52,7 +50,7 @@ const CodeDirectory = struct {
}
};
-alloc: *Allocator,
+allocator: *Allocator,
inner: macho.SuperBlob = .{
.magic = macho.CSMAGIC_EMBEDDED_SIGNATURE,
.length = @sizeOf(macho.SuperBlob),
@@ -60,13 +58,11 @@ inner: macho.SuperBlob = .{
},
cdir: ?CodeDirectory = null,
-pub fn init(alloc: *Allocator) CodeSignature {
- return .{
- .alloc = alloc,
- };
+pub fn init(allocator: *Allocator) CodeSignature {
+ return .{ .allocator = allocator };
}
-pub fn calcAdhocSignatureFile(
+pub fn calcAdhocSignature(
self: *CodeSignature,
file: fs.File,
id: []const u8,
@@ -107,10 +103,10 @@ pub fn calcAdhocSignatureFile(
const total_pages = mem.alignForward(file_size, page_size) / page_size;
var hash: [hash_size]u8 = undefined;
- var buffer = try self.alloc.alloc(u8, page_size);
- defer self.alloc.free(buffer);
+ var buffer = try self.allocator.alloc(u8, page_size);
+ defer self.allocator.free(buffer);
- try cdir.data.ensureCapacity(self.alloc, total_pages * hash_size + id.len + 1);
+ try cdir.data.ensureCapacity(self.allocator, total_pages * hash_size + id.len + 1);
// 1. Save the identifier and update offsets
cdir.inner.identOffset = cdir.inner.length;
@@ -142,80 +138,6 @@ pub fn calcAdhocSignatureFile(
self.cdir = cdir;
}
-pub fn calcAdhocSignature(self: *CodeSignature, bin_file: *const MachO) !void {
- const text_segment = bin_file.load_commands.items[bin_file.text_segment_cmd_index.?].Segment;
- const code_sig_cmd = bin_file.load_commands.items[bin_file.code_signature_cmd_index.?].LinkeditData;
-
- const execSegBase: u64 = text_segment.inner.fileoff;
- const execSegLimit: u64 = text_segment.inner.filesize;
- const execSegFlags: u64 = if (bin_file.base.options.output_mode == .Exe) macho.CS_EXECSEG_MAIN_BINARY else 0;
- const file_size = code_sig_cmd.dataoff;
- var cdir = CodeDirectory{
- .inner = .{
- .magic = macho.CSMAGIC_CODEDIRECTORY,
- .length = @sizeOf(macho.CodeDirectory),
- .version = macho.CS_SUPPORTSEXECSEG,
- .flags = macho.CS_ADHOC,
- .hashOffset = 0,
- .identOffset = 0,
- .nSpecialSlots = 0,
- .nCodeSlots = 0,
- .codeLimit = @intCast(u32, file_size),
- .hashSize = hash_size,
- .hashType = macho.CS_HASHTYPE_SHA256,
- .platform = 0,
- .pageSize = @truncate(u8, std.math.log2(page_size)),
- .spare2 = 0,
- .scatterOffset = 0,
- .teamOffset = 0,
- .spare3 = 0,
- .codeLimit64 = 0,
- .execSegBase = execSegBase,
- .execSegLimit = execSegLimit,
- .execSegFlags = execSegFlags,
- },
- };
-
- const total_pages = mem.alignForward(file_size, page_size) / page_size;
-
- var hash: [hash_size]u8 = undefined;
- var buffer = try bin_file.base.allocator.alloc(u8, page_size);
- defer bin_file.base.allocator.free(buffer);
- const macho_file = bin_file.base.file.?;
-
- const id = bin_file.base.options.emit.?.sub_path;
- try cdir.data.ensureCapacity(self.alloc, total_pages * hash_size + id.len + 1);
-
- // 1. Save the identifier and update offsets
- cdir.inner.identOffset = cdir.inner.length;
- cdir.data.appendSliceAssumeCapacity(id);
- cdir.data.appendAssumeCapacity(0);
-
- // 2. Calculate hash for each page (in file) and write it to the buffer
- // TODO figure out how we can cache several hashes since we won't update
- // every page during incremental linking
- cdir.inner.hashOffset = cdir.inner.identOffset + @intCast(u32, id.len) + 1;
- var i: usize = 0;
- while (i < total_pages) : (i += 1) {
- const fstart = i * page_size;
- const fsize = if (fstart + page_size > file_size) file_size - fstart else page_size;
- const len = try macho_file.preadAll(buffer, fstart);
- assert(fsize <= len);
-
- Sha256.hash(buffer[0..fsize], &hash, .{});
-
- cdir.data.appendSliceAssumeCapacity(hash[0..]);
- cdir.inner.nCodeSlots += 1;
- }
-
- // 3. Update CodeDirectory length
- cdir.inner.length += @intCast(u32, cdir.data.items.len);
-
- self.inner.length += @sizeOf(macho.BlobIndex) + cdir.size();
- self.inner.count = 1;
- self.cdir = cdir;
-}
-
pub fn size(self: CodeSignature) u32 {
return self.inner.length;
}
@@ -230,7 +152,7 @@ pub fn write(self: CodeSignature, buffer: []u8) void {
pub fn deinit(self: *CodeSignature) void {
if (self.cdir) |*cdir| {
- cdir.data.deinit(self.alloc);
+ cdir.data.deinit(self.allocator);
}
}
diff --git a/src/link/MachO/Parser.zig b/src/link/MachO/Parser.zig
index 2f2e74933e..de2a466f1f 100644
--- a/src/link/MachO/Parser.zig
+++ b/src/link/MachO/Parser.zig
@@ -18,9 +18,9 @@ header: ?macho.mach_header_64 = null,
/// Load commands
load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
-text_cmd_index: ?usize = null,
+text_cmd_index: ?u16 = null,
-linkedit_cmd_index: ?usize = null,
+linkedit_cmd_index: ?u16 = null,
linkedit_cmd_offset: ?u64 = null,
code_sig_cmd_offset: ?u64 = null,
@@ -28,9 +28,7 @@ code_sig_cmd_offset: ?u64 = null,
end_pos: ?u64 = null,
pub fn init(allocator: *Allocator) Parser {
- return .{
- .allocator = allocator,
- };
+ return .{ .allocator = allocator };
}
pub fn parse(self: *Parser, reader: anytype) !void {
@@ -46,10 +44,10 @@ pub fn parse(self: *Parser, reader: anytype) !void {
switch (cmd.cmd()) {
macho.LC_SEGMENT_64 => {
const x = cmd.Segment;
- if (mem.eql(u8, mem.trimRight(u8, x.inner.segname[0..], &[_]u8{0}), "__LINKEDIT")) {
+ if (mem.eql(u8, parseName(&x.inner.segname), "__LINKEDIT")) {
self.linkedit_cmd_index = i;
self.linkedit_cmd_offset = off;
- } else if (mem.eql(u8, mem.trimRight(u8, x.inner.segname[0..], &[_]u8{0}), "__TEXT")) {
+ } else if (mem.eql(u8, parseName(&x.inner.segname), "__TEXT")) {
self.text_cmd_index = i;
}
},
@@ -78,3 +76,7 @@ pub fn deinit(self: *Parser) void {
}
self.load_commands.deinit(self.allocator);
}
+
+fn parseName(name: *const [16]u8) []const u8 {
+ return mem.trimRight(u8, name.*[0..], &[_]u8{0});
+}