| ... | @@ -923,42 +923,9 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { | ... | @@ -923,42 +923,9 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { |
| 923 | return error.NoSymbolTableFound; | 923 | return error.NoSymbolTableFound; |
| 924 | } | 924 | } |
| 925 | | 925 | |
| 926 | // // Parse dyld info | 926 | // Patch dyld info |
| 927 | // try self.parseBindingInfoTable(); | 927 | try self.fixupBindInfo(next_ordinal); |
| 928 | // try self.parseLazyBindingInfoTable(); | 928 | try self.fixupLazyBindInfo(next_ordinal); |
| 929 | | | |
| 930 | // // Update the dylib ordinals. | | |
| 931 | // self.binding_info_table.dylib_ordinal = next_ordinal; | | |
| 932 | // for (self.lazy_binding_info_table.symbols.items) |*symbol| { | | |
| 933 | // symbol.dylib_ordinal = next_ordinal; | | |
| 934 | // } | | |
| 935 | | | |
| 936 | // // Write updated dyld info. | | |
| 937 | // const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; | | |
| 938 | // { | | |
| 939 | // const size = try self.binding_info_table.calcSize(); | | |
| 940 | // assert(dyld_info.bind_size >= size); | | |
| 941 | | | |
| 942 | // var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); | | |
| 943 | // defer self.base.allocator.free(buffer); | | |
| 944 | | | |
| 945 | // var stream = std.io.fixedBufferStream(buffer); | | |
| 946 | // try self.binding_info_table.write(stream.writer()); | | |
| 947 | | | |
| 948 | // try self.base.file.?.pwriteAll(buffer, dyld_info.bind_off); | | |
| 949 | // } | | |
| 950 | // { | | |
| 951 | // const size = try self.lazy_binding_info_table.calcSize(); | | |
| 952 | // assert(dyld_info.lazy_bind_size >= size); | | |
| 953 | | | |
| 954 | // var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); | | |
| 955 | // defer self.base.allocator.free(buffer); | | |
| 956 | | | |
| 957 | // var stream = std.io.fixedBufferStream(buffer); | | |
| 958 | // try self.lazy_binding_info_table.write(stream.writer()); | | |
| 959 | | | |
| 960 | // try self.base.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); | | |
| 961 | // } | | |
| 962 | | 929 | |
| 963 | // Write updated load commands and the header | 930 | // Write updated load commands and the header |
| 964 | try self.writeLoadCommands(); | 931 | try self.writeLoadCommands(); |
| ... | @@ -3068,24 +3035,61 @@ fn parseStringTable(self: *MachO) !void { | ... | @@ -3068,24 +3035,61 @@ fn parseStringTable(self: *MachO) !void { |
| 3068 | self.string_table.appendSliceAssumeCapacity(buffer); | 3035 | self.string_table.appendSliceAssumeCapacity(buffer); |
| 3069 | } | 3036 | } |
| 3070 | | 3037 | |
| 3071 | fn parseBindingInfoTable(self: *MachO) !void { | 3038 | fn fixupBindInfo(self: *MachO, dylib_ordinal: u32) !void { |
| 3072 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; | 3039 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 3073 | var buffer = try self.base.allocator.alloc(u8, dyld_info.bind_size); | 3040 | var buffer = try self.base.allocator.alloc(u8, dyld_info.bind_size); |
| 3074 | defer self.base.allocator.free(buffer); | 3041 | defer self.base.allocator.free(buffer); |
| 3075 | const nread = try self.base.file.?.preadAll(buffer, dyld_info.bind_off); | 3042 | const nread = try self.base.file.?.preadAll(buffer, dyld_info.bind_off); |
| 3076 | assert(nread == buffer.len); | 3043 | assert(nread == buffer.len); |
| 3077 | | 3044 | try self.fixupInfoCommon(buffer, dylib_ordinal); |
| 3078 | var stream = std.io.fixedBufferStream(buffer); | 3045 | try self.base.file.?.pwriteAll(buffer, dyld_info.bind_off); |
| 3079 | // try self.binding_info_table.read(stream.reader(), self.base.allocator); | | |
| 3080 | } | 3046 | } |
| 3081 | | 3047 | |
| 3082 | fn parseLazyBindingInfoTable(self: *MachO) !void { | 3048 | fn fixupLazyBindInfo(self: *MachO, dylib_ordinal: u32) !void { |
| 3083 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; | 3049 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 3084 | var buffer = try self.base.allocator.alloc(u8, dyld_info.lazy_bind_size); | 3050 | var buffer = try self.base.allocator.alloc(u8, dyld_info.lazy_bind_size); |
| 3085 | defer self.base.allocator.free(buffer); | 3051 | defer self.base.allocator.free(buffer); |
| 3086 | const nread = try self.base.file.?.preadAll(buffer, dyld_info.lazy_bind_off); | 3052 | const nread = try self.base.file.?.preadAll(buffer, dyld_info.lazy_bind_off); |
| 3087 | assert(nread == buffer.len); | 3053 | assert(nread == buffer.len); |
| | 3054 | try self.fixupInfoCommon(buffer, dylib_ordinal); |
| | 3055 | try self.base.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); |
| | 3056 | } |
| 3088 | | 3057 | |
| | 3058 | fn fixupInfoCommon(self: *MachO, buffer: []u8, dylib_ordinal: u32) !void { |
| 3089 | var stream = std.io.fixedBufferStream(buffer); | 3059 | var stream = std.io.fixedBufferStream(buffer); |
| 3090 | // try self.lazy_binding_info_table.read(stream.reader(), self.base.allocator); | 3060 | var reader = stream.reader(); |
| | 3061 | |
| | 3062 | while (true) { |
| | 3063 | const inst = reader.readByte() catch |err| switch (err) { |
| | 3064 | error.EndOfStream => break, |
| | 3065 | else => return err, |
| | 3066 | }; |
| | 3067 | const imm: u8 = inst & macho.BIND_IMMEDIATE_MASK; |
| | 3068 | const opcode: u8 = inst & macho.BIND_OPCODE_MASK; |
| | 3069 | |
| | 3070 | switch (opcode) { |
| | 3071 | macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM => { |
| | 3072 | var next = try reader.readByte(); |
| | 3073 | while (next != @as(u8, 0)) { |
| | 3074 | next = try reader.readByte(); |
| | 3075 | } |
| | 3076 | }, |
| | 3077 | macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => { |
| | 3078 | _ = try std.leb.readULEB128(u64, reader); |
| | 3079 | }, |
| | 3080 | macho.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM, macho.BIND_OPCODE_SET_DYLIB_ORDINAL_IMM => { |
| | 3081 | // Perform the fixup. |
| | 3082 | try stream.seekBy(-1); |
| | 3083 | var writer = stream.writer(); |
| | 3084 | try writer.writeByte(macho.BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | @truncate(u4, dylib_ordinal)); |
| | 3085 | }, |
| | 3086 | macho.BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB => { |
| | 3087 | _ = try std.leb.readULEB128(u64, reader); |
| | 3088 | }, |
| | 3089 | macho.BIND_OPCODE_SET_ADDEND_SLEB => { |
| | 3090 | _ = try std.leb.readILEB128(i64, reader); |
| | 3091 | }, |
| | 3092 | else => {}, |
| | 3093 | } |
| | 3094 | } |
| 3091 | } | 3095 | } |