authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-14 13:56:52+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-16 00:01:04+01:00
logec40c6b28fb1612f401db3c43b68aba670327e2e
tree984df1c4af912f44c2e19e822539c79dc94e5c6c
parentdb2052bc3588c1c52494eef32ef66c5cf3e09d96

macho: calculate UUID as a streaming MD5 hash of the file contents


3 files changed, 29 insertions(+), 9 deletions(-)

CMakeLists.txt+1
...@@ -593,6 +593,7 @@ set(ZIG_STAGE2_SOURCES...@@ -593,6 +593,7 @@ set(ZIG_STAGE2_SOURCES
593 "${CMAKE_SOURCE_DIR}/src/link/MachO/fat.zig"593 "${CMAKE_SOURCE_DIR}/src/link/MachO/fat.zig"
594 "${CMAKE_SOURCE_DIR}/src/link/MachO/load_commands.zig"594 "${CMAKE_SOURCE_DIR}/src/link/MachO/load_commands.zig"
595 "${CMAKE_SOURCE_DIR}/src/link/MachO/thunks.zig"595 "${CMAKE_SOURCE_DIR}/src/link/MachO/thunks.zig"
596 "${CMAKE_SOURCE_DIR}/src/link/MachO/uuid.zig"
596 "${CMAKE_SOURCE_DIR}/src/link/MachO/zld.zig"597 "${CMAKE_SOURCE_DIR}/src/link/MachO/zld.zig"
597 "${CMAKE_SOURCE_DIR}/src/link/Plan9.zig"598 "${CMAKE_SOURCE_DIR}/src/link/Plan9.zig"
598 "${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig"599 "${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig"
src/link/MachO/load_commands.zig+9
...@@ -323,3 +323,12 @@ pub fn writeSourceVersionLC(ncmds: *u32, lc_writer: anytype) !void {...@@ -323,3 +323,12 @@ pub fn writeSourceVersionLC(ncmds: *u32, lc_writer: anytype) !void {
323 });323 });
324 ncmds.* += 1;324 ncmds.* += 1;
325}325}
326
327pub fn writeUuidLC(uuid: *const [16]u8, ncmds: *u32, lc_writer: anytype) !void {
328 var uuid_lc = macho.uuid_command{
329 .cmdsize = @sizeOf(macho.uuid_command),
330 .uuid = uuid.*,
331 };
332 try lc_writer.writeStruct(uuid_lc);
333 ncmds.* += 1;
334}
src/link/MachO/zld.zig+19-9
...@@ -16,6 +16,7 @@ const link = @import("../../link.zig");...@@ -16,6 +16,7 @@ const link = @import("../../link.zig");
16const load_commands = @import("load_commands.zig");16const load_commands = @import("load_commands.zig");
17const thunks = @import("thunks.zig");17const thunks = @import("thunks.zig");
18const trace = @import("../../tracy.zig").trace;18const trace = @import("../../tracy.zig").trace;
19const uuid = @import("uuid.zig");
1920
20const Allocator = mem.Allocator;21const Allocator = mem.Allocator;
21const Archive = @import("Archive.zig");22const Archive = @import("Archive.zig");
...@@ -3986,6 +3987,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -3986,6 +3987,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
39863987
3987 var lc_buffer = std.ArrayList(u8).init(arena);3988 var lc_buffer = std.ArrayList(u8).init(arena);
3988 const lc_writer = lc_buffer.writer();3989 const lc_writer = lc_buffer.writer();
3990
3989 var ncmds: u32 = 0;3991 var ncmds: u32 = 0;
39903992
3991 try zld.writeLinkeditSegmentData(&ncmds, lc_writer, reverse_lookups);3993 try zld.writeLinkeditSegmentData(&ncmds, lc_writer, reverse_lookups);
...@@ -4030,15 +4032,14 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -4030,15 +4032,14 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
4030 try load_commands.writeSourceVersionLC(&ncmds, lc_writer);4032 try load_commands.writeSourceVersionLC(&ncmds, lc_writer);
4031 try load_commands.writeBuildVersionLC(zld.options, &ncmds, lc_writer);4033 try load_commands.writeBuildVersionLC(zld.options, &ncmds, lc_writer);
40324034
4033 {4035 // Looking forward into the future, we will want to offer `-no_uuid` support in which case
4034 var uuid_lc = macho.uuid_command{4036 // there will be nothing to backpatch.
4035 .cmdsize = @sizeOf(macho.uuid_command),4037 const uuid_offset_backpatch: ?usize = blk: {
4036 .uuid = undefined,4038 const index = lc_buffer.items.len;
4037 };4039 var uuid_buf: [16]u8 = [_]u8{0} ** 16;
4038 std.crypto.random.bytes(&uuid_lc.uuid);4040 try load_commands.writeUuidLC(&uuid_buf, &ncmds, lc_writer);
4039 try lc_writer.writeStruct(uuid_lc);4041 break :blk index;
4040 ncmds += 1;4042 };
4041 }
40424043
4043 try load_commands.writeLoadDylibLCs(zld.dylibs.items, zld.referenced_dylibs.keys(), &ncmds, lc_writer);4044 try load_commands.writeLoadDylibLCs(zld.dylibs.items, zld.referenced_dylibs.keys(), &ncmds, lc_writer);
40444045
...@@ -4071,6 +4072,15 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -4071,6 +4072,15 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
4071 try zld.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len);4072 try zld.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len);
4072 try zld.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len + headers_buf.items.len));4073 try zld.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len + headers_buf.items.len));
40734074
4075 if (uuid_offset_backpatch) |backpatch| {
4076 const seg = zld.getLinkeditSegmentPtr();
4077 const file_size = seg.fileoff + seg.filesize;
4078 var uuid_buf: [16]u8 = undefined;
4079 try uuid.calcMd5Hash(zld.gpa, zld.file, file_size, &uuid_buf);
4080 const offset = @sizeOf(macho.mach_header_64) + headers_buf.items.len + backpatch + @sizeOf(macho.load_command);
4081 try zld.file.pwriteAll(&uuid_buf, offset);
4082 }
4083
4074 if (codesig) |*csig| {4084 if (codesig) |*csig| {
4075 try zld.writeCodeSignature(comp, csig, codesig_offset.?); // code signing always comes last4085 try zld.writeCodeSignature(comp, csig, codesig_offset.?); // code signing always comes last
4076 }4086 }