| ... | @@ -10,8 +10,6 @@ const testing = std.testing; | ... | @@ -10,8 +10,6 @@ const testing = std.testing; |
| 10 | const Allocator = mem.Allocator; | 10 | const Allocator = mem.Allocator; |
| 11 | const Sha256 = std.crypto.hash.sha2.Sha256; | 11 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 12 | | 12 | |
| 13 | const MachO = @import("../MachO.zig"); | | |
| 14 | | | |
| 15 | const hash_size: u8 = 32; | 13 | const hash_size: u8 = 32; |
| 16 | const page_size: u16 = 0x1000; | 14 | const page_size: u16 = 0x1000; |
| 17 | | 15 | |
| ... | @@ -52,7 +50,7 @@ const CodeDirectory = struct { | ... | @@ -52,7 +50,7 @@ const CodeDirectory = struct { |
| 52 | } | 50 | } |
| 53 | }; | 51 | }; |
| 54 | | 52 | |
| 55 | alloc: *Allocator, | 53 | allocator: *Allocator, |
| 56 | inner: macho.SuperBlob = .{ | 54 | inner: macho.SuperBlob = .{ |
| 57 | .magic = macho.CSMAGIC_EMBEDDED_SIGNATURE, | 55 | .magic = macho.CSMAGIC_EMBEDDED_SIGNATURE, |
| 58 | .length = @sizeOf(macho.SuperBlob), | 56 | .length = @sizeOf(macho.SuperBlob), |
| ... | @@ -60,13 +58,11 @@ inner: macho.SuperBlob = .{ | ... | @@ -60,13 +58,11 @@ inner: macho.SuperBlob = .{ |
| 60 | }, | 58 | }, |
| 61 | cdir: ?CodeDirectory = null, | 59 | cdir: ?CodeDirectory = null, |
| 62 | | 60 | |
| 63 | pub fn init(alloc: *Allocator) CodeSignature { | 61 | pub fn init(allocator: *Allocator) CodeSignature { |
| 64 | return .{ | 62 | return .{ .allocator = allocator }; |
| 65 | .alloc = alloc, | | |
| 66 | }; | | |
| 67 | } | 63 | } |
| 68 | | 64 | |
| 69 | pub fn calcAdhocSignatureFile( | 65 | pub fn calcAdhocSignature( |
| 70 | self: *CodeSignature, | 66 | self: *CodeSignature, |
| 71 | file: fs.File, | 67 | file: fs.File, |
| 72 | id: []const u8, | 68 | id: []const u8, |
| ... | @@ -107,10 +103,10 @@ pub fn calcAdhocSignatureFile( | ... | @@ -107,10 +103,10 @@ pub fn calcAdhocSignatureFile( |
| 107 | const total_pages = mem.alignForward(file_size, page_size) / page_size; | 103 | const total_pages = mem.alignForward(file_size, page_size) / page_size; |
| 108 | | 104 | |
| 109 | var hash: [hash_size]u8 = undefined; | 105 | var hash: [hash_size]u8 = undefined; |
| 110 | var buffer = try self.alloc.alloc(u8, page_size); | 106 | var buffer = try self.allocator.alloc(u8, page_size); |
| 111 | defer self.alloc.free(buffer); | 107 | defer self.allocator.free(buffer); |
| 112 | | 108 | |
| 113 | try cdir.data.ensureCapacity(self.alloc, total_pages * hash_size + id.len + 1); | 109 | try cdir.data.ensureCapacity(self.allocator, total_pages * hash_size + id.len + 1); |
| 114 | | 110 | |
| 115 | // 1. Save the identifier and update offsets | 111 | // 1. Save the identifier and update offsets |
| 116 | cdir.inner.identOffset = cdir.inner.length; | 112 | cdir.inner.identOffset = cdir.inner.length; |
| ... | @@ -142,80 +138,6 @@ pub fn calcAdhocSignatureFile( | ... | @@ -142,80 +138,6 @@ pub fn calcAdhocSignatureFile( |
| 142 | self.cdir = cdir; | 138 | self.cdir = cdir; |
| 143 | } | 139 | } |
| 144 | | 140 | |
| 145 | pub fn calcAdhocSignature(self: *CodeSignature, bin_file: *const MachO) !void { | | |
| 146 | const text_segment = bin_file.load_commands.items[bin_file.text_segment_cmd_index.?].Segment; | | |
| 147 | const code_sig_cmd = bin_file.load_commands.items[bin_file.code_signature_cmd_index.?].LinkeditData; | | |
| 148 | | | |
| 149 | const execSegBase: u64 = text_segment.inner.fileoff; | | |
| 150 | const execSegLimit: u64 = text_segment.inner.filesize; | | |
| 151 | const execSegFlags: u64 = if (bin_file.base.options.output_mode == .Exe) macho.CS_EXECSEG_MAIN_BINARY else 0; | | |
| 152 | const file_size = code_sig_cmd.dataoff; | | |
| 153 | var cdir = CodeDirectory{ | | |
| 154 | .inner = .{ | | |
| 155 | .magic = macho.CSMAGIC_CODEDIRECTORY, | | |
| 156 | .length = @sizeOf(macho.CodeDirectory), | | |
| 157 | .version = macho.CS_SUPPORTSEXECSEG, | | |
| 158 | .flags = macho.CS_ADHOC, | | |
| 159 | .hashOffset = 0, | | |
| 160 | .identOffset = 0, | | |
| 161 | .nSpecialSlots = 0, | | |
| 162 | .nCodeSlots = 0, | | |
| 163 | .codeLimit = @intCast(u32, file_size), | | |
| 164 | .hashSize = hash_size, | | |
| 165 | .hashType = macho.CS_HASHTYPE_SHA256, | | |
| 166 | .platform = 0, | | |
| 167 | .pageSize = @truncate(u8, std.math.log2(page_size)), | | |
| 168 | .spare2 = 0, | | |
| 169 | .scatterOffset = 0, | | |
| 170 | .teamOffset = 0, | | |
| 171 | .spare3 = 0, | | |
| 172 | .codeLimit64 = 0, | | |
| 173 | .execSegBase = execSegBase, | | |
| 174 | .execSegLimit = execSegLimit, | | |
| 175 | .execSegFlags = execSegFlags, | | |
| 176 | }, | | |
| 177 | }; | | |
| 178 | | | |
| 179 | const total_pages = mem.alignForward(file_size, page_size) / page_size; | | |
| 180 | | | |
| 181 | var hash: [hash_size]u8 = undefined; | | |
| 182 | var buffer = try bin_file.base.allocator.alloc(u8, page_size); | | |
| 183 | defer bin_file.base.allocator.free(buffer); | | |
| 184 | const macho_file = bin_file.base.file.?; | | |
| 185 | | | |
| 186 | const id = bin_file.base.options.emit.?.sub_path; | | |
| 187 | try cdir.data.ensureCapacity(self.alloc, total_pages * hash_size + id.len + 1); | | |
| 188 | | | |
| 189 | // 1. Save the identifier and update offsets | | |
| 190 | cdir.inner.identOffset = cdir.inner.length; | | |
| 191 | cdir.data.appendSliceAssumeCapacity(id); | | |
| 192 | cdir.data.appendAssumeCapacity(0); | | |
| 193 | | | |
| 194 | // 2. Calculate hash for each page (in file) and write it to the buffer | | |
| 195 | // TODO figure out how we can cache several hashes since we won't update | | |
| 196 | // every page during incremental linking | | |
| 197 | cdir.inner.hashOffset = cdir.inner.identOffset + @intCast(u32, id.len) + 1; | | |
| 198 | var i: usize = 0; | | |
| 199 | while (i < total_pages) : (i += 1) { | | |
| 200 | const fstart = i * page_size; | | |
| 201 | const fsize = if (fstart + page_size > file_size) file_size - fstart else page_size; | | |
| 202 | const len = try macho_file.preadAll(buffer, fstart); | | |
| 203 | assert(fsize <= len); | | |
| 204 | | | |
| 205 | Sha256.hash(buffer[0..fsize], &hash, .{}); | | |
| 206 | | | |
| 207 | cdir.data.appendSliceAssumeCapacity(hash[0..]); | | |
| 208 | cdir.inner.nCodeSlots += 1; | | |
| 209 | } | | |
| 210 | | | |
| 211 | // 3. Update CodeDirectory length | | |
| 212 | cdir.inner.length += @intCast(u32, cdir.data.items.len); | | |
| 213 | | | |
| 214 | self.inner.length += @sizeOf(macho.BlobIndex) + cdir.size(); | | |
| 215 | self.inner.count = 1; | | |
| 216 | self.cdir = cdir; | | |
| 217 | } | | |
| 218 | | | |
| 219 | pub fn size(self: CodeSignature) u32 { | 141 | pub fn size(self: CodeSignature) u32 { |
| 220 | return self.inner.length; | 142 | return self.inner.length; |
| 221 | } | 143 | } |
| ... | @@ -230,7 +152,7 @@ pub fn write(self: CodeSignature, buffer: []u8) void { | ... | @@ -230,7 +152,7 @@ pub fn write(self: CodeSignature, buffer: []u8) void { |
| 230 | | 152 | |
| 231 | pub fn deinit(self: *CodeSignature) void { | 153 | pub fn deinit(self: *CodeSignature) void { |
| 232 | if (self.cdir) |*cdir| { | 154 | if (self.cdir) |*cdir| { |
| 233 | cdir.data.deinit(self.alloc); | 155 | cdir.data.deinit(self.allocator); |
| 234 | } | 156 | } |
| 235 | } | 157 | } |
| 236 | | 158 | |