authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-26 21:16:53+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-31 10:19:04+01:00
log0ff56e8bb14273fa8abe4503855e9f53d699c8cd
treefe601218cccefa19aaf4b2f4ff427cd8dd35c35d
parente1451f92f8e49f844c528386c4463c9b6fc9a0f3

macho: add and populate UUID load command


2 files changed, 25 insertions(+), 0 deletions(-)

src/link/MachO.zig+17
...@@ -74,6 +74,8 @@ main_cmd_index: ?u16 = null,...@@ -74,6 +74,8 @@ main_cmd_index: ?u16 = null,
74version_min_cmd_index: ?u16 = null,74version_min_cmd_index: ?u16 = null,
75/// Source version75/// Source version
76source_version_cmd_index: ?u16 = null,76source_version_cmd_index: ?u16 = null,
77/// UUID load command
78uuid_cmd_index: ?u16 = null,
77/// Code signature79/// Code signature
78code_signature_cmd_index: ?u16 = null,80code_signature_cmd_index: ?u16 = null,
7981
...@@ -1609,6 +1611,18 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1609,6 +1611,18 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1609 self.header_dirty = true;1611 self.header_dirty = true;
1610 self.load_commands_dirty = true;1612 self.load_commands_dirty = true;
1611 }1613 }
1614 if (self.uuid_cmd_index == null) {
1615 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
1616 var uuid_cmd: macho.uuid_command = .{
1617 .cmd = macho.LC_UUID,
1618 .cmdsize = @sizeOf(macho.uuid_command),
1619 .uuid = undefined,
1620 };
1621 std.crypto.random.bytes(&uuid_cmd.uuid);
1622 try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd });
1623 self.header_dirty = true;
1624 self.load_commands_dirty = true;
1625 }
1612 if (self.code_signature_cmd_index == null) {1626 if (self.code_signature_cmd_index == null) {
1613 self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);1627 self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);
1614 try self.load_commands.append(self.base.allocator, .{1628 try self.load_commands.append(self.base.allocator, .{
...@@ -2347,6 +2361,9 @@ fn parseFromFile(self: *MachO, file: fs.File) !void {...@@ -2347,6 +2361,9 @@ fn parseFromFile(self: *MachO, file: fs.File) !void {
2347 macho.LC_SOURCE_VERSION => {2361 macho.LC_SOURCE_VERSION => {
2348 self.source_version_cmd_index = i;2362 self.source_version_cmd_index = i;
2349 },2363 },
2364 macho.LC_UUID => {
2365 self.uuid_cmd_index = i;
2366 },
2350 macho.LC_MAIN => {2367 macho.LC_MAIN => {
2351 self.main_cmd_index = i;2368 self.main_cmd_index = i;
2352 },2369 },
src/link/MachO/commands.zig+8
...@@ -23,6 +23,7 @@ pub const LoadCommand = union(enum) {...@@ -23,6 +23,7 @@ pub const LoadCommand = union(enum) {
23 Main: macho.entry_point_command,23 Main: macho.entry_point_command,
24 VersionMin: macho.version_min_command,24 VersionMin: macho.version_min_command,
25 SourceVersion: macho.source_version_command,25 SourceVersion: macho.source_version_command,
26 Uuid: macho.uuid_command,
26 LinkeditData: macho.linkedit_data_command,27 LinkeditData: macho.linkedit_data_command,
27 Unknown: GenericCommandWithData(macho.load_command),28 Unknown: GenericCommandWithData(macho.load_command),
2829
...@@ -62,6 +63,9 @@ pub const LoadCommand = union(enum) {...@@ -62,6 +63,9 @@ pub const LoadCommand = union(enum) {
62 macho.LC_SOURCE_VERSION => LoadCommand{63 macho.LC_SOURCE_VERSION => LoadCommand{
63 .SourceVersion = try stream.reader().readStruct(macho.source_version_command),64 .SourceVersion = try stream.reader().readStruct(macho.source_version_command),
64 },65 },
66 macho.LC_UUID => LoadCommand{
67 .Uuid = try stream.reader().readStruct(macho.uuid_command),
68 },
65 macho.LC_FUNCTION_STARTS, macho.LC_DATA_IN_CODE, macho.LC_CODE_SIGNATURE => LoadCommand{69 macho.LC_FUNCTION_STARTS, macho.LC_DATA_IN_CODE, macho.LC_CODE_SIGNATURE => LoadCommand{
66 .LinkeditData = try stream.reader().readStruct(macho.linkedit_data_command),70 .LinkeditData = try stream.reader().readStruct(macho.linkedit_data_command),
67 },71 },
...@@ -79,6 +83,7 @@ pub const LoadCommand = union(enum) {...@@ -79,6 +83,7 @@ pub const LoadCommand = union(enum) {
79 .Main => |x| writeStruct(x, writer),83 .Main => |x| writeStruct(x, writer),
80 .VersionMin => |x| writeStruct(x, writer),84 .VersionMin => |x| writeStruct(x, writer),
81 .SourceVersion => |x| writeStruct(x, writer),85 .SourceVersion => |x| writeStruct(x, writer),
86 .Uuid => |x| writeStruct(x, writer),
82 .LinkeditData => |x| writeStruct(x, writer),87 .LinkeditData => |x| writeStruct(x, writer),
83 .Segment => |x| x.write(writer),88 .Segment => |x| x.write(writer),
84 .Dylinker => |x| x.write(writer),89 .Dylinker => |x| x.write(writer),
...@@ -95,6 +100,7 @@ pub const LoadCommand = union(enum) {...@@ -95,6 +100,7 @@ pub const LoadCommand = union(enum) {
95 .Main => |x| x.cmd,100 .Main => |x| x.cmd,
96 .VersionMin => |x| x.cmd,101 .VersionMin => |x| x.cmd,
97 .SourceVersion => |x| x.cmd,102 .SourceVersion => |x| x.cmd,
103 .Uuid => |x| x.cmd,
98 .LinkeditData => |x| x.cmd,104 .LinkeditData => |x| x.cmd,
99 .Segment => |x| x.inner.cmd,105 .Segment => |x| x.inner.cmd,
100 .Dylinker => |x| x.inner.cmd,106 .Dylinker => |x| x.inner.cmd,
...@@ -112,6 +118,7 @@ pub const LoadCommand = union(enum) {...@@ -112,6 +118,7 @@ pub const LoadCommand = union(enum) {
112 .VersionMin => |x| x.cmdsize,118 .VersionMin => |x| x.cmdsize,
113 .SourceVersion => |x| x.cmdsize,119 .SourceVersion => |x| x.cmdsize,
114 .LinkeditData => |x| x.cmdsize,120 .LinkeditData => |x| x.cmdsize,
121 .Uuid => |x| x.cmdsize,
115 .Segment => |x| x.inner.cmdsize,122 .Segment => |x| x.inner.cmdsize,
116 .Dylinker => |x| x.inner.cmdsize,123 .Dylinker => |x| x.inner.cmdsize,
117 .Dylib => |x| x.inner.cmdsize,124 .Dylib => |x| x.inner.cmdsize,
...@@ -142,6 +149,7 @@ pub const LoadCommand = union(enum) {...@@ -142,6 +149,7 @@ pub const LoadCommand = union(enum) {
142 .Main => |x| meta.eql(x, other.Main),149 .Main => |x| meta.eql(x, other.Main),
143 .VersionMin => |x| meta.eql(x, other.VersionMin),150 .VersionMin => |x| meta.eql(x, other.VersionMin),
144 .SourceVersion => |x| meta.eql(x, other.SourceVersion),151 .SourceVersion => |x| meta.eql(x, other.SourceVersion),
152 .Uuid => |x| meta.eql(x, other.Uuid),
145 .LinkeditData => |x| meta.eql(x, other.LinkeditData),153 .LinkeditData => |x| meta.eql(x, other.LinkeditData),
146 .Segment => |x| x.eql(other.Segment),154 .Segment => |x| x.eql(other.Segment),
147 .Dylinker => |x| x.eql(other.Dylinker),155 .Dylinker => |x| x.eql(other.Dylinker),