| ... | @@ -16,6 +16,7 @@ const CodeSignature = @import("CodeSignature.zig"); | ... | @@ -16,6 +16,7 @@ const CodeSignature = @import("CodeSignature.zig"); |
| 16 | const Archive = @import("Archive.zig"); | 16 | const Archive = @import("Archive.zig"); |
| 17 | const Object = @import("Object.zig"); | 17 | const Object = @import("Object.zig"); |
| 18 | const Trie = @import("Trie.zig"); | 18 | const Trie = @import("Trie.zig"); |
| | 19 | const aarch64 = @import("../../codegen/aarch64.zig"); |
| 19 | | 20 | |
| 20 | usingnamespace @import("commands.zig"); | 21 | usingnamespace @import("commands.zig"); |
| 21 | usingnamespace @import("bind.zig"); | 22 | usingnamespace @import("bind.zig"); |
| ... | @@ -299,6 +300,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | ... | @@ -299,6 +300,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 299 | fn parseObjectFile(self: *Zld, object: *const Object) !void { | 300 | fn parseObjectFile(self: *Zld, object: *const Object) !void { |
| 300 | const seg_cmd = object.load_commands.items[object.segment_cmd_index.?].Segment; | 301 | const seg_cmd = object.load_commands.items[object.segment_cmd_index.?].Segment; |
| 301 | for (seg_cmd.sections.items) |sect| { | 302 | for (seg_cmd.sections.items) |sect| { |
| | 303 | const segname = parseName(&sect.segname); |
| 302 | const sectname = parseName(&sect.sectname); | 304 | const sectname = parseName(&sect.sectname); |
| 303 | | 305 | |
| 304 | const seg_index = self.segments_directory.get(sect.segname) orelse { | 306 | const seg_index = self.segments_directory.get(sect.segname) orelse { |
| ... | @@ -384,7 +386,7 @@ fn resolveImports(self: *Zld) !void { | ... | @@ -384,7 +386,7 @@ fn resolveImports(self: *Zld) !void { |
| 384 | mem.eql(u8, sym_name, "___stack_chk_guard") or | 386 | mem.eql(u8, sym_name, "___stack_chk_guard") or |
| 385 | mem.eql(u8, sym_name, "_environ")) | 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 | const index = @intCast(u32, self.nonlazy_imports.items().len); | 390 | const index = @intCast(u32, self.nonlazy_imports.items().len); |
| 389 | try self.nonlazy_imports.putNoClobber(self.allocator, key, .{ | 391 | try self.nonlazy_imports.putNoClobber(self.allocator, key, .{ |
| 390 | .symbol = new_sym, | 392 | .symbol = new_sym, |
| ... | @@ -392,7 +394,7 @@ fn resolveImports(self: *Zld) !void { | ... | @@ -392,7 +394,7 @@ fn resolveImports(self: *Zld) !void { |
| 392 | .index = index, | 394 | .index = index, |
| 393 | }); | 395 | }); |
| 394 | } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) { | 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 | const index = @intCast(u32, self.threadlocal_imports.items().len); | 398 | const index = @intCast(u32, self.threadlocal_imports.items().len); |
| 397 | try self.threadlocal_imports.putNoClobber(self.allocator, key, .{ | 399 | try self.threadlocal_imports.putNoClobber(self.allocator, key, .{ |
| 398 | .symbol = new_sym, | 400 | .symbol = new_sym, |
| ... | @@ -400,7 +402,7 @@ fn resolveImports(self: *Zld) !void { | ... | @@ -400,7 +402,7 @@ fn resolveImports(self: *Zld) !void { |
| 400 | .index = index, | 402 | .index = index, |
| 401 | }); | 403 | }); |
| 402 | } else { | 404 | } else { |
| 403 | log.debug("writing lazy symbol '{s}'", .{sym_name}); | 405 | log.warn("writing lazy symbol '{s}'", .{sym_name}); |
| 404 | const index = @intCast(u32, self.lazy_imports.items().len); | 406 | const index = @intCast(u32, self.lazy_imports.items().len); |
| 405 | try self.lazy_imports.putNoClobber(self.allocator, key, .{ | 407 | try self.lazy_imports.putNoClobber(self.allocator, key, .{ |
| 406 | .symbol = new_sym, | 408 | .symbol = new_sym, |
| ... | @@ -412,7 +414,7 @@ fn resolveImports(self: *Zld) !void { | ... | @@ -412,7 +414,7 @@ fn resolveImports(self: *Zld) !void { |
| 412 | | 414 | |
| 413 | const n_strx = try self.makeString("dyld_stub_binder"); | 415 | const n_strx = try self.makeString("dyld_stub_binder"); |
| 414 | const name = try self.allocator.dupe(u8, "dyld_stub_binder"); | 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 | const index = @intCast(u32, self.nonlazy_imports.items().len); | 418 | const index = @intCast(u32, self.nonlazy_imports.items().len); |
| 417 | try self.nonlazy_imports.putNoClobber(self.allocator, name, .{ | 419 | try self.nonlazy_imports.putNoClobber(self.allocator, name, .{ |
| 418 | .symbol = .{ | 420 | .symbol = .{ |
| ... | @@ -606,7 +608,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { | ... | @@ -606,7 +608,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { |
| 606 | var buf: [@sizeOf(u64)]u8 = undefined; | 608 | var buf: [@sizeOf(u64)]u8 = undefined; |
| 607 | mem.writeIntLittle(u64, &buf, end); | 609 | mem.writeIntLittle(u64, &buf, end); |
| 608 | const off = la_symbol_ptr.offset + index * @sizeOf(u64); | 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 | try self.file.?.pwriteAll(&buf, off); | 612 | try self.file.?.pwriteAll(&buf, off); |
| 611 | } | 613 | } |
| 612 | | 614 | |
| ... | @@ -619,7 +621,7 @@ fn writeStub(self: *Zld, index: u32) !void { | ... | @@ -619,7 +621,7 @@ fn writeStub(self: *Zld, index: u32) !void { |
| 619 | const stub_off = stubs.offset + index * stubs.reserved2; | 621 | const stub_off = stubs.offset + index * stubs.reserved2; |
| 620 | const stub_addr = stubs.addr + index * stubs.reserved2; | 622 | const stub_addr = stubs.addr + index * stubs.reserved2; |
| 621 | const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64); | 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 | var code = try self.allocator.alloc(u8, stubs.reserved2); | 625 | var code = try self.allocator.alloc(u8, stubs.reserved2); |
| 624 | defer self.allocator.free(code); | 626 | defer self.allocator.free(code); |
| 625 | switch (self.arch.?) { | 627 | switch (self.arch.?) { |
| ... | @@ -720,7 +722,7 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -720,7 +722,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 720 | const sym_name = object.getString(sym.n_strx); | 722 | const sym_name = object.getString(sym.n_strx); |
| 721 | | 723 | |
| 722 | if (isLocal(&sym) and self.locals.get(sym_name) != null) { | 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 | continue; | 726 | continue; |
| 725 | } | 727 | } |
| 726 | | 728 | |
| ... | @@ -734,7 +736,7 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -734,7 +736,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 734 | const n_strx = try self.makeString(sym_name); | 736 | const n_strx = try self.makeString(sym_name); |
| 735 | const n_value = sym.n_value - sect.addr + next_address.get(key).?.addr; | 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 | var n_sect = res.sect_index + 1; | 741 | var n_sect = res.sect_index + 1; |
| 740 | for (self.load_commands.items) |sseg, i| { | 742 | for (self.load_commands.items) |sseg, i| { |
| ... | @@ -766,8 +768,8 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -766,8 +768,8 @@ fn doRelocs(self: *Zld) !void { |
| 766 | defer next_space.deinit(); | 768 | defer next_space.deinit(); |
| 767 | | 769 | |
| 768 | for (self.objects.items) |object| { | 770 | for (self.objects.items) |object| { |
| 769 | log.debug("\n\n", .{}); | 771 | log.warn("\n\n", .{}); |
| 770 | log.debug("relocating object {s}", .{object.name}); | 772 | log.warn("relocating object {s}", .{object.name}); |
| 771 | | 773 | |
| 772 | const seg = object.load_commands.items[object.segment_cmd_index.?].Segment; | 774 | const seg = object.load_commands.items[object.segment_cmd_index.?].Segment; |
| 773 | | 775 | |
| ... | @@ -802,9 +804,12 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -802,9 +804,12 @@ fn doRelocs(self: *Zld) !void { |
| 802 | }; | 804 | }; |
| 803 | const next = next_space.get(key) orelse continue; | 805 | const next = next_space.get(key) orelse continue; |
| 804 | | 806 | |
| 805 | var code = try self.allocator.alloc(u8, sect.size); | 807 | var code = blk: { |
| 806 | defer self.allocator.free(code); | 808 | var buf = try self.allocator.alloc(u8, sect.size); |
| 807 | _ = try object.file.preadAll(code, sect.offset); | 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 | // Parse relocs (if any) | 814 | // Parse relocs (if any) |
| 810 | var raw_relocs = try self.allocator.alloc(u8, @sizeOf(macho.relocation_info) * sect.nreloc); | 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,34 +827,34 @@ fn doRelocs(self: *Zld) !void { |
| 822 | switch (self.arch.?) { | 827 | switch (self.arch.?) { |
| 823 | .aarch64 => { | 828 | .aarch64 => { |
| 824 | const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type); | 829 | const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type); |
| 825 | log.debug("{s}", .{rel_type}); | 830 | log.warn("{s}", .{rel_type}); |
| 826 | log.debug(" | source address 0x{x}", .{this_addr}); | 831 | log.warn(" | source address 0x{x}", .{this_addr}); |
| 827 | log.debug(" | offset 0x{x}", .{off}); | 832 | log.warn(" | offset 0x{x}", .{off}); |
| 828 | | 833 | |
| 829 | if (rel_type == .ARM64_RELOC_ADDEND) { | 834 | if (rel_type == .ARM64_RELOC_ADDEND) { |
| 830 | addend = rel.r_symbolnum; | 835 | addend = rel.r_symbolnum; |
| 831 | log.debug(" | calculated addend = 0x{x}", .{addend}); | 836 | log.warn(" | calculated addend = 0x{x}", .{addend}); |
| 832 | // TODO followed by either PAGE21 or PAGEOFF12 only. | 837 | // TODO followed by either PAGE21 or PAGEOFF12 only. |
| 833 | continue; | 838 | continue; |
| 834 | } | 839 | } |
| 835 | }, | 840 | }, |
| 836 | .x86_64 => { | 841 | .x86_64 => { |
| 837 | const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type); | 842 | const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type); |
| 838 | log.debug("{s}", .{rel_type}); | 843 | log.warn("{s}", .{rel_type}); |
| 839 | log.debug(" | source address 0x{x}", .{this_addr}); | 844 | log.warn(" | source address 0x{x}", .{this_addr}); |
| 840 | log.debug(" | offset 0x{x}", .{off}); | 845 | log.warn(" | offset 0x{x}", .{off}); |
| 841 | }, | 846 | }, |
| 842 | else => {}, | 847 | else => {}, |
| 843 | } | 848 | } |
| 844 | | 849 | |
| 845 | const target_addr = try self.relocTargetAddr(object, rel, next_space); | 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 | if (rel.r_extern == 1) { | 852 | if (rel.r_extern == 1) { |
| 848 | const target_symname = object.getString(object.symtab.items[rel.r_symbolnum].n_strx); | 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 | } else { | 855 | } else { |
| 851 | const target_sectname = seg.sections.items[rel.r_symbolnum - 1].sectname; | 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 | switch (self.arch.?) { | 860 | switch (self.arch.?) { |
| ... | @@ -862,16 +867,16 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -862,16 +867,16 @@ fn doRelocs(self: *Zld) !void { |
| 862 | .X86_64_RELOC_GOT, | 867 | .X86_64_RELOC_GOT, |
| 863 | => { | 868 | => { |
| 864 | assert(rel.r_length == 2); | 869 | assert(rel.r_length == 2); |
| 865 | const inst = code[off..][0..4]; | 870 | const inst = code.items[off..][0..4]; |
| 866 | const displacement = @bitCast(u32, @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4)); | 871 | const displacement = @bitCast(u32, @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4)); |
| 867 | mem.writeIntLittle(u32, inst, displacement); | 872 | mem.writeIntLittle(u32, inst, displacement); |
| 868 | }, | 873 | }, |
| 869 | .X86_64_RELOC_TLV => { | 874 | .X86_64_RELOC_TLV => { |
| 870 | assert(rel.r_length == 2); | 875 | assert(rel.r_length == 2); |
| 871 | // We need to rewrite the opcode from movq to leaq. | 876 | // We need to rewrite the opcode from movq to leaq. |
| 872 | code[off - 2] = 0x8d; | 877 | code.items[off - 2] = 0x8d; |
| 873 | // Add displacement. | 878 | // Add displacement. |
| 874 | const inst = code[off..][0..4]; | 879 | const inst = code.items[off..][0..4]; |
| 875 | const displacement = @bitCast(u32, @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4)); | 880 | const displacement = @bitCast(u32, @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4)); |
| 876 | mem.writeIntLittle(u32, inst, displacement); | 881 | mem.writeIntLittle(u32, inst, displacement); |
| 877 | }, | 882 | }, |
| ... | @@ -881,7 +886,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -881,7 +886,7 @@ fn doRelocs(self: *Zld) !void { |
| 881 | .X86_64_RELOC_SIGNED_4, | 886 | .X86_64_RELOC_SIGNED_4, |
| 882 | => { | 887 | => { |
| 883 | assert(rel.r_length == 2); | 888 | assert(rel.r_length == 2); |
| 884 | const inst = code[off..][0..4]; | 889 | const inst = code.items[off..][0..4]; |
| 885 | const offset: i32 = blk: { | 890 | const offset: i32 = blk: { |
| 886 | if (rel.r_extern == 1) { | 891 | if (rel.r_extern == 1) { |
| 887 | break :blk mem.readIntLittle(i32, inst); | 892 | break :blk mem.readIntLittle(i32, inst); |
| ... | @@ -899,7 +904,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -899,7 +904,7 @@ fn doRelocs(self: *Zld) !void { |
| 899 | break :blk correction; | 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 | const result = @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4 + offset; | 908 | const result = @intCast(i64, target_addr) - @intCast(i64, this_addr) - 4 + offset; |
| 904 | const displacement = @bitCast(u32, @intCast(i32, result)); | 909 | const displacement = @bitCast(u32, @intCast(i32, result)); |
| 905 | mem.writeIntLittle(u32, inst, displacement); | 910 | mem.writeIntLittle(u32, inst, displacement); |
| ... | @@ -910,9 +915,9 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -910,9 +915,9 @@ fn doRelocs(self: *Zld) !void { |
| 910 | .X86_64_RELOC_UNSIGNED => { | 915 | .X86_64_RELOC_UNSIGNED => { |
| 911 | switch (rel.r_length) { | 916 | switch (rel.r_length) { |
| 912 | 3 => { | 917 | 3 => { |
| 913 | const inst = code[off..][0..8]; | 918 | const inst = code.items[off..][0..8]; |
| 914 | const offset = mem.readIntLittle(i64, inst); | 919 | const offset = mem.readIntLittle(i64, inst); |
| 915 | log.debug(" | calculated addend 0x{x}", .{offset}); | 920 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 916 | const result = if (sub) |s| | 921 | const result = if (sub) |s| |
| 917 | @intCast(i64, target_addr) - s + offset | 922 | @intCast(i64, target_addr) - s + offset |
| 918 | else | 923 | else |
| ... | @@ -934,9 +939,9 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -934,9 +939,9 @@ fn doRelocs(self: *Zld) !void { |
| 934 | } | 939 | } |
| 935 | }, | 940 | }, |
| 936 | 2 => { | 941 | 2 => { |
| 937 | const inst = code[off..][0..4]; | 942 | const inst = code.items[off..][0..4]; |
| 938 | const offset = mem.readIntLittle(i32, inst); | 943 | const offset = mem.readIntLittle(i32, inst); |
| 939 | log.debug(" | calculated addend 0x{x}", .{offset}); | 944 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 940 | const result = if (sub) |s| | 945 | const result = if (sub) |s| |
| 941 | @intCast(i64, target_addr) - s + offset | 946 | @intCast(i64, target_addr) - s + offset |
| 942 | else | 947 | else |
| ... | @@ -958,7 +963,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -958,7 +963,7 @@ fn doRelocs(self: *Zld) !void { |
| 958 | switch (rel_type) { | 963 | switch (rel_type) { |
| 959 | .ARM64_RELOC_BRANCH26 => { | 964 | .ARM64_RELOC_BRANCH26 => { |
| 960 | assert(rel.r_length == 2); | 965 | assert(rel.r_length == 2); |
| 961 | const inst = code[off..][0..4]; | 966 | const inst = code.items[off..][0..4]; |
| 962 | const displacement = @intCast(i28, @intCast(i64, target_addr) - @intCast(i64, this_addr)); | 967 | const displacement = @intCast(i28, @intCast(i64, target_addr) - @intCast(i64, this_addr)); |
| 963 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Branch), inst); | 968 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Branch), inst); |
| 964 | parsed.disp = @truncate(u26, @bitCast(u28, displacement) >> 2); | 969 | parsed.disp = @truncate(u26, @bitCast(u28, displacement) >> 2); |
| ... | @@ -968,12 +973,18 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -968,12 +973,18 @@ fn doRelocs(self: *Zld) !void { |
| 968 | .ARM64_RELOC_TLVP_LOAD_PAGE21, | 973 | .ARM64_RELOC_TLVP_LOAD_PAGE21, |
| 969 | => { | 974 | => { |
| 970 | assert(rel.r_length == 2); | 975 | assert(rel.r_length == 2); |
| 971 | const inst = code[off..][0..4]; | 976 | const inst = code.items[off..][0..4]; |
| 972 | const ta = if (addend) |a| target_addr + a else target_addr; | 977 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 973 | const this_page = @intCast(i32, this_addr >> 12); | 978 | const this_page = @intCast(i32, this_addr >> 12); |
| 974 | const target_page = @intCast(i32, ta >> 12); | 979 | const target_page = @intCast(i32, ta >> 12); |
| 975 | const pages = @bitCast(u21, @intCast(i21, target_page - this_page)); | 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 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Address), inst); | 988 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Address), inst); |
| 978 | parsed.immhi = @truncate(u19, pages >> 2); | 989 | parsed.immhi = @truncate(u19, pages >> 2); |
| 979 | parsed.immlo = @truncate(u2, pages); | 990 | parsed.immlo = @truncate(u2, pages); |
| ... | @@ -982,22 +993,42 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -982,22 +993,42 @@ fn doRelocs(self: *Zld) !void { |
| 982 | .ARM64_RELOC_PAGEOFF12, | 993 | .ARM64_RELOC_PAGEOFF12, |
| 983 | .ARM64_RELOC_GOT_LOAD_PAGEOFF12, | 994 | .ARM64_RELOC_GOT_LOAD_PAGEOFF12, |
| 984 | => { | 995 | => { |
| 985 | const inst = code[off..][0..4]; | 996 | const inst = code.items[off..][0..4]; |
| 986 | if (Arm64.isArithmetic(inst)) { | 997 | if (Arm64.isArithmetic(inst)) { |
| 987 | log.debug(" | detected ADD opcode", .{}); | 998 | log.warn(" | detected ADD opcode", .{}); |
| 988 | // add | 999 | // add |
| 989 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); | 1000 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); |
| 990 | const ta = if (addend) |a| target_addr + a else target_addr; | 1001 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 991 | const narrowed = @truncate(u12, ta); | 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 | parsed.offset = narrowed; | 1009 | parsed.offset = narrowed; |
| 993 | } else { | 1010 | } else { |
| 994 | log.debug(" | detected LDR/STR opcode", .{}); | 1011 | log.warn(" | detected LDR/STR opcode", .{}); |
| 995 | // ldr/str | 1012 | // ldr/str |
| 996 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.LoadRegister), inst); | 1013 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.LoadRegister), inst); |
| 997 | const ta = if (addend) |a| target_addr + a else target_addr; | 1014 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 998 | const narrowed = @truncate(u12, ta); | 1015 | const narrowed = @truncate(u12, ta); |
| 999 | const offset = if (parsed.size == 1) @divExact(narrowed, 8) else @divExact(narrowed, 4); | 1016 | if (narrowed == 0) { |
| 1000 | parsed.offset = @truncate(u12, offset); | 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 | addend = null; | 1033 | addend = null; |
| 1003 | }, | 1034 | }, |
| ... | @@ -1008,7 +1039,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -1008,7 +1039,7 @@ fn doRelocs(self: *Zld) !void { |
| 1008 | rn: u5, | 1039 | rn: u5, |
| 1009 | size: u1, | 1040 | size: u1, |
| 1010 | }; | 1041 | }; |
| 1011 | const inst = code[off..][0..4]; | 1042 | const inst = code.items[off..][0..4]; |
| 1012 | const parsed: RegInfo = blk: { | 1043 | const parsed: RegInfo = blk: { |
| 1013 | if (Arm64.isArithmetic(inst)) { | 1044 | if (Arm64.isArithmetic(inst)) { |
| 1014 | const curr = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); | 1045 | const curr = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); |
| ... | @@ -1020,7 +1051,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -1020,7 +1051,7 @@ fn doRelocs(self: *Zld) !void { |
| 1020 | }; | 1051 | }; |
| 1021 | const ta = if (addend) |a| target_addr + a else target_addr; | 1052 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 1022 | const narrowed = @truncate(u12, ta); | 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 | // For TLV, we always generate an add instruction. | 1055 | // For TLV, we always generate an add instruction. |
| 1025 | mem.writeIntLittle(u32, inst, Arm64.add(parsed.rt, parsed.rn, narrowed, parsed.size).toU32()); | 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,9 +1061,9 @@ fn doRelocs(self: *Zld) !void { |
| 1030 | .ARM64_RELOC_UNSIGNED => { | 1061 | .ARM64_RELOC_UNSIGNED => { |
| 1031 | switch (rel.r_length) { | 1062 | switch (rel.r_length) { |
| 1032 | 3 => { | 1063 | 3 => { |
| 1033 | const inst = code[off..][0..8]; | 1064 | const inst = code.items[off..][0..8]; |
| 1034 | const offset = mem.readIntLittle(i64, inst); | 1065 | const offset = mem.readIntLittle(i64, inst); |
| 1035 | log.debug(" | calculated addend 0x{x}", .{offset}); | 1066 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 1036 | const result = if (sub) |s| | 1067 | const result = if (sub) |s| |
| 1037 | @intCast(i64, target_addr) - s + offset | 1068 | @intCast(i64, target_addr) - s + offset |
| 1038 | else | 1069 | else |
| ... | @@ -1054,9 +1085,9 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -1054,9 +1085,9 @@ fn doRelocs(self: *Zld) !void { |
| 1054 | } | 1085 | } |
| 1055 | }, | 1086 | }, |
| 1056 | 2 => { | 1087 | 2 => { |
| 1057 | const inst = code[off..][0..4]; | 1088 | const inst = code.items[off..][0..4]; |
| 1058 | const offset = mem.readIntLittle(i32, inst); | 1089 | const offset = mem.readIntLittle(i32, inst); |
| 1059 | log.debug(" | calculated addend 0x{x}", .{offset}); | 1090 | log.warn(" | calculated addend 0x{x}", .{offset}); |
| 1060 | const result = if (sub) |s| | 1091 | const result = if (sub) |s| |
| 1061 | @intCast(i64, target_addr) - s + offset | 1092 | @intCast(i64, target_addr) - s + offset |
| 1062 | else | 1093 | else |
| ... | @@ -1078,7 +1109,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -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 | segname, | 1113 | segname, |
| 1083 | sectname, | 1114 | sectname, |
| 1084 | object.name, | 1115 | object.name, |
| ... | @@ -1096,7 +1127,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -1096,7 +1127,7 @@ fn doRelocs(self: *Zld) !void { |
| 1096 | mem.set(u8, zeroes, 0); | 1127 | mem.set(u8, zeroes, 0); |
| 1097 | try self.file.?.pwriteAll(zeroes, next.offset); | 1128 | try self.file.?.pwriteAll(zeroes, next.offset); |
| 1098 | } else { | 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,7 +1703,7 @@ fn writeRebaseInfoTable(self: *Zld) !void { |
| 1672 | dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64))); | 1703 | dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64))); |
| 1673 | seg.inner.filesize += dyld_info.rebase_size; | 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 | try self.file.?.pwriteAll(buffer, dyld_info.rebase_off); | 1708 | try self.file.?.pwriteAll(buffer, dyld_info.rebase_off); |
| 1678 | } | 1709 | } |
| ... | @@ -1725,7 +1756,7 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -1725,7 +1756,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 1725 | dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); | 1756 | dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 1726 | seg.inner.filesize += dyld_info.bind_size; | 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 | try self.file.?.pwriteAll(buffer, dyld_info.bind_off); | 1761 | try self.file.?.pwriteAll(buffer, dyld_info.bind_off); |
| 1731 | } | 1762 | } |
| ... | @@ -1764,7 +1795,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { | ... | @@ -1764,7 +1795,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { |
| 1764 | dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); | 1795 | dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 1765 | seg.inner.filesize += dyld_info.lazy_bind_size; | 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 | try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); | 1800 | try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); |
| 1770 | try self.populateLazyBindOffsetsInStubHelper(buffer); | 1801 | try self.populateLazyBindOffsetsInStubHelper(buffer); |
| ... | @@ -1866,7 +1897,7 @@ fn writeExportInfo(self: *Zld) !void { | ... | @@ -1866,7 +1897,7 @@ fn writeExportInfo(self: *Zld) !void { |
| 1866 | dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); | 1897 | dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 1867 | seg.inner.filesize += dyld_info.export_size; | 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 | try self.file.?.pwriteAll(buffer, dyld_info.export_off); | 1902 | try self.file.?.pwriteAll(buffer, dyld_info.export_off); |
| 1872 | } | 1903 | } |
| ... | @@ -1995,7 +2026,7 @@ fn writeDebugInfo(self: *Zld) !void { | ... | @@ -1995,7 +2026,7 @@ fn writeDebugInfo(self: *Zld) !void { |
| 1995 | | 2026 | |
| 1996 | const stabs_off = symtab.symoff; | 2027 | const stabs_off = symtab.symoff; |
| 1997 | const stabs_size = symtab.nsyms * @sizeOf(macho.nlist_64); | 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 | try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off); | 2030 | try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off); |
| 2000 | | 2031 | |
| 2001 | linkedit.inner.filesize += stabs_size; | 2032 | linkedit.inner.filesize += stabs_size; |
| ... | @@ -2044,17 +2075,17 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2044,17 +2075,17 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2044 | | 2075 | |
| 2045 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); | 2076 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); |
| 2046 | const locals_size = nlocals * @sizeOf(macho.nlist_64); | 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 | try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); | 2079 | try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); |
| 2049 | | 2080 | |
| 2050 | const exports_off = locals_off + locals_size; | 2081 | const exports_off = locals_off + locals_size; |
| 2051 | const exports_size = nexports * @sizeOf(macho.nlist_64); | 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 | try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); | 2084 | try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); |
| 2054 | | 2085 | |
| 2055 | const undefs_off = exports_off + exports_size; | 2086 | const undefs_off = exports_off + exports_size; |
| 2056 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); | 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 | try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off); | 2089 | try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off); |
| 2059 | | 2090 | |
| 2060 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); | 2091 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); |
| ... | @@ -2085,7 +2116,7 @@ fn writeDynamicSymbolTable(self: *Zld) !void { | ... | @@ -2085,7 +2116,7 @@ fn writeDynamicSymbolTable(self: *Zld) !void { |
| 2085 | const needed_size = dysymtab.nindirectsyms * @sizeOf(u32); | 2116 | const needed_size = dysymtab.nindirectsyms * @sizeOf(u32); |
| 2086 | seg.inner.filesize += needed_size; | 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 | dysymtab.indirectsymoff, | 2120 | dysymtab.indirectsymoff, |
| 2090 | dysymtab.indirectsymoff + needed_size, | 2121 | dysymtab.indirectsymoff + needed_size, |
| 2091 | }); | 2122 | }); |
| ... | @@ -2124,7 +2155,7 @@ fn writeStringTable(self: *Zld) !void { | ... | @@ -2124,7 +2155,7 @@ fn writeStringTable(self: *Zld) !void { |
| 2124 | symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64))); | 2155 | symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64))); |
| 2125 | seg.inner.filesize += symtab.strsize; | 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 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); | 2160 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); |
| 2130 | | 2161 | |
| ... | @@ -2150,7 +2181,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { | ... | @@ -2150,7 +2181,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { |
| 2150 | seg.inner.filesize += needed_size; | 2181 | seg.inner.filesize += needed_size; |
| 2151 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); | 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 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file | 2186 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file |
| 2156 | // except for code signature data. | 2187 | // except for code signature data. |
| ... | @@ -2176,7 +2207,7 @@ fn writeCodeSignature(self: *Zld) !void { | ... | @@ -2176,7 +2207,7 @@ fn writeCodeSignature(self: *Zld) !void { |
| 2176 | var stream = std.io.fixedBufferStream(buffer); | 2207 | var stream = std.io.fixedBufferStream(buffer); |
| 2177 | try code_sig.write(stream.writer()); | 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 | try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff); | 2212 | try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff); |
| 2182 | } | 2213 | } |
| ... | @@ -2195,7 +2226,7 @@ fn writeLoadCommands(self: *Zld) !void { | ... | @@ -2195,7 +2226,7 @@ fn writeLoadCommands(self: *Zld) !void { |
| 2195 | } | 2226 | } |
| 2196 | | 2227 | |
| 2197 | const off = @sizeOf(macho.mach_header_64); | 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 | try self.file.?.pwriteAll(buffer, off); | 2230 | try self.file.?.pwriteAll(buffer, off); |
| 2200 | } | 2231 | } |
| 2201 | | 2232 | |
| ... | @@ -2233,7 +2264,7 @@ fn writeHeader(self: *Zld) !void { | ... | @@ -2233,7 +2264,7 @@ fn writeHeader(self: *Zld) !void { |
| 2233 | for (self.load_commands.items) |cmd| { | 2264 | for (self.load_commands.items) |cmd| { |
| 2234 | header.sizeofcmds += cmd.cmdsize(); | 2265 | header.sizeofcmds += cmd.cmdsize(); |
| 2235 | } | 2266 | } |
| 2236 | log.debug("writing Mach-O header {}", .{header}); | 2267 | log.warn("writing Mach-O header {}", .{header}); |
| 2237 | try self.file.?.pwriteAll(mem.asBytes(&header), 0); | 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,7 +2278,7 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| 2247 | fn makeString(self: *Zld, bytes: []const u8) !u32 { | 2278 | fn makeString(self: *Zld, bytes: []const u8) !u32 { |
| 2248 | try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1); | 2279 | try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1); |
| 2249 | const offset = @intCast(u32, self.strtab.items.len); | 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 | self.strtab.appendSliceAssumeCapacity(bytes); | 2282 | self.strtab.appendSliceAssumeCapacity(bytes); |
| 2252 | self.strtab.appendAssumeCapacity(0); | 2283 | self.strtab.appendAssumeCapacity(0); |
| 2253 | return offset; | 2284 | return offset; |