diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index 765add1e68..644429f871 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -92,6 +92,34 @@ pub fn hashString(s: []const u8) u64 { return std.hash.Wyhash.hash(0, s); } +pub const StringIndexContext = struct { + bytes: *std.ArrayListUnmanaged(u8), + + pub fn eql(self: @This(), a: u32, b: u32) bool { + _ = self; + return a == b; + } + + pub fn hash(self: @This(), x: u32) u64 { + const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + x); + return hashString(x_slice); + } +}; + +pub const StringIndexAdapter = struct { + bytes: *std.ArrayListUnmanaged(u8), + + pub fn eql(self: @This(), a_slice: []const u8, b: u32) bool { + const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + b); + return mem.eql(u8, a_slice, b_slice); + } + + pub fn hash(self: @This(), adapted_key: []const u8) u64 { + _ = self; + return hashString(adapted_key); + } +}; + /// Deprecated use `default_max_load_percentage` pub const DefaultMaxLoadPercentage = default_max_load_percentage; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index b2d75ab658..12556b53d6 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -37,6 +37,8 @@ const LlvmObject = @import("../codegen/llvm.zig").Object; const LoadCommand = commands.LoadCommand; const Module = @import("../Module.zig"); const SegmentCommand = commands.SegmentCommand; +const StringIndexAdapter = std.hash_map.StringIndexAdapter; +const StringIndexContext = std.hash_map.StringIndexContext; pub const TextBlock = @import("MachO/TextBlock.zig"); const Trie = @import("MachO/Trie.zig"); @@ -224,33 +226,6 @@ decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{}, /// somewhere else in the codegen. active_decl: ?*Module.Decl = null, -const StringIndexContext = struct { - strtab: *std.ArrayListUnmanaged(u8), - - pub fn eql(_: StringIndexContext, a: u32, b: u32) bool { - return a == b; - } - - pub fn hash(self: StringIndexContext, x: u32) u64 { - const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + x); - return std.hash_map.hashString(x_slice); - } -}; - -pub const StringSliceAdapter = struct { - strtab: *std.ArrayListUnmanaged(u8), - - pub fn eql(self: StringSliceAdapter, a_slice: []const u8, b: u32) bool { - const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + b); - return mem.eql(u8, a_slice, b_slice); - } - - pub fn hash(self: StringSliceAdapter, adapted_key: []const u8) u64 { - _ = self; - return std.hash_map.hashString(adapted_key); - } -}; - const SymbolWithLoc = struct { // Table where the symbol can be found. where: enum { @@ -938,8 +913,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { { // Add dyld_stub_binder as the final GOT entry. - const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ - .strtab = &self.strtab, + const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ + .bytes = &self.strtab, }) orelse unreachable; const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; const got_index = @intCast(u32, self.got_entries.items.len); @@ -1966,8 +1941,8 @@ fn writeStubHelperCommon(self: *MachO) !void { code[9] = 0xff; code[10] = 0x25; { - const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ - .strtab = &self.strtab, + const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ + .bytes = &self.strtab, }) orelse unreachable; const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; const got_index = self.got_entries_map.get(.{ @@ -2017,8 +1992,8 @@ fn writeStubHelperCommon(self: *MachO) !void { code[10] = 0xbf; code[11] = 0xa9; binder_blk_outer: { - const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ - .strtab = &self.strtab, + const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ + .bytes = &self.strtab, }) orelse unreachable; const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; const got_index = self.got_entries_map.get(.{ @@ -2435,8 +2410,8 @@ fn resolveSymbols(self: *MachO) !void { } // Fourth pass, handle synthetic symbols and flag any undefined references. - if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{ - .strtab = &self.strtab, + if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringIndexAdapter{ + .bytes = &self.strtab, })) |n_strx| blk: { const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk; if (resolv.where != .undef) break :blk; @@ -2985,8 +2960,8 @@ fn setEntryPoint(self: *MachO) !void { // TODO we should respect the -entry flag passed in by the user to set a custom // entrypoint. For now, assume default of `_main`. const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; - const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{ - .strtab = &self.strtab, + const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringIndexAdapter{ + .bytes = &self.strtab, }) orelse { log.err("'_main' export not found", .{}); return error.MissingMainEntrypoint; @@ -4475,8 +4450,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { }); self.load_commands_dirty = true; } - if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ - .strtab = &self.strtab, + if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ + .bytes = &self.strtab, })) { const import_sym_index = @intCast(u32, self.undefs.items.len); const n_strx = try self.makeString("dyld_stub_binder"); @@ -4616,8 +4591,8 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name}); defer self.base.allocator.free(sym_name); - if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{ - .strtab = &self.strtab, + if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{ + .bytes = &self.strtab, })) |n_strx| { const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; return resolv.where_index; @@ -5858,10 +5833,10 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { } pub fn makeString(self: *MachO, string: []const u8) !u32 { - const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{ - .strtab = &self.strtab, + const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringIndexAdapter{ + .bytes = &self.strtab, }, StringIndexContext{ - .strtab = &self.strtab, + .bytes = &self.strtab, }); if (gop.found_existing) { const off = gop.key_ptr.*; diff --git a/src/link/MachO/TextBlock.zig b/src/link/MachO/TextBlock.zig index 4d103fa6eb..7e08ae3a35 100644 --- a/src/link/MachO/TextBlock.zig +++ b/src/link/MachO/TextBlock.zig @@ -14,6 +14,7 @@ const Allocator = mem.Allocator; const Arch = std.Target.Cpu.Arch; const MachO = @import("../MachO.zig"); const Object = @import("Object.zig"); +const StringIndexAdapter = std.hash_map.StringIndexAdapter; /// Each decl always gets a local symbol with the fully qualified name. /// The vaddr and size are found here directly. @@ -656,8 +657,8 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc parsed_rel.where = .local; parsed_rel.where_index = where_index; } else { - const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ - .strtab = &context.macho_file.strtab, + const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{ + .bytes = &context.macho_file.strtab, }) orelse unreachable; const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable; switch (resolv.where) { @@ -717,8 +718,8 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable; subtractor = where_index; } else { - const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ - .strtab = &context.macho_file.strtab, + const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{ + .bytes = &context.macho_file.strtab, }) orelse unreachable; const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable; assert(resolv.where == .global);