| 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 | 156 | .Lib => emit.lower.link_mode == .Static, |
| 157 | 157 | }; |
| 158 | 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 | 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 | 164 | const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) |
| 164 | 165 | .zig_got_load |
src/codegen.zig+1-1| ... | ... | @@ -993,7 +993,7 @@ fn genDeclRef( |
| 993 | 993 | else |
| 994 | 994 | null; |
| 995 | 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 | 997 | return GenResult.mcv(.{ .load_symbol = sym_index }); |
| 998 | 998 | } |
| 999 | 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 | 542 | self.internal_object = index; |
| 543 | 543 | } |
| 544 | 544 | |
| 545 | state_log.debug("{}", .{self.dumpState()}); | |
| 546 | ||
| 547 | 545 | try self.addUndefinedGlobals(); |
| 548 | 546 | try self.resolveSymbols(); |
| 549 | 547 | try self.resolveSyntheticSymbols(); |
| ... | ... | @@ -2389,14 +2387,23 @@ fn initDyldInfoSections(self: *MachO) !void { |
| 2389 | 2387 | if (self.la_symbol_ptr_sect_index != null) try self.la_symbol_ptr.addDyldRelocs(self); |
| 2390 | 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 | 2395 | var nrebases: usize = 0; |
| 2393 | 2396 | var nbinds: usize = 0; |
| 2394 | 2397 | var nweak_binds: usize = 0; |
| 2395 | for (self.objects.items) |index| { | |
| 2396 | const object = self.getFile(index).?.object; | |
| 2397 | nrebases += object.num_rebase_relocs; | |
| 2398 | nbinds += object.num_bind_relocs; | |
| 2399 | nweak_binds += object.num_weak_bind_relocs; | |
| 2398 | for (objects.items) |index| { | |
| 2399 | const ctx = switch (self.getFile(index).?) { | |
| 2400 | .zig_object => |x| x.dynamic_relocs, | |
| 2401 | .object => |x| x.dynamic_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 | 2408 | try self.rebase.entries.ensureUnusedCapacity(gpa, nrebases); |
| 2402 | 2409 | try self.bind.entries.ensureUnusedCapacity(gpa, nbinds); |
| ... | ... | @@ -3947,6 +3954,12 @@ const HotUpdateState = struct { |
| 3947 | 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 | 3963 | pub const SymtabCtx = struct { |
| 3951 | 3964 | ilocal: u32 = 0, |
| 3952 | 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 | 402 | defer tracy.end(); |
| 403 | 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 | 410 | const relocs = self.getRelocs(macho_file); |
| 407 | 411 | |
| 408 | 412 | for (relocs) |rel| { |
| ... | ... | @@ -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 | 448 | .got => { |
| 441 | 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 | 456 | const symbol = rel.getTargetSymbol(macho_file); |
| 449 | 457 | if (!symbol.flags.tlv) { |
| 450 | 458 | try macho_file.reportParseError2( |
| 451 | object.index, | |
| 459 | self.getFile(macho_file).getIndex(), | |
| 452 | 460 | "{s}: illegal thread-local variable reference to regular symbol {s}", |
| 453 | 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 | 478 | continue; |
| 471 | 479 | } |
| 472 | 480 | if (symbol.flags.import) { |
| 473 | object.num_bind_relocs += 1; | |
| 481 | dynrel_ctx.bind_relocs += 1; | |
| 474 | 482 | if (symbol.flags.weak) { |
| 475 | object.num_weak_bind_relocs += 1; | |
| 483 | dynrel_ctx.weak_bind_relocs += 1; | |
| 476 | 484 | macho_file.binds_to_weak = true; |
| 477 | 485 | } |
| 478 | 486 | continue; |
| 479 | 487 | } |
| 480 | 488 | if (symbol.flags.@"export") { |
| 481 | 489 | if (symbol.flags.weak) { |
| 482 | object.num_weak_bind_relocs += 1; | |
| 490 | dynrel_ctx.weak_bind_relocs += 1; | |
| 483 | 491 | macho_file.binds_to_weak = true; |
| 484 | 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 | 25 | |
| 26 | 26 | alive: bool = true, |
| 27 | 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 | 30 | output_symtab_ctx: MachO.SymtabCtx = .{}, |
| 33 | 31 | |
| 34 | 32 | pub fn isObject(path: []const u8) !bool { |
src/link/MachO/ZigObject.zig+28-5| ... | ... | @@ -41,6 +41,7 @@ anon_decls: AnonDeclTable = .{}, |
| 41 | 41 | /// A table of relocations. |
| 42 | 42 | relocs: RelocationTable = .{}, |
| 43 | 43 | |
| 44 | dynamic_relocs: MachO.DynamicRelocs = .{}, | |
| 44 | 45 | output_symtab_ctx: MachO.SymtabCtx = .{}, |
| 45 | 46 | |
| 46 | 47 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { |
| ... | ... | @@ -222,10 +223,31 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void { |
| 222 | 223 | } |
| 223 | 224 | |
| 224 | 225 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void { |
| 225 | _ = self; | |
| 226 | _ = dupes; | |
| 227 | _ = macho_file; | |
| 228 | @panic("TODO checkDuplicates"); | |
| 226 | for (self.symbols.items, 0..) |index, nlist_idx| { | |
| 227 | const sym = macho_file.getSymbol(index); | |
| 228 | if (sym.visibility != .global) continue; | |
| 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 | 253 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void { |
| ... | ... | @@ -537,7 +559,8 @@ pub fn updateDecl( |
| 537 | 559 | const name = mod.intern_pool.stringToSlice(decl.name); |
| 538 | 560 | const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); |
| 539 | 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 | 564 | return; |
| 542 | 565 | } |
| 543 | 566 |