| ... | ... | @@ -923,42 +923,9 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { |
| 923 | 923 | return error.NoSymbolTableFound; |
| 924 | 924 | } |
| 925 | 925 | |
| 926 | | // // Parse dyld info |
| 927 | | // try self.parseBindingInfoTable(); |
| 928 | | // try self.parseLazyBindingInfoTable(); |
| 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 | | // } |
| 926 | // Patch dyld info |
| 927 | try self.fixupBindInfo(next_ordinal); |
| 928 | try self.fixupLazyBindInfo(next_ordinal); |
| 962 | 929 | |
| 963 | 930 | // Write updated load commands and the header |
| 964 | 931 | try self.writeLoadCommands(); |
| ... | ... | @@ -3068,24 +3035,61 @@ fn parseStringTable(self: *MachO) !void { |
| 3068 | 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 | 3039 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 3073 | 3040 | var buffer = try self.base.allocator.alloc(u8, dyld_info.bind_size); |
| 3074 | 3041 | defer self.base.allocator.free(buffer); |
| 3075 | 3042 | const nread = try self.base.file.?.preadAll(buffer, dyld_info.bind_off); |
| 3076 | 3043 | assert(nread == buffer.len); |
| 3077 | | |
| 3078 | | var stream = std.io.fixedBufferStream(buffer); |
| 3079 | | // try self.binding_info_table.read(stream.reader(), self.base.allocator); |
| 3044 | try self.fixupInfoCommon(buffer, dylib_ordinal); |
| 3045 | try self.base.file.?.pwriteAll(buffer, dyld_info.bind_off); |
| 3080 | 3046 | } |
| 3081 | 3047 | |
| 3082 | | fn parseLazyBindingInfoTable(self: *MachO) !void { |
| 3048 | fn fixupLazyBindInfo(self: *MachO, dylib_ordinal: u32) !void { |
| 3083 | 3049 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 3084 | 3050 | var buffer = try self.base.allocator.alloc(u8, dyld_info.lazy_bind_size); |
| 3085 | 3051 | defer self.base.allocator.free(buffer); |
| 3086 | 3052 | const nread = try self.base.file.?.preadAll(buffer, dyld_info.lazy_bind_off); |
| 3087 | 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 | 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 | } |