authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-15 16:04:10+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-16 18:05:58+01:00
logb323e14b1c50d731b643180972361552f8e5f5ec
treeef79cdc6afcba81e76b01cd69d0e9a2daa9d19f1
parent660270b7a9c492dbd7c0b76a823bcba5a13da71c

macho: exclude linkedit and symtab/dysymtab load commands from the uuid calc


1 files changed, 66 insertions(+), 23 deletions(-)

src/link/MachO/zld.zig+66-23
...@@ -2675,7 +2675,11 @@ pub const Zld = struct {...@@ -2675,7 +2675,11 @@ pub const Zld = struct {
2675 self.dysymtab_cmd.nindirectsyms = nindirectsyms;2675 self.dysymtab_cmd.nindirectsyms = nindirectsyms;
2676 }2676 }
26772677
2678 fn writeUuid(self: *Zld, comp: *const Compilation, offset: u32) !void {2678 fn writeUuid(self: *Zld, comp: *const Compilation, args: struct {
2679 linkedit_cmd_offset: u32,
2680 symtab_cmd_offset: u32,
2681 uuid_cmd_offset: u32,
2682 }) !void {
2679 switch (self.options.optimize_mode) {2683 switch (self.options.optimize_mode) {
2680 .Debug => {2684 .Debug => {
2681 // In Debug we don't really care about reproducibility, so put in a random value2685 // In Debug we don't really care about reproducibility, so put in a random value
...@@ -2691,8 +2695,24 @@ pub const Zld = struct {...@@ -2691,8 +2695,24 @@ pub const Zld = struct {
2691 var hashes = std.ArrayList([Md5.digest_length]u8).init(self.gpa);2695 var hashes = std.ArrayList([Md5.digest_length]u8).init(self.gpa);
2692 defer hashes.deinit();2696 defer hashes.deinit();
26932697
2698 var subsections: [4]FileSubsection = undefined;
2699 var count: usize = 2;
2700
2701 // Exclude LINKEDIT segment command as it contains file size that includes stabs contribution
2702 // and code signature.
2703 subsections[0] = .{
2704 .start = 0,
2705 .end = args.linkedit_cmd_offset,
2706 };
2707
2708 // Exclude SYMTAB and DYSYMTAB commands for the same reason.
2709 subsections[1] = .{
2710 .start = args.linkedit_cmd_offset + @sizeOf(macho.segment_command_64),
2711 .end = args.symtab_cmd_offset,
2712 };
2713
2694 if (!self.options.strip) {2714 if (!self.options.strip) {
2695 // First exclusion region will comprise all symbol stabs.2715 // Exclude region comprising all symbol stabs.
2696 const nlocals = self.dysymtab_cmd.nlocalsym;2716 const nlocals = self.dysymtab_cmd.nlocalsym;
26972717
2698 const locals_buf = try self.gpa.alloc(u8, nlocals * @sizeOf(macho.nlist_64));2718 const locals_buf = try self.gpa.alloc(u8, nlocals * @sizeOf(macho.nlist_64));
...@@ -2706,26 +2726,40 @@ pub const Zld = struct {...@@ -2706,26 +2726,40 @@ pub const Zld = struct {
2706 if (local.stab()) break i;2726 if (local.stab()) break i;
2707 } else locals.len;2727 } else locals.len;
2708 const nstabs = locals.len - istab;2728 const nstabs = locals.len - istab;
27092729 if (nstabs == 0) {
2710 // Next, a subsection of the strtab.2730 subsections[2] = .{
2711 // We do not care about anything succeeding strtab as it is the code signature data which is2731 .start = args.symtab_cmd_offset + @sizeOf(macho.symtab_command) + @sizeOf(macho.dysymtab_command),
2712 // not part of the UUID calculation anyway.2732 .end = max_file_size,
2713 const stab_stroff = locals[istab].n_strx;2733 };
27142734 count += 1;
2715 const first_cut = FileSubsection{2735 } else {
2716 .start = 0,2736 // Exclude a subsection of the strtab with names of the stabs.
2717 .end = @intCast(u32, self.symtab_cmd.symoff + istab * @sizeOf(macho.nlist_64)),2737 // We do not care about anything succeeding strtab as it is the code signature data which is
2718 };2738 // not part of the UUID calculation anyway.
2719 const second_cut = FileSubsection{2739 const stab_stroff = locals[istab].n_strx;
2720 .start = first_cut.end + @intCast(u32, nstabs * @sizeOf(macho.nlist_64)),2740
2721 .end = self.symtab_cmd.stroff + stab_stroff,2741 subsections[2] = .{
2722 };2742 .start = args.symtab_cmd_offset + @sizeOf(macho.symtab_command) + @sizeOf(macho.dysymtab_command),
27232743 .end = @intCast(u32, self.symtab_cmd.symoff + istab * @sizeOf(macho.nlist_64)),
2724 for (&[_]FileSubsection{ first_cut, second_cut }) |cut| {2744 };
2725 try self.calcUuidHashes(comp, cut, &hashes);2745 subsections[3] = .{
2746 .start = subsections[2].end + @intCast(u32, nstabs * @sizeOf(macho.nlist_64)),
2747 .end = self.symtab_cmd.stroff + stab_stroff,
2748 };
2749
2750 count += 2;
2726 }2751 }
2727 } else {2752 } else {
2728 try self.calcUuidHashes(comp, .{ .start = 0, .end = max_file_size }, &hashes);2753 subsections[2] = .{
2754 .start = args.symtab_cmd_offset + @sizeOf(macho.symtab_command) + @sizeOf(macho.dysymtab_command),
2755 .end = max_file_size,
2756 };
2757 count += 1;
2758 }
2759
2760 for (subsections[0..count]) |cut| {
2761 std.debug.print("{x} - {x}\n", .{ cut.start, cut.end });
2762 try self.calcUuidHashes(comp, cut, &hashes);
2729 }2763 }
27302764
2731 const final_buffer = try self.gpa.alloc(u8, hashes.items.len * Md5.digest_length);2765 const final_buffer = try self.gpa.alloc(u8, hashes.items.len * Md5.digest_length);
...@@ -2740,7 +2774,7 @@ pub const Zld = struct {...@@ -2740,7 +2774,7 @@ pub const Zld = struct {
2740 },2774 },
2741 }2775 }
27422776
2743 const in_file = @sizeOf(macho.mach_header_64) + offset + @sizeOf(macho.load_command);2777 const in_file = args.uuid_cmd_offset + @sizeOf(macho.load_command);
2744 try self.file.pwriteAll(&self.uuid_cmd.uuid, in_file);2778 try self.file.pwriteAll(&self.uuid_cmd.uuid, in_file);
2745 }2779 }
27462780
...@@ -4057,11 +4091,16 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -4057,11 +4091,16 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
4057 const lc_writer = lc_buffer.writer();4091 const lc_writer = lc_buffer.writer();
40584092
4059 try zld.writeSegmentHeaders(lc_writer);4093 try zld.writeSegmentHeaders(lc_writer);
4094 const linkedit_cmd_offset = @sizeOf(macho.mach_header_64) + @intCast(u32, lc_buffer.items.len - @sizeOf(macho.segment_command_64));
4095
4060 try lc_writer.writeStruct(zld.dyld_info_cmd);4096 try lc_writer.writeStruct(zld.dyld_info_cmd);
4061 try lc_writer.writeStruct(zld.function_starts_cmd);4097 try lc_writer.writeStruct(zld.function_starts_cmd);
4062 try lc_writer.writeStruct(zld.data_in_code_cmd);4098 try lc_writer.writeStruct(zld.data_in_code_cmd);
4099
4100 const symtab_cmd_offset = @sizeOf(macho.mach_header_64) + @intCast(u32, lc_buffer.items.len);
4063 try lc_writer.writeStruct(zld.symtab_cmd);4101 try lc_writer.writeStruct(zld.symtab_cmd);
4064 try lc_writer.writeStruct(zld.dysymtab_cmd);4102 try lc_writer.writeStruct(zld.dysymtab_cmd);
4103
4065 try load_commands.writeDylinkerLC(lc_writer);4104 try load_commands.writeDylinkerLC(lc_writer);
40664105
4067 if (zld.options.output_mode == .Exe) {4106 if (zld.options.output_mode == .Exe) {
...@@ -4084,7 +4123,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -4084,7 +4123,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
4084 });4123 });
4085 try load_commands.writeBuildVersionLC(zld.options, lc_writer);4124 try load_commands.writeBuildVersionLC(zld.options, lc_writer);
40864125
4087 const uuid_offset = @intCast(u32, lc_buffer.items.len);4126 const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + @intCast(u32, lc_buffer.items.len);
4088 try lc_writer.writeStruct(zld.uuid_cmd);4127 try lc_writer.writeStruct(zld.uuid_cmd);
40894128
4090 try load_commands.writeLoadDylibLCs(zld.dylibs.items, zld.referenced_dylibs.keys(), lc_writer);4129 try load_commands.writeLoadDylibLCs(zld.dylibs.items, zld.referenced_dylibs.keys(), lc_writer);
...@@ -4115,7 +4154,11 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -4115,7 +4154,11 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
4115 try zld.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64));4154 try zld.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64));
4116 try zld.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len));4155 try zld.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len));
41174156
4118 try zld.writeUuid(comp, uuid_offset);4157 try zld.writeUuid(comp, .{
4158 .linkedit_cmd_offset = linkedit_cmd_offset,
4159 .symtab_cmd_offset = symtab_cmd_offset,
4160 .uuid_cmd_offset = uuid_cmd_offset,
4161 });
41194162
4120 if (codesig) |*csig| {4163 if (codesig) |*csig| {
4121 try zld.writeCodeSignature(comp, csig); // code signing always comes last4164 try zld.writeCodeSignature(comp, csig); // code signing always comes last