| ... | ... | @@ -25,10 +25,10 @@ usingnamespace @import("bind.zig"); |
| 25 | 25 | |
| 26 | 26 | allocator: *Allocator, |
| 27 | 27 | |
| 28 | | arch: ?std.Target.Cpu.Arch = null, |
| 28 | target: ?std.Target = null, |
| 29 | 29 | page_size: ?u16 = null, |
| 30 | 30 | file: ?fs.File = null, |
| 31 | | out_path: ?[]const u8 = null, |
| 31 | output: ?Output = null, |
| 32 | 32 | |
| 33 | 33 | // TODO these args will become obselete once Zld is coalesced with incremental |
| 34 | 34 | // linker. |
| ... | ... | @@ -54,6 +54,7 @@ dylinker_cmd_index: ?u16 = null, |
| 54 | 54 | data_in_code_cmd_index: ?u16 = null, |
| 55 | 55 | function_starts_cmd_index: ?u16 = null, |
| 56 | 56 | main_cmd_index: ?u16 = null, |
| 57 | dylib_id_cmd_index: ?u16 = null, |
| 57 | 58 | version_min_cmd_index: ?u16 = null, |
| 58 | 59 | source_version_cmd_index: ?u16 = null, |
| 59 | 60 | uuid_cmd_index: ?u16 = null, |
| ... | ... | @@ -118,6 +119,12 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{}, |
| 118 | 119 | |
| 119 | 120 | stub_helper_stubs_start_off: ?u64 = null, |
| 120 | 121 | |
| 122 | pub const Output = struct { |
| 123 | tag: enum { exe, dylib }, |
| 124 | path: []const u8, |
| 125 | install_name: ?[]const u8 = null, |
| 126 | }; |
| 127 | |
| 121 | 128 | const TlvOffset = struct { |
| 122 | 129 | source_addr: u64, |
| 123 | 130 | offset: u64, |
| ... | ... | @@ -200,36 +207,17 @@ const LinkArgs = struct { |
| 200 | 207 | rpaths: []const []const u8, |
| 201 | 208 | }; |
| 202 | 209 | |
| 203 | | pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: LinkArgs) !void { |
| 210 | pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArgs) !void { |
| 204 | 211 | if (files.len == 0) return error.NoInputFiles; |
| 205 | | if (out_path.len == 0) return error.EmptyOutputPath; |
| 206 | | |
| 207 | | if (self.arch == null) { |
| 208 | | // Try inferring the arch from the object files. |
| 209 | | self.arch = blk: { |
| 210 | | const file = try fs.cwd().openFile(files[0], .{}); |
| 211 | | defer file.close(); |
| 212 | | var reader = file.reader(); |
| 213 | | const header = try reader.readStruct(macho.mach_header_64); |
| 214 | | const arch: std.Target.Cpu.Arch = switch (header.cputype) { |
| 215 | | macho.CPU_TYPE_X86_64 => .x86_64, |
| 216 | | macho.CPU_TYPE_ARM64 => .aarch64, |
| 217 | | else => |value| { |
| 218 | | log.err("unsupported cpu architecture 0x{x}", .{value}); |
| 219 | | return error.UnsupportedCpuArchitecture; |
| 220 | | }, |
| 221 | | }; |
| 222 | | break :blk arch; |
| 223 | | }; |
| 224 | | } |
| 212 | if (output.path.len == 0) return error.EmptyOutputPath; |
| 225 | 213 | |
| 226 | | self.page_size = switch (self.arch.?) { |
| 214 | self.page_size = switch (self.target.?.cpu.arch) { |
| 227 | 215 | .aarch64 => 0x4000, |
| 228 | 216 | .x86_64 => 0x1000, |
| 229 | 217 | else => unreachable, |
| 230 | 218 | }; |
| 231 | | self.out_path = out_path; |
| 232 | | self.file = try fs.cwd().createFile(out_path, .{ |
| 219 | self.output = output; |
| 220 | self.file = try fs.cwd().createFile(self.output.?.path, .{ |
| 233 | 221 | .truncate = true, |
| 234 | 222 | .read = true, |
| 235 | 223 | .mode = if (std.Target.current.os.tag == .windows) 0 else 0o777, |
| ... | ... | @@ -263,19 +251,19 @@ fn parseInputFiles(self: *Zld, files: []const []const u8, syslibroot: ?[]const u |
| 263 | 251 | break :full_path try self.allocator.dupe(u8, path); |
| 264 | 252 | }; |
| 265 | 253 | |
| 266 | | if (try Object.createAndParseFromPath(self.allocator, self.arch.?, full_path)) |object| { |
| 254 | if (try Object.createAndParseFromPath(self.allocator, self.target.?.cpu.arch, full_path)) |object| { |
| 267 | 255 | try self.objects.append(self.allocator, object); |
| 268 | 256 | continue; |
| 269 | 257 | } |
| 270 | 258 | |
| 271 | | if (try Archive.createAndParseFromPath(self.allocator, self.arch.?, full_path)) |archive| { |
| 259 | if (try Archive.createAndParseFromPath(self.allocator, self.target.?.cpu.arch, full_path)) |archive| { |
| 272 | 260 | try self.archives.append(self.allocator, archive); |
| 273 | 261 | continue; |
| 274 | 262 | } |
| 275 | 263 | |
| 276 | 264 | if (try Dylib.createAndParseFromPath( |
| 277 | 265 | self.allocator, |
| 278 | | self.arch.?, |
| 266 | self.target.?.cpu.arch, |
| 279 | 267 | full_path, |
| 280 | 268 | .{ .syslibroot = syslibroot }, |
| 281 | 269 | )) |dylibs| { |
| ... | ... | @@ -292,7 +280,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi |
| 292 | 280 | for (libs) |lib| { |
| 293 | 281 | if (try Dylib.createAndParseFromPath( |
| 294 | 282 | self.allocator, |
| 295 | | self.arch.?, |
| 283 | self.target.?.cpu.arch, |
| 296 | 284 | lib, |
| 297 | 285 | .{ .syslibroot = syslibroot }, |
| 298 | 286 | )) |dylibs| { |
| ... | ... | @@ -301,7 +289,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi |
| 301 | 289 | continue; |
| 302 | 290 | } |
| 303 | 291 | |
| 304 | | if (try Archive.createAndParseFromPath(self.allocator, self.arch.?, lib)) |archive| { |
| 292 | if (try Archive.createAndParseFromPath(self.allocator, self.target.?.cpu.arch, lib)) |archive| { |
| 305 | 293 | try self.archives.append(self.allocator, archive); |
| 306 | 294 | continue; |
| 307 | 295 | } |
| ... | ... | @@ -989,7 +977,7 @@ fn allocateTextSegment(self: *Zld) !void { |
| 989 | 977 | const stub_helper = &seg.sections.items[self.stub_helper_section_index.?]; |
| 990 | 978 | stubs.size += nstubs * stubs.reserved2; |
| 991 | 979 | |
| 992 | | const stub_size: u4 = switch (self.arch.?) { |
| 980 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 993 | 981 | .x86_64 => 10, |
| 994 | 982 | .aarch64 => 3 * @sizeOf(u32), |
| 995 | 983 | else => unreachable, |
| ... | ... | @@ -1226,7 +1214,7 @@ fn writeStubHelperCommon(self: *Zld) !void { |
| 1226 | 1214 | const data = &data_segment.sections.items[self.data_section_index.?]; |
| 1227 | 1215 | |
| 1228 | 1216 | self.stub_helper_stubs_start_off = blk: { |
| 1229 | | switch (self.arch.?) { |
| 1217 | switch (self.target.?.cpu.arch) { |
| 1230 | 1218 | .x86_64 => { |
| 1231 | 1219 | const code_size = 15; |
| 1232 | 1220 | var code: [code_size]u8 = undefined; |
| ... | ... | @@ -1358,7 +1346,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { |
| 1358 | 1346 | const data_segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1359 | 1347 | const la_symbol_ptr = data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 1360 | 1348 | |
| 1361 | | const stub_size: u4 = switch (self.arch.?) { |
| 1349 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 1362 | 1350 | .x86_64 => 10, |
| 1363 | 1351 | .aarch64 => 3 * @sizeOf(u32), |
| 1364 | 1352 | else => unreachable, |
| ... | ... | @@ -1384,7 +1372,7 @@ fn writeStub(self: *Zld, index: u32) !void { |
| 1384 | 1372 | log.debug("writing stub at 0x{x}", .{stub_off}); |
| 1385 | 1373 | var code = try self.allocator.alloc(u8, stubs.reserved2); |
| 1386 | 1374 | defer self.allocator.free(code); |
| 1387 | | switch (self.arch.?) { |
| 1375 | switch (self.target.?.cpu.arch) { |
| 1388 | 1376 | .x86_64 => { |
| 1389 | 1377 | assert(la_ptr_addr >= stub_addr + stubs.reserved2); |
| 1390 | 1378 | const displacement = try math.cast(u32, la_ptr_addr - stub_addr - stubs.reserved2); |
| ... | ... | @@ -1447,7 +1435,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { |
| 1447 | 1435 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1448 | 1436 | const stub_helper = text_segment.sections.items[self.stub_helper_section_index.?]; |
| 1449 | 1437 | |
| 1450 | | const stub_size: u4 = switch (self.arch.?) { |
| 1438 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 1451 | 1439 | .x86_64 => 10, |
| 1452 | 1440 | .aarch64 => 3 * @sizeOf(u32), |
| 1453 | 1441 | else => unreachable, |
| ... | ... | @@ -1455,7 +1443,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { |
| 1455 | 1443 | const stub_off = self.stub_helper_stubs_start_off.? + index * stub_size; |
| 1456 | 1444 | var code = try self.allocator.alloc(u8, stub_size); |
| 1457 | 1445 | defer self.allocator.free(code); |
| 1458 | | switch (self.arch.?) { |
| 1446 | switch (self.target.?.cpu.arch) { |
| 1459 | 1447 | .x86_64 => { |
| 1460 | 1448 | const displacement = try math.cast( |
| 1461 | 1449 | i32, |
| ... | ... | @@ -1999,7 +1987,7 @@ fn populateMetadata(self: *Zld) !void { |
| 1999 | 1987 | if (self.text_section_index == null) { |
| 2000 | 1988 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2001 | 1989 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2002 | | const alignment: u2 = switch (self.arch.?) { |
| 1990 | const alignment: u2 = switch (self.target.?.cpu.arch) { |
| 2003 | 1991 | .x86_64 => 0, |
| 2004 | 1992 | .aarch64 => 2, |
| 2005 | 1993 | else => unreachable, // unhandled architecture type |
| ... | ... | @@ -2013,12 +2001,12 @@ fn populateMetadata(self: *Zld) !void { |
| 2013 | 2001 | if (self.stubs_section_index == null) { |
| 2014 | 2002 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2015 | 2003 | self.stubs_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2016 | | const alignment: u2 = switch (self.arch.?) { |
| 2004 | const alignment: u2 = switch (self.target.?.cpu.arch) { |
| 2017 | 2005 | .x86_64 => 0, |
| 2018 | 2006 | .aarch64 => 2, |
| 2019 | 2007 | else => unreachable, // unhandled architecture type |
| 2020 | 2008 | }; |
| 2021 | | const stub_size: u4 = switch (self.arch.?) { |
| 2009 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 2022 | 2010 | .x86_64 => 6, |
| 2023 | 2011 | .aarch64 => 3 * @sizeOf(u32), |
| 2024 | 2012 | else => unreachable, // unhandled architecture type |
| ... | ... | @@ -2033,12 +2021,12 @@ fn populateMetadata(self: *Zld) !void { |
| 2033 | 2021 | if (self.stub_helper_section_index == null) { |
| 2034 | 2022 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2035 | 2023 | self.stub_helper_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2036 | | const alignment: u2 = switch (self.arch.?) { |
| 2024 | const alignment: u2 = switch (self.target.?.cpu.arch) { |
| 2037 | 2025 | .x86_64 => 0, |
| 2038 | 2026 | .aarch64 => 2, |
| 2039 | 2027 | else => unreachable, // unhandled architecture type |
| 2040 | 2028 | }; |
| 2041 | | const stub_helper_size: u6 = switch (self.arch.?) { |
| 2029 | const stub_helper_size: u6 = switch (self.target.?.cpu.arch) { |
| 2042 | 2030 | .x86_64 => 15, |
| 2043 | 2031 | .aarch64 => 6 * @sizeOf(u32), |
| 2044 | 2032 | else => unreachable, |
| ... | ... | @@ -2187,7 +2175,7 @@ fn populateMetadata(self: *Zld) !void { |
| 2187 | 2175 | try self.load_commands.append(self.allocator, .{ .Dylinker = dylinker_cmd }); |
| 2188 | 2176 | } |
| 2189 | 2177 | |
| 2190 | | if (self.main_cmd_index == null) { |
| 2178 | if (self.main_cmd_index == null and self.output.?.tag == .exe) { |
| 2191 | 2179 | self.main_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2192 | 2180 | try self.load_commands.append(self.allocator, .{ |
| 2193 | 2181 | .Main = .{ |
| ... | ... | @@ -2199,6 +2187,41 @@ fn populateMetadata(self: *Zld) !void { |
| 2199 | 2187 | }); |
| 2200 | 2188 | } |
| 2201 | 2189 | |
| 2190 | if (self.dylib_id_cmd_index == null and self.output.?.tag == .dylib) { |
| 2191 | self.dylib_id_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2192 | var dylib_cmd = try createLoadDylibCommand( |
| 2193 | self.allocator, |
| 2194 | self.output.?.install_name.?, |
| 2195 | 2, |
| 2196 | 0x10000, // TODO forward user-provided versions |
| 2197 | 0x10000, |
| 2198 | ); |
| 2199 | errdefer dylib_cmd.deinit(self.allocator); |
| 2200 | dylib_cmd.inner.cmd = macho.LC_ID_DYLIB; |
| 2201 | try self.load_commands.append(self.allocator, .{ .Dylib = dylib_cmd }); |
| 2202 | } |
| 2203 | |
| 2204 | if (self.version_min_cmd_index == null) { |
| 2205 | self.version_min_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2206 | const cmd: u32 = switch (self.target.?.os.tag) { |
| 2207 | .macos => macho.LC_VERSION_MIN_MACOSX, |
| 2208 | .ios => macho.LC_VERSION_MIN_IPHONEOS, |
| 2209 | .tvos => macho.LC_VERSION_MIN_TVOS, |
| 2210 | .watchos => macho.LC_VERSION_MIN_WATCHOS, |
| 2211 | else => unreachable, // wrong OS |
| 2212 | }; |
| 2213 | const ver = self.target.?.os.version_range.semver.min; |
| 2214 | const version = ver.major << 16 | ver.minor << 8 | ver.patch; |
| 2215 | try self.load_commands.append(self.allocator, .{ |
| 2216 | .VersionMin = .{ |
| 2217 | .cmd = cmd, |
| 2218 | .cmdsize = @sizeOf(macho.version_min_command), |
| 2219 | .version = version, |
| 2220 | .sdk = version, |
| 2221 | }, |
| 2222 | }); |
| 2223 | } |
| 2224 | |
| 2202 | 2225 | if (self.source_version_cmd_index == null) { |
| 2203 | 2226 | self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2204 | 2227 | try self.load_commands.append(self.allocator, .{ |
| ... | ... | @@ -2237,7 +2260,7 @@ fn addDataInCodeLC(self: *Zld) !void { |
| 2237 | 2260 | } |
| 2238 | 2261 | |
| 2239 | 2262 | fn addCodeSignatureLC(self: *Zld) !void { |
| 2240 | | if (self.code_signature_cmd_index == null and self.arch.? == .aarch64) { |
| 2263 | if (self.code_signature_cmd_index == null and self.target.?.cpu.arch == .aarch64) { |
| 2241 | 2264 | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2242 | 2265 | try self.load_commands.append(self.allocator, .{ |
| 2243 | 2266 | .LinkeditData = .{ |
| ... | ... | @@ -2355,19 +2378,20 @@ fn flush(self: *Zld) !void { |
| 2355 | 2378 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); |
| 2356 | 2379 | } |
| 2357 | 2380 | |
| 2358 | | if (self.arch.? == .aarch64) { |
| 2381 | if (self.target.?.cpu.arch == .aarch64) { |
| 2359 | 2382 | try self.writeCodeSignaturePadding(); |
| 2360 | 2383 | } |
| 2361 | 2384 | |
| 2362 | 2385 | try self.writeLoadCommands(); |
| 2363 | 2386 | try self.writeHeader(); |
| 2364 | 2387 | |
| 2365 | | if (self.arch.? == .aarch64) { |
| 2388 | if (self.target.?.cpu.arch == .aarch64) { |
| 2366 | 2389 | try self.writeCodeSignature(); |
| 2367 | 2390 | } |
| 2368 | 2391 | |
| 2369 | 2392 | if (comptime std.Target.current.isDarwin() and std.Target.current.cpu.arch == .aarch64) { |
| 2370 | | try fs.cwd().copyFile(self.out_path.?, fs.cwd(), self.out_path.?, .{}); |
| 2393 | const out_path = self.output.?.path; |
| 2394 | try fs.cwd().copyFile(out_path, fs.cwd(), out_path, .{}); |
| 2371 | 2395 | } |
| 2372 | 2396 | } |
| 2373 | 2397 | |
| ... | ... | @@ -2392,6 +2416,8 @@ fn writeGotEntries(self: *Zld) !void { |
| 2392 | 2416 | } |
| 2393 | 2417 | |
| 2394 | 2418 | fn setEntryPoint(self: *Zld) !void { |
| 2419 | if (self.output.?.tag != .exe) return; |
| 2420 | |
| 2395 | 2421 | // TODO we should respect the -entry flag passed in by the user to set a custom |
| 2396 | 2422 | // entrypoint. For now, assume default of `_main`. |
| 2397 | 2423 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| ... | ... | @@ -2636,12 +2662,12 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void { |
| 2636 | 2662 | } |
| 2637 | 2663 | assert(self.stubs.items.len <= offsets.items.len); |
| 2638 | 2664 | |
| 2639 | | const stub_size: u4 = switch (self.arch.?) { |
| 2665 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 2640 | 2666 | .x86_64 => 10, |
| 2641 | 2667 | .aarch64 => 3 * @sizeOf(u32), |
| 2642 | 2668 | else => unreachable, |
| 2643 | 2669 | }; |
| 2644 | | const off: u4 = switch (self.arch.?) { |
| 2670 | const off: u4 = switch (self.target.?.cpu.arch) { |
| 2645 | 2671 | .x86_64 => 1, |
| 2646 | 2672 | .aarch64 => 2 * @sizeOf(u32), |
| 2647 | 2673 | else => unreachable, |
| ... | ... | @@ -2998,7 +3024,7 @@ fn writeStringTable(self: *Zld) !void { |
| 2998 | 3024 | |
| 2999 | 3025 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); |
| 3000 | 3026 | |
| 3001 | | if (symtab.strsize > self.strtab.items.len and self.arch.? == .x86_64) { |
| 3027 | if (symtab.strsize > self.strtab.items.len and self.target.?.cpu.arch == .x86_64) { |
| 3002 | 3028 | // This is the last section, so we need to pad it out. |
| 3003 | 3029 | try self.file.?.pwriteAll(&[_]u8{0}, seg.inner.fileoff + seg.inner.filesize - 1); |
| 3004 | 3030 | } |
| ... | ... | @@ -3046,7 +3072,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { |
| 3046 | 3072 | const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData; |
| 3047 | 3073 | const fileoff = seg.inner.fileoff + seg.inner.filesize; |
| 3048 | 3074 | const needed_size = CodeSignature.calcCodeSignaturePaddingSize( |
| 3049 | | self.out_path.?, |
| 3075 | self.output.?.path, |
| 3050 | 3076 | fileoff, |
| 3051 | 3077 | self.page_size.?, |
| 3052 | 3078 | ); |
| ... | ... | @@ -3072,7 +3098,7 @@ fn writeCodeSignature(self: *Zld) !void { |
| 3072 | 3098 | defer code_sig.deinit(); |
| 3073 | 3099 | try code_sig.calcAdhocSignature( |
| 3074 | 3100 | self.file.?, |
| 3075 | | self.out_path.?, |
| 3101 | self.output.?.path, |
| 3076 | 3102 | text_seg.inner, |
| 3077 | 3103 | code_sig_cmd, |
| 3078 | 3104 | .Exe, |
| ... | ... | @@ -3114,7 +3140,7 @@ fn writeHeader(self: *Zld) !void { |
| 3114 | 3140 | cpu_subtype: macho.cpu_subtype_t, |
| 3115 | 3141 | }; |
| 3116 | 3142 | |
| 3117 | | const cpu_info: CpuInfo = switch (self.arch.?) { |
| 3143 | const cpu_info: CpuInfo = switch (self.target.?.cpu.arch) { |
| 3118 | 3144 | .aarch64 => .{ |
| 3119 | 3145 | .cpu_type = macho.CPU_TYPE_ARM64, |
| 3120 | 3146 | .cpu_subtype = macho.CPU_SUBTYPE_ARM_ALL, |
| ... | ... | @@ -3127,8 +3153,22 @@ fn writeHeader(self: *Zld) !void { |
| 3127 | 3153 | }; |
| 3128 | 3154 | header.cputype = cpu_info.cpu_type; |
| 3129 | 3155 | header.cpusubtype = cpu_info.cpu_subtype; |
| 3130 | | header.filetype = macho.MH_EXECUTE; |
| 3131 | | header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; |
| 3156 | |
| 3157 | switch (self.output.?.tag) { |
| 3158 | .exe => { |
| 3159 | header.filetype = macho.MH_EXECUTE; |
| 3160 | header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; |
| 3161 | }, |
| 3162 | .dylib => { |
| 3163 | header.filetype = macho.MH_DYLIB; |
| 3164 | header.flags = macho.MH_NOUNDEFS | |
| 3165 | macho.MH_DYLDLINK | |
| 3166 | macho.MH_PIE | |
| 3167 | macho.MH_TWOLEVEL | |
| 3168 | macho.MH_NO_REEXPORTED_DYLIBS; |
| 3169 | }, |
| 3170 | } |
| 3171 | |
| 3132 | 3172 | header.reserved = 0; |
| 3133 | 3173 | |
| 3134 | 3174 | if (self.tlv_section_index) |_| |