authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-20 11:05:16+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-26 11:50:09+01:00
log79381dc4fb1f7eb92b5e01d21f866f550ca3ff20
treeff2762e71eef07d8b9e148248d44604a02afc013
parentd14cd59ef0d9f03114ea6467a8446c17bf33ab9a

stage2 macho: add empty CodeDirectory blob


2 files changed, 93 insertions(+), 12 deletions(-)

lib/std/macho.zig+13-3
......@@ -1446,6 +1446,18 @@ pub const CodeDirectory = extern struct {
14461446 /// Unused (must be zero)
14471447 spare2: u32,
14481448
1449 ///
1450 scatterOffset: u32,
1451
1452 ///
1453 teamOffset: u32,
1454
1455 ///
1456 spare3: u32,
1457
1458 ///
1459 codeLimit64: u64,
1460
14491461 /// Offset of executable segment
14501462 execSegBase: u64,
14511463
......@@ -1453,9 +1465,7 @@ pub const CodeDirectory = extern struct {
14531465 execSegLimit: u64,
14541466
14551467 /// Executable segment flags
1456 execSegFlags,
1457
1458 // end_withExecSeg: [*]u8,
1468 execSegFlags: u64,
14591469};
14601470
14611471/// Structure of an embedded-signature SuperBlob
src/link/MachO/CodeSignature.zig+80-9
......@@ -8,11 +8,39 @@ const mem = std.mem;
88const testing = std.testing;
99const Allocator = mem.Allocator;
1010
11// pub const Blob = union(enum) {
12// Signature: struct{
13// inner:
14// }
15// };
11const Blob = struct {
12 inner: macho.CodeDirectory,
13 data: std.ArrayListUnmanaged(u8) = .{},
14
15 fn size(self: Blob) u32 {
16 return self.inner.length;
17 }
18
19 fn write(self: Blob, buffer: []u8) void {
20 assert(buffer.len >= self.inner.length);
21 mem.writeIntBig(u32, buffer[0..4], self.inner.magic);
22 mem.writeIntBig(u32, buffer[4..8], self.inner.length);
23 mem.writeIntBig(u32, buffer[8..12], self.inner.version);
24 mem.writeIntBig(u32, buffer[12..16], self.inner.flags);
25 mem.writeIntBig(u32, buffer[16..20], self.inner.hashOffset);
26 mem.writeIntBig(u32, buffer[20..24], self.inner.identOffset);
27 mem.writeIntBig(u32, buffer[24..28], self.inner.nSpecialSlots);
28 mem.writeIntBig(u32, buffer[28..32], self.inner.nCodeSlots);
29 mem.writeIntBig(u32, buffer[32..36], self.inner.codeLimit);
30 mem.writeIntBig(u8, buffer[36..37], self.inner.hashSize);
31 mem.writeIntBig(u8, buffer[37..38], self.inner.hashType);
32 mem.writeIntBig(u8, buffer[38..39], self.inner.platform);
33 mem.writeIntBig(u8, buffer[39..40], self.inner.pageSize);
34 mem.writeIntBig(u32, buffer[40..44], self.inner.spare2);
35 mem.writeIntBig(u32, buffer[44..48], self.inner.scatterOffset);
36 mem.writeIntBig(u32, buffer[48..52], self.inner.teamOffset);
37 mem.writeIntBig(u32, buffer[52..56], self.inner.spare3);
38 mem.writeIntBig(u64, buffer[56..64], self.inner.codeLimit64);
39 mem.writeIntBig(u64, buffer[64..72], self.inner.execSegBase);
40 mem.writeIntBig(u64, buffer[72..80], self.inner.execSegLimit);
41 mem.writeIntBig(u64, buffer[80..88], self.inner.execSegFlags);
42 }
43};
1644
1745alloc: *Allocator,
1846inner: macho.SuperBlob = .{
......@@ -20,16 +48,44 @@ inner: macho.SuperBlob = .{
2048 .length = @sizeOf(macho.SuperBlob),
2149 .count = 0,
2250},
23// blobs: std.ArrayList(Blob),
51blob: ?Blob = null,
2452
2553pub fn init(alloc: *Allocator) CodeSignature {
2654 return .{
2755 .alloc = alloc,
28 // .indices = std.ArrayList(Blob).init(alloc),
2956 };
3057}
3158
32pub fn calcAdhocSignature(self: *CodeSignature) !void {}
59pub fn calcAdhocSignature(self: *CodeSignature) !void {
60 var blob = Blob{
61 .inner = .{
62 .magic = macho.CSMAGIC_CODEDIRECTORY,
63 .length = @sizeOf(macho.CodeDirectory),
64 .version = 0x20400,
65 .flags = 0,
66 .hashOffset = 0,
67 .identOffset = 0,
68 .nSpecialSlots = 0,
69 .nCodeSlots = 0,
70 .codeLimit = 0,
71 .hashSize = 0,
72 .hashType = 0,
73 .platform = 0,
74 .pageSize = 0,
75 .spare2 = 0,
76 .scatterOffset = 0,
77 .teamOffset = 0,
78 .spare3 = 0,
79 .codeLimit64 = 0,
80 .execSegBase = 0,
81 .execSegLimit = 0,
82 .execSegFlags = 0,
83 },
84 };
85 self.inner.length += @sizeOf(macho.BlobIndex) + blob.size();
86 self.inner.count = 1;
87 self.blob = blob;
88}
3389
3490pub fn size(self: CodeSignature) u32 {
3591 return self.inner.length;
......@@ -38,9 +94,16 @@ pub fn size(self: CodeSignature) u32 {
3894pub fn write(self: CodeSignature, buffer: []u8) void {
3995 assert(buffer.len >= self.inner.length);
4096 self.writeHeader(buffer);
97 const offset: u32 = @sizeOf(macho.SuperBlob) + @sizeOf(macho.BlobIndex);
98 writeBlobIndex(macho.CSSLOT_CODEDIRECTORY, offset, buffer[@sizeOf(macho.SuperBlob)..]);
99 self.blob.?.write(buffer[offset..]);
41100}
42101
43pub fn deinit(self: *CodeSignature) void {}
102pub fn deinit(self: *CodeSignature) void {
103 if (self.blob) |*b| {
104 b.data.deinit(self.alloc);
105 }
106}
44107
45108fn writeHeader(self: CodeSignature, buffer: []u8) void {
46109 assert(buffer.len >= @sizeOf(macho.SuperBlob));
......@@ -49,11 +112,19 @@ fn writeHeader(self: CodeSignature, buffer: []u8) void {
49112 mem.writeIntBig(u32, buffer[8..12], self.inner.count);
50113}
51114
115fn writeBlobIndex(tt: u32, offset: u32, buffer: []u8) void {
116 assert(buffer.len >= @sizeOf(macho.BlobIndex));
117 mem.writeIntBig(u32, buffer[0..4], tt);
118 mem.writeIntBig(u32, buffer[4..8], offset);
119}
120
52121test "CodeSignature header" {
53122 var code_sig = CodeSignature.init(testing.allocator);
54123 defer code_sig.deinit();
124
55125 var buffer: [@sizeOf(macho.SuperBlob)]u8 = undefined;
56126 code_sig.writeHeader(buffer[0..]);
127
57128 const expected = &[_]u8{ 0xfa, 0xde, 0x0c, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0 };
58129 testing.expect(mem.eql(u8, expected[0..], buffer[0..]));
59130}