| ... | ... | @@ -62,6 +62,10 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 |
| 62 | 62 | assume_max_path_len, |
| 63 | 63 | ); |
| 64 | 64 | } |
| 65 | // LC_ENCRYPTION_INFO_64 |
| 66 | if (macho_file.needsEncryptionInfo()) { |
| 67 | sizeofcmds += @sizeOf(macho.encryption_info_command_64); |
| 68 | } |
| 65 | 69 | // LC_RPATH |
| 66 | 70 | { |
| 67 | 71 | for (macho_file.rpath_list) |rpath| { |
| ... | ... | @@ -163,23 +167,29 @@ pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 { |
| 163 | 167 | return @as(u32, @intCast(sizeofcmds)); |
| 164 | 168 | } |
| 165 | 169 | |
| 166 | | pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 { |
| 170 | pub fn calcMinHeaderSize(macho_file: *MachO) !u32 { |
| 167 | 171 | var padding: u32 = (try calcLoadCommandsSize(macho_file, false)) + |
| 168 | 172 | (macho_file.headerpad_size orelse MachO.default_headerpad_size); |
| 169 | | log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); |
| 173 | log.debug("minimum requested header + padding size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); |
| 170 | 174 | |
| 171 | 175 | if (macho_file.headerpad_max_install_names) { |
| 172 | 176 | const min_headerpad_size: u32 = try calcLoadCommandsSize(macho_file, true); |
| 173 | | log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{ |
| 177 | log.debug("headerpad_max_install_names minimum header + padding size 0x{x}", .{ |
| 174 | 178 | min_headerpad_size + @sizeOf(macho.mach_header_64), |
| 175 | 179 | }); |
| 176 | 180 | padding = @max(padding, min_headerpad_size); |
| 177 | 181 | } |
| 178 | 182 | |
| 179 | 183 | const offset = @sizeOf(macho.mach_header_64) + padding; |
| 180 | | log.debug("actual headerpad size 0x{x}", .{offset}); |
| 184 | log.debug("actual header + padding size 0x{x}", .{offset}); |
| 181 | 185 | |
| 182 | | return offset; |
| 186 | // Encryption is done at page granularity, so if the output needs a load |
| 187 | // command for encryption info, ensure that the header + load commands have |
| 188 | // at least one full, unencrypted page. |
| 189 | return if (macho_file.needsEncryptionInfo()) |
| 190 | mem.alignForward(u32, offset, macho_file.getPageSize()) |
| 191 | else |
| 192 | offset; |
| 183 | 193 | } |
| 184 | 194 | |
| 185 | 195 | pub fn writeDylinkerLC(writer: *Writer) !void { |
| ... | ... | @@ -260,6 +270,13 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: *Writer) !void { |
| 260 | 270 | }, writer); |
| 261 | 271 | } |
| 262 | 272 | |
| 273 | pub fn writeEncryptionInfoLC(macho_file: *MachO, writer: *Writer) !void { |
| 274 | try writer.writeAll(mem.asBytes(&macho.encryption_info_command_64{ |
| 275 | .cryptoff = macho_file.header_size.?, |
| 276 | .cryptsize = @as(u32, @intCast(macho_file.getTextSegment().filesize)) - macho_file.header_size.?, |
| 277 | })); |
| 278 | } |
| 279 | |
| 263 | 280 | pub fn writeRpathLC(rpath: []const u8, writer: *Writer) !void { |
| 264 | 281 | const rpath_len = rpath.len + 1; |
| 265 | 282 | const cmdsize = @as(u32, @intCast(mem.alignForward( |