Commit 0ff56e8bb1

Jakub Konka <kubkon@jakubkonka.com>
2020-12-26 21:16:53
macho: add and populate UUID load command
1 parent e1451f9
Changed files (2)
src
src/link/MachO/commands.zig
@@ -23,6 +23,7 @@ pub const LoadCommand = union(enum) {
     Main: macho.entry_point_command,
     VersionMin: macho.version_min_command,
     SourceVersion: macho.source_version_command,
+    Uuid: macho.uuid_command,
     LinkeditData: macho.linkedit_data_command,
     Unknown: GenericCommandWithData(macho.load_command),
 
@@ -62,6 +63,9 @@ pub const LoadCommand = union(enum) {
             macho.LC_SOURCE_VERSION => LoadCommand{
                 .SourceVersion = try stream.reader().readStruct(macho.source_version_command),
             },
+            macho.LC_UUID => LoadCommand{
+                .Uuid = try stream.reader().readStruct(macho.uuid_command),
+            },
             macho.LC_FUNCTION_STARTS, macho.LC_DATA_IN_CODE, macho.LC_CODE_SIGNATURE => LoadCommand{
                 .LinkeditData = try stream.reader().readStruct(macho.linkedit_data_command),
             },
@@ -79,6 +83,7 @@ pub const LoadCommand = union(enum) {
             .Main => |x| writeStruct(x, writer),
             .VersionMin => |x| writeStruct(x, writer),
             .SourceVersion => |x| writeStruct(x, writer),
+            .Uuid => |x| writeStruct(x, writer),
             .LinkeditData => |x| writeStruct(x, writer),
             .Segment => |x| x.write(writer),
             .Dylinker => |x| x.write(writer),
@@ -95,6 +100,7 @@ pub const LoadCommand = union(enum) {
             .Main => |x| x.cmd,
             .VersionMin => |x| x.cmd,
             .SourceVersion => |x| x.cmd,
+            .Uuid => |x| x.cmd,
             .LinkeditData => |x| x.cmd,
             .Segment => |x| x.inner.cmd,
             .Dylinker => |x| x.inner.cmd,
@@ -112,6 +118,7 @@ pub const LoadCommand = union(enum) {
             .VersionMin => |x| x.cmdsize,
             .SourceVersion => |x| x.cmdsize,
             .LinkeditData => |x| x.cmdsize,
+            .Uuid => |x| x.cmdsize,
             .Segment => |x| x.inner.cmdsize,
             .Dylinker => |x| x.inner.cmdsize,
             .Dylib => |x| x.inner.cmdsize,
@@ -142,6 +149,7 @@ pub const LoadCommand = union(enum) {
             .Main => |x| meta.eql(x, other.Main),
             .VersionMin => |x| meta.eql(x, other.VersionMin),
             .SourceVersion => |x| meta.eql(x, other.SourceVersion),
+            .Uuid => |x| meta.eql(x, other.Uuid),
             .LinkeditData => |x| meta.eql(x, other.LinkeditData),
             .Segment => |x| x.eql(other.Segment),
             .Dylinker => |x| x.eql(other.Dylinker),
src/link/MachO.zig
@@ -74,6 +74,8 @@ main_cmd_index: ?u16 = null,
 version_min_cmd_index: ?u16 = null,
 /// Source version
 source_version_cmd_index: ?u16 = null,
+/// UUID load command
+uuid_cmd_index: ?u16 = null,
 /// Code signature
 code_signature_cmd_index: ?u16 = null,
 
@@ -1609,6 +1611,18 @@ pub fn populateMissingMetadata(self: *MachO) !void {
         self.header_dirty = true;
         self.load_commands_dirty = true;
     }
+    if (self.uuid_cmd_index == null) {
+        self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
+        var uuid_cmd: macho.uuid_command = .{
+            .cmd = macho.LC_UUID,
+            .cmdsize = @sizeOf(macho.uuid_command),
+            .uuid = undefined,
+        };
+        std.crypto.random.bytes(&uuid_cmd.uuid);
+        try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd });
+        self.header_dirty = true;
+        self.load_commands_dirty = true;
+    }
     if (self.code_signature_cmd_index == null) {
         self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);
         try self.load_commands.append(self.base.allocator, .{
@@ -2347,6 +2361,9 @@ fn parseFromFile(self: *MachO, file: fs.File) !void {
             macho.LC_SOURCE_VERSION => {
                 self.source_version_cmd_index = i;
             },
+            macho.LC_UUID => {
+                self.uuid_cmd_index = i;
+            },
             macho.LC_MAIN => {
                 self.main_cmd_index = i;
             },