| author | |
| committer | |
| log | 7b282dffe68a7187a4fa4b5c11c82f1f67248a96 |
| tree | ae1592746bfa08e3882358d7108c296f95dee003 |
| parent | 702bcfecf5732eceada9bfbca0804c706c238d49 |
12 files changed, 88 insertions(+), 127 deletions(-)
src/arch/aarch64/Emit.zig+4-4| ... | @@ -670,7 +670,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -670,7 +670,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 670 | 670 | ||
| 671 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | 671 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 672 | // Add relocation to the decl. | 672 | // Add relocation to the decl. |
| 673 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; | 673 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index }).?; |
| 674 | const target = macho_file.getGlobalByIndex(relocation.sym_index); | 674 | const target = macho_file.getGlobalByIndex(relocation.sym_index); |
| 675 | try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ | 675 | try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ |
| 676 | .type = .branch, | 676 | .type = .branch, |
| ... | @@ -885,9 +885,9 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -885,9 +885,9 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 885 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | 885 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 886 | const Atom = link.File.MachO.Atom; | 886 | const Atom = link.File.MachO.Atom; |
| 887 | const Relocation = Atom.Relocation; | 887 | const Relocation = Atom.Relocation; |
| 888 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?; | 888 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index }).?; |
| 889 | try Atom.addRelocations(macho_file, atom_index, &[_]Relocation{ .{ | 889 | try Atom.addRelocations(macho_file, atom_index, &[_]Relocation{ .{ |
| 890 | .target = .{ .sym_index = data.sym_index, .file = null }, | 890 | .target = .{ .sym_index = data.sym_index }, |
| 891 | .offset = offset, | 891 | .offset = offset, |
| 892 | .addend = 0, | 892 | .addend = 0, |
| 893 | .pcrel = true, | 893 | .pcrel = true, |
| ... | @@ -898,7 +898,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -898,7 +898,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 898 | else => unreachable, | 898 | else => unreachable, |
| 899 | }, | 899 | }, |
| 900 | }, .{ | 900 | }, .{ |
| 901 | .target = .{ .sym_index = data.sym_index, .file = null }, | 901 | .target = .{ .sym_index = data.sym_index }, |
| 902 | .offset = offset + 4, | 902 | .offset = offset + 4, |
| 903 | .addend = 0, | 903 | .addend = 0, |
| 904 | .pcrel = false, | 904 | .pcrel = false, |
src/arch/x86_64/Emit.zig+3-8| ... | @@ -43,9 +43,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -43,9 +43,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 43 | }), | 43 | }), |
| 44 | .linker_extern_fn => |symbol| if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | 44 | .linker_extern_fn => |symbol| if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 45 | // Add relocation to the decl. | 45 | // Add relocation to the decl. |
| 46 | const atom_index = macho_file.getAtomIndexForSymbol( | 46 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?; |
| 47 | .{ .sym_index = symbol.atom_index, .file = null }, | ||
| 48 | ).?; | ||
| 49 | const target = macho_file.getGlobalByIndex(symbol.sym_index); | 47 | const target = macho_file.getGlobalByIndex(symbol.sym_index); |
| 50 | try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ | 48 | try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ |
| 51 | .type = .branch, | 49 | .type = .branch, |
| ... | @@ -77,10 +75,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -77,10 +75,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 77 | .linker_import, | 75 | .linker_import, |
| 78 | .linker_tlv, | 76 | .linker_tlv, |
| 79 | => |symbol| if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | 77 | => |symbol| if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 80 | const atom_index = macho_file.getAtomIndexForSymbol(.{ | 78 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?; |
| 81 | .sym_index = symbol.atom_index, | ||
| 82 | .file = null, | ||
| 83 | }).?; | ||
| 84 | try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ | 79 | try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ |
| 85 | .type = switch (lowered_relocs[0].target) { | 80 | .type = switch (lowered_relocs[0].target) { |
| 86 | .linker_got => .got, | 81 | .linker_got => .got, |
| ... | @@ -88,7 +83,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -88,7 +83,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 88 | .linker_tlv => .tlv, | 83 | .linker_tlv => .tlv, |
| 89 | else => unreachable, | 84 | else => unreachable, |
| 90 | }, | 85 | }, |
| 91 | .target = .{ .sym_index = symbol.sym_index, .file = null }, | 86 | .target = .{ .sym_index = symbol.sym_index }, |
| 92 | .offset = @as(u32, @intCast(end_offset - 4)), | 87 | .offset = @as(u32, @intCast(end_offset - 4)), |
| 93 | .addend = 0, | 88 | .addend = 0, |
| 94 | .pcrel = true, | 89 | .pcrel = true, |
src/link/MachO.zig+48-43| ... | @@ -249,20 +249,14 @@ const DeclMetadata = struct { | ... | @@ -249,20 +249,14 @@ const DeclMetadata = struct { |
| 249 | 249 | ||
| 250 | fn getExport(m: DeclMetadata, macho_file: *const MachO, name: []const u8) ?u32 { | 250 | fn getExport(m: DeclMetadata, macho_file: *const MachO, name: []const u8) ?u32 { |
| 251 | for (m.exports.items) |exp| { | 251 | for (m.exports.items) |exp| { |
| 252 | if (mem.eql(u8, name, macho_file.getSymbolName(.{ | 252 | if (mem.eql(u8, name, macho_file.getSymbolName(.{ .sym_index = exp }))) return exp; |
| 253 | .sym_index = exp, | ||
| 254 | .file = null, | ||
| 255 | }))) return exp; | ||
| 256 | } | 253 | } |
| 257 | return null; | 254 | return null; |
| 258 | } | 255 | } |
| 259 | 256 | ||
| 260 | fn getExportPtr(m: *DeclMetadata, macho_file: *MachO, name: []const u8) ?*u32 { | 257 | fn getExportPtr(m: *DeclMetadata, macho_file: *MachO, name: []const u8) ?*u32 { |
| 261 | for (m.exports.items) |*exp| { | 258 | for (m.exports.items) |*exp| { |
| 262 | if (mem.eql(u8, name, macho_file.getSymbolName(.{ | 259 | if (mem.eql(u8, name, macho_file.getSymbolName(.{ .sym_index = exp.* }))) return exp; |
| 263 | .sym_index = exp.*, | ||
| 264 | .file = null, | ||
| 265 | }))) return exp; | ||
| 266 | } | 260 | } |
| 267 | return null; | 261 | return null; |
| 268 | } | 262 | } |
| ... | @@ -284,21 +278,20 @@ const ResolveAction = struct { | ... | @@ -284,21 +278,20 @@ const ResolveAction = struct { |
| 284 | }; | 278 | }; |
| 285 | }; | 279 | }; |
| 286 | 280 | ||
| 287 | pub const SymbolWithLoc = struct { | 281 | pub const SymbolWithLoc = extern struct { |
| 288 | // Index into the respective symbol table. | 282 | // Index into the respective symbol table. |
| 289 | sym_index: u32, | 283 | sym_index: u32, |
| 290 | 284 | ||
| 291 | // null means it's a synthetic global. | 285 | // 0 means it's a synthetic global. |
| 292 | file: ?u32 = null, | 286 | file: u32 = 0, |
| 293 | 287 | ||
| 294 | pub fn eql(this: SymbolWithLoc, other: SymbolWithLoc) bool { | 288 | pub fn getFile(self: SymbolWithLoc) ?u32 { |
| 295 | if (this.file == null and other.file == null) { | 289 | if (self.file == 0) return null; |
| 296 | return this.sym_index == other.sym_index; | 290 | return self.file - 1; |
| 297 | } | 291 | } |
| 298 | if (this.file != null and other.file != null) { | 292 | |
| 299 | return this.sym_index == other.sym_index and this.file.? == other.file.?; | 293 | pub fn eql(self: SymbolWithLoc, other: SymbolWithLoc) bool { |
| 300 | } | 294 | return self.file == other.file and self.sym_index == other.sym_index; |
| 301 | return false; | ||
| 302 | } | 295 | } |
| 303 | }; | 296 | }; |
| 304 | 297 | ||
| ... | @@ -1576,7 +1569,7 @@ pub fn allocateSpecialSymbols(self: *MachO) !void { | ... | @@ -1576,7 +1569,7 @@ pub fn allocateSpecialSymbols(self: *MachO) !void { |
| 1576 | "__mh_execute_header", | 1569 | "__mh_execute_header", |
| 1577 | }) |name| { | 1570 | }) |name| { |
| 1578 | const global = self.getGlobal(name) orelse continue; | 1571 | const global = self.getGlobal(name) orelse continue; |
| 1579 | if (global.file != null) continue; | 1572 | if (global.getFile() != null) continue; |
| 1580 | const sym = self.getSymbolPtr(global); | 1573 | const sym = self.getSymbolPtr(global); |
| 1581 | const seg = self.getSegment(self.text_section_index.?); | 1574 | const seg = self.getSegment(self.text_section_index.?); |
| 1582 | sym.n_sect = 1; | 1575 | sym.n_sect = 1; |
| ... | @@ -1597,7 +1590,7 @@ pub fn createAtom(self: *MachO) !Atom.Index { | ... | @@ -1597,7 +1590,7 @@ pub fn createAtom(self: *MachO) !Atom.Index { |
| 1597 | try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index); | 1590 | try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index); |
| 1598 | atom.* = .{ | 1591 | atom.* = .{ |
| 1599 | .sym_index = sym_index, | 1592 | .sym_index = sym_index, |
| 1600 | .file = null, | 1593 | .file = 0, |
| 1601 | .size = 0, | 1594 | .size = 0, |
| 1602 | .prev_index = null, | 1595 | .prev_index = null, |
| 1603 | .next_index = null, | 1596 | .next_index = null, |
| ... | @@ -1664,7 +1657,7 @@ fn createMhExecuteHeaderSymbol(self: *MachO) !void { | ... | @@ -1664,7 +1657,7 @@ fn createMhExecuteHeaderSymbol(self: *MachO) !void { |
| 1664 | 1657 | ||
| 1665 | const gpa = self.base.allocator; | 1658 | const gpa = self.base.allocator; |
| 1666 | const sym_index = try self.allocateSymbol(); | 1659 | const sym_index = try self.allocateSymbol(); |
| 1667 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1660 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 1668 | const sym = self.getSymbolPtr(sym_loc); | 1661 | const sym = self.getSymbolPtr(sym_loc); |
| 1669 | sym.* = .{ | 1662 | sym.* = .{ |
| 1670 | .n_strx = try self.strtab.insert(gpa, "__mh_execute_header"), | 1663 | .n_strx = try self.strtab.insert(gpa, "__mh_execute_header"), |
| ... | @@ -1684,7 +1677,7 @@ fn createDsoHandleSymbol(self: *MachO) !void { | ... | @@ -1684,7 +1677,7 @@ fn createDsoHandleSymbol(self: *MachO) !void { |
| 1684 | 1677 | ||
| 1685 | const gpa = self.base.allocator; | 1678 | const gpa = self.base.allocator; |
| 1686 | const sym_index = try self.allocateSymbol(); | 1679 | const sym_index = try self.allocateSymbol(); |
| 1687 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1680 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 1688 | const sym = self.getSymbolPtr(sym_loc); | 1681 | const sym = self.getSymbolPtr(sym_loc); |
| 1689 | sym.* = .{ | 1682 | sym.* = .{ |
| 1690 | .n_strx = try self.strtab.insert(gpa, "___dso_handle"), | 1683 | .n_strx = try self.strtab.insert(gpa, "___dso_handle"), |
| ... | @@ -1998,10 +1991,7 @@ fn allocateGlobal(self: *MachO) !u32 { | ... | @@ -1998,10 +1991,7 @@ fn allocateGlobal(self: *MachO) !u32 { |
| 1998 | } | 1991 | } |
| 1999 | }; | 1992 | }; |
| 2000 | 1993 | ||
| 2001 | self.globals.items[index] = .{ | 1994 | self.globals.items[index] = .{ .sym_index = 0 }; |
| 2002 | .sym_index = 0, | ||
| 2003 | .file = null, | ||
| 2004 | }; | ||
| 2005 | 1995 | ||
| 2006 | return index; | 1996 | return index; |
| 2007 | } | 1997 | } |
| ... | @@ -2613,7 +2603,7 @@ pub fn updateDeclExports( | ... | @@ -2613,7 +2603,7 @@ pub fn updateDeclExports( |
| 2613 | try decl_metadata.exports.append(gpa, sym_index); | 2603 | try decl_metadata.exports.append(gpa, sym_index); |
| 2614 | break :blk sym_index; | 2604 | break :blk sym_index; |
| 2615 | }; | 2605 | }; |
| 2616 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 2606 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 2617 | const sym = self.getSymbolPtr(sym_loc); | 2607 | const sym = self.getSymbolPtr(sym_loc); |
| 2618 | sym.* = .{ | 2608 | sym.* = .{ |
| 2619 | .n_strx = try self.strtab.insert(gpa, exp_name), | 2609 | .n_strx = try self.strtab.insert(gpa, exp_name), |
| ... | @@ -2643,7 +2633,7 @@ pub fn updateDeclExports( | ... | @@ -2643,7 +2633,7 @@ pub fn updateDeclExports( |
| 2643 | error.MultipleSymbolDefinitions => { | 2633 | error.MultipleSymbolDefinitions => { |
| 2644 | // TODO: this needs rethinking | 2634 | // TODO: this needs rethinking |
| 2645 | const global = self.getGlobal(exp_name).?; | 2635 | const global = self.getGlobal(exp_name).?; |
| 2646 | if (sym_loc.sym_index != global.sym_index and global.file != null) { | 2636 | if (sym_loc.sym_index != global.sym_index and global.getFile() != null) { |
| 2647 | _ = try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create( | 2637 | _ = try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create( |
| 2648 | gpa, | 2638 | gpa, |
| 2649 | decl.srcLoc(mod), | 2639 | decl.srcLoc(mod), |
| ... | @@ -2672,7 +2662,7 @@ pub fn deleteDeclExport( | ... | @@ -2672,7 +2662,7 @@ pub fn deleteDeclExport( |
| 2672 | defer gpa.free(exp_name); | 2662 | defer gpa.free(exp_name); |
| 2673 | const sym_index = metadata.getExportPtr(self, exp_name) orelse return; | 2663 | const sym_index = metadata.getExportPtr(self, exp_name) orelse return; |
| 2674 | 2664 | ||
| 2675 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null }; | 2665 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index.* }; |
| 2676 | const sym = self.getSymbolPtr(sym_loc); | 2666 | const sym = self.getSymbolPtr(sym_loc); |
| 2677 | log.debug("deleting export '{s}'", .{exp_name}); | 2667 | log.debug("deleting export '{s}'", .{exp_name}); |
| 2678 | assert(sym.sect() and sym.ext()); | 2668 | assert(sym.sect() and sym.ext()); |
| ... | @@ -2688,10 +2678,7 @@ pub fn deleteDeclExport( | ... | @@ -2688,10 +2678,7 @@ pub fn deleteDeclExport( |
| 2688 | if (self.resolver.fetchRemove(exp_name)) |entry| { | 2678 | if (self.resolver.fetchRemove(exp_name)) |entry| { |
| 2689 | defer gpa.free(entry.key); | 2679 | defer gpa.free(entry.key); |
| 2690 | self.globals_free_list.append(gpa, entry.value) catch {}; | 2680 | self.globals_free_list.append(gpa, entry.value) catch {}; |
| 2691 | self.globals.items[entry.value] = .{ | 2681 | self.globals.items[entry.value] = .{ .sym_index = 0 }; |
| 2692 | .sym_index = 0, | ||
| 2693 | .file = null, | ||
| 2694 | }; | ||
| 2695 | } | 2682 | } |
| 2696 | 2683 | ||
| 2697 | sym_index.* = 0; | 2684 | sym_index.* = 0; |
| ... | @@ -2730,10 +2717,10 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil | ... | @@ -2730,10 +2717,10 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil |
| 2730 | 2717 | ||
| 2731 | const this_atom_index = try self.getOrCreateAtomForDecl(decl_index); | 2718 | const this_atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 2732 | const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; | 2719 | const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; |
| 2733 | const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; | 2720 | const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index }).?; |
| 2734 | try Atom.addRelocation(self, atom_index, .{ | 2721 | try Atom.addRelocation(self, atom_index, .{ |
| 2735 | .type = .unsigned, | 2722 | .type = .unsigned, |
| 2736 | .target = .{ .sym_index = sym_index, .file = null }, | 2723 | .target = .{ .sym_index = sym_index }, |
| 2737 | .offset = @as(u32, @intCast(reloc_info.offset)), | 2724 | .offset = @as(u32, @intCast(reloc_info.offset)), |
| 2738 | .addend = reloc_info.addend, | 2725 | .addend = reloc_info.addend, |
| 2739 | .pcrel = false, | 2726 | .pcrel = false, |
| ... | @@ -3514,7 +3501,7 @@ fn writeSymtab(self: *MachO) !SymtabCtx { | ... | @@ -3514,7 +3501,7 @@ fn writeSymtab(self: *MachO) !SymtabCtx { |
| 3514 | 3501 | ||
| 3515 | for (self.locals.items, 0..) |sym, sym_id| { | 3502 | for (self.locals.items, 0..) |sym, sym_id| { |
| 3516 | if (sym.n_strx == 0) continue; // no name, skip | 3503 | if (sym.n_strx == 0) continue; // no name, skip |
| 3517 | const sym_loc = SymbolWithLoc{ .sym_index = @as(u32, @intCast(sym_id)), .file = null }; | 3504 | const sym_loc = SymbolWithLoc{ .sym_index = @as(u32, @intCast(sym_id)) }; |
| 3518 | if (self.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip | 3505 | if (self.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip |
| 3519 | if (self.getGlobal(self.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip | 3506 | if (self.getGlobal(self.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip |
| 3520 | try locals.append(sym); | 3507 | try locals.append(sym); |
| ... | @@ -3934,13 +3921,13 @@ pub fn symbolIsTemp(self: *MachO, sym_with_loc: SymbolWithLoc) bool { | ... | @@ -3934,13 +3921,13 @@ pub fn symbolIsTemp(self: *MachO, sym_with_loc: SymbolWithLoc) bool { |
| 3934 | 3921 | ||
| 3935 | /// Returns pointer-to-symbol described by `sym_with_loc` descriptor. | 3922 | /// Returns pointer-to-symbol described by `sym_with_loc` descriptor. |
| 3936 | pub fn getSymbolPtr(self: *MachO, sym_with_loc: SymbolWithLoc) *macho.nlist_64 { | 3923 | pub fn getSymbolPtr(self: *MachO, sym_with_loc: SymbolWithLoc) *macho.nlist_64 { |
| 3937 | assert(sym_with_loc.file == null); | 3924 | assert(sym_with_loc.getFile() == null); |
| 3938 | return &self.locals.items[sym_with_loc.sym_index]; | 3925 | return &self.locals.items[sym_with_loc.sym_index]; |
| 3939 | } | 3926 | } |
| 3940 | 3927 | ||
| 3941 | /// Returns symbol described by `sym_with_loc` descriptor. | 3928 | /// Returns symbol described by `sym_with_loc` descriptor. |
| 3942 | pub fn getSymbol(self: *const MachO, sym_with_loc: SymbolWithLoc) macho.nlist_64 { | 3929 | pub fn getSymbol(self: *const MachO, sym_with_loc: SymbolWithLoc) macho.nlist_64 { |
| 3943 | assert(sym_with_loc.file == null); | 3930 | assert(sym_with_loc.getFile() == null); |
| 3944 | return self.locals.items[sym_with_loc.sym_index]; | 3931 | return self.locals.items[sym_with_loc.sym_index]; |
| 3945 | } | 3932 | } |
| 3946 | 3933 | ||
| ... | @@ -4006,7 +3993,7 @@ pub fn getAtomPtr(self: *MachO, atom_index: Atom.Index) *Atom { | ... | @@ -4006,7 +3993,7 @@ pub fn getAtomPtr(self: *MachO, atom_index: Atom.Index) *Atom { |
| 4006 | /// Returns atom if there is an atom referenced by the symbol described by `sym_with_loc` descriptor. | 3993 | /// Returns atom if there is an atom referenced by the symbol described by `sym_with_loc` descriptor. |
| 4007 | /// Returns null on failure. | 3994 | /// Returns null on failure. |
| 4008 | pub fn getAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index { | 3995 | pub fn getAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index { |
| 4009 | assert(sym_with_loc.file == null); | 3996 | assert(sym_with_loc.getFile() == null); |
| 4010 | return self.atom_by_index_table.get(sym_with_loc.sym_index); | 3997 | return self.atom_by_index_table.get(sym_with_loc.sym_index); |
| 4011 | } | 3998 | } |
| 4012 | 3999 | ||
| ... | @@ -4034,13 +4021,31 @@ pub inline fn getPageSize(cpu_arch: std.Target.Cpu.Arch) u16 { | ... | @@ -4034,13 +4021,31 @@ pub inline fn getPageSize(cpu_arch: std.Target.Cpu.Arch) u16 { |
| 4034 | }; | 4021 | }; |
| 4035 | } | 4022 | } |
| 4036 | 4023 | ||
| 4037 | pub fn findFirst(comptime T: type, haystack: []align(1) const T, start: usize, predicate: anytype) usize { | 4024 | /// Binary search |
| 4025 | pub fn bsearch(comptime T: type, haystack: []align(1) const T, predicate: anytype) usize { | ||
| 4038 | if (!@hasDecl(@TypeOf(predicate), "predicate")) | 4026 | if (!@hasDecl(@TypeOf(predicate), "predicate")) |
| 4039 | @compileError("Predicate is required to define fn predicate(@This(), T) bool"); | 4027 | @compileError("Predicate is required to define fn predicate(@This(), T) bool"); |
| 4040 | 4028 | ||
| 4041 | if (start == haystack.len) return start; | 4029 | var min: usize = 0; |
| 4030 | var max: usize = haystack.len; | ||
| 4031 | while (min < max) { | ||
| 4032 | const index = (min + max) / 2; | ||
| 4033 | const curr = haystack[index]; | ||
| 4034 | if (predicate.predicate(curr)) { | ||
| 4035 | min = index + 1; | ||
| 4036 | } else { | ||
| 4037 | max = index; | ||
| 4038 | } | ||
| 4039 | } | ||
| 4040 | return min; | ||
| 4041 | } | ||
| 4042 | |||
| 4043 | /// Linear search | ||
| 4044 | pub fn lsearch(comptime T: type, haystack: []align(1) const T, predicate: anytype) usize { | ||
| 4045 | if (!@hasDecl(@TypeOf(predicate), "predicate")) | ||
| 4046 | @compileError("Predicate is required to define fn predicate(@This(), T) bool"); | ||
| 4042 | 4047 | ||
| 4043 | var i = start; | 4048 | var i: usize = 0; |
| 4044 | while (i < haystack.len) : (i += 1) { | 4049 | while (i < haystack.len) : (i += 1) { |
| 4045 | if (predicate.predicate(haystack[i])) break; | 4050 | if (predicate.predicate(haystack[i])) break; |
| 4046 | } | 4051 | } |
src/link/MachO/Atom.zig+9-6| ... | @@ -17,16 +17,19 @@ const MachO = @import("../MachO.zig"); | ... | @@ -17,16 +17,19 @@ const MachO = @import("../MachO.zig"); |
| 17 | pub const Relocation = @import("Relocation.zig"); | 17 | pub const Relocation = @import("Relocation.zig"); |
| 18 | const SymbolWithLoc = MachO.SymbolWithLoc; | 18 | const SymbolWithLoc = MachO.SymbolWithLoc; |
| 19 | 19 | ||
| 20 | /// Each decl always gets a local symbol with the fully qualified name. | 20 | /// Each Atom always gets a symbol with the fully qualified name. |
| 21 | /// The vaddr and size are found here directly. | 21 | /// The symbol can reside in any object file context structure in `symtab` array |
| 22 | /// The file offset is found by computing the vaddr offset from the section vaddr | 22 | /// (see `Object`), or if the symbol is a synthetic symbol such as a GOT cell or |
| 23 | /// the symbol references, and adding that to the file offset of the section. | 23 | /// a stub trampoline, it can be found in the linkers `locals` arraylist. |
| 24 | /// If this field is 0, it means the codegen size = 0 and there is no symbol or | 24 | /// If this field is 0, it means the codegen size = 0 and there is no symbol or |
| 25 | /// offset table entry. | 25 | /// offset table entry. |
| 26 | sym_index: u32, | 26 | sym_index: u32, |
| 27 | 27 | ||
| 28 | /// null means symbol defined by Zig source. | 28 | /// 0 means an Atom is a synthetic Atom such as a GOT cell defined by the linker. |
| 29 | file: ?u32, | 29 | /// Otherwise, it is the index into appropriate object file (indexing from 1). |
| 30 | /// Prefer using `getFile()` helper to get the file index out rather than using | ||
| 31 | /// the field directly. | ||
| 32 | file: u32, | ||
| 30 | 33 | ||
| 31 | /// Size and alignment of this atom | 34 | /// Size and alignment of this atom |
| 32 | /// Unlike in Elf, we need to store the size of this symbol as part of | 35 | /// Unlike in Elf, we need to store the size of this symbol as part of |
src/link/MachO/DebugSymbols.zig+1-1| ... | @@ -475,7 +475,7 @@ fn writeSymtab(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -475,7 +475,7 @@ fn writeSymtab(self: *DebugSymbols, macho_file: *MachO) !void { |
| 475 | 475 | ||
| 476 | for (macho_file.locals.items, 0..) |sym, sym_id| { | 476 | for (macho_file.locals.items, 0..) |sym, sym_id| { |
| 477 | if (sym.n_strx == 0) continue; // no name, skip | 477 | if (sym.n_strx == 0) continue; // no name, skip |
| 478 | const sym_loc = MachO.SymbolWithLoc{ .sym_index = @as(u32, @intCast(sym_id)), .file = null }; | 478 | const sym_loc = MachO.SymbolWithLoc{ .sym_index = @as(u32, @intCast(sym_id)) }; |
| 479 | if (macho_file.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip | 479 | if (macho_file.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip |
| 480 | if (macho_file.getGlobal(macho_file.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip | 480 | if (macho_file.getGlobal(macho_file.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip |
| 481 | var out_sym = sym; | 481 | var out_sym = sym; |
src/link/MachO/Object.zig+11-10| ... | @@ -23,9 +23,10 @@ const Atom = @import("ZldAtom.zig"); | ... | @@ -23,9 +23,10 @@ const Atom = @import("ZldAtom.zig"); |
| 23 | const AtomIndex = @import("zld.zig").AtomIndex; | 23 | const AtomIndex = @import("zld.zig").AtomIndex; |
| 24 | const DwarfInfo = @import("DwarfInfo.zig"); | 24 | const DwarfInfo = @import("DwarfInfo.zig"); |
| 25 | const LoadCommandIterator = macho.LoadCommandIterator; | 25 | const LoadCommandIterator = macho.LoadCommandIterator; |
| 26 | const Zld = @import("zld.zig").Zld; | 26 | const MachO = @import("../MachO.zig"); |
| 27 | const SymbolWithLoc = @import("zld.zig").SymbolWithLoc; | 27 | const SymbolWithLoc = MachO.SymbolWithLoc; |
| 28 | const UnwindInfo = @import("UnwindInfo.zig"); | 28 | const UnwindInfo = @import("UnwindInfo.zig"); |
| 29 | const Zld = @import("zld.zig").Zld; | ||
| 29 | 30 | ||
| 30 | name: []const u8, | 31 | name: []const u8, |
| 31 | mtime: u64, | 32 | mtime: u64, |
| ... | @@ -314,10 +315,10 @@ fn filterSymbolsBySection(symbols: []macho.nlist_64, n_sect: u8) struct { | ... | @@ -314,10 +315,10 @@ fn filterSymbolsBySection(symbols: []macho.nlist_64, n_sect: u8) struct { |
| 314 | } | 315 | } |
| 315 | }; | 316 | }; |
| 316 | 317 | ||
| 317 | const index = @import("zld.zig").lsearch(macho.nlist_64, symbols, FirstMatch{ | 318 | const index = MachO.lsearch(macho.nlist_64, symbols, FirstMatch{ |
| 318 | .n_sect = n_sect, | 319 | .n_sect = n_sect, |
| 319 | }); | 320 | }); |
| 320 | const len = @import("zld.zig").lsearch(macho.nlist_64, symbols[index..], FirstNonMatch{ | 321 | const len = MachO.lsearch(macho.nlist_64, symbols[index..], FirstNonMatch{ |
| 321 | .n_sect = n_sect, | 322 | .n_sect = n_sect, |
| 322 | }); | 323 | }); |
| 323 | 324 | ||
| ... | @@ -336,10 +337,10 @@ fn filterSymbolsByAddress(symbols: []macho.nlist_64, start_addr: u64, end_addr: | ... | @@ -336,10 +337,10 @@ fn filterSymbolsByAddress(symbols: []macho.nlist_64, start_addr: u64, end_addr: |
| 336 | } | 337 | } |
| 337 | }; | 338 | }; |
| 338 | 339 | ||
| 339 | const index = @import("zld.zig").lsearch(macho.nlist_64, symbols, Predicate{ | 340 | const index = MachO.lsearch(macho.nlist_64, symbols, Predicate{ |
| 340 | .addr = start_addr, | 341 | .addr = start_addr, |
| 341 | }); | 342 | }); |
| 342 | const len = @import("zld.zig").lsearch(macho.nlist_64, symbols[index..], Predicate{ | 343 | const len = MachO.lsearch(macho.nlist_64, symbols[index..], Predicate{ |
| 343 | .addr = end_addr, | 344 | .addr = end_addr, |
| 344 | }); | 345 | }); |
| 345 | 346 | ||
| ... | @@ -631,8 +632,8 @@ fn filterRelocs( | ... | @@ -631,8 +632,8 @@ fn filterRelocs( |
| 631 | } | 632 | } |
| 632 | }; | 633 | }; |
| 633 | 634 | ||
| 634 | const start = @import("zld.zig").bsearch(macho.relocation_info, relocs, Predicate{ .addr = end_addr }); | 635 | const start = MachO.bsearch(macho.relocation_info, relocs, Predicate{ .addr = end_addr }); |
| 635 | const len = @import("zld.zig").lsearch(macho.relocation_info, relocs[start..], LPredicate{ .addr = start_addr }); | 636 | const len = MachO.lsearch(macho.relocation_info, relocs[start..], LPredicate{ .addr = start_addr }); |
| 636 | 637 | ||
| 637 | return .{ .start = @as(u32, @intCast(start)), .len = @as(u32, @intCast(len)) }; | 638 | return .{ .start = @as(u32, @intCast(start)), .len = @as(u32, @intCast(len)) }; |
| 638 | } | 639 | } |
| ... | @@ -1031,7 +1032,7 @@ pub fn getSymbolByAddress(self: Object, addr: u64, sect_hint: ?u8) u32 { | ... | @@ -1031,7 +1032,7 @@ pub fn getSymbolByAddress(self: Object, addr: u64, sect_hint: ?u8) u32 { |
| 1031 | if (sect_hint) |sect_id| { | 1032 | if (sect_hint) |sect_id| { |
| 1032 | if (self.source_section_index_lookup[sect_id].len > 0) { | 1033 | if (self.source_section_index_lookup[sect_id].len > 0) { |
| 1033 | const lookup = self.source_section_index_lookup[sect_id]; | 1034 | const lookup = self.source_section_index_lookup[sect_id]; |
| 1034 | const target_sym_index = @import("zld.zig").lsearch( | 1035 | const target_sym_index = MachO.lsearch( |
| 1035 | i64, | 1036 | i64, |
| 1036 | self.source_address_lookup[lookup.start..][0..lookup.len], | 1037 | self.source_address_lookup[lookup.start..][0..lookup.len], |
| 1037 | Predicate{ .addr = @as(i64, @intCast(addr)) }, | 1038 | Predicate{ .addr = @as(i64, @intCast(addr)) }, |
| ... | @@ -1046,7 +1047,7 @@ pub fn getSymbolByAddress(self: Object, addr: u64, sect_hint: ?u8) u32 { | ... | @@ -1046,7 +1047,7 @@ pub fn getSymbolByAddress(self: Object, addr: u64, sect_hint: ?u8) u32 { |
| 1046 | return self.getSectionAliasSymbolIndex(sect_id); | 1047 | return self.getSectionAliasSymbolIndex(sect_id); |
| 1047 | } | 1048 | } |
| 1048 | 1049 | ||
| 1049 | const target_sym_index = @import("zld.zig").lsearch(i64, self.source_address_lookup, Predicate{ | 1050 | const target_sym_index = MachO.lsearch(i64, self.source_address_lookup, Predicate{ |
| 1050 | .addr = @as(i64, @intCast(addr)), | 1051 | .addr = @as(i64, @intCast(addr)), |
| 1051 | }); | 1052 | }); |
| 1052 | assert(target_sym_index > 0); | 1053 | assert(target_sym_index > 0); |
src/link/MachO/UnwindInfo.zig+2-1| ... | @@ -15,8 +15,9 @@ const Allocator = mem.Allocator; | ... | @@ -15,8 +15,9 @@ const Allocator = mem.Allocator; |
| 15 | const Atom = @import("ZldAtom.zig"); | 15 | const Atom = @import("ZldAtom.zig"); |
| 16 | const AtomIndex = @import("zld.zig").AtomIndex; | 16 | const AtomIndex = @import("zld.zig").AtomIndex; |
| 17 | const EhFrameRecord = eh_frame.EhFrameRecord; | 17 | const EhFrameRecord = eh_frame.EhFrameRecord; |
| 18 | const MachO = @import("../MachO.zig"); | ||
| 18 | const Object = @import("Object.zig"); | 19 | const Object = @import("Object.zig"); |
| 19 | const SymbolWithLoc = @import("zld.zig").SymbolWithLoc; | 20 | const SymbolWithLoc = MachO.SymbolWithLoc; |
| 20 | const Zld = @import("zld.zig").Zld; | 21 | const Zld = @import("zld.zig").Zld; |
| 21 | 22 | ||
| 22 | const N_DEAD = @import("zld.zig").N_DEAD; | 23 | const N_DEAD = @import("zld.zig").N_DEAD; |
src/link/MachO/ZldAtom.zig+1-1| ... | @@ -22,7 +22,7 @@ const Arch = std.Target.Cpu.Arch; | ... | @@ -22,7 +22,7 @@ const Arch = std.Target.Cpu.Arch; |
| 22 | const AtomIndex = @import("zld.zig").AtomIndex; | 22 | const AtomIndex = @import("zld.zig").AtomIndex; |
| 23 | const Object = @import("Object.zig"); | 23 | const Object = @import("Object.zig"); |
| 24 | const Relocation = @import("Relocation.zig"); | 24 | const Relocation = @import("Relocation.zig"); |
| 25 | const SymbolWithLoc = @import("zld.zig").SymbolWithLoc; | 25 | const SymbolWithLoc = @import("../MachO.zig").SymbolWithLoc; |
| 26 | const Zld = @import("zld.zig").Zld; | 26 | const Zld = @import("zld.zig").Zld; |
| 27 | 27 | ||
| 28 | /// Each Atom always gets a symbol with the fully qualified name. | 28 | /// Each Atom always gets a symbol with the fully qualified name. |
src/link/MachO/dead_strip.zig+2-1| ... | @@ -11,7 +11,8 @@ const mem = std.mem; | ... | @@ -11,7 +11,8 @@ const mem = std.mem; |
| 11 | const Allocator = mem.Allocator; | 11 | const Allocator = mem.Allocator; |
| 12 | const AtomIndex = @import("zld.zig").AtomIndex; | 12 | const AtomIndex = @import("zld.zig").AtomIndex; |
| 13 | const Atom = @import("ZldAtom.zig"); | 13 | const Atom = @import("ZldAtom.zig"); |
| 14 | const SymbolWithLoc = @import("zld.zig").SymbolWithLoc; | 14 | const MachO = @import("../MachO.zig"); |
| 15 | const SymbolWithLoc = MachO.SymbolWithLoc; | ||
| 15 | const SymbolResolver = @import("zld.zig").SymbolResolver; | 16 | const SymbolResolver = @import("zld.zig").SymbolResolver; |
| 16 | const UnwindInfo = @import("UnwindInfo.zig"); | 17 | const UnwindInfo = @import("UnwindInfo.zig"); |
| 17 | const Zld = @import("zld.zig").Zld; | 18 | const Zld = @import("zld.zig").Zld; |
src/link/MachO/eh_frame.zig+2-1| ... | @@ -9,8 +9,9 @@ const log = std.log.scoped(.eh_frame); | ... | @@ -9,8 +9,9 @@ const log = std.log.scoped(.eh_frame); |
| 9 | const Allocator = mem.Allocator; | 9 | const Allocator = mem.Allocator; |
| 10 | const AtomIndex = @import("zld.zig").AtomIndex; | 10 | const AtomIndex = @import("zld.zig").AtomIndex; |
| 11 | const Atom = @import("ZldAtom.zig"); | 11 | const Atom = @import("ZldAtom.zig"); |
| 12 | const MachO = @import("../MachO.zig"); | ||
| 12 | const Relocation = @import("Relocation.zig"); | 13 | const Relocation = @import("Relocation.zig"); |
| 13 | const SymbolWithLoc = @import("zld.zig").SymbolWithLoc; | 14 | const SymbolWithLoc = MachO.SymbolWithLoc; |
| 14 | const UnwindInfo = @import("UnwindInfo.zig"); | 15 | const UnwindInfo = @import("UnwindInfo.zig"); |
| 15 | const Zld = @import("zld.zig").Zld; | 16 | const Zld = @import("zld.zig").Zld; |
| 16 | 17 |
src/link/MachO/thunks.zig+2-1| ... | @@ -17,8 +17,9 @@ const aarch64 = @import("../../arch/aarch64/bits.zig"); | ... | @@ -17,8 +17,9 @@ const aarch64 = @import("../../arch/aarch64/bits.zig"); |
| 17 | const Allocator = mem.Allocator; | 17 | const Allocator = mem.Allocator; |
| 18 | const Atom = @import("ZldAtom.zig"); | 18 | const Atom = @import("ZldAtom.zig"); |
| 19 | const AtomIndex = @import("zld.zig").AtomIndex; | 19 | const AtomIndex = @import("zld.zig").AtomIndex; |
| 20 | const MachO = @import("../MachO.zig"); | ||
| 20 | const Relocation = @import("Relocation.zig"); | 21 | const Relocation = @import("Relocation.zig"); |
| 21 | const SymbolWithLoc = @import("zld.zig").SymbolWithLoc; | 22 | const SymbolWithLoc = MachO.SymbolWithLoc; |
| 22 | const Zld = @import("zld.zig").Zld; | 23 | const Zld = @import("zld.zig").Zld; |
| 23 | 24 | ||
| 24 | pub const ThunkIndex = u32; | 25 | pub const ThunkIndex = u32; |
src/link/MachO/zld.zig+3-50| ... | @@ -32,6 +32,7 @@ const Md5 = std.crypto.hash.Md5; | ... | @@ -32,6 +32,7 @@ const Md5 = std.crypto.hash.Md5; |
| 32 | const LibStub = @import("../tapi.zig").LibStub; | 32 | const LibStub = @import("../tapi.zig").LibStub; |
| 33 | const Object = @import("Object.zig"); | 33 | const Object = @import("Object.zig"); |
| 34 | const StringTable = @import("../strtab.zig").StringTable; | 34 | const StringTable = @import("../strtab.zig").StringTable; |
| 35 | const SymbolWithLoc = MachO.SymbolWithLoc; | ||
| 35 | const Trie = @import("Trie.zig"); | 36 | const Trie = @import("Trie.zig"); |
| 36 | const UnwindInfo = @import("UnwindInfo.zig"); | 37 | const UnwindInfo = @import("UnwindInfo.zig"); |
| 37 | 38 | ||
| ... | @@ -2038,8 +2039,8 @@ pub const Zld = struct { | ... | @@ -2038,8 +2039,8 @@ pub const Zld = struct { |
| 2038 | } | 2039 | } |
| 2039 | }; | 2040 | }; |
| 2040 | 2041 | ||
| 2041 | const start = lsearch(macho.data_in_code_entry, dices, Predicate{ .addr = start_addr }); | 2042 | const start = MachO.lsearch(macho.data_in_code_entry, dices, Predicate{ .addr = start_addr }); |
| 2042 | const end = lsearch(macho.data_in_code_entry, dices[start..], Predicate{ .addr = end_addr }) + start; | 2043 | const end = MachO.lsearch(macho.data_in_code_entry, dices[start..], Predicate{ .addr = end_addr }) + start; |
| 2043 | 2044 | ||
| 2044 | return dices[start..end]; | 2045 | return dices[start..end]; |
| 2045 | } | 2046 | } |
| ... | @@ -3021,23 +3022,6 @@ const IndirectPointer = struct { | ... | @@ -3021,23 +3022,6 @@ const IndirectPointer = struct { |
| 3021 | } | 3022 | } |
| 3022 | }; | 3023 | }; |
| 3023 | 3024 | ||
| 3024 | pub const SymbolWithLoc = extern struct { | ||
| 3025 | // Index into the respective symbol table. | ||
| 3026 | sym_index: u32, | ||
| 3027 | |||
| 3028 | // 0 means it's a synthetic global. | ||
| 3029 | file: u32 = 0, | ||
| 3030 | |||
| 3031 | pub fn getFile(self: SymbolWithLoc) ?u32 { | ||
| 3032 | if (self.file == 0) return null; | ||
| 3033 | return self.file - 1; | ||
| 3034 | } | ||
| 3035 | |||
| 3036 | pub fn eql(self: SymbolWithLoc, other: SymbolWithLoc) bool { | ||
| 3037 | return self.file == other.file and self.sym_index == other.sym_index; | ||
| 3038 | } | ||
| 3039 | }; | ||
| 3040 | |||
| 3041 | pub const SymbolResolver = struct { | 3025 | pub const SymbolResolver = struct { |
| 3042 | arena: Allocator, | 3026 | arena: Allocator, |
| 3043 | table: std.StringHashMap(u32), | 3027 | table: std.StringHashMap(u32), |
| ... | @@ -3636,34 +3620,3 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3636,34 +3620,3 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3636 | macho_file.base.lock = man.toOwnedLock(); | 3620 | macho_file.base.lock = man.toOwnedLock(); |
| 3637 | } | 3621 | } |
| 3638 | } | 3622 | } |
| 3639 | |||
| 3640 | /// Binary search | ||
| 3641 | pub fn bsearch(comptime T: type, haystack: []align(1) const T, predicate: anytype) usize { | ||
| 3642 | if (!@hasDecl(@TypeOf(predicate), "predicate")) | ||
| 3643 | @compileError("Predicate is required to define fn predicate(@This(), T) bool"); | ||
| 3644 | |||
| 3645 | var min: usize = 0; | ||
| 3646 | var max: usize = haystack.len; | ||
| 3647 | while (min < max) { | ||
| 3648 | const index = (min + max) / 2; | ||
| 3649 | const curr = haystack[index]; | ||
| 3650 | if (predicate.predicate(curr)) { | ||
| 3651 | min = index + 1; | ||
| 3652 | } else { | ||
| 3653 | max = index; | ||
| 3654 | } | ||
| 3655 | } | ||
| 3656 | return min; | ||
| 3657 | } | ||
| 3658 | |||
| 3659 | /// Linear search | ||
| 3660 | pub fn lsearch(comptime T: type, haystack: []align(1) const T, predicate: anytype) usize { | ||
| 3661 | if (!@hasDecl(@TypeOf(predicate), "predicate")) | ||
| 3662 | @compileError("Predicate is required to define fn predicate(@This(), T) bool"); | ||
| 3663 | |||
| 3664 | var i: usize = 0; | ||
| 3665 | while (i < haystack.len) : (i += 1) { | ||
| 3666 | if (predicate.predicate(haystack[i])) break; | ||
| 3667 | } | ||
| 3668 | return i; | ||
| 3669 | } |