| author | |
| committer | |
| log | b25e58b0acb3153814c96161f5d6bc1fa3316800 |
| tree | faa127fa9c94c8805d44dad0192c4d74c81cbae3 |
| parent | ede47d49eba1a2b03a991b8e33bc5f4ff7e24bb9 |
| signature |
4 files changed, 109 insertions(+), 13 deletions(-)
lib/std/array_hash_map.zig+44| ... | ... | @@ -293,6 +293,22 @@ pub fn ArrayHashMap( |
| 293 | 293 | return self.unmanaged.getPtrAdapted(key, ctx); |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | /// Find the actual key associated with an adapted key | |
| 297 | pub fn getKey(self: Self, key: K) ?K { | |
| 298 | return self.unmanaged.getKeyContext(key, self.ctx); | |
| 299 | } | |
| 300 | pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K { | |
| 301 | return self.unmanaged.getKeyAdapted(key, ctx); | |
| 302 | } | |
| 303 | ||
| 304 | /// Find a pointer to the actual key associated with an adapted key | |
| 305 | pub fn getKeyPtr(self: Self, key: K) ?*K { | |
| 306 | return self.unmanaged.getKeyPtrContext(key, self.ctx); | |
| 307 | } | |
| 308 | pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K { | |
| 309 | return self.unmanaged.getKeyPtrAdapted(key, ctx); | |
| 310 | } | |
| 311 | ||
| 296 | 312 | /// Check whether a key is stored in the map |
| 297 | 313 | pub fn contains(self: Self, key: K) bool { |
| 298 | 314 | return self.unmanaged.containsContext(key, self.ctx); |
| ... | ... | @@ -967,6 +983,34 @@ pub fn ArrayHashMapUnmanaged( |
| 967 | 983 | return if (@sizeOf(*V) == 0) @as(*V, undefined) else &self.values()[index]; |
| 968 | 984 | } |
| 969 | 985 | |
| 986 | /// Find the actual key associated with an adapted key | |
| 987 | pub fn getKey(self: Self, key: K) ?K { | |
| 988 | if (@sizeOf(Context) != 0) | |
| 989 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyContext instead."); | |
| 990 | return self.getKeyContext(key, undefined); | |
| 991 | } | |
| 992 | pub fn getKeyContext(self: Self, key: K, ctx: Context) ?K { | |
| 993 | return self.getKeyAdapted(key, ctx); | |
| 994 | } | |
| 995 | pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K { | |
| 996 | const index = self.getIndexAdapted(key, ctx) orelse return null; | |
| 997 | return self.keys()[index]; | |
| 998 | } | |
| 999 | ||
| 1000 | /// Find a pointer to the actual key associated with an adapted key | |
| 1001 | pub fn getKeyPtr(self: Self, key: K) ?*K { | |
| 1002 | if (@sizeOf(Context) != 0) | |
| 1003 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyPtrContext instead."); | |
| 1004 | return self.getKeyPtrContext(key, undefined); | |
| 1005 | } | |
| 1006 | pub fn getKeyPtrContext(self: Self, key: K, ctx: Context) ?*K { | |
| 1007 | return self.getKeyPtrAdapted(key, ctx); | |
| 1008 | } | |
| 1009 | pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K { | |
| 1010 | const index = self.getIndexAdapted(key, ctx) orelse return null; | |
| 1011 | return &self.keys()[index]; | |
| 1012 | } | |
| 1013 | ||
| 970 | 1014 | /// Check whether a key is stored in the map |
| 971 | 1015 | pub fn contains(self: Self, key: K) bool { |
| 972 | 1016 | if (@sizeOf(Context) != 0) |
lib/std/hash_map.zig+48| ... | ... | @@ -561,6 +561,21 @@ pub fn HashMap( |
| 561 | 561 | return self.unmanaged.getPtrAdapted(key, ctx); |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | /// Finds the actual key associated with an adapted key in the map | |
| 565 | pub fn getKey(self: Self, key: K) ?K { | |
| 566 | return self.unmanaged.getKeyContext(key, self.ctx); | |
| 567 | } | |
| 568 | pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K { | |
| 569 | return self.unmanaged.getKeyAdapted(key, ctx); | |
| 570 | } | |
| 571 | ||
| 572 | pub fn getKeyPtr(self: Self, key: K) ?*K { | |
| 573 | return self.unmanaged.getKeyPtrContext(key, self.ctx); | |
| 574 | } | |
| 575 | pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K { | |
| 576 | return self.unmanaged.getKeyPtrAdapted(key, ctx); | |
| 577 | } | |
| 578 | ||
| 564 | 579 | /// Finds the key and value associated with a key in the map |
| 565 | 580 | pub fn getEntry(self: Self, key: K) ?Entry { |
| 566 | 581 | return self.unmanaged.getEntryContext(key, self.ctx); |
| ... | ... | @@ -1124,6 +1139,38 @@ pub fn HashMapUnmanaged( |
| 1124 | 1139 | result.value_ptr.* = value; |
| 1125 | 1140 | } |
| 1126 | 1141 | |
| 1142 | /// Get an optional pointer to the actual key associated with adapted key, if present. | |
| 1143 | pub fn getKeyPtr(self: Self, key: K) ?*K { | |
| 1144 | if (@sizeOf(Context) != 0) | |
| 1145 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyPtrContext instead."); | |
| 1146 | return self.getKeyPtrContext(key, undefined); | |
| 1147 | } | |
| 1148 | pub fn getKeyPtrContext(self: Self, key: K, ctx: Context) ?*K { | |
| 1149 | return self.getKeyPtrAdapted(key, ctx); | |
| 1150 | } | |
| 1151 | pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K { | |
| 1152 | if (self.getIndex(key, ctx)) |idx| { | |
| 1153 | return &self.keys()[idx]; | |
| 1154 | } | |
| 1155 | return null; | |
| 1156 | } | |
| 1157 | ||
| 1158 | /// Get a copy of the actual key associated with adapted key, if present. | |
| 1159 | pub fn getKey(self: Self, key: K) ?K { | |
| 1160 | if (@sizeOf(Context) != 0) | |
| 1161 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyContext instead."); | |
| 1162 | return self.getKeyContext(key, undefined); | |
| 1163 | } | |
| 1164 | pub fn getKeyContext(self: Self, key: K, ctx: Context) ?K { | |
| 1165 | return self.getKeyAdapted(key, ctx); | |
| 1166 | } | |
| 1167 | pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K { | |
| 1168 | if (self.getIndex(key, ctx)) |idx| { | |
| 1169 | return self.keys()[idx]; | |
| 1170 | } | |
| 1171 | return null; | |
| 1172 | } | |
| 1173 | ||
| 1127 | 1174 | /// Get an optional pointer to the value associated with key, if present. |
| 1128 | 1175 | pub fn getPtr(self: Self, key: K) ?*V { |
| 1129 | 1176 | if (@sizeOf(Context) != 0) |
| ... | ... | @@ -1948,6 +1995,7 @@ test "std.hash_map getOrPutAdapted" { |
| 1948 | 1995 | try testing.expect(result.found_existing); |
| 1949 | 1996 | try testing.expectEqual(real_keys[i], result.key_ptr.*); |
| 1950 | 1997 | try testing.expectEqual(@as(u64, i) * 2, result.value_ptr.*); |
| 1998 | try testing.expectEqual(real_keys[i], map.getKeyAdapted(key_str, AdaptedContext{}).?); | |
| 1951 | 1999 | } |
| 1952 | 2000 | } |
| 1953 | 2001 |
src/link/MachO.zig+15-11| ... | ... | @@ -148,7 +148,7 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 148 | 148 | stub_helper_stubs_start_off: ?u64 = null, |
| 149 | 149 | |
| 150 | 150 | strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 151 | strtab_dir: std.HashMapUnmanaged(u32, u32, StringIndexContext, std.hash_map.default_max_load_percentage) = .{}, | |
| 151 | strtab_dir: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{}, | |
| 152 | 152 | |
| 153 | 153 | got_entries: std.ArrayListUnmanaged(GotIndirectionKey) = .{}, |
| 154 | 154 | got_entries_map: std.AutoHashMapUnmanaged(GotIndirectionKey, u32) = .{}, |
| ... | ... | @@ -938,7 +938,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { |
| 938 | 938 | |
| 939 | 939 | { |
| 940 | 940 | // Add dyld_stub_binder as the final GOT entry. |
| 941 | const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 941 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 942 | 942 | .strtab = &self.strtab, |
| 943 | 943 | }) orelse unreachable; |
| 944 | 944 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| ... | ... | @@ -1966,7 +1966,7 @@ fn writeStubHelperCommon(self: *MachO) !void { |
| 1966 | 1966 | code[9] = 0xff; |
| 1967 | 1967 | code[10] = 0x25; |
| 1968 | 1968 | { |
| 1969 | const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 1969 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 1970 | 1970 | .strtab = &self.strtab, |
| 1971 | 1971 | }) orelse unreachable; |
| 1972 | 1972 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| ... | ... | @@ -2017,7 +2017,7 @@ fn writeStubHelperCommon(self: *MachO) !void { |
| 2017 | 2017 | code[10] = 0xbf; |
| 2018 | 2018 | code[11] = 0xa9; |
| 2019 | 2019 | binder_blk_outer: { |
| 2020 | const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 2020 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 2021 | 2021 | .strtab = &self.strtab, |
| 2022 | 2022 | }) orelse unreachable; |
| 2023 | 2023 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| ... | ... | @@ -2435,7 +2435,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2435 | 2435 | } |
| 2436 | 2436 | |
| 2437 | 2437 | // Fourth pass, handle synthetic symbols and flag any undefined references. |
| 2438 | if (self.strtab_dir.getAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{ | |
| 2438 | if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{ | |
| 2439 | 2439 | .strtab = &self.strtab, |
| 2440 | 2440 | })) |n_strx| blk: { |
| 2441 | 2441 | const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk; |
| ... | ... | @@ -2985,7 +2985,7 @@ fn setEntryPoint(self: *MachO) !void { |
| 2985 | 2985 | // TODO we should respect the -entry flag passed in by the user to set a custom |
| 2986 | 2986 | // entrypoint. For now, assume default of `_main`. |
| 2987 | 2987 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2988 | const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "_main"), StringSliceAdapter{ | |
| 2988 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{ | |
| 2989 | 2989 | .strtab = &self.strtab, |
| 2990 | 2990 | }) orelse { |
| 2991 | 2991 | log.err("'_main' export not found", .{}); |
| ... | ... | @@ -4616,7 +4616,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { |
| 4616 | 4616 | const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name}); |
| 4617 | 4617 | defer self.base.allocator.free(sym_name); |
| 4618 | 4618 | |
| 4619 | if (self.strtab_dir.getAdapted(@as([]const u8, sym_name), StringSliceAdapter{ | |
| 4619 | if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{ | |
| 4620 | 4620 | .strtab = &self.strtab, |
| 4621 | 4621 | })) |n_strx| { |
| 4622 | 4622 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| ... | ... | @@ -5858,7 +5858,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 5858 | 5858 | } |
| 5859 | 5859 | |
| 5860 | 5860 | pub fn makeString(self: *MachO, string: []const u8) !u32 { |
| 5861 | if (self.strtab_dir.getAdapted(@as([]const u8, string), StringSliceAdapter{ .strtab = &self.strtab })) |off| { | |
| 5861 | const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{ | |
| 5862 | .strtab = &self.strtab, | |
| 5863 | }, StringIndexContext{ | |
| 5864 | .strtab = &self.strtab, | |
| 5865 | }); | |
| 5866 | if (gop.found_existing) { | |
| 5867 | const off = gop.key_ptr.*; | |
| 5862 | 5868 | log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off }); |
| 5863 | 5869 | return off; |
| 5864 | 5870 | } |
| ... | ... | @@ -5871,9 +5877,7 @@ pub fn makeString(self: *MachO, string: []const u8) !u32 { |
| 5871 | 5877 | self.strtab.appendSliceAssumeCapacity(string); |
| 5872 | 5878 | self.strtab.appendAssumeCapacity(0); |
| 5873 | 5879 | |
| 5874 | try self.strtab_dir.putContext(self.base.allocator, new_off, new_off, StringIndexContext{ | |
| 5875 | .strtab = &self.strtab, | |
| 5876 | }); | |
| 5880 | gop.key_ptr.* = new_off; | |
| 5877 | 5881 | |
| 5878 | 5882 | return new_off; |
| 5879 | 5883 | } |
src/link/MachO/TextBlock.zig+2-2| ... | ... | @@ -656,7 +656,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc |
| 656 | 656 | parsed_rel.where = .local; |
| 657 | 657 | parsed_rel.where_index = where_index; |
| 658 | 658 | } else { |
| 659 | const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ | |
| 659 | const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ | |
| 660 | 660 | .strtab = &context.macho_file.strtab, |
| 661 | 661 | }) orelse unreachable; |
| 662 | 662 | const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable; |
| ... | ... | @@ -717,7 +717,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R |
| 717 | 717 | const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable; |
| 718 | 718 | subtractor = where_index; |
| 719 | 719 | } else { |
| 720 | const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ | |
| 720 | const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ | |
| 721 | 721 | .strtab = &context.macho_file.strtab, |
| 722 | 722 | }) orelse unreachable; |
| 723 | 723 | const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable; |