authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-06 14:42:32+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-06 14:42:32+02:00
log93120a81fee404e3ae90c5ea6d0ad2e71037bee0
tree8e65cc321757f8cc42a5c83e562d13f7a63a5bcf
parenta9df098cd2dd04e2c363b439233ff2e14e198413

elf: lift-off - get it to compile and run until the error!


5 files changed, 151 insertions(+), 131 deletions(-)

src/link/Elf.zig+65-108
......@@ -105,7 +105,7 @@ atoms: std.ArrayListUnmanaged(Atom) = .{},
105105///
106106/// value assigned to label `foo` is an unnamed constant belonging/associated
107107/// with `Decl` `main`, and lives as long as that `Decl`.
108unnamed_const_atoms: UnnamedConstTable = .{},
108unnamed_consts: UnnamedConstTable = .{},
109109
110110/// A table of relocations indexed by the owning them `TextBlock`.
111111relocs: RelocTable = .{},
......@@ -251,11 +251,11 @@ pub fn deinit(self: *Elf) void {
251251 self.lazy_syms.deinit(gpa);
252252
253253 {
254 var it = self.unnamed_const_atoms.valueIterator();
255 while (it.next()) |atoms| {
256 atoms.deinit(gpa);
254 var it = self.unnamed_consts.valueIterator();
255 while (it.next()) |syms| {
256 syms.deinit(gpa);
257257 }
258 self.unnamed_const_atoms.deinit(gpa);
258 self.unnamed_consts.deinit(gpa);
259259 }
260260
261261 {
......@@ -279,7 +279,7 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
279279 const vaddr = this_sym.value;
280280 const parent_atom_index = self.symbol(reloc_info.parent_atom_index).atom_index;
281281 try Atom.addRelocation(self, parent_atom_index, .{
282 .target = this_sym,
282 .target = this_sym_index,
283283 .offset = reloc_info.offset,
284284 .addend = reloc_info.addend,
285285 .prev_vaddr = vaddr,
......@@ -830,6 +830,12 @@ pub fn populateMissingMetadata(self: *Elf) !void {
830830
831831 try self.base.file.?.pwriteAll(&[_]u8{0}, max_file_offset);
832832 }
833
834 if (self.zig_module_index == null) {
835 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
836 self.files.set(index, .{ .zig_module = .{ .index = index } });
837 self.zig_module_index = index;
838 }
833839}
834840
835841pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
......@@ -967,12 +973,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
967973 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
968974 _ = module;
969975
970 self.zig_module_index = blk: {
971 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
972 self.files.set(index, .{ .zig_module = .{ .index = index } });
973 break :blk index;
974 };
975
976976 self.linker_defined_index = blk: {
977977 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
978978 self.files.set(index, .{ .linker_defined = .{ .index = index } });
......@@ -980,6 +980,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
980980 };
981981
982982 std.debug.print("{}\n", .{self.dumpState()});
983 return error.FlushFailure;
983984
984985 // if (self.lazy_syms.getPtr(.none)) |metadata| {
985986 // // Most lazy symbols can be updated on first use, but
......@@ -2078,78 +2079,21 @@ fn writeElfHeader(self: *Elf) !void {
20782079 try self.base.file.?.pwriteAll(hdr_buf[0..index], 0);
20792080}
20802081
2081fn freeAtom(self: *Elf, atom_index: Atom.Index) void {
2082 const atom_ptr = self.atom(atom_index);
2083 log.debug("freeAtom {d} ({s})", .{ atom_index, atom_ptr.name(self) });
2084
2085 Atom.freeRelocations(self, atom_index);
2086
2087 const gpa = self.base.allocator;
2088 const shndx = atom_ptr.symbol(self).st_shndx;
2089 const free_list = &self.sections.items(.free_list)[shndx];
2090 var already_have_free_list_node = false;
2091 {
2092 var i: usize = 0;
2093 // TODO turn free_list into a hash map
2094 while (i < free_list.items.len) {
2095 if (free_list.items[i] == atom_index) {
2096 _ = free_list.swapRemove(i);
2097 continue;
2098 }
2099 if (free_list.items[i] == atom_ptr.prev_index) {
2100 already_have_free_list_node = true;
2101 }
2102 i += 1;
2103 }
2104 }
2105
2106 const maybe_last_atom_index = &self.sections.items(.last_atom_index)[shndx];
2107 if (maybe_last_atom_index.*) |last_atom_index| {
2108 if (last_atom_index == atom_index) {
2109 if (atom_ptr.prev_index) |prev_index| {
2110 // TODO shrink the section size here
2111 maybe_last_atom_index.* = prev_index;
2112 } else {
2113 maybe_last_atom_index.* = null;
2114 }
2115 }
2116 }
2117
2118 if (atom_ptr.prev_index) |prev_index| {
2119 const prev = self.atom(prev_index);
2120 prev.next_index = atom_ptr.next_index;
2121
2122 if (!already_have_free_list_node and prev.*.freeListEligible(self)) {
2123 // The free list is heuristics, it doesn't have to be perfect, so we can
2124 // ignore the OOM here.
2125 free_list.append(gpa, prev_index) catch {};
2126 }
2127 } else {
2128 atom_ptr.prev_index = null;
2129 }
2130
2131 if (atom_ptr.next_index) |next_index| {
2132 self.atom(next_index).prev_index = atom_ptr.prev_index;
2133 } else {
2134 atom_ptr.next_index = null;
2082fn freeUnnamedConsts(self: *Elf, decl_index: Module.Decl.Index) void {
2083 const unnamed_consts = self.unnamed_consts.getPtr(decl_index) orelse return;
2084 for (unnamed_consts.items) |sym_index| {
2085 self.freeDeclMetadata(sym_index);
21352086 }
2087 unnamed_consts.clearAndFree(self.base.allocator);
2088}
21362089
2137 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
2138 const sym_index = atom_ptr.symbolIndex().?;
2139
2090fn freeDeclMetadata(self: *Elf, sym_index: Symbol.Index) void {
2091 const sym = self.symbol(sym_index);
2092 sym.atom(self).?.free(self);
21402093 log.debug("adding %{d} to local symbols free list", .{sym_index});
2141 self.symbols_free_list.append(gpa, sym_index) catch {};
2094 self.symbols_free_list.append(self.base.allocator, sym_index) catch {};
21422095 self.symbols.items[sym_index] = .{};
2143 atom_ptr.sym_index = 0;
2144 self.got_table.freeEntry(gpa, sym_index);
2145}
2146
2147fn freeUnnamedConsts(self: *Elf, decl_index: Module.Decl.Index) void {
2148 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
2149 for (unnamed_consts.items) |atom_index| {
2150 self.freeAtom(atom_index);
2151 }
2152 unnamed_consts.clearAndFree(self.base.allocator);
2096 self.got_table.freeEntry(self.base.allocator, sym_index);
21532097}
21542098
21552099pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
......@@ -2162,7 +2106,8 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
21622106
21632107 if (self.decls.fetchRemove(decl_index)) |const_kv| {
21642108 var kv = const_kv;
2165 self.freeAtom(kv.value.atom);
2109 const sym_index = kv.value.symbol_index;
2110 self.freeDeclMetadata(sym_index);
21662111 self.freeUnnamedConsts(decl_index);
21672112 kv.value.exports.deinit(self.base.allocator);
21682113 }
......@@ -2196,7 +2141,7 @@ pub fn getOrCreateMetadataForLazySymbol(self: *Elf, sym: link.File.LazySymbol) !
21962141 .code => self.text_section_index.?,
21972142 .const_data => self.rodata_section_index.?,
21982143 }, self),
2199 .pending_flush => return metadata.atom.*,
2144 .pending_flush => return metadata.symbol_index.*,
22002145 .flushed => {},
22012146 }
22022147 metadata.state.* = .pending_flush;
......@@ -2271,6 +2216,7 @@ fn updateDeclCode(
22712216 esym.st_size = code.len;
22722217
22732218 const old_size = atom_ptr.size;
2219 const old_vaddr = atom_ptr.value;
22742220 atom_ptr.alignment = math.log2_int(u64, required_alignment);
22752221 atom_ptr.size = code.len;
22762222
......@@ -2278,11 +2224,11 @@ fn updateDeclCode(
22782224 const capacity = atom_ptr.capacity(self);
22792225 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);
22802226 if (need_realloc) {
2281 const vaddr = try atom_ptr.grow(self);
2282 log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, sym.value, vaddr });
2283 if (vaddr != sym.value) {
2284 sym.value = vaddr;
2285 esym.st_value = vaddr;
2227 try atom_ptr.grow(self);
2228 log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, old_vaddr, atom_ptr.value });
2229 if (old_vaddr != atom_ptr.value) {
2230 sym.value = atom_ptr.value;
2231 esym.st_value = atom_ptr.value;
22862232
22872233 log.debug(" (writing new offset table entry)", .{});
22882234 const got_entry_index = self.got_table.lookup.get(sym_index).?;
......@@ -2293,12 +2239,16 @@ fn updateDeclCode(
22932239 atom_ptr.shrink(self);
22942240 }
22952241 } else {
2296 const vaddr = try atom_ptr.allocate(self);
2297 errdefer self.freeAtom(atom_ptr);
2298 log.debug("allocated text block for {s} at 0x{x}", .{ decl_name, vaddr });
2242 try atom_ptr.allocate(self);
2243 errdefer self.freeDeclMetadata(sym_index);
2244 log.debug("allocated atom for {s} at 0x{x} to 0x{x}", .{
2245 decl_name,
2246 atom_ptr.value,
2247 atom_ptr.value + atom_ptr.size,
2248 });
22992249
2300 sym.value = vaddr;
2301 esym.st_value = vaddr;
2250 sym.value = atom_ptr.value;
2251 esym.st_value = atom_ptr.value;
23022252
23032253 const got_entry_index = try sym.getOrCreateOffsetTableEntry(self);
23042254 try self.writeOffsetTableEntry(got_entry_index);
......@@ -2518,17 +2468,23 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.
25182468 const atom_ptr = local_sym.atom(self).?;
25192469 atom_ptr.alignment = math.log2_int(u64, required_alignment);
25202470 atom_ptr.size = code.len;
2521 const vaddr = try atom_ptr.allocate(self);
2522 errdefer self.freeAtom(atom_ptr);
2523 log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr });
25242471
2525 local_sym.value = vaddr;
2526 local_esym.st_value = vaddr;
2472 try atom_ptr.allocate(self);
2473 errdefer self.freeDeclMetadata(symbol_index);
2474
2475 log.debug("allocated atom for {s} at 0x{x} to 0x{x}", .{
2476 name,
2477 atom_ptr.value,
2478 atom_ptr.value + atom_ptr.size,
2479 });
2480
2481 local_sym.value = atom_ptr.value;
2482 local_esym.st_value = atom_ptr.value;
25272483
25282484 const got_entry_index = try local_sym.getOrCreateOffsetTableEntry(self);
25292485 try self.writeOffsetTableEntry(got_entry_index);
25302486
2531 const section_offset = vaddr - self.program_headers.items[phdr_index].p_vaddr;
2487 const section_offset = atom_ptr.value - self.program_headers.items[phdr_index].p_vaddr;
25322488 const file_offset = self.sections.items(.shdr)[local_sym.output_section_index].sh_offset + section_offset;
25332489 try self.base.file.?.pwriteAll(code, file_offset);
25342490}
......@@ -2540,7 +2496,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
25402496 defer code_buffer.deinit();
25412497
25422498 const mod = self.base.options.module.?;
2543 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
2499 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);
25442500 if (!gop.found_existing) {
25452501 gop.value_ptr.* = .{};
25462502 }
......@@ -2586,17 +2542,18 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
25862542 const atom_ptr = local_sym.atom(self).?;
25872543 atom_ptr.alignment = math.log2_int(u64, required_alignment);
25882544 atom_ptr.size = code.len;
2589 const vaddr = try atom_ptr.allocateAtom(self);
2590 errdefer self.freeAtom(atom_ptr);
25912545
2592 log.debug("allocated text block for {s} at 0x{x}", .{ name, local_sym.st_value });
2546 try atom_ptr.allocate(self);
2547 errdefer self.freeDeclMetadata(sym_index);
2548
2549 log.debug("allocated atom for {s} at 0x{x} to 0x{x}", .{ name, atom_ptr.value, atom_ptr.value + atom_ptr.size });
25932550
2594 local_sym.value = vaddr;
2595 local_esym.st_value = vaddr;
2551 local_sym.value = atom_ptr.value;
2552 local_esym.st_value = atom_ptr.value;
25962553
25972554 try unnamed_consts.append(gpa, atom_ptr.atom_index);
25982555
2599 const section_offset = local_sym.value - self.program_headers.items[phdr_index].p_vaddr;
2556 const section_offset = atom_ptr.value - self.program_headers.items[phdr_index].p_vaddr;
26002557 const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset;
26012558 try self.base.file.?.pwriteAll(code, file_offset);
26022559
......@@ -2624,7 +2581,7 @@ pub fn updateDeclExports(
26242581 const decl = mod.declPtr(decl_index);
26252582 const decl_sym_index = try self.getOrCreateMetadataForDecl(decl_index);
26262583 const decl_sym = self.symbol(decl_sym_index);
2627 const decl_esym = symbol.sourceSymbol(self);
2584 const decl_esym = decl_sym.sourceSymbol(self);
26282585 const decl_metadata = self.decls.getPtr(decl_index).?;
26292586
26302587 for (exports) |exp| {
......@@ -2658,7 +2615,7 @@ pub fn updateDeclExports(
26582615 continue;
26592616 },
26602617 };
2661 const stt_bits: u8 = @as(u4, @truncate(decl_sym.st_info));
2618 const stt_bits: u8 = @as(u4, @truncate(decl_esym.st_info));
26622619
26632620 const sym_index = if (decl_metadata.@"export"(self, exp_name)) |exp_index| exp_index.* else blk: {
26642621 const zig_module = self.file(self.zig_module_index.?).?.zig_module;
......@@ -3220,7 +3177,7 @@ pub fn addSymbol(self: *Elf) !Symbol.Index {
32203177 break :blk index;
32213178 }
32223179 };
3223 self.symbols.items[index] = .{ .symbol_index = index };
3180 self.symbols.items[index] = .{ .index = index };
32243181 return index;
32253182}
32263183
src/link/Elf/Atom.zig+64-7
......@@ -79,7 +79,7 @@ pub fn freeRelocations(elf_file: *Elf, atom_index: Index) void {
7979 if (removed_relocs) |*relocs| relocs.value.deinit(elf_file.base.allocator);
8080}
8181
82pub fn allocate(self: *Atom, elf_file: *Elf) !u64 {
82pub fn allocate(self: *Atom, elf_file: *Elf) !void {
8383 const phdr_index = elf_file.sections.items(.phdr_index)[self.output_section_index];
8484 const phdr = &elf_file.program_headers.items[phdr_index];
8585 const shdr = &elf_file.sections.items(.shdr)[self.output_section_index];
......@@ -98,7 +98,7 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !u64 {
9898
9999 // First we look for an appropriately sized free list node.
100100 // The list is unordered. We'll just take the first thing that works.
101 const vaddr = blk: {
101 self.value = blk: {
102102 var i: usize = if (elf_file.base.child_pid == null) 0 else free_list.items.len;
103103 while (i < free_list.items.len) {
104104 const big_atom_index = free_list.items[i];
......@@ -152,7 +152,7 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !u64 {
152152 else
153153 true;
154154 if (expand_section) {
155 const needed_size = (vaddr + self.size) - phdr.p_vaddr;
155 const needed_size = (self.value + self.size) - phdr.p_vaddr;
156156 try elf_file.growAllocSection(self.output_section_index, needed_size);
157157 maybe_last_atom_index.* = self.atom_index;
158158
......@@ -193,7 +193,6 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !u64 {
193193 if (free_list_removal) |i| {
194194 _ = free_list.swapRemove(i);
195195 }
196 return vaddr;
197196}
198197
199198pub fn shrink(self: *Atom, elf_file: *Elf) void {
......@@ -201,12 +200,69 @@ pub fn shrink(self: *Atom, elf_file: *Elf) void {
201200 _ = elf_file;
202201}
203202
204pub fn grow(self: *Atom, elf_file: *Elf) !u64 {
203pub fn grow(self: *Atom, elf_file: *Elf) !void {
205204 const alignment = try std.math.powi(u64, 2, self.alignment);
206205 const align_ok = std.mem.alignBackward(u64, self.value, alignment) == self.value;
207206 const need_realloc = !align_ok or self.size > self.capacity(elf_file);
208 if (!need_realloc) return self.value;
209 return self.allocate(elf_file);
207 if (need_realloc) try self.allocate(elf_file);
208}
209
210pub fn free(self: *Atom, elf_file: *Elf) void {
211 log.debug("freeAtom {d} ({s})", .{ self.atom_index, self.name(elf_file) });
212
213 Atom.freeRelocations(elf_file, self.atom_index);
214
215 const gpa = elf_file.base.allocator;
216 const shndx = self.output_section_index;
217 const free_list = &elf_file.sections.items(.free_list)[shndx];
218 var already_have_free_list_node = false;
219 {
220 var i: usize = 0;
221 // TODO turn free_list into a hash map
222 while (i < free_list.items.len) {
223 if (free_list.items[i] == self.atom_index) {
224 _ = free_list.swapRemove(i);
225 continue;
226 }
227 if (free_list.items[i] == self.prev_index) {
228 already_have_free_list_node = true;
229 }
230 i += 1;
231 }
232 }
233
234 const maybe_last_atom_index = &elf_file.sections.items(.last_atom_index)[shndx];
235 if (maybe_last_atom_index.*) |last_atom_index| {
236 if (last_atom_index == self.atom_index) {
237 if (self.prev_index) |prev_index| {
238 // TODO shrink the section size here
239 maybe_last_atom_index.* = prev_index;
240 } else {
241 maybe_last_atom_index.* = null;
242 }
243 }
244 }
245
246 if (self.prev_index) |prev_index| {
247 const prev = elf_file.atom(prev_index);
248 prev.next_index = self.next_index;
249
250 if (!already_have_free_list_node and prev.*.freeListEligible(elf_file)) {
251 // The free list is heuristics, it doesn't have to be perfect, so we can
252 // ignore the OOM here.
253 free_list.append(gpa, prev_index) catch {};
254 }
255 } else {
256 self.prev_index = null;
257 }
258
259 if (self.next_index) |next_index| {
260 elf_file.atom(next_index).prev_index = self.prev_index;
261 } else {
262 self.next_index = null;
263 }
264
265 self.* = .{};
210266}
211267
212268pub const Index = u32;
......@@ -221,6 +277,7 @@ pub const Reloc = struct {
221277const std = @import("std");
222278const assert = std.debug.assert;
223279const elf = std.elf;
280const log = std.log.scoped(.link);
224281
225282const Atom = @This();
226283const Elf = @import("../Elf.zig");
src/link/Elf/Symbol.zig+13-7
......@@ -1,5 +1,7 @@
11//! Represents a defined symbol.
22
3index: Index = 0,
4
35/// Allocated address value of this symbol.
46value: u64 = 0,
57
......@@ -18,8 +20,8 @@ atom_index: Atom.Index = 0,
1820output_section_index: u16 = 0,
1921
2022/// Index of the source symbol this symbol references.
21/// Use `getSourceSymbol` to pull the source symbol from the relevant file.
22symbol_index: Index = 0,
23/// Use `sourceSymbol` to pull the source symbol from the relevant file.
24esym_index: Index = 0,
2325
2426/// Index of the source version symbol this symbol references if any.
2527/// If the symbol is unversioned it will have either VER_NDX_LOCAL or VER_NDX_GLOBAL.
......@@ -64,7 +66,11 @@ pub fn file(symbol: Symbol, elf_file: *Elf) ?File {
6466}
6567
6668pub fn sourceSymbol(symbol: Symbol, elf_file: *Elf) *elf.Elf64_Sym {
67 return symbol.file(elf_file).?.sourceSymbol(symbol.symbol_index);
69 const file_ptr = symbol.file(elf_file).?;
70 switch (file_ptr) {
71 .zig_module => return file_ptr.zig_module.sourceSymbol(symbol.index, elf_file),
72 .linker_defined => return file_ptr.linker_defined.sourceSymbol(symbol.esym_index),
73 }
6874}
6975
7076pub fn symbolRank(symbol: Symbol, elf_file: *Elf) u32 {
......@@ -80,14 +86,14 @@ pub fn symbolRank(symbol: Symbol, elf_file: *Elf) u32 {
8086/// If entry already exists, returns index to it.
8187/// Otherwise, creates a new entry in the Global Offset Table for this Symbol.
8288pub fn getOrCreateOffsetTableEntry(self: Symbol, elf_file: *Elf) !Symbol.Index {
83 if (elf_file.got_table.lookup.get(self.symbol_index)) |index| return index;
84 const index = try elf_file.got_table.allocateEntry(elf_file.base.allocator, self.symbol_index);
89 if (elf_file.got_table.lookup.get(self.index)) |index| return index;
90 const index = try elf_file.got_table.allocateEntry(elf_file.base.allocator, self.index);
8591 elf_file.got_table_count_dirty = true;
8692 return index;
8793}
8894
8995pub fn getOffsetTableAddress(self: Symbol, elf_file: *Elf) u64 {
90 const got_entry_index = elf_file.got_table.lookup.get(self.symbol_index).?;
96 const got_entry_index = elf_file.got_table.lookup.get(self.index).?;
9197 const target = elf_file.base.options.target;
9298 const ptr_bits = target.ptrBitWidth();
9399 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
......@@ -263,7 +269,7 @@ fn format2(
263269 _ = options;
264270 _ = unused_fmt_string;
265271 const symbol = ctx.symbol;
266 try writer.print("%{d} : {s} : @{x}", .{ symbol.symbol_index, symbol.fmtName(ctx.elf_file), symbol.value });
272 try writer.print("%{d} : {s} : @{x}", .{ symbol.index, symbol.fmtName(ctx.elf_file), symbol.value });
267273 if (symbol.file(ctx.elf_file)) |file_ptr| {
268274 if (symbol.isAbs(ctx.elf_file)) {
269275 if (symbol.sourceSymbol(ctx.elf_file).st_shndx == elf.SHN_UNDEF) {
src/link/Elf/ZigModule.zig+9-3
......@@ -33,6 +33,7 @@ pub fn createAtom(self: *ZigModule, output_section_index: u16, elf_file: *Elf) !
3333 symbol_ptr.file_index = self.index;
3434 symbol_ptr.atom_index = atom_index;
3535 symbol_ptr.output_section_index = output_section_index;
36 symbol_ptr.esym_index = @as(Symbol.Index, @intCast(self.elf_local_symbols.items.len));
3637
3738 const local_esym = try self.elf_local_symbols.addOne(gpa);
3839 local_esym.* = .{
......@@ -55,6 +56,7 @@ pub fn addGlobal(self: *ZigModule, name: [:0]const u8, elf_file: *Elf) !Symbol.I
5556 try self.elf_global_symbols.ensureUnusedCapacity(gpa, 1);
5657 try self.global_symbols.ensureUnusedCapacity(gpa, 1);
5758 const off = try elf_file.strtab.insert(gpa, name);
59 const esym_index = @as(Symbol.Index, @intCast(self.elf_global_symbols.items.len));
5860 self.elf_global_symbols.appendAssumeCapacity(.{
5961 .st_name = off,
6062 .st_info = elf.STB_GLOBAL << 4,
......@@ -64,14 +66,18 @@ pub fn addGlobal(self: *ZigModule, name: [:0]const u8, elf_file: *Elf) !Symbol.I
6466 .st_size = 0,
6567 });
6668 const gop = try elf_file.getOrPutGlobal(off);
69 const sym = elf_file.symbol(gop.index);
70 sym.file_index = self.index;
71 sym.esym_index = esym_index;
6772 self.global_symbols.putAssumeCapacityNoClobber(gop.index, {});
6873 return gop.index;
6974}
7075
71pub fn sourceSymbol(self: *ZigModule, symbol_index: Symbol.Index) *elf.Elf64_Sym {
72 if (self.local_symbols.get(symbol_index)) |_| return &self.elf_local_symbols.items[symbol_index];
76pub fn sourceSymbol(self: *ZigModule, symbol_index: Symbol.Index, elf_file: *Elf) *elf.Elf64_Sym {
77 const sym = elf_file.symbol(symbol_index);
78 if (self.local_symbols.get(symbol_index)) |_| return &self.elf_local_symbols.items[sym.esym_index];
7379 assert(self.global_symbols.get(symbol_index) != null);
74 return &self.elf_global_symbols.items[symbol_index];
80 return &self.elf_global_symbols.items[sym.esym_index];
7581}
7682
7783pub fn locals(self: *ZigModule) []const Symbol.Index {
src/link/Elf/file.zig-6
......@@ -10,12 +10,6 @@ pub const File = union(enum) {
1010 };
1111 }
1212
13 pub fn sourceSymbol(file: File, symbol_index: Symbol.Index) *elf.Elf64_Sym {
14 return switch (file) {
15 inline else => |x| x.sourceSymbol(symbol_index),
16 };
17 }
18
1913 pub fn fmtPath(file: File) std.fmt.Formatter(formatPath) {
2014 return .{ .data = file };
2115 }