| ... | ... | @@ -16,6 +16,7 @@ const CodeSignature = @import("CodeSignature.zig"); |
| 16 | 16 | const Archive = @import("Archive.zig"); |
| 17 | 17 | const Object = @import("Object.zig"); |
| 18 | 18 | const Trie = @import("Trie.zig"); |
| 19 | const aarch64 = @import("../../codegen/aarch64.zig"); |
| 19 | 20 | |
| 20 | 21 | usingnamespace @import("commands.zig"); |
| 21 | 22 | usingnamespace @import("bind.zig"); |
| ... | ... | @@ -299,6 +300,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 299 | 300 | fn parseObjectFile(self: *Zld, object: *const Object) !void { |
| 300 | 301 | const seg_cmd = object.load_commands.items[object.segment_cmd_index.?].Segment; |
| 301 | 302 | for (seg_cmd.sections.items) |sect| { |
| 303 | const segname = parseName(&sect.segname); |
| 302 | 304 | const sectname = parseName(&sect.sectname); |
| 303 | 305 | |
| 304 | 306 | const seg_index = self.segments_directory.get(sect.segname) orelse { |
| ... | ... | @@ -384,7 +386,7 @@ fn resolveImports(self: *Zld) !void { |
| 384 | 386 | mem.eql(u8, sym_name, "___stack_chk_guard") or |
| 385 | 387 | mem.eql(u8, sym_name, "_environ")) |
| 386 | 388 | { |
| 387 | | log.debug("writing nonlazy symbol '{s}'", .{sym_name}); |
| 389 | log.warn("writing nonlazy symbol '{s}'", .{sym_name}); |
| 388 | 390 | const index = @intCast(u32, self.nonlazy_imports.items().len); |
| 389 | 391 | try self.nonlazy_imports.putNoClobber(self.allocator, key, .{ |
| 390 | 392 | .symbol = new_sym, |
| ... | ... | @@ -392,7 +394,7 @@ fn resolveImports(self: *Zld) !void { |
| 392 | 394 | .index = index, |
| 393 | 395 | }); |
| 394 | 396 | } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) { |
| 395 | | log.debug("writing threadlocal symbol '{s}'", .{sym_name}); |
| 397 | log.warn("writing threadlocal symbol '{s}'", .{sym_name}); |
| 396 | 398 | const index = @intCast(u32, self.threadlocal_imports.items().len); |
| 397 | 399 | try self.threadlocal_imports.putNoClobber(self.allocator, key, .{ |
| 398 | 400 | .symbol = new_sym, |
| ... | ... | @@ -400,7 +402,7 @@ fn resolveImports(self: *Zld) !void { |
| 400 | 402 | .index = index, |
| 401 | 403 | }); |
| 402 | 404 | } else { |
| 403 | | log.debug("writing lazy symbol '{s}'", .{sym_name}); |
| 405 | log.warn("writing lazy symbol '{s}'", .{sym_name}); |
| 404 | 406 | const index = @intCast(u32, self.lazy_imports.items().len); |
| 405 | 407 | try self.lazy_imports.putNoClobber(self.allocator, key, .{ |
| 406 | 408 | .symbol = new_sym, |
| ... | ... | @@ -412,7 +414,7 @@ fn resolveImports(self: *Zld) !void { |
| 412 | 414 | |
| 413 | 415 | const n_strx = try self.makeString("dyld_stub_binder"); |
| 414 | 416 | const name = try self.allocator.dupe(u8, "dyld_stub_binder"); |
| 415 | | log.debug("writing nonlazy symbol 'dyld_stub_binder'", .{}); |
| 417 | log.warn("writing nonlazy symbol 'dyld_stub_binder'", .{}); |
| 416 | 418 | const index = @intCast(u32, self.nonlazy_imports.items().len); |
| 417 | 419 | try self.nonlazy_imports.putNoClobber(self.allocator, name, .{ |
| 418 | 420 | .symbol = .{ |
| ... | ... | @@ -606,7 +608,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { |
| 606 | 608 | var buf: [@sizeOf(u64)]u8 = undefined; |
| 607 | 609 | mem.writeIntLittle(u64, &buf, end); |
| 608 | 610 | const off = la_symbol_ptr.offset + index * @sizeOf(u64); |
| 609 | | log.debug("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off }); |
| 611 | log.warn("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off }); |
| 610 | 612 | try self.file.?.pwriteAll(&buf, off); |
| 611 | 613 | } |
| 612 | 614 | |
| ... | ... | @@ -619,7 +621,7 @@ fn writeStub(self: *Zld, index: u32) !void { |
| 619 | 621 | const stub_off = stubs.offset + index * stubs.reserved2; |
| 620 | 622 | const stub_addr = stubs.addr + index * stubs.reserved2; |
| 621 | 623 | const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64); |
| 622 | | log.debug("writing stub at 0x{x}", .{stub_off}); |
| 624 | log.warn("writing stub at 0x{x}", .{stub_off}); |
| 623 | 625 | var code = try self.allocator.alloc(u8, stubs.reserved2); |
| 624 | 626 | defer self.allocator.free(code); |
| 625 | 627 | switch (self.arch.?) { |
| ... | ... | @@ -720,7 +722,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 720 | 722 | const sym_name = object.getString(sym.n_strx); |
| 721 | 723 | |
| 722 | 724 | if (isLocal(&sym) and self.locals.get(sym_name) != null) { |
| 723 | | log.debug("symbol '{s}' already exists; skipping", .{sym_name}); |
| 725 | log.warn("symbol '{s}' already exists; skipping", .{sym_name}); |
| 724 | 726 | continue; |
| 725 | 727 | } |
| 726 | 728 | |
| ... | ... | @@ -734,7 +736,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 734 | 736 | const n_strx = try self.makeString(sym_name); |
| 735 | 737 | const n_value = sym.n_value - sect.addr + next_address.get(key).?.addr; |
| 736 | 738 | |
| 737 | | log.debug("resolving '{s}' as local symbol at 0x{x}", .{ sym_name, n_value }); |
| 739 | log.warn("resolving '{s}' as local symbol at 0x{x}", .{ sym_name, n_value }); |
| 738 | 740 | |
| 739 | 741 | var n_sect = res.sect_index + 1; |
| 740 | 742 | for (self.load_commands.items) |sseg, i| { |
| ... | ... | @@ -766,8 +768,8 @@ fn doRelocs(self: *Zld) !void { |
| 766 | 768 | defer next_space.deinit(); |
| 767 | 769 | |
| 768 | 770 | for (self.objects.items) |object| { |
| 769 | | log.debug("\n\n", .{}); |
| 770 | | log.debug("relocating object {s}", .{object.name}); |
| 771 | log.warn("\n\n", .{}); |
| 772 | log.warn("relocating object {s}", .{object.name}); |
| 771 | 773 | |
| 772 | 774 | const seg = object.load_commands.items[object.segment_cmd_index.?].Segment; |
| 773 | 775 | |
| ... | ... | @@ -802,9 +804,12 @@ fn doRelocs(self: *Zld) !void { |
| 802 | 804 | }; |
| 803 | 805 | const next = next_space.get(key) orelse continue; |
| 804 | 806 | |
| 805 | | var code = try self.allocator.alloc(u8, sect.size); |
| 806 | | defer self.allocator.free(code); |
| 807 | | _ = try object.file.preadAll(code, sect.offset); |
| 807 | var code = blk: { |
| 808 | var buf = try self.allocator.alloc(u8, sect.size); |
| 809 | _ = try object.file.preadAll(buf, sect.offset); |
| 810 | break :blk std.ArrayList(u8).fromOwnedSlice(self.allocator, buf); |
| 811 | }; |
| 812 | defer code.deinit(); |
| 808 | 813 | |
| 809 | 814 | // Parse relocs (if any) |
| 810 | 815 | var raw_relocs = try self.allocator.alloc(u8, @sizeOf(macho.relocation_info) * sect.nreloc); |
| ... | ... | @@ -822,34 +827,34 @@ fn doRelocs(self: *Zld) !void { |
| 822 | 827 | switch (self.arch.?) { |
| 823 | 828 | .aarch64 => { |
| 824 | 829 | const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type); |
| 825 | | log.debug("{s}", .{rel_type}); |
| 826 | | log.debug(" | source address 0x{x}", .{this_addr}); |
| 827 | | log.debug(" | offset 0x{x}", .{off}); |
| 830 | log.warn("{s}", .{rel_type}); |
| 831 | log.warn(" | source address 0x{x}", .{this_addr}); |
| 832 | log.warn(" | offset 0x{x}", .{off}); |
| 828 | 833 | |
| 829 | 834 | if (rel_type == .ARM64_RELOC_ADDEND) { |
| 830 | 835 | addend = rel.r_symbolnum; |
| 831 | | log.debug(" | calculated addend = 0x{x}", .{addend}); |
| 836 | log.warn(" | calculated addend = 0x{x}", .{addend}); |
| 832 | 837 | // TODO followed by either PAGE21 or PAGEOFF12 only. |
| 833 | 838 | continue; |
| 834 | 839 | } |
| 835 | 840 | }, |
| 836 | 841 | .x86_64 => { |
| 837 | 842 | const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type); |
| 838 | | log.debug("{s}", .{rel_type}); |
| 839 | | log.debug(" | source address 0x{x}", .{this_addr}); |
| 840 | | log.debug(" | offset 0x{x}", .{off}); |
| 843 | log.warn("{s}", .{rel_type}); |
| 844 | log.warn(" | source address 0x{x}", .{this_addr}); |
| 845 | log.warn(" | offset 0x{x}", .{off}); |
| 841 | 846 | }, |
| 842 | 847 | else => {}, |
| 843 | 848 | } |
| 844 | 849 | |
| 845 | 850 | const target_addr = try self.relocTargetAddr(object, rel, next_space); |
| 846 | | log.debug(" | target address 0x{x}", .{target_addr}); |
| 851 | log.warn(" | target address 0x{x}", .{target_addr}); |
| 847 | 852 | if (rel.r_extern == 1) { |
| 848 | 853 | const target_symname = object.getString(object.symtab.items[rel.r_symbolnum].n_strx); |
| 849 | | log.debug(" | target symbol '{s}'", .{target_symname}); |
| 854 | log.warn(" | target symbol '{s}'", .{target_symname}); |
| 850 | 855 | } else { |
| 851 | 856 | const target_sectname = seg.sections.items[rel.r_symbolnum - 1].sectname; |
| 852 | | log.debug(" | target section '{s}'", .{parseName(&target_sectname)}); |
| 857 | log.warn(" | target section '{s}'", .{parseName(&target_sectname)}); |
| 853 | 858 | } |
| 854 | 859 | |
| 855 | 860 | switch (self.arch.?) { |
| ... | ... | @@ -862,16 +867,16 @@ fn doRelocs(self: *Zld) !void { |
| 862 | 867 | .X86_64_RELOC_GOT, |
| 863 | 868 | => { |
| 864 | 869 | assert(rel.r_length == 2); |
| 865 | | const inst = code[off..][0..4]; |
| 870 | const inst = code.items[off..][0..4]; |
| 866 | 871 | const displacement = @bitCast(u32, @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4)); |
| 867 | 872 | mem.writeIntLittle(u32, inst, displacement); |
| 868 | 873 | }, |
| 869 | 874 | .X86_64_RELOC_TLV => { |
| 870 | 875 | assert(rel.r_length == 2); |
| 871 | 876 | // We need to rewrite the opcode from movq to leaq. |
| 872 | | code[off - 2] = 0x8d; |
| 877 | code.items[off - 2] = 0x8d; |
| 873 | 878 | // Add displacement. |
| 874 | | const inst = code[off..][0..4]; |
| 879 | const inst = code.items[off..][0..4]; |
| 875 | 880 | const displacement = @bitCast(u32, @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4)); |
| 876 | 881 | mem.writeIntLittle(u32, inst, displacement); |
| 877 | 882 | }, |
| ... | ... | @@ -881,7 +886,7 @@ fn doRelocs(self: *Zld) !void { |
| 881 | 886 | .X86_64_RELOC_SIGNED_4, |
| 882 | 887 | => { |
| 883 | 888 | assert(rel.r_length == 2); |
| 884 | | const inst = code[off..][0..4]; |
| 889 | const inst = code.items[off..][0..4]; |
| 885 | 890 | const offset: i32 = blk: { |
| 886 | 891 | if (rel.r_extern == 1) { |
| 887 | 892 | break :blk mem.readIntLittle(i32, inst); |
| ... | ... | @@ -899,7 +904,7 @@ fn doRelocs(self: *Zld) !void { |
| 899 | 904 | break :blk correction; |
| 900 | 905 | } |
| 901 | 906 | }; |
| 902 | | log.debug(" | calculated addend 0x{x}", .{offset}); |
| 907 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 903 | 908 | const result = @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4 + offset; |
| 904 | 909 | const displacement = @bitCast(u32, @intCast(i32, result)); |
| 905 | 910 | mem.writeIntLittle(u32, inst, displacement); |
| ... | ... | @@ -910,9 +915,9 @@ fn doRelocs(self: *Zld) !void { |
| 910 | 915 | .X86_64_RELOC_UNSIGNED => { |
| 911 | 916 | switch (rel.r_length) { |
| 912 | 917 | 3 => { |
| 913 | | const inst = code[off..][0..8]; |
| 918 | const inst = code.items[off..][0..8]; |
| 914 | 919 | const offset = mem.readIntLittle(i64, inst); |
| 915 | | log.debug(" | calculated addend 0x{x}", .{offset}); |
| 920 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 916 | 921 | const result = if (sub) |s| |
| 917 | 922 | @intCast(i64, target_addr) - s + offset |
| 918 | 923 | else |
| ... | ... | @@ -934,9 +939,9 @@ fn doRelocs(self: *Zld) !void { |
| 934 | 939 | } |
| 935 | 940 | }, |
| 936 | 941 | 2 => { |
| 937 | | const inst = code[off..][0..4]; |
| 942 | const inst = code.items[off..][0..4]; |
| 938 | 943 | const offset = mem.readIntLittle(i32, inst); |
| 939 | | log.debug(" | calculated addend 0x{x}", .{offset}); |
| 944 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 940 | 945 | const result = if (sub) |s| |
| 941 | 946 | @intCast(i64, target_addr) - s + offset |
| 942 | 947 | else |
| ... | ... | @@ -958,7 +963,7 @@ fn doRelocs(self: *Zld) !void { |
| 958 | 963 | switch (rel_type) { |
| 959 | 964 | .ARM64_RELOC_BRANCH26 => { |
| 960 | 965 | assert(rel.r_length == 2); |
| 961 | | const inst = code[off..][0..4]; |
| 966 | const inst = code.items[off..][0..4]; |
| 962 | 967 | const displacement = @intCast(i28, @intCast(i64, target_addr) - @intCast(i64, this_addr)); |
| 963 | 968 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Branch), inst); |
| 964 | 969 | parsed.disp = @truncate(u26, @bitCast(u28, displacement) >> 2); |
| ... | ... | @@ -968,12 +973,18 @@ fn doRelocs(self: *Zld) !void { |
| 968 | 973 | .ARM64_RELOC_TLVP_LOAD_PAGE21, |
| 969 | 974 | => { |
| 970 | 975 | assert(rel.r_length == 2); |
| 971 | | const inst = code[off..][0..4]; |
| 976 | const inst = code.items[off..][0..4]; |
| 972 | 977 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 973 | 978 | const this_page = @intCast(i32, this_addr >> 12); |
| 974 | 979 | const target_page = @intCast(i32, ta >> 12); |
| 975 | 980 | const pages = @bitCast(u21, @intCast(i21, target_page - this_page)); |
| 976 | | log.debug(" | moving by {} pages", .{pages}); |
| 981 | if (pages == 0) { |
| 982 | // No need to execute adrp. Instead, replace with a nop. |
| 983 | log.warn(" | replacing ADRP with NOP", .{}); |
| 984 | mem.writeIntLittle(u32, inst, aarch64.Instruction.nop().toU32()); |
| 985 | continue; |
| 986 | } |
| 987 | log.warn(" | moving by {} pages", .{pages}); |
| 977 | 988 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Address), inst); |
| 978 | 989 | parsed.immhi = @truncate(u19, pages >> 2); |
| 979 | 990 | parsed.immlo = @truncate(u2, pages); |
| ... | ... | @@ -982,22 +993,42 @@ fn doRelocs(self: *Zld) !void { |
| 982 | 993 | .ARM64_RELOC_PAGEOFF12, |
| 983 | 994 | .ARM64_RELOC_GOT_LOAD_PAGEOFF12, |
| 984 | 995 | => { |
| 985 | | const inst = code[off..][0..4]; |
| 996 | const inst = code.items[off..][0..4]; |
| 986 | 997 | if (Arm64.isArithmetic(inst)) { |
| 987 | | log.debug(" | detected ADD opcode", .{}); |
| 998 | log.warn(" | detected ADD opcode", .{}); |
| 988 | 999 | // add |
| 989 | 1000 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); |
| 990 | 1001 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 991 | 1002 | const narrowed = @truncate(u12, ta); |
| 1003 | if (narrowed == 0) { |
| 1004 | // No need to execute add. Instead, replace with a nop. |
| 1005 | log.warn(" | replacing ADD with NOP", .{}); |
| 1006 | mem.writeIntLittle(u32, inst, aarch64.Instruction.nop().toU32()); |
| 1007 | continue; |
| 1008 | } |
| 992 | 1009 | parsed.offset = narrowed; |
| 993 | 1010 | } else { |
| 994 | | log.debug(" | detected LDR/STR opcode", .{}); |
| 1011 | log.warn(" | detected LDR/STR opcode", .{}); |
| 995 | 1012 | // ldr/str |
| 996 | 1013 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.LoadRegister), inst); |
| 997 | 1014 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 998 | 1015 | const narrowed = @truncate(u12, ta); |
| 999 | | const offset = if (parsed.size == 1) @divExact(narrowed, 8) else @divExact(narrowed, 4); |
| 1000 | | parsed.offset = @truncate(u12, offset); |
| 1016 | if (narrowed == 0) { |
| 1017 | // No need to execute ldr/str. Instead, replace with a nop. |
| 1018 | log.warn(" | replacing LDR/STR with NOP", .{}); |
| 1019 | mem.writeIntLittle(u32, inst, aarch64.Instruction.nop().toU32()); |
| 1020 | continue; |
| 1021 | } |
| 1022 | const denom: u12 = if (parsed.size == 1) 8 else 4; |
| 1023 | const offset = math.divExact(u12, narrowed, denom) catch |_| { |
| 1024 | // If we are here, then this means we are not able to divide the offset |
| 1025 | // exactly by the required denominator. Therefore, we will use add instead of |
| 1026 | // ldr as we expect ldr to follow this instruction nonetheless. |
| 1027 | // TODO I believe ldr/str can only occur for GOT_LOAD_PAGEOFF12. |
| 1028 | mem.writeIntLittle(u32, inst, Arm64.add(parsed.rn, parsed.rn, narrowed, parsed.size).toU32()); |
| 1029 | continue; |
| 1030 | }; |
| 1031 | parsed.offset = offset; |
| 1001 | 1032 | } |
| 1002 | 1033 | addend = null; |
| 1003 | 1034 | }, |
| ... | ... | @@ -1008,7 +1039,7 @@ fn doRelocs(self: *Zld) !void { |
| 1008 | 1039 | rn: u5, |
| 1009 | 1040 | size: u1, |
| 1010 | 1041 | }; |
| 1011 | | const inst = code[off..][0..4]; |
| 1042 | const inst = code.items[off..][0..4]; |
| 1012 | 1043 | const parsed: RegInfo = blk: { |
| 1013 | 1044 | if (Arm64.isArithmetic(inst)) { |
| 1014 | 1045 | const curr = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); |
| ... | ... | @@ -1020,7 +1051,7 @@ fn doRelocs(self: *Zld) !void { |
| 1020 | 1051 | }; |
| 1021 | 1052 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 1022 | 1053 | const narrowed = @truncate(u12, ta); |
| 1023 | | log.debug(" | rewriting TLV access to ADD opcode", .{}); |
| 1054 | log.warn(" | rewriting TLV access to ADD opcode", .{}); |
| 1024 | 1055 | // For TLV, we always generate an add instruction. |
| 1025 | 1056 | mem.writeIntLittle(u32, inst, Arm64.add(parsed.rt, parsed.rn, narrowed, parsed.size).toU32()); |
| 1026 | 1057 | }, |
| ... | ... | @@ -1030,9 +1061,9 @@ fn doRelocs(self: *Zld) !void { |
| 1030 | 1061 | .ARM64_RELOC_UNSIGNED => { |
| 1031 | 1062 | switch (rel.r_length) { |
| 1032 | 1063 | 3 => { |
| 1033 | | const inst = code[off..][0..8]; |
| 1064 | const inst = code.items[off..][0..8]; |
| 1034 | 1065 | const offset = mem.readIntLittle(i64, inst); |
| 1035 | | log.debug(" | calculated addend 0x{x}", .{offset}); |
| 1066 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 1036 | 1067 | const result = if (sub) |s| |
| 1037 | 1068 | @intCast(i64, target_addr) - s + offset |
| 1038 | 1069 | else |
| ... | ... | @@ -1054,9 +1085,9 @@ fn doRelocs(self: *Zld) !void { |
| 1054 | 1085 | } |
| 1055 | 1086 | }, |
| 1056 | 1087 | 2 => { |
| 1057 | | const inst = code[off..][0..4]; |
| 1088 | const inst = code.items[off..][0..4]; |
| 1058 | 1089 | const offset = mem.readIntLittle(i32, inst); |
| 1059 | | log.debug(" | calculated addend 0x{x}", .{offset}); |
| 1090 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 1060 | 1091 | const result = if (sub) |s| |
| 1061 | 1092 | @intCast(i64, target_addr) - s + offset |
| 1062 | 1093 | else |
| ... | ... | @@ -1078,7 +1109,7 @@ fn doRelocs(self: *Zld) !void { |
| 1078 | 1109 | } |
| 1079 | 1110 | } |
| 1080 | 1111 | |
| 1081 | | log.debug("writing contents of '{s},{s}' section from '{s}' from 0x{x} to 0x{x}", .{ |
| 1112 | log.warn("writing contents of '{s},{s}' section from '{s}' from 0x{x} to 0x{x}", .{ |
| 1082 | 1113 | segname, |
| 1083 | 1114 | sectname, |
| 1084 | 1115 | object.name, |
| ... | ... | @@ -1096,7 +1127,7 @@ fn doRelocs(self: *Zld) !void { |
| 1096 | 1127 | mem.set(u8, zeroes, 0); |
| 1097 | 1128 | try self.file.?.pwriteAll(zeroes, next.offset); |
| 1098 | 1129 | } else { |
| 1099 | | try self.file.?.pwriteAll(code, next.offset); |
| 1130 | try self.file.?.pwriteAll(code.items, next.offset); |
| 1100 | 1131 | } |
| 1101 | 1132 | } |
| 1102 | 1133 | } |
| ... | ... | @@ -1672,7 +1703,7 @@ fn writeRebaseInfoTable(self: *Zld) !void { |
| 1672 | 1703 | dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64))); |
| 1673 | 1704 | seg.inner.filesize += dyld_info.rebase_size; |
| 1674 | 1705 | |
| 1675 | | log.debug("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size }); |
| 1706 | log.warn("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size }); |
| 1676 | 1707 | |
| 1677 | 1708 | try self.file.?.pwriteAll(buffer, dyld_info.rebase_off); |
| 1678 | 1709 | } |
| ... | ... | @@ -1725,7 +1756,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 1725 | 1756 | dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 1726 | 1757 | seg.inner.filesize += dyld_info.bind_size; |
| 1727 | 1758 | |
| 1728 | | log.debug("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size }); |
| 1759 | log.warn("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size }); |
| 1729 | 1760 | |
| 1730 | 1761 | try self.file.?.pwriteAll(buffer, dyld_info.bind_off); |
| 1731 | 1762 | } |
| ... | ... | @@ -1764,7 +1795,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { |
| 1764 | 1795 | dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 1765 | 1796 | seg.inner.filesize += dyld_info.lazy_bind_size; |
| 1766 | 1797 | |
| 1767 | | log.debug("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size }); |
| 1798 | log.warn("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size }); |
| 1768 | 1799 | |
| 1769 | 1800 | try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); |
| 1770 | 1801 | try self.populateLazyBindOffsetsInStubHelper(buffer); |
| ... | ... | @@ -1866,7 +1897,7 @@ fn writeExportInfo(self: *Zld) !void { |
| 1866 | 1897 | dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 1867 | 1898 | seg.inner.filesize += dyld_info.export_size; |
| 1868 | 1899 | |
| 1869 | | log.debug("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size }); |
| 1900 | log.warn("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size }); |
| 1870 | 1901 | |
| 1871 | 1902 | try self.file.?.pwriteAll(buffer, dyld_info.export_off); |
| 1872 | 1903 | } |
| ... | ... | @@ -1995,7 +2026,7 @@ fn writeDebugInfo(self: *Zld) !void { |
| 1995 | 2026 | |
| 1996 | 2027 | const stabs_off = symtab.symoff; |
| 1997 | 2028 | const stabs_size = symtab.nsyms * @sizeOf(macho.nlist_64); |
| 1998 | | log.debug("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off }); |
| 2029 | log.warn("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off }); |
| 1999 | 2030 | try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off); |
| 2000 | 2031 | |
| 2001 | 2032 | linkedit.inner.filesize += stabs_size; |
| ... | ... | @@ -2044,17 +2075,17 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2044 | 2075 | |
| 2045 | 2076 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); |
| 2046 | 2077 | const locals_size = nlocals * @sizeOf(macho.nlist_64); |
| 2047 | | log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); |
| 2078 | log.warn("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); |
| 2048 | 2079 | try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); |
| 2049 | 2080 | |
| 2050 | 2081 | const exports_off = locals_off + locals_size; |
| 2051 | 2082 | const exports_size = nexports * @sizeOf(macho.nlist_64); |
| 2052 | | log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); |
| 2083 | log.warn("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); |
| 2053 | 2084 | try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); |
| 2054 | 2085 | |
| 2055 | 2086 | const undefs_off = exports_off + exports_size; |
| 2056 | 2087 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| 2057 | | log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 2088 | log.warn("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 2058 | 2089 | try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off); |
| 2059 | 2090 | |
| 2060 | 2091 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); |
| ... | ... | @@ -2085,7 +2116,7 @@ fn writeDynamicSymbolTable(self: *Zld) !void { |
| 2085 | 2116 | const needed_size = dysymtab.nindirectsyms * @sizeOf(u32); |
| 2086 | 2117 | seg.inner.filesize += needed_size; |
| 2087 | 2118 | |
| 2088 | | log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{ |
| 2119 | log.warn("writing indirect symbol table from 0x{x} to 0x{x}", .{ |
| 2089 | 2120 | dysymtab.indirectsymoff, |
| 2090 | 2121 | dysymtab.indirectsymoff + needed_size, |
| 2091 | 2122 | }); |
| ... | ... | @@ -2124,7 +2155,7 @@ fn writeStringTable(self: *Zld) !void { |
| 2124 | 2155 | symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64))); |
| 2125 | 2156 | seg.inner.filesize += symtab.strsize; |
| 2126 | 2157 | |
| 2127 | | log.debug("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| 2158 | log.warn("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| 2128 | 2159 | |
| 2129 | 2160 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); |
| 2130 | 2161 | |
| ... | ... | @@ -2150,7 +2181,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { |
| 2150 | 2181 | seg.inner.filesize += needed_size; |
| 2151 | 2182 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); |
| 2152 | 2183 | |
| 2153 | | log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size }); |
| 2184 | log.warn("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size }); |
| 2154 | 2185 | |
| 2155 | 2186 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file |
| 2156 | 2187 | // except for code signature data. |
| ... | ... | @@ -2176,7 +2207,7 @@ fn writeCodeSignature(self: *Zld) !void { |
| 2176 | 2207 | var stream = std.io.fixedBufferStream(buffer); |
| 2177 | 2208 | try code_sig.write(stream.writer()); |
| 2178 | 2209 | |
| 2179 | | log.debug("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len }); |
| 2210 | log.warn("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len }); |
| 2180 | 2211 | |
| 2181 | 2212 | try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff); |
| 2182 | 2213 | } |
| ... | ... | @@ -2195,7 +2226,7 @@ fn writeLoadCommands(self: *Zld) !void { |
| 2195 | 2226 | } |
| 2196 | 2227 | |
| 2197 | 2228 | const off = @sizeOf(macho.mach_header_64); |
| 2198 | | log.debug("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds }); |
| 2229 | log.warn("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds }); |
| 2199 | 2230 | try self.file.?.pwriteAll(buffer, off); |
| 2200 | 2231 | } |
| 2201 | 2232 | |
| ... | ... | @@ -2233,7 +2264,7 @@ fn writeHeader(self: *Zld) !void { |
| 2233 | 2264 | for (self.load_commands.items) |cmd| { |
| 2234 | 2265 | header.sizeofcmds += cmd.cmdsize(); |
| 2235 | 2266 | } |
| 2236 | | log.debug("writing Mach-O header {}", .{header}); |
| 2267 | log.warn("writing Mach-O header {}", .{header}); |
| 2237 | 2268 | try self.file.?.pwriteAll(mem.asBytes(&header), 0); |
| 2238 | 2269 | } |
| 2239 | 2270 | |
| ... | ... | @@ -2247,7 +2278,7 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| 2247 | 2278 | fn makeString(self: *Zld, bytes: []const u8) !u32 { |
| 2248 | 2279 | try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1); |
| 2249 | 2280 | const offset = @intCast(u32, self.strtab.items.len); |
| 2250 | | log.debug("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset }); |
| 2281 | log.warn("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset }); |
| 2251 | 2282 | self.strtab.appendSliceAssumeCapacity(bytes); |
| 2252 | 2283 | self.strtab.appendAssumeCapacity(0); |
| 2253 | 2284 | return offset; |