| author | |
| committer | |
| log | 518c7908f01cafac9acfbbb708fc49d2c3b5d460 |
| tree | 1091aff77fc5b0011d72dc257dbdf868b6785261 |
| parent | f9f894200891c8af6ce3a3ad222cd0bf1ee15587 |
7 files changed, 31 insertions(+), 44 deletions(-)
src/link/Elf.zig+4-18| ... | ... | @@ -176,7 +176,6 @@ symtab_section_index: ?u32 = null, |
| 176 | 176 | /// An array of symbols parsed across all input files. |
| 177 | 177 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, |
| 178 | 178 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 179 | symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, | |
| 180 | 179 | |
| 181 | 180 | resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{}, |
| 182 | 181 | |
| ... | ... | @@ -343,8 +342,6 @@ pub fn createEmpty( |
| 343 | 342 | |
| 344 | 343 | // Index 0 is always a null symbol. |
| 345 | 344 | try self.symbols.append(gpa, .{}); |
| 346 | // Index 0 is always a null symbol. | |
| 347 | try self.symbols_extra.append(gpa, 0); | |
| 348 | 345 | // Append null file at index 0 |
| 349 | 346 | try self.files.append(gpa, .null); |
| 350 | 347 | // Append null byte to string tables |
| ... | ... | @@ -462,7 +459,6 @@ pub fn deinit(self: *Elf) void { |
| 462 | 459 | self.strtab.deinit(gpa); |
| 463 | 460 | self.symbols.deinit(gpa); |
| 464 | 461 | self.symbols_extra.deinit(gpa); |
| 465 | self.symbols_free_list.deinit(gpa); | |
| 466 | 462 | self.resolver.deinit(gpa); |
| 467 | 463 | |
| 468 | 464 | for (self.thunks.items) |*th| { |
| ... | ... | @@ -5389,17 +5385,8 @@ pub fn symbol(self: *Elf, sym_index: Symbol.Index) *Symbol { |
| 5389 | 5385 | pub fn addSymbol(self: *Elf) !Symbol.Index { |
| 5390 | 5386 | const gpa = self.base.comp.gpa; |
| 5391 | 5387 | try self.symbols.ensureUnusedCapacity(gpa, 1); |
| 5392 | const index = blk: { | |
| 5393 | if (self.symbols_free_list.popOrNull()) |index| { | |
| 5394 | log.debug(" (reusing symbol index {d})", .{index}); | |
| 5395 | break :blk index; | |
| 5396 | } else { | |
| 5397 | log.debug(" (allocating symbol index {d})", .{self.symbols.items.len}); | |
| 5398 | const index: Symbol.Index = @intCast(self.symbols.items.len); | |
| 5399 | _ = self.symbols.addOneAssumeCapacity(); | |
| 5400 | break :blk index; | |
| 5401 | } | |
| 5402 | }; | |
| 5388 | const index: Symbol.Index = @intCast(self.symbols.items.len); | |
| 5389 | _ = self.symbols.addOneAssumeCapacity(); | |
| 5403 | 5390 | self.symbols.items[index] = .{}; |
| 5404 | 5391 | return index; |
| 5405 | 5392 | } |
| ... | ... | @@ -5423,8 +5410,7 @@ pub fn addSymbolExtraAssumeCapacity(self: *Elf, extra: Symbol.Extra) u32 { |
| 5423 | 5410 | return index; |
| 5424 | 5411 | } |
| 5425 | 5412 | |
| 5426 | pub fn symbolExtra(self: *Elf, index: u32) ?Symbol.Extra { | |
| 5427 | if (index == 0) return null; | |
| 5413 | pub fn symbolExtra(self: *Elf, index: u32) Symbol.Extra { | |
| 5428 | 5414 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| 5429 | 5415 | var i: usize = index; |
| 5430 | 5416 | var result: Symbol.Extra = undefined; |
| ... | ... | @@ -5439,7 +5425,6 @@ pub fn symbolExtra(self: *Elf, index: u32) ?Symbol.Extra { |
| 5439 | 5425 | } |
| 5440 | 5426 | |
| 5441 | 5427 | pub fn setSymbolExtra(self: *Elf, index: u32, extra: Symbol.Extra) void { |
| 5442 | assert(index > 0); | |
| 5443 | 5428 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| 5444 | 5429 | inline for (fields, 0..) |field, i| { |
| 5445 | 5430 | self.symbols_extra.items[index + i] = switch (field.type) { |
| ... | ... | @@ -5464,6 +5449,7 @@ pub fn getOrPutGlobal(self: *Elf, name: []const u8) !GetOrPutGlobalResult { |
| 5464 | 5449 | const global = self.symbol(index); |
| 5465 | 5450 | global.name_offset = name_off; |
| 5466 | 5451 | global.flags.global = true; |
| 5452 | global.extra_index = try self.addSymbolExtra(.{}); | |
| 5467 | 5453 | gop.value_ptr.* = index; |
| 5468 | 5454 | } |
| 5469 | 5455 | return .{ |
src/link/Elf/Atom.zig+3-3| ... | ... | @@ -845,7 +845,7 @@ fn resolveDynAbsReloc( |
| 845 | 845 | if (is_writeable or elf_file.z_nocopyreloc) { |
| 846 | 846 | elf_file.addRelaDynAssumeCapacity(.{ |
| 847 | 847 | .offset = P, |
| 848 | .sym = target.extra(elf_file).?.dynamic, | |
| 848 | .sym = target.extra(elf_file).dynamic, | |
| 849 | 849 | .type = relocation.encode(.abs, cpu_arch), |
| 850 | 850 | .addend = A, |
| 851 | 851 | }); |
| ... | ... | @@ -859,7 +859,7 @@ fn resolveDynAbsReloc( |
| 859 | 859 | if (is_writeable) { |
| 860 | 860 | elf_file.addRelaDynAssumeCapacity(.{ |
| 861 | 861 | .offset = P, |
| 862 | .sym = target.extra(elf_file).?.dynamic, | |
| 862 | .sym = target.extra(elf_file).dynamic, | |
| 863 | 863 | .type = relocation.encode(.abs, cpu_arch), |
| 864 | 864 | .addend = A, |
| 865 | 865 | }); |
| ... | ... | @@ -872,7 +872,7 @@ fn resolveDynAbsReloc( |
| 872 | 872 | .dynrel => { |
| 873 | 873 | elf_file.addRelaDynAssumeCapacity(.{ |
| 874 | 874 | .offset = P, |
| 875 | .sym = target.extra(elf_file).?.dynamic, | |
| 875 | .sym = target.extra(elf_file).dynamic, | |
| 876 | 876 | .type = relocation.encode(.abs, cpu_arch), |
| 877 | 877 | .addend = A, |
| 878 | 878 | }); |
src/link/Elf/Object.zig+2| ... | ... | @@ -387,6 +387,7 @@ fn initSymtab(self: *Object, allocator: Allocator, elf_file: *Elf) !void { |
| 387 | 387 | sym_ptr.name_offset = sym.st_name; |
| 388 | 388 | sym_ptr.esym_index = @as(u32, @intCast(i)); |
| 389 | 389 | sym_ptr.file_index = self.index; |
| 390 | sym_ptr.extra_index = try elf_file.addSymbolExtra(.{}); | |
| 390 | 391 | if (sym.st_shndx != elf.SHN_ABS) { |
| 391 | 392 | sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index }; |
| 392 | 393 | } |
| ... | ... | @@ -865,6 +866,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 865 | 866 | .name_offset = try self.addString(gpa, name), |
| 866 | 867 | .esym_index = rel.r_sym(), |
| 867 | 868 | .file_index = self.index, |
| 869 | .extra_index = try elf_file.addSymbolExtra(.{}), | |
| 868 | 870 | }; |
| 869 | 871 | sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index }; |
| 870 | 872 | sym.flags.merge_subsection = true; |
src/link/Elf/Symbol.zig+12-15| ... | ... | @@ -159,20 +159,20 @@ pub fn outputSymtabIndex(symbol: Symbol, elf_file: *Elf) ?u32 { |
| 159 | 159 | const symtab_ctx = switch (file_ptr) { |
| 160 | 160 | inline else => |x| x.output_symtab_ctx, |
| 161 | 161 | }; |
| 162 | const idx = symbol.extra(elf_file).?.symtab; | |
| 162 | const idx = symbol.extra(elf_file).symtab; | |
| 163 | 163 | return if (symbol.isLocal(elf_file)) idx + symtab_ctx.ilocal else idx + symtab_ctx.iglobal; |
| 164 | 164 | } |
| 165 | 165 | |
| 166 | 166 | pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 167 | 167 | if (!symbol.flags.has_got) return 0; |
| 168 | const extras = symbol.extra(elf_file).?; | |
| 168 | const extras = symbol.extra(elf_file); | |
| 169 | 169 | const entry = elf_file.got.entries.items[extras.got]; |
| 170 | 170 | return entry.address(elf_file); |
| 171 | 171 | } |
| 172 | 172 | |
| 173 | 173 | pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 174 | 174 | if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0; |
| 175 | const extras = symbol.extra(elf_file).?; | |
| 175 | const extras = symbol.extra(elf_file); | |
| 176 | 176 | const shdr = elf_file.shdrs.items[elf_file.plt_got_section_index.?]; |
| 177 | 177 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 178 | 178 | return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch)); |
| ... | ... | @@ -180,7 +180,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 180 | 180 | |
| 181 | 181 | pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 182 | 182 | if (!symbol.flags.has_plt) return 0; |
| 183 | const extras = symbol.extra(elf_file).?; | |
| 183 | const extras = symbol.extra(elf_file); | |
| 184 | 184 | const shdr = elf_file.shdrs.items[elf_file.plt_section_index.?]; |
| 185 | 185 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 186 | 186 | return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch)); |
| ... | ... | @@ -188,7 +188,7 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 188 | 188 | |
| 189 | 189 | pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 190 | 190 | if (!symbol.flags.has_plt) return 0; |
| 191 | const extras = symbol.extra(elf_file).?; | |
| 191 | const extras = symbol.extra(elf_file); | |
| 192 | 192 | const shdr = elf_file.shdrs.items[elf_file.got_plt_section_index.?]; |
| 193 | 193 | return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size); |
| 194 | 194 | } |
| ... | ... | @@ -201,21 +201,21 @@ pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 201 | 201 | |
| 202 | 202 | pub fn tlsGdAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 203 | 203 | if (!symbol.flags.has_tlsgd) return 0; |
| 204 | const extras = symbol.extra(elf_file).?; | |
| 204 | const extras = symbol.extra(elf_file); | |
| 205 | 205 | const entry = elf_file.got.entries.items[extras.tlsgd]; |
| 206 | 206 | return entry.address(elf_file); |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | pub fn gotTpAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 210 | 210 | if (!symbol.flags.has_gottp) return 0; |
| 211 | const extras = symbol.extra(elf_file).?; | |
| 211 | const extras = symbol.extra(elf_file); | |
| 212 | 212 | const entry = elf_file.got.entries.items[extras.gottp]; |
| 213 | 213 | return entry.address(elf_file); |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | 216 | pub fn tlsDescAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 217 | 217 | if (!symbol.flags.has_tlsdesc) return 0; |
| 218 | const extras = symbol.extra(elf_file).?; | |
| 218 | const extras = symbol.extra(elf_file); | |
| 219 | 219 | const entry = elf_file.got.entries.items[extras.tlsdesc]; |
| 220 | 220 | return entry.address(elf_file); |
| 221 | 221 | } |
| ... | ... | @@ -228,14 +228,14 @@ const GetOrCreateZigGotEntryResult = struct { |
| 228 | 228 | pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult { |
| 229 | 229 | assert(!elf_file.base.isRelocatable()); |
| 230 | 230 | assert(symbol.flags.needs_zig_got); |
| 231 | if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got }; | |
| 231 | if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).zig_got }; | |
| 232 | 232 | const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file); |
| 233 | 233 | return .{ .found_existing = false, .index = index }; |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | 236 | pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 237 | 237 | if (!symbol.flags.has_zig_got) return 0; |
| 238 | const extras = symbol.extra(elf_file).?; | |
| 238 | const extras = symbol.extra(elf_file); | |
| 239 | 239 | return elf_file.zig_got.entryAddress(extras.zig_got, elf_file); |
| 240 | 240 | } |
| 241 | 241 | |
| ... | ... | @@ -266,10 +266,7 @@ const AddExtraOpts = struct { |
| 266 | 266 | }; |
| 267 | 267 | |
| 268 | 268 | pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void { |
| 269 | if (symbol.extra(elf_file) == null) { | |
| 270 | symbol.extra_index = try elf_file.addSymbolExtra(.{}); | |
| 271 | } | |
| 272 | var extras = symbol.extra(elf_file).?; | |
| 269 | var extras = symbol.extra(elf_file); | |
| 273 | 270 | inline for (@typeInfo(@TypeOf(opts)).Struct.fields) |field| { |
| 274 | 271 | if (@field(opts, field.name)) |x| { |
| 275 | 272 | @field(extras, field.name) = x; |
| ... | ... | @@ -278,7 +275,7 @@ pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void { |
| 278 | 275 | symbol.setExtra(extras, elf_file); |
| 279 | 276 | } |
| 280 | 277 | |
| 281 | pub fn extra(symbol: Symbol, elf_file: *Elf) ?Extra { | |
| 278 | pub fn extra(symbol: Symbol, elf_file: *Elf) Extra { | |
| 282 | 279 | return elf_file.symbolExtra(symbol.extra_index); |
| 283 | 280 | } |
| 284 | 281 |
src/link/Elf/ZigObject.zig+3-3| ... | ... | @@ -92,6 +92,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { |
| 92 | 92 | const symbol_ptr = elf_file.symbol(symbol_index); |
| 93 | 93 | symbol_ptr.file_index = self.index; |
| 94 | 94 | symbol_ptr.name_offset = name_off; |
| 95 | symbol_ptr.extra_index = try elf_file.addSymbolExtra(.{}); | |
| 95 | 96 | |
| 96 | 97 | const esym_index = try self.addLocalEsym(gpa); |
| 97 | 98 | const esym = &self.local_esyms.items(.elf_sym)[esym_index]; |
| ... | ... | @@ -292,6 +293,7 @@ pub fn newAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { |
| 292 | 293 | const symbol_ptr = elf_file.symbol(symbol_index); |
| 293 | 294 | symbol_ptr.file_index = self.index; |
| 294 | 295 | symbol_ptr.ref = .{ .index = atom_index, .file = self.index }; |
| 296 | symbol_ptr.extra_index = try elf_file.addSymbolExtra(.{}); | |
| 295 | 297 | |
| 296 | 298 | self.local_esyms.items(.shndx)[esym_index] = atom_index; |
| 297 | 299 | self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; |
| ... | ... | @@ -779,11 +781,9 @@ fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.De |
| 779 | 781 | |
| 780 | 782 | fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void { |
| 781 | 783 | _ = self; |
| 782 | const gpa = elf_file.base.comp.gpa; | |
| 783 | 784 | const sym = elf_file.symbol(sym_index); |
| 784 | 785 | sym.atom(elf_file).?.free(elf_file); |
| 785 | 786 | log.debug("adding %{d} to local symbols free list", .{sym_index}); |
| 786 | elf_file.symbols_free_list.append(gpa, sym_index) catch {}; | |
| 787 | 787 | elf_file.symbols.items[sym_index] = .{}; |
| 788 | 788 | // TODO free GOT entry here |
| 789 | 789 | } |
| ... | ... | @@ -940,7 +940,7 @@ fn updateDeclCode( |
| 940 | 940 | if (!elf_file.base.isRelocatable()) { |
| 941 | 941 | log.debug(" (writing new offset table entry)", .{}); |
| 942 | 942 | assert(sym.flags.has_zig_got); |
| 943 | const extra = sym.extra(elf_file).?; | |
| 943 | const extra = sym.extra(elf_file); | |
| 944 | 944 | try elf_file.zig_got.writeOne(elf_file, extra.zig_got); |
| 945 | 945 | } |
| 946 | 946 | } |
src/link/Elf/file.zig+2| ... | ... | @@ -71,9 +71,11 @@ pub const File = union(enum) { |
| 71 | 71 | for (file.globals()) |global_index| { |
| 72 | 72 | const global = elf_file.symbol(global_index); |
| 73 | 73 | const name_offset = global.name_offset; |
| 74 | const extra_index = global.extra_index; | |
| 74 | 75 | global.* = .{}; |
| 75 | 76 | global.name_offset = name_offset; |
| 76 | 77 | global.flags.global = true; |
| 78 | global.extra_index = extra_index; | |
| 77 | 79 | } |
| 78 | 80 | } |
| 79 | 81 |
src/link/Elf/synthetic_sections.zig+5-5| ... | ... | @@ -641,7 +641,7 @@ pub const GotSection = struct { |
| 641 | 641 | .tlsld => null, |
| 642 | 642 | inline else => elf_file.symbol(entry.symbol_index), |
| 643 | 643 | }; |
| 644 | const extra = if (symbol) |s| s.extra(elf_file).? else null; | |
| 644 | const extra = if (symbol) |s| s.extra(elf_file) else null; | |
| 645 | 645 | |
| 646 | 646 | switch (entry.tag) { |
| 647 | 647 | .got => { |
| ... | ... | @@ -898,7 +898,7 @@ pub const PltSection = struct { |
| 898 | 898 | for (plt.symbols.items) |sym_index| { |
| 899 | 899 | const sym = elf_file.symbol(sym_index); |
| 900 | 900 | assert(sym.flags.import); |
| 901 | const extra = sym.extra(elf_file).?; | |
| 901 | const extra = sym.extra(elf_file); | |
| 902 | 902 | const r_offset: u64 = @intCast(sym.gotPltAddress(elf_file)); |
| 903 | 903 | const r_sym: u64 = extra.dynamic; |
| 904 | 904 | const r_type = relocation.encode(.jump_slot, cpu_arch); |
| ... | ... | @@ -1267,7 +1267,7 @@ pub const CopyRelSection = struct { |
| 1267 | 1267 | for (copy_rel.symbols.items) |sym_index| { |
| 1268 | 1268 | const sym = elf_file.symbol(sym_index); |
| 1269 | 1269 | assert(sym.flags.import and sym.flags.has_copy_rel); |
| 1270 | const extra = sym.extra(elf_file).?; | |
| 1270 | const extra = sym.extra(elf_file); | |
| 1271 | 1271 | elf_file.addRelaDynAssumeCapacity(.{ |
| 1272 | 1272 | .offset = @intCast(sym.address(.{}, elf_file)), |
| 1273 | 1273 | .sym = extra.dynamic, |
| ... | ... | @@ -1322,7 +1322,7 @@ pub const DynsymSection = struct { |
| 1322 | 1322 | const rhs_hash = GnuHashSection.hasher(rhs_sym.name(ctx)) % nbuckets; |
| 1323 | 1323 | |
| 1324 | 1324 | if (lhs_hash == rhs_hash) |
| 1325 | return lhs_sym.extra(ctx).?.dynamic < rhs_sym.extra(ctx).?.dynamic; | |
| 1325 | return lhs_sym.extra(ctx).dynamic < rhs_sym.extra(ctx).dynamic; | |
| 1326 | 1326 | return lhs_hash < rhs_hash; |
| 1327 | 1327 | } |
| 1328 | 1328 | }; |
| ... | ... | @@ -1339,7 +1339,7 @@ pub const DynsymSection = struct { |
| 1339 | 1339 | |
| 1340 | 1340 | for (dynsym.entries.items, 1..) |entry, index| { |
| 1341 | 1341 | const sym = elf_file.symbol(entry.symbol_index); |
| 1342 | var extra = sym.extra(elf_file).?; | |
| 1342 | var extra = sym.extra(elf_file); | |
| 1343 | 1343 | extra.dynamic = @as(u32, @intCast(index)); |
| 1344 | 1344 | sym.setExtra(extra, elf_file); |
| 1345 | 1345 | } |