authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-09 23:04:00+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-13 23:55:28+01:00
log1b91a9f4c840741e77e5c7ce826c5f80c9f9ee80
tree4fc39d38b1da3c69f961a75329d88fc589d89da7
parent7d40aaad2b514703995458909b315f222543c4cd

macho: bring back lld cc hot-fix


1 files changed, 46 insertions(+), 42 deletions(-)

src/link/MachO.zig+46-42
...@@ -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 }
925925
926 // // Parse dyld info926 // 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 // }
962929
963 // Write updated load commands and the header930 // 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}
30703037
3071fn parseBindingInfoTable(self: *MachO) !void {3038fn 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);
30773044 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}
30813047
3082fn parseLazyBindingInfoTable(self: *MachO) !void {3048fn 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}
30883057
3058fn 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}