authorgravatar for fncontroloption@noreply.codeberg.orgFnControlOption <fncontroloption@noreply.codeberg.org> 2021-09-03 06:50:27-07:00
committergravatar for fncontroloption@noreply.codeberg.orgFnControlOption <fncontroloption@noreply.codeberg.org> 2021-09-03 06:50:27-07:00
logfdf1918b39c7554daeaa05e3c537ff9a83e9c3bd
tree10fc75584c727112c121b9f8bb324d4d1e9c850c
parent594271f8dba0143280990ac2e01dd68a791c05b0

std.hash_map: add StringIndexAdapter and StringIndexContext


3 files changed, 52 insertions(+), 48 deletions(-)

lib/std/hash_map.zig+28
...@@ -92,6 +92,34 @@ pub fn hashString(s: []const u8) u64 {...@@ -92,6 +92,34 @@ pub fn hashString(s: []const u8) u64 {
92 return std.hash.Wyhash.hash(0, s);92 return std.hash.Wyhash.hash(0, s);
93}93}
9494
95pub const StringIndexContext = struct {
96 bytes: *std.ArrayListUnmanaged(u8),
97
98 pub fn eql(self: @This(), a: u32, b: u32) bool {
99 _ = self;
100 return a == b;
101 }
102
103 pub fn hash(self: @This(), x: u32) u64 {
104 const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + x);
105 return hashString(x_slice);
106 }
107};
108
109pub const StringIndexAdapter = struct {
110 bytes: *std.ArrayListUnmanaged(u8),
111
112 pub fn eql(self: @This(), a_slice: []const u8, b: u32) bool {
113 const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + b);
114 return mem.eql(u8, a_slice, b_slice);
115 }
116
117 pub fn hash(self: @This(), adapted_key: []const u8) u64 {
118 _ = self;
119 return hashString(adapted_key);
120 }
121};
122
95/// Deprecated use `default_max_load_percentage`123/// Deprecated use `default_max_load_percentage`
96pub const DefaultMaxLoadPercentage = default_max_load_percentage;124pub const DefaultMaxLoadPercentage = default_max_load_percentage;
97125
src/link/MachO.zig+19-44
...@@ -37,6 +37,8 @@ const LlvmObject = @import("../codegen/llvm.zig").Object;...@@ -37,6 +37,8 @@ const LlvmObject = @import("../codegen/llvm.zig").Object;
37const LoadCommand = commands.LoadCommand;37const LoadCommand = commands.LoadCommand;
38const Module = @import("../Module.zig");38const Module = @import("../Module.zig");
39const SegmentCommand = commands.SegmentCommand;39const SegmentCommand = commands.SegmentCommand;
40const StringIndexAdapter = std.hash_map.StringIndexAdapter;
41const StringIndexContext = std.hash_map.StringIndexContext;
40pub const TextBlock = @import("MachO/TextBlock.zig");42pub const TextBlock = @import("MachO/TextBlock.zig");
41const Trie = @import("MachO/Trie.zig");43const Trie = @import("MachO/Trie.zig");
4244
...@@ -224,33 +226,6 @@ decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},...@@ -224,33 +226,6 @@ decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},
224/// somewhere else in the codegen.226/// somewhere else in the codegen.
225active_decl: ?*Module.Decl = null,227active_decl: ?*Module.Decl = null,
226228
227const StringIndexContext = struct {
228 strtab: *std.ArrayListUnmanaged(u8),
229
230 pub fn eql(_: StringIndexContext, a: u32, b: u32) bool {
231 return a == b;
232 }
233
234 pub fn hash(self: StringIndexContext, x: u32) u64 {
235 const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + x);
236 return std.hash_map.hashString(x_slice);
237 }
238};
239
240pub const StringSliceAdapter = struct {
241 strtab: *std.ArrayListUnmanaged(u8),
242
243 pub fn eql(self: StringSliceAdapter, a_slice: []const u8, b: u32) bool {
244 const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + b);
245 return mem.eql(u8, a_slice, b_slice);
246 }
247
248 pub fn hash(self: StringSliceAdapter, adapted_key: []const u8) u64 {
249 _ = self;
250 return std.hash_map.hashString(adapted_key);
251 }
252};
253
254const SymbolWithLoc = struct {229const SymbolWithLoc = struct {
255 // Table where the symbol can be found.230 // Table where the symbol can be found.
256 where: enum {231 where: enum {
...@@ -938,8 +913,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -938,8 +913,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
938913
939 {914 {
940 // Add dyld_stub_binder as the final GOT entry.915 // Add dyld_stub_binder as the final GOT entry.
941 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{916 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{
942 .strtab = &self.strtab,917 .bytes = &self.strtab,
943 }) orelse unreachable;918 }) orelse unreachable;
944 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;919 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
945 const got_index = @intCast(u32, self.got_entries.items.len);920 const got_index = @intCast(u32, self.got_entries.items.len);
...@@ -1966,8 +1941,8 @@ fn writeStubHelperCommon(self: *MachO) !void {...@@ -1966,8 +1941,8 @@ fn writeStubHelperCommon(self: *MachO) !void {
1966 code[9] = 0xff;1941 code[9] = 0xff;
1967 code[10] = 0x25;1942 code[10] = 0x25;
1968 {1943 {
1969 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{1944 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{
1970 .strtab = &self.strtab,1945 .bytes = &self.strtab,
1971 }) orelse unreachable;1946 }) orelse unreachable;
1972 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;1947 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
1973 const got_index = self.got_entries_map.get(.{1948 const got_index = self.got_entries_map.get(.{
...@@ -2017,8 +1992,8 @@ fn writeStubHelperCommon(self: *MachO) !void {...@@ -2017,8 +1992,8 @@ fn writeStubHelperCommon(self: *MachO) !void {
2017 code[10] = 0xbf;1992 code[10] = 0xbf;
2018 code[11] = 0xa9;1993 code[11] = 0xa9;
2019 binder_blk_outer: {1994 binder_blk_outer: {
2020 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{1995 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{
2021 .strtab = &self.strtab,1996 .bytes = &self.strtab,
2022 }) orelse unreachable;1997 }) orelse unreachable;
2023 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;1998 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
2024 const got_index = self.got_entries_map.get(.{1999 const got_index = self.got_entries_map.get(.{
...@@ -2435,8 +2410,8 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2435,8 +2410,8 @@ fn resolveSymbols(self: *MachO) !void {
2435 }2410 }
24362411
2437 // Fourth pass, handle synthetic symbols and flag any undefined references.2412 // Fourth pass, handle synthetic symbols and flag any undefined references.
2438 if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{2413 if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringIndexAdapter{
2439 .strtab = &self.strtab,2414 .bytes = &self.strtab,
2440 })) |n_strx| blk: {2415 })) |n_strx| blk: {
2441 const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;2416 const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;
2442 if (resolv.where != .undef) break :blk;2417 if (resolv.where != .undef) break :blk;
...@@ -2985,8 +2960,8 @@ fn setEntryPoint(self: *MachO) !void {...@@ -2985,8 +2960,8 @@ fn setEntryPoint(self: *MachO) !void {
2985 // TODO we should respect the -entry flag passed in by the user to set a custom2960 // TODO we should respect the -entry flag passed in by the user to set a custom
2986 // entrypoint. For now, assume default of `_main`.2961 // entrypoint. For now, assume default of `_main`.
2987 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;2962 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2988 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{2963 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringIndexAdapter{
2989 .strtab = &self.strtab,2964 .bytes = &self.strtab,
2990 }) orelse {2965 }) orelse {
2991 log.err("'_main' export not found", .{});2966 log.err("'_main' export not found", .{});
2992 return error.MissingMainEntrypoint;2967 return error.MissingMainEntrypoint;
...@@ -4475,8 +4450,8 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -4475,8 +4450,8 @@ pub fn populateMissingMetadata(self: *MachO) !void {
4475 });4450 });
4476 self.load_commands_dirty = true;4451 self.load_commands_dirty = true;
4477 }4452 }
4478 if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{4453 if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{
4479 .strtab = &self.strtab,4454 .bytes = &self.strtab,
4480 })) {4455 })) {
4481 const import_sym_index = @intCast(u32, self.undefs.items.len);4456 const import_sym_index = @intCast(u32, self.undefs.items.len);
4482 const n_strx = try self.makeString("dyld_stub_binder");4457 const n_strx = try self.makeString("dyld_stub_binder");
...@@ -4616,8 +4591,8 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {...@@ -4616,8 +4591,8 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
4616 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});4591 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
4617 defer self.base.allocator.free(sym_name);4592 defer self.base.allocator.free(sym_name);
46184593
4619 if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{4594 if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
4620 .strtab = &self.strtab,4595 .bytes = &self.strtab,
4621 })) |n_strx| {4596 })) |n_strx| {
4622 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;4597 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
4623 return resolv.where_index;4598 return resolv.where_index;
...@@ -5858,10 +5833,10 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {...@@ -5858,10 +5833,10 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
5858}5833}
58595834
5860pub fn makeString(self: *MachO, string: []const u8) !u32 {5835pub fn makeString(self: *MachO, string: []const u8) !u32 {
5861 const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{5836 const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringIndexAdapter{
5862 .strtab = &self.strtab,5837 .bytes = &self.strtab,
5863 }, StringIndexContext{5838 }, StringIndexContext{
5864 .strtab = &self.strtab,5839 .bytes = &self.strtab,
5865 });5840 });
5866 if (gop.found_existing) {5841 if (gop.found_existing) {
5867 const off = gop.key_ptr.*;5842 const off = gop.key_ptr.*;
src/link/MachO/TextBlock.zig+5-4
...@@ -14,6 +14,7 @@ const Allocator = mem.Allocator;...@@ -14,6 +14,7 @@ const Allocator = mem.Allocator;
14const Arch = std.Target.Cpu.Arch;14const Arch = std.Target.Cpu.Arch;
15const MachO = @import("../MachO.zig");15const MachO = @import("../MachO.zig");
16const Object = @import("Object.zig");16const Object = @import("Object.zig");
17const StringIndexAdapter = std.hash_map.StringIndexAdapter;
1718
18/// Each decl always gets a local symbol with the fully qualified name.19/// Each decl always gets a local symbol with the fully qualified name.
19/// The vaddr and size are found here directly.20/// The vaddr and size are found here directly.
...@@ -656,8 +657,8 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc...@@ -656,8 +657,8 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc
656 parsed_rel.where = .local;657 parsed_rel.where = .local;
657 parsed_rel.where_index = where_index;658 parsed_rel.where_index = where_index;
658 } else {659 } else {
659 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{660 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
660 .strtab = &context.macho_file.strtab,661 .bytes = &context.macho_file.strtab,
661 }) orelse unreachable;662 }) orelse unreachable;
662 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;663 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
663 switch (resolv.where) {664 switch (resolv.where) {
...@@ -717,8 +718,8 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R...@@ -717,8 +718,8 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
717 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;718 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
718 subtractor = where_index;719 subtractor = where_index;
719 } else {720 } else {
720 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{721 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
721 .strtab = &context.macho_file.strtab,722 .bytes = &context.macho_file.strtab,
722 }) orelse unreachable;723 }) orelse unreachable;
723 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;724 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
724 assert(resolv.where == .global);725 assert(resolv.where == .global);