authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-31 16:30:45+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-07 10:21:02+02:00
logde80e4fec2a29c5aac70c8d72b11a90cb96feeaf
treea5f0015e29bec5c87a75c1c3e2a1c6404aeca946
parent9fe69cc0b588ff96075854d687f3fce3d4457258

elf: move symbol ownership to LinkerDefined


2 files changed, 237 insertions(+), 142 deletions(-)

src/link/Elf/LinkerDefined.zig+235-140
......@@ -2,7 +2,10 @@ index: File.Index,
22
33symtab: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
44strtab: std.ArrayListUnmanaged(u8) = .{},
5symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
5
6symbols: std.ArrayListUnmanaged(Symbol) = .{},
7symbols_extra: std.ArrayListUnmanaged(u32) = .{},
8symbols_resolver: std.ArrayListUnmanaged(Elf.SymbolResolver.Index) = .{},
69
710entry_index: ?Symbol.Index = null,
811dynamic_index: ?Symbol.Index = null,
......@@ -29,6 +32,8 @@ pub fn deinit(self: *LinkerDefined, allocator: Allocator) void {
2932 self.symtab.deinit(allocator);
3033 self.strtab.deinit(allocator);
3134 self.symbols.deinit(allocator);
35 self.symbols_extra.deinit(allocator);
36 self.symbols_resolver.deinit(allocator);
3237 self.start_stop_indexes.deinit(allocator);
3338}
3439
......@@ -38,85 +43,137 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void {
3843}
3944
4045pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
46 const newSymbolAssumeCapacity = struct {
47 fn newSymbolAssumeCapacity(ld: *LinkerDefined, name_off: u32) Symbol.Index {
48 const esym_index: u32 = @intCast(ld.symtab.items.len);
49 const esym = ld.symtab.addOneAssumeCapacity();
50 esym.* = .{
51 .st_name = name_off,
52 .st_info = elf.STB_GLOBAL << 4,
53 .st_other = @intFromEnum(elf.STV.HIDDEN),
54 .st_shndx = elf.SHN_ABS,
55 .st_value = 0,
56 .st_size = 0,
57 };
58 const index = ld.addSymbolAssumeCapacity();
59 const symbol = &ld.symbols.items[index];
60 symbol.name_offset = name_off;
61 symbol.extra_index = ld.addSymbolExtraAssumeCapacity(.{});
62 symbol.ref = .{ .index = 0, .file = 0 };
63 symbol.esym_index = esym_index;
64 symbol.version_index = elf_file.default_sym_version;
65 }
66 }.newSymbolAssumeCapacity;
67
4168 const gpa = elf_file.base.comp.gpa;
4269
43 if (elf_file.entry_name) |name| {
44 self.entry_index = try self.addGlobal(name, elf_file);
70 var nsyms: usize = 0;
71 if (elf_file.entry_name) |_| {
72 nsyms += 1; // entry
4573 }
46
47 self.dynamic_index = try self.addGlobal("_DYNAMIC", elf_file);
48 self.ehdr_start_index = try self.addGlobal("__ehdr_start", elf_file);
49 self.init_array_start_index = try self.addGlobal("__init_array_start", elf_file);
50 self.init_array_end_index = try self.addGlobal("__init_array_end", elf_file);
51 self.fini_array_start_index = try self.addGlobal("__fini_array_start", elf_file);
52 self.fini_array_end_index = try self.addGlobal("__fini_array_end", elf_file);
53 self.preinit_array_start_index = try self.addGlobal("__preinit_array_start", elf_file);
54 self.preinit_array_end_index = try self.addGlobal("__preinit_array_end", elf_file);
55 self.got_index = try self.addGlobal("_GLOBAL_OFFSET_TABLE_", elf_file);
56 self.plt_index = try self.addGlobal("_PROCEDURE_LINKAGE_TABLE_", elf_file);
57 self.end_index = try self.addGlobal("_end", elf_file);
58
74 nsyms += 1; // _DYNAMIC
75 nsyms += 1; // __ehdr_start
76 nsyms += 1; // __init_array_start
77 nsyms += 1; // __init_array_end
78 nsyms += 1; // __fini_array_start
79 nsyms += 1; // __fini_array_end
80 nsyms += 1; // __preinit_array_start
81 nsyms += 1; // __preinit_array_end
82 nsyms += 1; // _GLOBAL_OFFSET_TABLE_
83 nsyms += 1; // _PROCEDURE_LINKAGE_TABLE_
84 nsyms += 1; // _end
5985 if (elf_file.base.comp.link_eh_frame_hdr) {
60 self.gnu_eh_frame_hdr_index = try self.addGlobal("__GNU_EH_FRAME_HDR", elf_file);
86 nsyms += 1; // __GNU_EH_FRAME_HDR
87 }
88 nsyms += 1; // __dso_handle
89 nsyms += 1; // __rela_iplt_start
90 nsyms += 1; // __rela_iplt_end
91 if (elf_file.getTarget().cpu.arch.isRISCV() and elf_file.isEffectivelyDynLib()) {
92 nsyms += 1; // __global_pointer$
6193 }
6294
63 self.dso_handle_index = try self.addGlobal("__dso_handle", elf_file);
64 self.rela_iplt_start_index = try self.addGlobal("__rela_iplt_start", elf_file);
65 self.rela_iplt_end_index = try self.addGlobal("__rela_iplt_end", elf_file);
95 var start_stop_count: usize = 0;
96 for (elf_file.objects.items) |index| {
97 for (elf_file.file(index).?.object.shdrs.items) |shdr| {
98 if (elf_file.getStartStopBasename(shdr)) |_| {
99 start_stop_count += 2; // __start_, __stop_
100 }
101 }
102 }
103 nsyms += start_stop_count;
66104
67 for (elf_file.shdrs.items) |shdr| {
68 if (elf_file.getStartStopBasename(shdr)) |name| {
69 try self.start_stop_indexes.ensureUnusedCapacity(gpa, 2);
105 try self.start_stop_indexes.ensureTotalCapacityPrecise(gpa, start_stop_count);
106 try self.symtab.ensureTotalCapacityPrecise(gpa, nsyms);
107 try self.symbols.ensureTotalCapacityPrecise(gpa, nsyms);
108 try self.symbols_extra.ensureTotalCapacityPrecise(gpa, nsyms * @sizeOf(Symbol.Extra));
109 try self.symbols_resolver.ensureTotalCapacityPrecise(gpa, nsyms);
110 self.symbols_resolver.resize(gpa, nsyms) catch unreachable;
111 @memset(self.symbols_resolver.items, 0);
70112
71 const start = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
72 defer gpa.free(start);
73 const stop = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name});
74 defer gpa.free(stop);
113 if (elf_file.entry_name) |name| {
114 self.entry_index = newSymbolAssumeCapacity(self, try self.addString(gpa, name));
115 }
75116
76 self.start_stop_indexes.appendAssumeCapacity(try self.addGlobal(start, elf_file));
77 self.start_stop_indexes.appendAssumeCapacity(try self.addGlobal(stop, elf_file));
78 }
117 self.dynamic_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_DYNAMIC"));
118 self.ehdr_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__ehdr_start"));
119 self.init_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_start"));
120 self.init_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_end"));
121 self.fini_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_start"));
122 self.fini_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_end"));
123 self.preinit_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_start"));
124 self.preinit_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_end"));
125 self.got_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"));
126 self.plt_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"));
127 self.end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_end"));
128
129 if (elf_file.base.comp.link_eh_frame_hdr) {
130 self.gnu_eh_frame_hdr_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__GNU_EH_FRAME_HDR"));
79131 }
80132
133 self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__dso_handle"));
134 self.rela_iplt_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_start"));
135 self.rela_iplt_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_end"));
136
81137 if (elf_file.getTarget().cpu.arch.isRISCV() and elf_file.isEffectivelyDynLib()) {
82 self.global_pointer_index = try self.addGlobal("__global_pointer$", elf_file);
138 self.global_pointer_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__global_pointer$"));
83139 }
84}
85140
86fn addGlobal(self: *LinkerDefined, name: []const u8, elf_file: *Elf) !u32 {
87 const comp = elf_file.base.comp;
88 const gpa = comp.gpa;
89 try self.symtab.ensureUnusedCapacity(gpa, 1);
90 try self.symbols.ensureUnusedCapacity(gpa, 1);
91 const name_off = @as(u32, @intCast(self.strtab.items.len));
92 try self.strtab.writer(gpa).print("{s}\x00", .{name});
93 self.symtab.appendAssumeCapacity(.{
94 .st_name = name_off,
95 .st_info = elf.STB_GLOBAL << 4,
96 .st_other = @intFromEnum(elf.STV.HIDDEN),
97 .st_shndx = elf.SHN_ABS,
98 .st_value = 0,
99 .st_size = 0,
100 });
101 const gop = try elf_file.getOrPutGlobal(name);
102 self.symbols.addOneAssumeCapacity().* = gop.index;
103 return gop.index;
141 for (elf_file.objects.items) |index| {
142 for (elf_file.file(index).?.object.shdrs.items) |shdr| {
143 if (elf_file.getStartStopBasename(shdr)) |name| {
144 const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
145 defer gpa.free(start_name);
146 const stop_name = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name});
147 defer gpa.free(stop_name);
148 const start = newSymbolAssumeCapacity(self, try self.addString(gpa, start_name));
149 const stop = newSymbolAssumeCapacity(self, try self.addString(gpa, stop_name));
150 self.start_stop_indexes.appendSliceAssumeCapacity(&.{ start, stop });
151 }
152 }
153 }
104154}
105155
106pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) void {
107 for (self.symbols.items, 0..) |index, i| {
108 const sym_idx = @as(Symbol.Index, @intCast(i));
109 const this_sym = self.symtab.items[sym_idx];
156pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
157 const gpa = elf_file.base.comp.gpa;
158
159 for (self.symtab.items, self.symbols_resolver.items, 0..) |esym, *resolv, i| {
160 const gop = try elf_file.resolver.getOrPut(gpa, .{
161 .index = @intCast(i),
162 .file = self.index,
163 }, elf_file);
164 if (!gop.found_existing) {
165 gop.ref.* = .{ .index = 0, .file = 0 };
166 }
167 resolv.* = gop.index;
110168
111 if (this_sym.st_shndx == elf.SHN_UNDEF) continue;
169 if (esym.st_shndx == elf.SHN_UNDEF) continue;
170 if (elf_file.symbol(gop.ref.*) == null) {
171 gop.ref.* = .{ .index = @intCast(i), .file = self.index };
172 continue;
173 }
112174
113 const global = elf_file.symbol(index);
114 if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) {
115 global.value = 0;
116 global.ref = .{ .index = 0, .file = 0 };
117 global.file_index = self.index;
118 global.esym_index = sym_idx;
119 global.version_index = elf_file.default_sym_version;
175 if (self.asFile().symbolRank(esym, false) < elf_file.symbol(gop.ref.*).?.symbolRank(elf_file)) {
176 gop.ref.* = .{ .index = @intCast(i), .file = self.index };
120177 }
121178 }
122179}
......@@ -125,93 +182,73 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
125182 const comp = elf_file.base.comp;
126183 const link_mode = comp.config.link_mode;
127184
185 const allocSymbol = struct {
186 fn allocSymbol(ld: *LinkerDefined, index: Symbol.Index, value: u64, osec: u32, ef: *Elf) void {
187 const sym = ef.symbol(ld.resolveSymbol(index, ef)).?;
188 sym.value = @intCast(value);
189 sym.output_section_index = osec;
190 }
191 }.allocSymbol;
192
128193 // _DYNAMIC
129194 if (elf_file.dynamic_section_index) |shndx| {
130195 const shdr = &elf_file.shdrs.items[shndx];
131 const symbol_ptr = elf_file.symbol(self.dynamic_index.?);
132 symbol_ptr.value = @intCast(shdr.sh_addr);
133 symbol_ptr.output_section_index = shndx;
196 allocSymbol(self, self.dynamic_index.?, shdr.sh_addr, shndx, elf_file);
134197 }
135198
136199 // __ehdr_start
137 {
138 const symbol_ptr = elf_file.symbol(self.ehdr_start_index.?);
139 symbol_ptr.value = @intCast(elf_file.image_base);
140 symbol_ptr.output_section_index = 1;
141 }
200 allocSymbol(self, self.ehdr_start_index.?, elf_file.image_base, 1, elf_file);
142201
143202 // __init_array_start, __init_array_end
144203 if (elf_file.sectionByName(".init_array")) |shndx| {
145 const start_sym = elf_file.symbol(self.init_array_start_index.?);
146 const end_sym = elf_file.symbol(self.init_array_end_index.?);
147204 const shdr = &elf_file.shdrs.items[shndx];
148 start_sym.output_section_index = shndx;
149 start_sym.value = @intCast(shdr.sh_addr);
150 end_sym.output_section_index = shndx;
151 end_sym.value = @intCast(shdr.sh_addr + shdr.sh_size);
205 allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file);
206 allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
152207 }
153208
154209 // __fini_array_start, __fini_array_end
155210 if (elf_file.sectionByName(".fini_array")) |shndx| {
156 const start_sym = elf_file.symbol(self.fini_array_start_index.?);
157 const end_sym = elf_file.symbol(self.fini_array_end_index.?);
158211 const shdr = &elf_file.shdrs.items[shndx];
159 start_sym.output_section_index = shndx;
160 start_sym.value = @intCast(shdr.sh_addr);
161 end_sym.output_section_index = shndx;
162 end_sym.value = @intCast(shdr.sh_addr + shdr.sh_size);
212 allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file);
213 allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
163214 }
164215
165216 // __preinit_array_start, __preinit_array_end
166217 if (elf_file.sectionByName(".preinit_array")) |shndx| {
167 const start_sym = elf_file.symbol(self.preinit_array_start_index.?);
168 const end_sym = elf_file.symbol(self.preinit_array_end_index.?);
169218 const shdr = &elf_file.shdrs.items[shndx];
170 start_sym.output_section_index = shndx;
171 start_sym.value = @intCast(shdr.sh_addr);
172 end_sym.output_section_index = shndx;
173 end_sym.value = @intCast(shdr.sh_addr + shdr.sh_size);
219 allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file);
220 allocSymbol(self, self.preinit_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
174221 }
175222
176223 // _GLOBAL_OFFSET_TABLE_
177224 if (elf_file.getTarget().cpu.arch == .x86_64) {
178225 if (elf_file.got_plt_section_index) |shndx| {
179226 const shdr = elf_file.shdrs.items[shndx];
180 const sym = elf_file.symbol(self.got_index.?);
181 sym.value = @intCast(shdr.sh_addr);
182 sym.output_section_index = shndx;
227 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
183228 }
184229 } else {
185230 if (elf_file.got_section_index) |shndx| {
186231 const shdr = elf_file.shdrs.items[shndx];
187 const sym = elf_file.symbol(self.got_index.?);
188 sym.value = @intCast(shdr.sh_addr);
189 sym.output_section_index = shndx;
232 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
190233 }
191234 }
192235
193236 // _PROCEDURE_LINKAGE_TABLE_
194237 if (elf_file.plt_section_index) |shndx| {
195238 const shdr = &elf_file.shdrs.items[shndx];
196 const symbol_ptr = elf_file.symbol(self.plt_index.?);
197 symbol_ptr.value = @intCast(shdr.sh_addr);
198 symbol_ptr.output_section_index = shndx;
239 allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file);
199240 }
200241
201242 // __dso_handle
202243 if (self.dso_handle_index) |index| {
203244 const shdr = &elf_file.shdrs.items[1];
204 const symbol_ptr = elf_file.symbol(index);
205 symbol_ptr.value = @intCast(shdr.sh_addr);
206 symbol_ptr.output_section_index = 0;
245 allocSymbol(self, index, shdr.sh_addr, 0, elf_file);
207246 }
208247
209248 // __GNU_EH_FRAME_HDR
210249 if (elf_file.eh_frame_hdr_section_index) |shndx| {
211250 const shdr = &elf_file.shdrs.items[shndx];
212 const symbol_ptr = elf_file.symbol(self.gnu_eh_frame_hdr_index.?);
213 symbol_ptr.value = @intCast(shdr.sh_addr);
214 symbol_ptr.output_section_index = shndx;
251 allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file);
215252 }
216253
217254 // __rela_iplt_start, __rela_iplt_end
......@@ -220,32 +257,41 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
220257 const shdr = &elf_file.shdrs.items[shndx];
221258 const end_addr = shdr.sh_addr + shdr.sh_size;
222259 const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela);
223 const start_sym = elf_file.symbol(self.rela_iplt_start_index.?);
224 const end_sym = elf_file.symbol(self.rela_iplt_end_index.?);
225 start_sym.value = @intCast(start_addr);
226 start_sym.output_section_index = shndx;
227 end_sym.value = @intCast(end_addr);
228 end_sym.output_section_index = shndx;
260 allocSymbol(self, self.rela_iplt_start_index.?, start_addr, shndx, elf_file);
261 allocSymbol(self, self.rela_iplt_end_index.?, end_addr, shndx, elf_file);
229262 }
230263
231264 // _end
232265 {
233 const end_symbol = elf_file.symbol(self.end_index.?);
266 var value: u64 = 0;
267 var osec: u32 = 0;
234268 for (elf_file.shdrs.items, 0..) |shdr, shndx| {
235269 if (shdr.sh_flags & elf.SHF_ALLOC != 0) {
236 end_symbol.value = @intCast(shdr.sh_addr + shdr.sh_size);
237 end_symbol.output_section_index = @intCast(shndx);
270 value = shdr.sh_addr + shdr.sh_size;
271 osec = shndx;
238272 }
239273 }
274 allocSymbol(self, self.end_index.?, value, osec, elf_file);
275 }
276
277 // __global_pointer$
278 if (self.global_pointer_index) |index| {
279 const value, const osec = if (elf_file.sectionByName(".sdata")) |shndx| .{
280 elf_file.shdrs.items[shndx].sh_addr + 0x800,
281 shndx,
282 } else .{ 0, 0 };
283 allocSymbol(self, index, value, osec, elf_file);
240284 }
241285
242286 // __start_*, __stop_*
243287 {
244288 var index: usize = 0;
245289 while (index < self.start_stop_indexes.items.len) : (index += 2) {
246 const start = elf_file.symbol(self.start_stop_indexes.items[index]);
290 const start_ref = self.resolveSymbol(self.start_stop_indexes.items[index]);
291 const start = elf_file.symbol(start_ref).?;
247292 const name = start.name(elf_file);
248 const stop = elf_file.symbol(self.start_stop_indexes.items[index + 1]);
293 const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1]);
294 const stop = elf_file.symbol(stop_ref).?;
249295 const shndx = elf_file.sectionByName(name["__start_".len..]).?;
250296 const shdr = &elf_file.shdrs.items[shndx];
251297 start.value = @intCast(shdr.sh_addr);
......@@ -254,47 +300,34 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
254300 stop.output_section_index = shndx;
255301 }
256302 }
257
258 // __global_pointer$
259 if (self.global_pointer_index) |index| {
260 const sym = elf_file.symbol(index);
261 if (elf_file.sectionByName(".sdata")) |shndx| {
262 const shdr = elf_file.shdrs.items[shndx];
263 sym.value = @intCast(shdr.sh_addr + 0x800);
264 sym.output_section_index = shndx;
265 } else {
266 sym.value = 0;
267 sym.output_section_index = 0;
268 }
269 }
270303}
271304
272pub fn globals(self: LinkerDefined) []const Symbol.Index {
305pub fn globals(self: *LinkerDefined) []Symbol {
273306 return self.symbols.items;
274307}
275308
276pub fn updateSymtabSize(self: *LinkerDefined, elf_file: *Elf) !void {
277 for (self.globals()) |global_index| {
278 const global = elf_file.symbol(global_index);
279 const file_ptr = global.file(elf_file) orelse continue;
280 if (file_ptr.index() != self.index) continue;
309pub fn updateSymtabSize(self: *LinkerDefined, elf_file: *Elf) void {
310 for (self.globals(), self.symbols_resolver.items) |*global, resolv| {
311 const ref = elf_file.resolver.get(resolv).?;
312 const ref_sym = elf_file.symbol(ref) orelse continue;
313 if (ref_sym.file(elf_file).?.index() != self.index) continue;
281314 global.flags.output_symtab = true;
282315 if (global.isLocal(elf_file)) {
283 try global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
316 global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
284317 self.output_symtab_ctx.nlocals += 1;
285318 } else {
286 try global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
319 global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
287320 self.output_symtab_ctx.nglobals += 1;
288321 }
289322 self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
290323 }
291324}
292325
293pub fn writeSymtab(self: LinkerDefined, elf_file: *Elf) void {
294 for (self.globals()) |global_index| {
295 const global = elf_file.symbol(global_index);
296 const file_ptr = global.file(elf_file) orelse continue;
297 if (file_ptr.index() != self.index) continue;
326pub fn writeSymtab(self: *LinkerDefined, elf_file: *Elf) void {
327 for (self.globals(), self.symbols_resolver.items) |global, resolv| {
328 const ref = elf_file.resolver.get(resolv).?;
329 const ref_sym = elf_file.symbol(ref) orelse continue;
330 if (ref_sym.file(elf_file).?.index() != self.index) continue;
298331 const idx = global.outputSymtabIndex(elf_file) orelse continue;
299332 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
300333 elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
......@@ -309,11 +342,73 @@ pub fn asFile(self: *LinkerDefined) File {
309342 return .{ .linker_defined = self };
310343}
311344
345fn addString(self: *LinkerDefined, allocator: Allocator, str: []const u8) !u32 {
346 const off: u32 = @intCast(self.strtab.items.len);
347 try self.strtab.ensureUnusedCapacity(allocator, str.len + 1);
348 self.strtab.appendSliceAssumeCapacity(str);
349 self.strtab.appendAssumeCapacity(0);
350 return off;
351}
352
312353pub fn getString(self: LinkerDefined, off: u32) [:0]const u8 {
313354 assert(off < self.strtab.items.len);
314355 return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0);
315356}
316357
358pub fn resolveSymbol(self: LinkerDefined, index: Symbol.Index, elf_file: *Elf) Elf.Ref {
359 const resolv = self.symbols_resolver.items[index];
360 return elf_file.resolver.get(resolv).?;
361}
362
363pub fn addSymbol(self: *LinkerDefined, allocator: Allocator) !Symbol.Index {
364 try self.symbols.ensureUnusedCapacity(allocator, 1);
365 const index: Symbol.Index = @intCast(self.symbols.items.len);
366 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
367 return index;
368}
369
370pub fn addSymbolExtra(self: *LinkerDefined, allocator: Allocator, extra: Symbol.Extra) !u32 {
371 const fields = @typeInfo(Symbol.Extra).Struct.fields;
372 try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len);
373 return self.addSymbolExtraAssumeCapacity(extra);
374}
375
376pub fn addSymbolExtraAssumeCapacity(self: *LinkerDefined, extra: Symbol.Extra) u32 {
377 const index = @as(u32, @intCast(self.symbols_extra.items.len));
378 const fields = @typeInfo(Symbol.Extra).Struct.fields;
379 inline for (fields) |field| {
380 self.symbols_extra.appendAssumeCapacity(switch (field.type) {
381 u32 => @field(extra, field.name),
382 else => @compileError("bad field type"),
383 });
384 }
385 return index;
386}
387
388pub fn symbolExtra(self: *LinkerDefined, index: u32) Symbol.Extra {
389 const fields = @typeInfo(Symbol.Extra).Struct.fields;
390 var i: usize = index;
391 var result: Symbol.Extra = undefined;
392 inline for (fields) |field| {
393 @field(result, field.name) = switch (field.type) {
394 u32 => self.symbols_extra.items[i],
395 else => @compileError("bad field type"),
396 };
397 i += 1;
398 }
399 return result;
400}
401
402pub fn setSymbolExtra(self: *LinkerDefined, index: u32, extra: Symbol.Extra) void {
403 const fields = @typeInfo(Symbol.Extra).Struct.fields;
404 inline for (fields, 0..) |field, i| {
405 self.symbols_extra.items[index + i] = switch (field.type) {
406 u32 => @field(extra, field.name),
407 else => @compileError("bad field type"),
408 };
409 }
410}
411
317412pub fn fmtSymtab(self: *LinkerDefined, elf_file: *Elf) std.fmt.Formatter(formatSymtab) {
318413 return .{ .data = .{
319414 .self = self,
src/link/Elf/SharedObject.zig+2-2
......@@ -282,7 +282,7 @@ pub fn markLive(self: *SharedObject, elf_file: *Elf) void {
282282 }
283283}
284284
285pub fn globals(self: SharedObject) []const Symbol.Index {
285pub fn globals(self: *SharedObject) []Symbol {
286286 return self.symbols.items;
287287}
288288
......@@ -299,7 +299,7 @@ pub fn updateSymtabSize(self: *SharedObject, elf_file: *Elf) void {
299299 }
300300}
301301
302pub fn writeSymtab(self: SharedObject, elf_file: *Elf) void {
302pub fn writeSymtab(self: *SharedObject, elf_file: *Elf) void {
303303 for (self.globals(), self.symbols_resolver.items) |global, resolv| {
304304 const ref = elf_file.resolver.get(resolv).?;
305305 const ref_sym = elf_file.symbol(ref) orelse continue;