stage2 macho: move code signature logic into struct

This commit is contained in:
Jakub Konka 2020-11-20 10:11:16 +01:00
parent 3ac804628f
commit d14cd59ef0
2 changed files with 74 additions and 54 deletions

View File

@ -21,6 +21,7 @@ const Cache = @import("../Cache.zig");
const target_util = @import("../target.zig");
const Trie = @import("MachO/Trie.zig");
const CodeSignature = @import("MachO/CodeSignature.zig");
pub const base_tag: File.Tag = File.Tag.macho;
@ -385,7 +386,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
self.libsystem_cmd_dirty = false;
}
try self.codeSign();
try self.writecodeSignature();
},
.Obj => {},
.Lib => return error.TODOImplementWritingLibFiles,
@ -1751,60 +1752,20 @@ fn writeAllUndefSymbols(self: *MachO) !void {
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undef_symbols.items), off);
}
fn codeSign(self: *MachO) !void {
fn writecodeSignature(self: *MachO) !void {
const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData;
// TODO add actual code signing mechanism
var buffer: std.ArrayListUnmanaged(u8) = .{};
defer buffer.deinit(self.base.allocator);
// var super_blob = macho.SuperBlob{
// .magic = macho.CSMAGIC_EMBEDDED_SIGNATURE,
// .length = 0,
// .count = 2,
// };
const length: u32 = @sizeOf(u32) * 12;
try buffer.ensureCapacity(self.base.allocator, length);
var buf: [@sizeOf(u32)]u8 = undefined;
mem.writeIntBig(u32, &buf, macho.CSMAGIC_EMBEDDED_SIGNATURE);
buffer.appendSliceAssumeCapacity(buf[0..]);
mem.writeIntBig(u32, &buf, length);
buffer.appendSliceAssumeCapacity(buf[0..]);
mem.writeIntBig(u32, &buf, 2);
buffer.appendSliceAssumeCapacity(buf[0..]);
// macho.BlobIndex{
// .type = macho.CSSLOT_REQUIREMENTS,
// .offset = offset,
// };
mem.writeIntBig(u32, &buf, macho.CSSLOT_REQUIREMENTS);
buffer.appendSliceAssumeCapacity(buf[0..]);
mem.writeIntBig(u32, &buf, 28);
buffer.appendSliceAssumeCapacity(buf[0..]);
// macho.BlobIndex{
// .type = macho.CSSLOT_SIGNATURESLOT,
// .offset = offset,
// };
mem.writeIntBig(u32, &buf, macho.CSSLOT_SIGNATURESLOT);
buffer.appendSliceAssumeCapacity(buf[0..]);
mem.writeIntBig(u32, &buf, 40);
buffer.appendSliceAssumeCapacity(buf[0..]);
// const requirements_blob = macho.GenericBlob{
// .magic = macho.CSMAGIC_REQUIREMENTS,
// .length = 0,
// };
mem.writeIntBig(u32, &buf, macho.CSMAGIC_REQUIREMENTS);
buffer.appendSliceAssumeCapacity(buf[0..]);
mem.writeIntBig(u32, &buf, @sizeOf(u32) * 3);
buffer.appendSliceAssumeCapacity(buf[0..]);
mem.writeIntBig(u32, &buf, 0);
buffer.appendSliceAssumeCapacity(buf[0..]);
// const signature_blob = macho.GenericBlob{
// .magic = macho.CSSLOT_SIGNATURESLOT,
// .length = 0,
// };
mem.writeIntBig(u32, &buf, macho.CSMAGIC_BLOBWRAPPER);
buffer.appendSliceAssumeCapacity(buf[0..]);
mem.writeIntBig(u32, &buf, @sizeOf(u32) * 2);
buffer.appendSliceAssumeCapacity(buf[0..]);
try self.base.file.?.pwriteAll(buffer.items[0..], code_sig_cmd.dataoff);
var code_sig = CodeSignature.init(self.base.allocator);
defer code_sig.deinit();
try code_sig.calcAdhocSignature();
var buffer = try self.base.allocator.alloc(u8, code_sig.size());
defer self.base.allocator.free(buffer);
code_sig.write(buffer);
try self.base.file.?.pwriteAll(buffer, code_sig_cmd.dataoff);
try self.base.file.?.pwriteAll(&[_]u8{ 0 }, code_sig_cmd.dataoff + code_sig_cmd.datasize - 1);
}

View File

@ -0,0 +1,59 @@
const CodeSignature = @This();
const std = @import("std");
const assert = std.debug.assert;
const log = std.log.scoped(.link);
const macho = std.macho;
const mem = std.mem;
const testing = std.testing;
const Allocator = mem.Allocator;
// pub const Blob = union(enum) {
// Signature: struct{
// inner:
// }
// };
alloc: *Allocator,
inner: macho.SuperBlob = .{
.magic = macho.CSMAGIC_EMBEDDED_SIGNATURE,
.length = @sizeOf(macho.SuperBlob),
.count = 0,
},
// blobs: std.ArrayList(Blob),
pub fn init(alloc: *Allocator) CodeSignature {
return .{
.alloc = alloc,
// .indices = std.ArrayList(Blob).init(alloc),
};
}
pub fn calcAdhocSignature(self: *CodeSignature) !void {}
pub fn size(self: CodeSignature) u32 {
return self.inner.length;
}
pub fn write(self: CodeSignature, buffer: []u8) void {
assert(buffer.len >= self.inner.length);
self.writeHeader(buffer);
}
pub fn deinit(self: *CodeSignature) void {}
fn writeHeader(self: CodeSignature, buffer: []u8) void {
assert(buffer.len >= @sizeOf(macho.SuperBlob));
mem.writeIntBig(u32, buffer[0..4], self.inner.magic);
mem.writeIntBig(u32, buffer[4..8], self.inner.length);
mem.writeIntBig(u32, buffer[8..12], self.inner.count);
}
test "CodeSignature header" {
var code_sig = CodeSignature.init(testing.allocator);
defer code_sig.deinit();
var buffer: [@sizeOf(macho.SuperBlob)]u8 = undefined;
code_sig.writeHeader(buffer[0..]);
const expected = &[_]u8{ 0xfa, 0xde, 0x0c, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0 };
testing.expect(mem.eql(u8, expected[0..], buffer[0..]));
}