| author | |
| committer | |
| log | a8629fb8501275d826912085ccd120eb48a53199 |
| tree | ab66d59c57765b63804c62dd6e14ed5e817cbd78 |
| parent | 30b7d3e45f25195791f8eba74a2f89d41b325049 |
This is incredibly confusing and I really need to simplify it.
Elf also possesses this shortcoming so once I get Coff up to speed
it should hopefully become clear on how to refactor this.6 files changed, 76 insertions(+), 26 deletions(-)
src/arch/x86_64/Emit.zig+3-2| ... | @@ -156,9 +156,10 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -156,9 +156,10 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 156 | .Lib => emit.lower.link_mode == .Static, | 156 | .Lib => emit.lower.link_mode == .Static, |
| 157 | }; | 157 | }; |
| 158 | const atom = macho_file.getSymbol(data.atom_index).getAtom(macho_file).?; | 158 | const atom = macho_file.getSymbol(data.atom_index).getAtom(macho_file).?; |
| 159 | const sym = macho_file.getSymbol(data.sym_index); | 159 | const sym_index = macho_file.getZigObject().?.symbols.items[data.sym_index]; |
| 160 | const sym = macho_file.getSymbol(sym_index); | ||
| 160 | if (sym.flags.needs_zig_got and !is_obj_or_static_lib) { | 161 | if (sym.flags.needs_zig_got and !is_obj_or_static_lib) { |
| 161 | _ = try sym.getOrCreateZigGotEntry(data.sym_index, macho_file); | 162 | _ = try sym.getOrCreateZigGotEntry(sym_index, macho_file); |
| 162 | } | 163 | } |
| 163 | const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) | 164 | const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) |
| 164 | .zig_got_load | 165 | .zig_got_load |
src/codegen.zig+1-1| ... | @@ -993,7 +993,7 @@ fn genDeclRef( | ... | @@ -993,7 +993,7 @@ fn genDeclRef( |
| 993 | else | 993 | else |
| 994 | null; | 994 | null; |
| 995 | const sym_index = try macho_file.getGlobalSymbol(sym_name, lib_name); | 995 | const sym_index = try macho_file.getGlobalSymbol(sym_name, lib_name); |
| 996 | macho_file.getSymbol(sym_index).flags.needs_got = true; | 996 | macho_file.getSymbol(macho_file.getZigObject().?.symbols.items[sym_index]).flags.needs_got = true; |
| 997 | return GenResult.mcv(.{ .load_symbol = sym_index }); | 997 | return GenResult.mcv(.{ .load_symbol = sym_index }); |
| 998 | } | 998 | } |
| 999 | const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, decl_index); | 999 | const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, decl_index); |
src/link/MachO.zig+20-7| ... | @@ -542,8 +542,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node | ... | @@ -542,8 +542,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 542 | self.internal_object = index; | 542 | self.internal_object = index; |
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | state_log.debug("{}", .{self.dumpState()}); | ||
| 546 | |||
| 547 | try self.addUndefinedGlobals(); | 545 | try self.addUndefinedGlobals(); |
| 548 | try self.resolveSymbols(); | 546 | try self.resolveSymbols(); |
| 549 | try self.resolveSyntheticSymbols(); | 547 | try self.resolveSyntheticSymbols(); |
| ... | @@ -2389,14 +2387,23 @@ fn initDyldInfoSections(self: *MachO) !void { | ... | @@ -2389,14 +2387,23 @@ fn initDyldInfoSections(self: *MachO) !void { |
| 2389 | if (self.la_symbol_ptr_sect_index != null) try self.la_symbol_ptr.addDyldRelocs(self); | 2387 | if (self.la_symbol_ptr_sect_index != null) try self.la_symbol_ptr.addDyldRelocs(self); |
| 2390 | try self.initExportTrie(); | 2388 | try self.initExportTrie(); |
| 2391 | 2389 | ||
| 2390 | var objects = try std.ArrayList(File.Index).initCapacity(gpa, self.objects.items.len + 1); | ||
| 2391 | defer objects.deinit(); | ||
| 2392 | if (self.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index); | ||
| 2393 | objects.appendSliceAssumeCapacity(self.objects.items); | ||
| 2394 | |||
| 2392 | var nrebases: usize = 0; | 2395 | var nrebases: usize = 0; |
| 2393 | var nbinds: usize = 0; | 2396 | var nbinds: usize = 0; |
| 2394 | var nweak_binds: usize = 0; | 2397 | var nweak_binds: usize = 0; |
| 2395 | for (self.objects.items) |index| { | 2398 | for (objects.items) |index| { |
| 2396 | const object = self.getFile(index).?.object; | 2399 | const ctx = switch (self.getFile(index).?) { |
| 2397 | nrebases += object.num_rebase_relocs; | 2400 | .zig_object => |x| x.dynamic_relocs, |
| 2398 | nbinds += object.num_bind_relocs; | 2401 | .object => |x| x.dynamic_relocs, |
| 2399 | nweak_binds += object.num_weak_bind_relocs; | 2402 | else => unreachable, |
| 2403 | }; | ||
| 2404 | nrebases += ctx.rebase_relocs; | ||
| 2405 | nbinds += ctx.bind_relocs; | ||
| 2406 | nweak_binds += ctx.weak_bind_relocs; | ||
| 2400 | } | 2407 | } |
| 2401 | try self.rebase.entries.ensureUnusedCapacity(gpa, nrebases); | 2408 | try self.rebase.entries.ensureUnusedCapacity(gpa, nrebases); |
| 2402 | try self.bind.entries.ensureUnusedCapacity(gpa, nbinds); | 2409 | try self.bind.entries.ensureUnusedCapacity(gpa, nbinds); |
| ... | @@ -3947,6 +3954,12 @@ const HotUpdateState = struct { | ... | @@ -3947,6 +3954,12 @@ const HotUpdateState = struct { |
| 3947 | mach_task: ?std.os.darwin.MachTask = null, | 3954 | mach_task: ?std.os.darwin.MachTask = null, |
| 3948 | }; | 3955 | }; |
| 3949 | 3956 | ||
| 3957 | pub const DynamicRelocs = struct { | ||
| 3958 | rebase_relocs: u32 = 0, | ||
| 3959 | bind_relocs: u32 = 0, | ||
| 3960 | weak_bind_relocs: u32 = 0, | ||
| 3961 | }; | ||
| 3962 | |||
| 3950 | pub const SymtabCtx = struct { | 3963 | pub const SymtabCtx = struct { |
| 3951 | ilocal: u32 = 0, | 3964 | ilocal: u32 = 0, |
| 3952 | istab: u32 = 0, | 3965 | istab: u32 = 0, |
src/link/MachO/Atom.zig+23-8| ... | @@ -402,7 +402,11 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { | ... | @@ -402,7 +402,11 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { |
| 402 | defer tracy.end(); | 402 | defer tracy.end(); |
| 403 | assert(self.flags.alive); | 403 | assert(self.flags.alive); |
| 404 | 404 | ||
| 405 | const object = self.getFile(macho_file).object; | 405 | const dynrel_ctx = switch (self.getFile(macho_file)) { |
| 406 | .zig_object => |x| &x.dynamic_relocs, | ||
| 407 | .object => |x| &x.dynamic_relocs, | ||
| 408 | else => unreachable, | ||
| 409 | }; | ||
| 406 | const relocs = self.getRelocs(macho_file); | 410 | const relocs = self.getRelocs(macho_file); |
| 407 | 411 | ||
| 408 | for (relocs) |rel| { | 412 | for (relocs) |rel| { |
| ... | @@ -437,6 +441,10 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { | ... | @@ -437,6 +441,10 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { |
| 437 | } | 441 | } |
| 438 | }, | 442 | }, |
| 439 | 443 | ||
| 444 | .zig_got_load => { | ||
| 445 | assert(rel.getTargetSymbol(macho_file).flags.has_zig_got); | ||
| 446 | }, | ||
| 447 | |||
| 440 | .got => { | 448 | .got => { |
| 441 | rel.getTargetSymbol(macho_file).flags.needs_got = true; | 449 | rel.getTargetSymbol(macho_file).flags.needs_got = true; |
| 442 | }, | 450 | }, |
| ... | @@ -448,7 +456,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { | ... | @@ -448,7 +456,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { |
| 448 | const symbol = rel.getTargetSymbol(macho_file); | 456 | const symbol = rel.getTargetSymbol(macho_file); |
| 449 | if (!symbol.flags.tlv) { | 457 | if (!symbol.flags.tlv) { |
| 450 | try macho_file.reportParseError2( | 458 | try macho_file.reportParseError2( |
| 451 | object.index, | 459 | self.getFile(macho_file).getIndex(), |
| 452 | "{s}: illegal thread-local variable reference to regular symbol {s}", | 460 | "{s}: illegal thread-local variable reference to regular symbol {s}", |
| 453 | .{ self.getName(macho_file), symbol.getName(macho_file) }, | 461 | .{ self.getName(macho_file), symbol.getName(macho_file) }, |
| 454 | ); | 462 | ); |
| ... | @@ -470,27 +478,34 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { | ... | @@ -470,27 +478,34 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void { |
| 470 | continue; | 478 | continue; |
| 471 | } | 479 | } |
| 472 | if (symbol.flags.import) { | 480 | if (symbol.flags.import) { |
| 473 | object.num_bind_relocs += 1; | 481 | dynrel_ctx.bind_relocs += 1; |
| 474 | if (symbol.flags.weak) { | 482 | if (symbol.flags.weak) { |
| 475 | object.num_weak_bind_relocs += 1; | 483 | dynrel_ctx.weak_bind_relocs += 1; |
| 476 | macho_file.binds_to_weak = true; | 484 | macho_file.binds_to_weak = true; |
| 477 | } | 485 | } |
| 478 | continue; | 486 | continue; |
| 479 | } | 487 | } |
| 480 | if (symbol.flags.@"export") { | 488 | if (symbol.flags.@"export") { |
| 481 | if (symbol.flags.weak) { | 489 | if (symbol.flags.weak) { |
| 482 | object.num_weak_bind_relocs += 1; | 490 | dynrel_ctx.weak_bind_relocs += 1; |
| 483 | macho_file.binds_to_weak = true; | 491 | macho_file.binds_to_weak = true; |
| 484 | } else if (symbol.flags.interposable) { | 492 | } else if (symbol.flags.interposable) { |
| 485 | object.num_bind_relocs += 1; | 493 | dynrel_ctx.bind_relocs += 1; |
| 486 | } | 494 | } |
| 487 | } | 495 | } |
| 488 | } | 496 | } |
| 489 | object.num_rebase_relocs += 1; | 497 | dynrel_ctx.rebase_relocs += 1; |
| 490 | } | 498 | } |
| 491 | }, | 499 | }, |
| 492 | 500 | ||
| 493 | else => {}, | 501 | .signed, |
| 502 | .signed1, | ||
| 503 | .signed2, | ||
| 504 | .signed4, | ||
| 505 | .page, | ||
| 506 | .pageoff, | ||
| 507 | .subtractor, | ||
| 508 | => {}, | ||
| 494 | } | 509 | } |
| 495 | } | 510 | } |
| 496 | } | 511 | } |
src/link/MachO/Object.zig+1-3| ... | @@ -25,10 +25,8 @@ unwind_records: std.ArrayListUnmanaged(UnwindInfo.Record.Index) = .{}, | ... | @@ -25,10 +25,8 @@ unwind_records: std.ArrayListUnmanaged(UnwindInfo.Record.Index) = .{}, |
| 25 | 25 | ||
| 26 | alive: bool = true, | 26 | alive: bool = true, |
| 27 | hidden: bool = false, | 27 | hidden: bool = false, |
| 28 | num_rebase_relocs: u32 = 0, | ||
| 29 | num_bind_relocs: u32 = 0, | ||
| 30 | num_weak_bind_relocs: u32 = 0, | ||
| 31 | 28 | ||
| 29 | dynamic_relocs: MachO.DynamicRelocs = .{}, | ||
| 32 | output_symtab_ctx: MachO.SymtabCtx = .{}, | 30 | output_symtab_ctx: MachO.SymtabCtx = .{}, |
| 33 | 31 | ||
| 34 | pub fn isObject(path: []const u8) !bool { | 32 | pub fn isObject(path: []const u8) !bool { |
src/link/MachO/ZigObject.zig+28-5| ... | @@ -41,6 +41,7 @@ anon_decls: AnonDeclTable = .{}, | ... | @@ -41,6 +41,7 @@ anon_decls: AnonDeclTable = .{}, |
| 41 | /// A table of relocations. | 41 | /// A table of relocations. |
| 42 | relocs: RelocationTable = .{}, | 42 | relocs: RelocationTable = .{}, |
| 43 | 43 | ||
| 44 | dynamic_relocs: MachO.DynamicRelocs = .{}, | ||
| 44 | output_symtab_ctx: MachO.SymtabCtx = .{}, | 45 | output_symtab_ctx: MachO.SymtabCtx = .{}, |
| 45 | 46 | ||
| 46 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { | 47 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { |
| ... | @@ -222,10 +223,31 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void { | ... | @@ -222,10 +223,31 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void { |
| 222 | } | 223 | } |
| 223 | 224 | ||
| 224 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void { | 225 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void { |
| 225 | _ = self; | 226 | for (self.symbols.items, 0..) |index, nlist_idx| { |
| 226 | _ = dupes; | 227 | const sym = macho_file.getSymbol(index); |
| 227 | _ = macho_file; | 228 | if (sym.visibility != .global) continue; |
| 228 | @panic("TODO checkDuplicates"); | 229 | const file = sym.getFile(macho_file) orelse continue; |
| 230 | if (file.getIndex() == self.index) continue; | ||
| 231 | |||
| 232 | const nlist = self.symtab.items(.nlist)[nlist_idx]; | ||
| 233 | if (!nlist.undf() and !nlist.tentative() and !(nlist.weakDef() or nlist.pext())) { | ||
| 234 | const gop = try dupes.getOrPut(index); | ||
| 235 | if (!gop.found_existing) { | ||
| 236 | gop.value_ptr.* = .{}; | ||
| 237 | } | ||
| 238 | try gop.value_ptr.append(macho_file.base.comp.gpa, self.index); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { | ||
| 244 | for (self.atoms.items) |atom_index| { | ||
| 245 | const atom = macho_file.getAtom(atom_index) orelse continue; | ||
| 246 | if (!atom.flags.alive) continue; | ||
| 247 | const sect = atom.getInputSection(macho_file); | ||
| 248 | if (sect.isZerofill()) continue; | ||
| 249 | try atom.scanRelocs(macho_file); | ||
| 250 | } | ||
| 229 | } | 251 | } |
| 230 | 252 | ||
| 231 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void { | 253 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void { |
| ... | @@ -537,7 +559,8 @@ pub fn updateDecl( | ... | @@ -537,7 +559,8 @@ pub fn updateDecl( |
| 537 | const name = mod.intern_pool.stringToSlice(decl.name); | 559 | const name = mod.intern_pool.stringToSlice(decl.name); |
| 538 | const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); | 560 | const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); |
| 539 | const index = try self.getGlobalSymbol(macho_file, name, lib_name); | 561 | const index = try self.getGlobalSymbol(macho_file, name, lib_name); |
| 540 | macho_file.getSymbol(index).flags.needs_got = true; | 562 | const actual_index = self.symbols.items[index]; |
| 563 | macho_file.getSymbol(actual_index).flags.needs_got = true; | ||
| 541 | return; | 564 | return; |
| 542 | } | 565 | } |
| 543 | 566 |