authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-02 11:58:28+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-15 18:49:46+02:00
log980f2915fa15ab35029e8f3cab21d309811f6e30
tree8e0bafb88c9c250ec7ffda25f5474a4ce92e1a62
parentee6e25bc13b3f23b5f2fd0c8b57f0d115c239fc2

zld: use index to symbol in reloc

instead of pointer to the Symbol struct in the hope that we can overwrite the Symbol in the object's symbol table with the resolved Symbol later down the line.

5 files changed, 29 insertions(+), 34 deletions(-)

src/link/MachO/Object.zig+2-2
...@@ -377,7 +377,6 @@ pub fn parseSections(self: *Object) !void {...@@ -377,7 +377,6 @@ pub fn parseSections(self: *Object) !void {
377 self.arch.?,377 self.arch.?,
378 section.code,378 section.code,
379 mem.bytesAsSlice(macho.relocation_info, raw_relocs),379 mem.bytesAsSlice(macho.relocation_info, raw_relocs),
380 self.symbols.items,
381 );380 );
382 }381 }
383382
...@@ -395,7 +394,8 @@ pub fn parseInitializers(self: *Object) !void {...@@ -395,7 +394,8 @@ pub fn parseInitializers(self: *Object) !void {
395 const relocs = section.relocs orelse unreachable;394 const relocs = section.relocs orelse unreachable;
396 try self.initializers.ensureCapacity(self.allocator, relocs.len);395 try self.initializers.ensureCapacity(self.allocator, relocs.len);
397 for (relocs) |rel| {396 for (relocs) |rel| {
398 self.initializers.appendAssumeCapacity(rel.target.symbol);397 const sym = self.symbols.items[rel.target.symbol];
398 self.initializers.appendAssumeCapacity(sym);
399 }399 }
400400
401 mem.reverse(*Symbol, self.initializers.items);401 mem.reverse(*Symbol, self.initializers.items);
src/link/MachO/Zld.zig+9-7
...@@ -1172,7 +1172,7 @@ fn allocateProxyBindAddresses(self: *Zld) !void {...@@ -1172,7 +1172,7 @@ fn allocateProxyBindAddresses(self: *Zld) !void {
1172 if (rel.@"type" != .unsigned) continue; // GOT is currently special-cased1172 if (rel.@"type" != .unsigned) continue; // GOT is currently special-cased
1173 if (rel.target != .symbol) continue;1173 if (rel.target != .symbol) continue;
11741174
1175 const sym = rel.target.symbol.getTopmostAlias();1175 const sym = object.symbols.items[rel.target.symbol].getTopmostAlias();
1176 if (sym.cast(Symbol.Proxy)) |proxy| {1176 if (sym.cast(Symbol.Proxy)) |proxy| {
1177 const target_map = sect.target_map orelse continue;1177 const target_map = sect.target_map orelse continue;
1178 const target_seg = self.load_commands.items[target_map.segment_id].Segment;1178 const target_seg = self.load_commands.items[target_map.segment_id].Segment;
...@@ -1670,7 +1670,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {...@@ -1670,7 +1670,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {
1670 switch (rel.@"type") {1670 switch (rel.@"type") {
1671 .unsigned => continue,1671 .unsigned => continue,
1672 .got_page, .got_page_off, .got_load, .got, .pointer_to_got => {1672 .got_page, .got_page_off, .got_load, .got, .pointer_to_got => {
1673 const sym = rel.target.symbol.getTopmostAlias();1673 const sym = object.symbols.items[rel.target.symbol].getTopmostAlias();
1674 if (sym.got_index != null) continue;1674 if (sym.got_index != null) continue;
16751675
1676 const index = @intCast(u32, self.got_entries.items.len);1676 const index = @intCast(u32, self.got_entries.items.len);
...@@ -1682,7 +1682,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {...@@ -1682,7 +1682,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {
1682 else => {1682 else => {
1683 if (rel.target != .symbol) continue;1683 if (rel.target != .symbol) continue;
16841684
1685 const sym = rel.target.symbol.getTopmostAlias();1685 const sym = object.symbols.items[rel.target.symbol].getTopmostAlias();
1686 assert(sym.@"type" != .unresolved);1686 assert(sym.@"type" != .unresolved);
16871687
1688 if (sym.stubs_index != null) continue;1688 if (sym.stubs_index != null) continue;
...@@ -1781,7 +1781,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {...@@ -1781,7 +1781,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
1781 break :rebase false;1781 break :rebase false;
1782 }1782 }
1783 if (rel.target == .symbol) {1783 if (rel.target == .symbol) {
1784 const final = rel.target.symbol.getTopmostAlias();1784 const final = object.symbols.items[rel.target.symbol].getTopmostAlias();
1785 if (final.cast(Symbol.Proxy)) |_| {1785 if (final.cast(Symbol.Proxy)) |_| {
1786 break :rebase false;1786 break :rebase false;
1787 }1787 }
...@@ -1801,7 +1801,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {...@@ -1801,7 +1801,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
1801 // Calculate the offset to the initializer.1801 // Calculate the offset to the initializer.
1802 if (flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: {1802 if (flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: {
1803 // TODO we don't want to save offset to tlv_bootstrap1803 // TODO we don't want to save offset to tlv_bootstrap
1804 if (mem.eql(u8, rel.target.symbol.name, "__tlv_bootstrap")) break :tlv;1804 if (mem.eql(u8, object.symbols.items[rel.target.symbol].name, "__tlv_bootstrap")) break :tlv;
18051805
1806 const base_addr = blk: {1806 const base_addr = blk: {
1807 if (self.tlv_data_section_index) |index| {1807 if (self.tlv_data_section_index) |index| {
...@@ -1823,7 +1823,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {...@@ -1823,7 +1823,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
1823 .got_page, .got_page_off, .got_load, .got, .pointer_to_got => {1823 .got_page, .got_page_off, .got_load, .got, .pointer_to_got => {
1824 const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;1824 const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
1825 const got = dc_seg.sections.items[self.got_section_index.?];1825 const got = dc_seg.sections.items[self.got_section_index.?];
1826 const final = rel.target.symbol.getTopmostAlias();1826 const sym = object.symbols.items[rel.target.symbol];
1827 const final = sym.getTopmostAlias();
1827 const got_index = final.got_index orelse {1828 const got_index = final.got_index orelse {
1828 log.err("expected GOT index relocating symbol '{s}'", .{final.name});1829 log.err("expected GOT index relocating symbol '{s}'", .{final.name});
1829 log.err("this is an internal linker error", .{});1830 log.err("this is an internal linker error", .{});
...@@ -1879,7 +1880,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {...@@ -1879,7 +1880,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
1879fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.Target) !u64 {1880fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.Target) !u64 {
1880 const target_addr = blk: {1881 const target_addr = blk: {
1881 switch (target) {1882 switch (target) {
1882 .symbol => |sym| {1883 .symbol => |sym_id| {
1884 const sym = object.symbols.items[sym_id];
1883 const final = sym.getTopmostAlias();1885 const final = sym.getTopmostAlias();
1884 if (final.cast(Symbol.Regular)) |reg| {1886 if (final.cast(Symbol.Regular)) |reg| {
1885 log.debug(" | regular '{s}'", .{sym.name});1887 log.debug(" | regular '{s}'", .{sym.name});
src/link/MachO/reloc.zig+3-7
...@@ -10,7 +10,6 @@ const aarch64 = @import("reloc/aarch64.zig");...@@ -10,7 +10,6 @@ const aarch64 = @import("reloc/aarch64.zig");
10const x86_64 = @import("reloc/x86_64.zig");10const x86_64 = @import("reloc/x86_64.zig");
1111
12const Allocator = mem.Allocator;12const Allocator = mem.Allocator;
13const Symbol = @import("Symbol.zig");
1413
15pub const Relocation = struct {14pub const Relocation = struct {
16 @"type": Type,15 @"type": Type,
...@@ -81,12 +80,12 @@ pub const Relocation = struct {...@@ -81,12 +80,12 @@ pub const Relocation = struct {
81 };80 };
8281
83 pub const Target = union(enum) {82 pub const Target = union(enum) {
84 symbol: *Symbol,83 symbol: u32,
85 section: u16,84 section: u16,
8685
87 pub fn from_reloc(reloc: macho.relocation_info, symbols: []*Symbol) Target {86 pub fn fromReloc(reloc: macho.relocation_info) Target {
88 return if (reloc.r_extern == 1) .{87 return if (reloc.r_extern == 1) .{
89 .symbol = symbols[reloc.r_symbolnum],88 .symbol = reloc.r_symbolnum,
90 } else .{89 } else .{
91 .section = @intCast(u16, reloc.r_symbolnum - 1),90 .section = @intCast(u16, reloc.r_symbolnum - 1),
92 };91 };
...@@ -142,7 +141,6 @@ pub fn parse(...@@ -142,7 +141,6 @@ pub fn parse(
142 arch: std.Target.Cpu.Arch,141 arch: std.Target.Cpu.Arch,
143 code: []u8,142 code: []u8,
144 relocs: []const macho.relocation_info,143 relocs: []const macho.relocation_info,
145 symbols: []*Symbol,
146) ![]*Relocation {144) ![]*Relocation {
147 var it = RelocIterator{145 var it = RelocIterator{
148 .buffer = relocs,146 .buffer = relocs,
...@@ -155,7 +153,6 @@ pub fn parse(...@@ -155,7 +153,6 @@ pub fn parse(
155 .it = &it,153 .it = &it,
156 .code = code,154 .code = code,
157 .parsed = std.ArrayList(*Relocation).init(allocator),155 .parsed = std.ArrayList(*Relocation).init(allocator),
158 .symbols = symbols,
159 };156 };
160 defer parser.deinit();157 defer parser.deinit();
161 try parser.parse();158 try parser.parse();
...@@ -168,7 +165,6 @@ pub fn parse(...@@ -168,7 +165,6 @@ pub fn parse(
168 .it = &it,165 .it = &it,
169 .code = code,166 .code = code,
170 .parsed = std.ArrayList(*Relocation).init(allocator),167 .parsed = std.ArrayList(*Relocation).init(allocator),
171 .symbols = symbols,
172 };168 };
173 defer parser.deinit();169 defer parser.deinit();
174 try parser.parse();170 try parser.parse();
src/link/MachO/reloc/aarch64.zig+8-9
...@@ -203,7 +203,6 @@ pub const Parser = struct {...@@ -203,7 +203,6 @@ pub const Parser = struct {
203 it: *reloc.RelocIterator,203 it: *reloc.RelocIterator,
204 code: []u8,204 code: []u8,
205 parsed: std.ArrayList(*Relocation),205 parsed: std.ArrayList(*Relocation),
206 symbols: []*Symbol,
207 addend: ?u32 = null,206 addend: ?u32 = null,
208 subtractor: ?Relocation.Target = null,207 subtractor: ?Relocation.Target = null,
209208
...@@ -287,7 +286,7 @@ pub const Parser = struct {...@@ -287,7 +286,7 @@ pub const Parser = struct {
287 var branch = try parser.allocator.create(Branch);286 var branch = try parser.allocator.create(Branch);
288 errdefer parser.allocator.destroy(branch);287 errdefer parser.allocator.destroy(branch);
289288
290 const target = Relocation.Target.from_reloc(rel, parser.symbols);289 const target = Relocation.Target.fromReloc(rel);
291290
292 branch.* = .{291 branch.* = .{
293 .base = .{292 .base = .{
...@@ -308,7 +307,7 @@ pub const Parser = struct {...@@ -308,7 +307,7 @@ pub const Parser = struct {
308 assert(rel.r_length == 2);307 assert(rel.r_length == 2);
309308
310 const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type);309 const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type);
311 const target = Relocation.Target.from_reloc(rel, parser.symbols);310 const target = Relocation.Target.fromReloc(rel);
312311
313 const offset = @intCast(u32, rel.r_address);312 const offset = @intCast(u32, rel.r_address);
314 const inst = parser.code[offset..][0..4];313 const inst = parser.code[offset..][0..4];
...@@ -414,7 +413,7 @@ pub const Parser = struct {...@@ -414,7 +413,7 @@ pub const Parser = struct {
414 aarch64.Instruction.load_store_register,413 aarch64.Instruction.load_store_register,
415 ), inst) };414 ), inst) };
416 }415 }
417 const target = Relocation.Target.from_reloc(rel, parser.symbols);416 const target = Relocation.Target.fromReloc(rel);
418417
419 var page_off = try parser.allocator.create(PageOff);418 var page_off = try parser.allocator.create(PageOff);
420 errdefer parser.allocator.destroy(page_off);419 errdefer parser.allocator.destroy(page_off);
...@@ -451,7 +450,7 @@ pub const Parser = struct {...@@ -451,7 +450,7 @@ pub const Parser = struct {
451 ), inst);450 ), inst);
452 assert(parsed_inst.size == 3);451 assert(parsed_inst.size == 3);
453452
454 const target = Relocation.Target.from_reloc(rel, parser.symbols);453 const target = Relocation.Target.fromReloc(rel);
455454
456 var page_off = try parser.allocator.create(GotPageOff);455 var page_off = try parser.allocator.create(GotPageOff);
457 errdefer parser.allocator.destroy(page_off);456 errdefer parser.allocator.destroy(page_off);
...@@ -510,7 +509,7 @@ pub const Parser = struct {...@@ -510,7 +509,7 @@ pub const Parser = struct {
510 }509 }
511 };510 };
512511
513 const target = Relocation.Target.from_reloc(rel, parser.symbols);512 const target = Relocation.Target.fromReloc(rel);
514513
515 var page_off = try parser.allocator.create(TlvpPageOff);514 var page_off = try parser.allocator.create(TlvpPageOff);
516 errdefer parser.allocator.destroy(page_off);515 errdefer parser.allocator.destroy(page_off);
...@@ -545,7 +544,7 @@ pub const Parser = struct {...@@ -545,7 +544,7 @@ pub const Parser = struct {
545 assert(rel.r_pcrel == 0);544 assert(rel.r_pcrel == 0);
546 assert(parser.subtractor == null);545 assert(parser.subtractor == null);
547546
548 parser.subtractor = Relocation.Target.from_reloc(rel, parser.symbols);547 parser.subtractor = Relocation.Target.fromReloc(rel);
549548
550 // Verify SUBTRACTOR is followed by UNSIGNED.549 // Verify SUBTRACTOR is followed by UNSIGNED.
551 const next = @intToEnum(macho.reloc_type_arm64, parser.it.peek().r_type);550 const next = @intToEnum(macho.reloc_type_arm64, parser.it.peek().r_type);
...@@ -568,7 +567,7 @@ pub const Parser = struct {...@@ -568,7 +567,7 @@ pub const Parser = struct {
568 var unsigned = try parser.allocator.create(reloc.Unsigned);567 var unsigned = try parser.allocator.create(reloc.Unsigned);
569 errdefer parser.allocator.destroy(unsigned);568 errdefer parser.allocator.destroy(unsigned);
570569
571 const target = Relocation.Target.from_reloc(rel, parser.symbols);570 const target = Relocation.Target.fromReloc(rel);
572 const is_64bit: bool = switch (rel.r_length) {571 const is_64bit: bool = switch (rel.r_length) {
573 3 => true,572 3 => true,
574 2 => false,573 2 => false,
...@@ -605,7 +604,7 @@ pub const Parser = struct {...@@ -605,7 +604,7 @@ pub const Parser = struct {
605 var ptr_to_got = try parser.allocator.create(PointerToGot);604 var ptr_to_got = try parser.allocator.create(PointerToGot);
606 errdefer parser.allocator.destroy(ptr_to_got);605 errdefer parser.allocator.destroy(ptr_to_got);
607606
608 const target = Relocation.Target.from_reloc(rel, parser.symbols);607 const target = Relocation.Target.fromReloc(rel);
609 const offset = @intCast(u32, rel.r_address);608 const offset = @intCast(u32, rel.r_address);
610609
611 ptr_to_got.* = .{610 ptr_to_got.* = .{
src/link/MachO/reloc/x86_64.zig+7-9
...@@ -9,7 +9,6 @@ const reloc = @import("../reloc.zig");...@@ -9,7 +9,6 @@ const reloc = @import("../reloc.zig");
99
10const Allocator = mem.Allocator;10const Allocator = mem.Allocator;
11const Relocation = reloc.Relocation;11const Relocation = reloc.Relocation;
12const Symbol = @import("../Symbol.zig");
1312
14pub const Branch = struct {13pub const Branch = struct {
15 base: Relocation,14 base: Relocation,
...@@ -103,7 +102,6 @@ pub const Parser = struct {...@@ -103,7 +102,6 @@ pub const Parser = struct {
103 it: *reloc.RelocIterator,102 it: *reloc.RelocIterator,
104 code: []u8,103 code: []u8,
105 parsed: std.ArrayList(*Relocation),104 parsed: std.ArrayList(*Relocation),
106 symbols: []*Symbol,
107 subtractor: ?Relocation.Target = null,105 subtractor: ?Relocation.Target = null,
108106
109 pub fn deinit(parser: *Parser) void {107 pub fn deinit(parser: *Parser) void {
...@@ -154,7 +152,7 @@ pub const Parser = struct {...@@ -154,7 +152,7 @@ pub const Parser = struct {
154 var branch = try parser.allocator.create(Branch);152 var branch = try parser.allocator.create(Branch);
155 errdefer parser.allocator.destroy(branch);153 errdefer parser.allocator.destroy(branch);
156154
157 const target = Relocation.Target.from_reloc(rel, parser.symbols);155 const target = Relocation.Target.fromReloc(rel);
158156
159 branch.* = .{157 branch.* = .{
160 .base = .{158 .base = .{
...@@ -174,7 +172,7 @@ pub const Parser = struct {...@@ -174,7 +172,7 @@ pub const Parser = struct {
174 assert(rel.r_length == 2);172 assert(rel.r_length == 2);
175173
176 const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type);174 const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type);
177 const target = Relocation.Target.from_reloc(rel, parser.symbols);175 const target = Relocation.Target.fromReloc(rel);
178176
179 const offset = @intCast(u32, rel.r_address);177 const offset = @intCast(u32, rel.r_address);
180 const inst = parser.code[offset..][0..4];178 const inst = parser.code[offset..][0..4];
...@@ -213,7 +211,7 @@ pub const Parser = struct {...@@ -213,7 +211,7 @@ pub const Parser = struct {
213211
214 const offset = @intCast(u32, rel.r_address);212 const offset = @intCast(u32, rel.r_address);
215 const inst = parser.code[offset..][0..4];213 const inst = parser.code[offset..][0..4];
216 const target = Relocation.Target.from_reloc(rel, parser.symbols);214 const target = Relocation.Target.fromReloc(rel);
217215
218 var got_load = try parser.allocator.create(GotLoad);216 var got_load = try parser.allocator.create(GotLoad);
219 errdefer parser.allocator.destroy(got_load);217 errdefer parser.allocator.destroy(got_load);
...@@ -239,7 +237,7 @@ pub const Parser = struct {...@@ -239,7 +237,7 @@ pub const Parser = struct {
239237
240 const offset = @intCast(u32, rel.r_address);238 const offset = @intCast(u32, rel.r_address);
241 const inst = parser.code[offset..][0..4];239 const inst = parser.code[offset..][0..4];
242 const target = Relocation.Target.from_reloc(rel, parser.symbols);240 const target = Relocation.Target.fromReloc(rel);
243 const addend = mem.readIntLittle(i32, inst);241 const addend = mem.readIntLittle(i32, inst);
244242
245 var got = try parser.allocator.create(Got);243 var got = try parser.allocator.create(Got);
...@@ -267,7 +265,7 @@ pub const Parser = struct {...@@ -267,7 +265,7 @@ pub const Parser = struct {
267265
268 const offset = @intCast(u32, rel.r_address);266 const offset = @intCast(u32, rel.r_address);
269 const inst = parser.code[offset..][0..4];267 const inst = parser.code[offset..][0..4];
270 const target = Relocation.Target.from_reloc(rel, parser.symbols);268 const target = Relocation.Target.fromReloc(rel);
271269
272 var tlv = try parser.allocator.create(Tlv);270 var tlv = try parser.allocator.create(Tlv);
273 errdefer parser.allocator.destroy(tlv);271 errdefer parser.allocator.destroy(tlv);
...@@ -292,7 +290,7 @@ pub const Parser = struct {...@@ -292,7 +290,7 @@ pub const Parser = struct {
292 assert(rel.r_pcrel == 0);290 assert(rel.r_pcrel == 0);
293 assert(parser.subtractor == null);291 assert(parser.subtractor == null);
294292
295 parser.subtractor = Relocation.Target.from_reloc(rel, parser.symbols);293 parser.subtractor = Relocation.Target.fromReloc(rel);
296294
297 // Verify SUBTRACTOR is followed by UNSIGNED.295 // Verify SUBTRACTOR is followed by UNSIGNED.
298 const next = @intToEnum(macho.reloc_type_x86_64, parser.it.peek().r_type);296 const next = @intToEnum(macho.reloc_type_x86_64, parser.it.peek().r_type);
...@@ -315,7 +313,7 @@ pub const Parser = struct {...@@ -315,7 +313,7 @@ pub const Parser = struct {
315 var unsigned = try parser.allocator.create(reloc.Unsigned);313 var unsigned = try parser.allocator.create(reloc.Unsigned);
316 errdefer parser.allocator.destroy(unsigned);314 errdefer parser.allocator.destroy(unsigned);
317315
318 const target = Relocation.Target.from_reloc(rel, parser.symbols);316 const target = Relocation.Target.fromReloc(rel);
319 const is_64bit: bool = switch (rel.r_length) {317 const is_64bit: bool = switch (rel.r_length) {
320 3 => true,318 3 => true,
321 2 => false,319 2 => false,