| ... | @@ -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 | } |
| 2677 | | 2677 | |
| 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 value | 2685 | // 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(); |
| 2693 | | 2697 | |
| | 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; |
| 2697 | | 2717 | |
| 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; |
| 2709 | | 2729 | 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 is | 2731 | .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 | }; |
| 2714 | | 2734 | 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), |
| 2723 | | 2743 | .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 | } |
| 2730 | | 2764 | |
| 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 | } |
| 2742 | | 2776 | |
| 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 | } |
| 2746 | | 2780 | |
| ... | @@ -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(); |
| 4058 | | 4092 | |
| 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); |
| 4066 | | 4105 | |
| 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); |
| 4086 | | 4125 | |
| 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); |
| 4089 | | 4128 | |
| 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)); |
| 4117 | | 4156 | |
| 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 | }); |
| 4119 | | 4162 | |
| 4120 | if (codesig) |*csig| { | 4163 | if (codesig) |*csig| { |
| 4121 | try zld.writeCodeSignature(comp, csig); // code signing always comes last | 4164 | try zld.writeCodeSignature(comp, csig); // code signing always comes last |