authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-10-04 10:38:43+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-09 12:38:53-07:00
logc92c72d08cfb102206594d723e29dd0616290d31
tree1ca758efd321f90419178324b44a1e0440f60d72
parentef7bac4aa58abcf860c222f15eaba8e9c8c702a4

elf: do not create atoms for section symbols that do not require it


3 files changed, 123 insertions(+), 78 deletions(-)

src/link/Elf.zig+1-6
......@@ -3472,12 +3472,7 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
34723472 }
34733473 }
34743474
3475 if (self.zigObjectPtr()) |zo| {
3476 for (zo.atoms_indexes.items) |atom_index| {
3477 const atom_ptr = zo.atom(atom_index) orelse continue;
3478 atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];
3479 }
3480 }
3475 if (self.zigObjectPtr()) |zo| zo.resetShdrIndexes(backlinks);
34813476
34823477 for (self.comdat_group_sections.items) |*cg| {
34833478 cg.shndx = backlinks[cg.shndx];
src/link/Elf/Atom.zig+2-1
......@@ -935,9 +935,10 @@ fn format2(
935935 _ = unused_fmt_string;
936936 const atom = ctx.atom;
937937 const elf_file = ctx.elf_file;
938 try writer.print("atom({d}) : {s} : @{x} : shdr({d}) : align({x}) : size({x})", .{
938 try writer.print("atom({d}) : {s} : @{x} : shdr({d}) : align({x}) : size({x}) : prev({}) : next({})", .{
939939 atom.atom_index, atom.name(elf_file), atom.address(elf_file),
940940 atom.output_section_index, atom.alignment.toByteUnits() orelse 0, atom.size,
941 atom.prev_atom_ref, atom.next_atom_ref,
941942 });
942943 if (atom.fdes(elf_file).len > 0) {
943944 try writer.writeAll(" : fdes{ ");
src/link/Elf/ZigObject.zig+120-71
......@@ -101,6 +101,28 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
101101 .dwarf => |v| {
102102 var dwarf = Dwarf.init(&elf_file.base, v);
103103
104 const addSectionSymbolWithAtom = struct {
105 fn addSectionSymbolWithAtom(
106 zo: *ZigObject,
107 allocator: Allocator,
108 name: [:0]const u8,
109 alignment: Atom.Alignment,
110 shndx: u32,
111 ) !Symbol.Index {
112 const name_off = try zo.addString(allocator, name);
113 const sym_index = try zo.addSectionSymbol(allocator, name_off, shndx);
114 const sym = zo.symbol(sym_index);
115 const atom_index = try zo.newAtom(allocator, name_off);
116 const atom_ptr = zo.atom(atom_index).?;
117 atom_ptr.alignment = alignment;
118 atom_ptr.output_section_index = shndx;
119 sym.ref = .{ .index = atom_index, .file = zo.index };
120 zo.symtab.items(.shndx)[sym.esym_index] = atom_index;
121 zo.symtab.items(.elf_sym)[sym.esym_index].st_shndx = SHN_ATOM;
122 return sym_index;
123 }
124 }.addSectionSymbolWithAtom;
125
104126 if (self.debug_str_index == null) {
105127 const osec = try elf_file.addSection(.{
106128 .name = try elf_file.insertShString(".debug_str"),
......@@ -110,7 +132,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
110132 .addralign = 1,
111133 });
112134 self.debug_str_section_dirty = true;
113 self.debug_str_index = try self.addSectionSymbol(gpa, ".debug_str", .@"1", osec);
135 self.debug_str_index = try addSectionSymbolWithAtom(self, gpa, ".debug_str", .@"1", osec);
114136 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_str_index.?).ref;
115137 }
116138
......@@ -121,7 +143,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
121143 .addralign = 1,
122144 });
123145 self.debug_info_section_dirty = true;
124 self.debug_info_index = try self.addSectionSymbol(gpa, ".debug_info", .@"1", osec);
146 self.debug_info_index = try addSectionSymbolWithAtom(self, gpa, ".debug_info", .@"1", osec);
125147 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_info_index.?).ref;
126148 }
127149
......@@ -132,7 +154,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
132154 .addralign = 1,
133155 });
134156 self.debug_abbrev_section_dirty = true;
135 self.debug_abbrev_index = try self.addSectionSymbol(gpa, ".debug_abbrev", .@"1", osec);
157 self.debug_abbrev_index = try addSectionSymbolWithAtom(self, gpa, ".debug_abbrev", .@"1", osec);
136158 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_abbrev_index.?).ref;
137159 }
138160
......@@ -143,7 +165,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
143165 .addralign = 16,
144166 });
145167 self.debug_aranges_section_dirty = true;
146 self.debug_aranges_index = try self.addSectionSymbol(gpa, ".debug_aranges", .@"16", osec);
168 self.debug_aranges_index = try addSectionSymbolWithAtom(self, gpa, ".debug_aranges", .@"16", osec);
147169 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_aranges_index.?).ref;
148170 }
149171
......@@ -154,7 +176,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
154176 .addralign = 1,
155177 });
156178 self.debug_line_section_dirty = true;
157 self.debug_line_index = try self.addSectionSymbol(gpa, ".debug_line", .@"1", osec);
179 self.debug_line_index = try addSectionSymbolWithAtom(self, gpa, ".debug_line", .@"1", osec);
158180 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_line_index.?).ref;
159181 }
160182
......@@ -167,7 +189,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
167189 .addralign = 1,
168190 });
169191 self.debug_line_str_section_dirty = true;
170 self.debug_line_str_index = try self.addSectionSymbol(gpa, ".debug_line_str", .@"1", osec);
192 self.debug_line_str_index = try addSectionSymbolWithAtom(self, gpa, ".debug_line_str", .@"1", osec);
171193 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_line_str_index.?).ref;
172194 }
173195
......@@ -178,7 +200,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
178200 .addralign = 1,
179201 });
180202 self.debug_loclists_section_dirty = true;
181 self.debug_loclists_index = try self.addSectionSymbol(gpa, ".debug_loclists", .@"1", osec);
203 self.debug_loclists_index = try addSectionSymbolWithAtom(self, gpa, ".debug_loclists", .@"1", osec);
182204 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_loclists_index.?).ref;
183205 }
184206
......@@ -189,7 +211,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
189211 .addralign = 1,
190212 });
191213 self.debug_rnglists_section_dirty = true;
192 self.debug_rnglists_index = try self.addSectionSymbol(gpa, ".debug_rnglists", .@"1", osec);
214 self.debug_rnglists_index = try addSectionSymbolWithAtom(self, gpa, ".debug_rnglists", .@"1", osec);
193215 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_rnglists_index.?).ref;
194216 }
195217
......@@ -204,7 +226,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
204226 .addralign = ptr_size,
205227 });
206228 self.eh_frame_section_dirty = true;
207 self.eh_frame_index = try self.addSectionSymbol(gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), osec);
229 self.eh_frame_index = try addSectionSymbolWithAtom(self, gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), osec);
208230 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.eh_frame_index.?).ref;
209231 }
210232
......@@ -997,7 +1019,7 @@ pub fn lowerUav(
9971019 }
9981020
9991021 const osec = if (self.data_relro_index) |sym_index|
1000 self.symbol(sym_index).atom(elf_file).?.output_section_index
1022 self.symbol(sym_index).outputShndx(elf_file).?
10011023 else osec: {
10021024 const osec = try elf_file.addSection(.{
10031025 .name = try elf_file.insertShString(".data.rel.ro"),
......@@ -1006,7 +1028,7 @@ pub fn lowerUav(
10061028 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
10071029 .offset = std.math.maxInt(u64),
10081030 });
1009 self.data_relro_index = try self.addSectionSymbol(gpa, ".data.rel.ro", .@"1", osec);
1031 self.data_relro_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data.rel.ro"), osec);
10101032 break :osec osec;
10111033 };
10121034
......@@ -1112,24 +1134,14 @@ pub fn getOrCreateMetadataForNav(
11121134 return gop.value_ptr.symbol_index;
11131135}
11141136
1115// FIXME: we always create an atom to basically store size and alignment, however, this is only true for
1116// sections that have a single atom like the debug sections. It would be a better solution to decouple this
1117// concept from the atom, maybe.
1118fn addSectionSymbol(
1119 self: *ZigObject,
1120 allocator: Allocator,
1121 name: [:0]const u8,
1122 alignment: Atom.Alignment,
1123 shndx: u32,
1124) !Symbol.Index {
1125 const name_off = try self.addString(allocator, name);
1126 const index = try self.newSymbolWithAtom(allocator, name_off);
1137fn addSectionSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, shndx: u32) !Symbol.Index {
1138 const index = try self.newLocalSymbol(allocator, name_off);
11271139 const sym = self.symbol(index);
11281140 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
11291141 esym.st_info |= elf.STT_SECTION;
1130 const atom_ptr = self.atom(sym.ref.index).?;
1131 atom_ptr.alignment = alignment;
1132 atom_ptr.output_section_index = shndx;
1142 // TODO create fake shdrs?
1143 // esym.st_shndx = shndx;
1144 sym.output_section_index = shndx;
11331145 return index;
11341146}
11351147
......@@ -1148,7 +1160,7 @@ fn getNavShdrIndex(
11481160 const nav_val = zcu.navValue(nav_index);
11491161 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) {
11501162 if (self.text_index) |symbol_index|
1151 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1163 return self.symbol(symbol_index).outputShndx(elf_file).?;
11521164 const osec = try elf_file.addSection(.{
11531165 .type = elf.SHT_PROGBITS,
11541166 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
......@@ -1156,7 +1168,7 @@ fn getNavShdrIndex(
11561168 .addralign = 1,
11571169 .offset = std.math.maxInt(u64),
11581170 });
1159 self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
1171 self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec);
11601172 return osec;
11611173 }
11621174 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
......@@ -1171,18 +1183,18 @@ fn getNavShdrIndex(
11711183 } else true;
11721184 if (is_bss) {
11731185 if (self.tbss_index) |symbol_index|
1174 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1186 return self.symbol(symbol_index).outputShndx(elf_file).?;
11751187 const osec = try elf_file.addSection(.{
11761188 .name = try elf_file.insertShString(".tbss"),
11771189 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
11781190 .type = elf.SHT_NOBITS,
11791191 .addralign = 1,
11801192 });
1181 self.tbss_index = try self.addSectionSymbol(gpa, ".tbss", .@"1", osec);
1193 self.tbss_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".tbss"), osec);
11821194 return osec;
11831195 }
11841196 if (self.tdata_index) |symbol_index|
1185 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1197 return self.symbol(symbol_index).outputShndx(elf_file).?;
11861198 const osec = try elf_file.addSection(.{
11871199 .type = elf.SHT_PROGBITS,
11881200 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
......@@ -1190,12 +1202,12 @@ fn getNavShdrIndex(
11901202 .addralign = 1,
11911203 .offset = std.math.maxInt(u64),
11921204 });
1193 self.tdata_index = try self.addSectionSymbol(gpa, ".tdata", .@"1", osec);
1205 self.tdata_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".tdata"), osec);
11941206 return osec;
11951207 }
11961208 if (is_const) {
11971209 if (self.data_relro_index) |symbol_index|
1198 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1210 return self.symbol(symbol_index).outputShndx(elf_file).?;
11991211 const osec = try elf_file.addSection(.{
12001212 .name = try elf_file.insertShString(".data.rel.ro"),
12011213 .type = elf.SHT_PROGBITS,
......@@ -1203,14 +1215,14 @@ fn getNavShdrIndex(
12031215 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
12041216 .offset = std.math.maxInt(u64),
12051217 });
1206 self.data_relro_index = try self.addSectionSymbol(gpa, ".data.rel.ro", .@"1", osec);
1218 self.data_relro_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data.rel.ro"), osec);
12071219 return osec;
12081220 }
12091221 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
12101222 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
12111223 .Debug, .ReleaseSafe => {
12121224 if (self.data_index) |symbol_index|
1213 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1225 return self.symbol(symbol_index).outputShndx(elf_file).?;
12141226 const osec = try elf_file.addSection(.{
12151227 .name = try elf_file.insertShString(".data"),
12161228 .type = elf.SHT_PROGBITS,
......@@ -1218,24 +1230,19 @@ fn getNavShdrIndex(
12181230 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
12191231 .offset = std.math.maxInt(u64),
12201232 });
1221 self.data_index = try self.addSectionSymbol(
1222 gpa,
1223 ".data",
1224 Atom.Alignment.fromNonzeroByteUnits(ptr_size),
1225 osec,
1226 );
1233 self.data_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data"), osec);
12271234 return osec;
12281235 },
12291236 .ReleaseFast, .ReleaseSmall => {
12301237 if (self.bss_index) |symbol_index|
1231 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1238 return self.symbol(symbol_index).outputShndx(elf_file).?;
12321239 const osec = try elf_file.addSection(.{
12331240 .type = elf.SHT_NOBITS,
12341241 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
12351242 .name = try elf_file.insertShString(".bss"),
12361243 .addralign = 1,
12371244 });
1238 self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec);
1245 self.bss_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".bss"), osec);
12391246 return osec;
12401247 },
12411248 };
......@@ -1244,18 +1251,18 @@ fn getNavShdrIndex(
12441251 } else true;
12451252 if (is_bss) {
12461253 if (self.bss_index) |symbol_index|
1247 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1254 return self.symbol(symbol_index).outputShndx(elf_file).?;
12481255 const osec = try elf_file.addSection(.{
12491256 .type = elf.SHT_NOBITS,
12501257 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
12511258 .name = try elf_file.insertShString(".bss"),
12521259 .addralign = 1,
12531260 });
1254 self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec);
1261 self.bss_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".bss"), osec);
12551262 return osec;
12561263 }
12571264 if (self.data_index) |symbol_index|
1258 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1265 return self.symbol(symbol_index).outputShndx(elf_file).?;
12591266 const osec = try elf_file.addSection(.{
12601267 .name = try elf_file.insertShString(".data"),
12611268 .type = elf.SHT_PROGBITS,
......@@ -1263,12 +1270,7 @@ fn getNavShdrIndex(
12631270 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
12641271 .offset = std.math.maxInt(u64),
12651272 });
1266 self.data_index = try self.addSectionSymbol(
1267 gpa,
1268 ".data",
1269 Atom.Alignment.fromNonzeroByteUnits(ptr_size),
1270 osec,
1271 );
1273 self.data_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data"), osec);
12721274 return osec;
12731275}
12741276
......@@ -1521,7 +1523,7 @@ pub fn updateFunc(
15211523 .addralign = 1,
15221524 .offset = std.math.maxInt(u64),
15231525 });
1524 self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
1526 self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec);
15251527 break :osec osec;
15261528 };
15271529 const name_off = try self.addString(gpa, name);
......@@ -1688,7 +1690,7 @@ fn updateLazySymbol(
16881690
16891691 const output_section_index = switch (sym.kind) {
16901692 .code => if (self.text_index) |sym_index|
1691 self.symbol(sym_index).atom(elf_file).?.output_section_index
1693 self.symbol(sym_index).outputShndx(elf_file).?
16921694 else osec: {
16931695 const osec = try elf_file.addSection(.{
16941696 .name = try elf_file.insertShString(".text"),
......@@ -1697,11 +1699,11 @@ fn updateLazySymbol(
16971699 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
16981700 .offset = std.math.maxInt(u64),
16991701 });
1700 self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
1702 self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec);
17011703 break :osec osec;
17021704 },
17031705 .const_data => if (self.rodata_index) |sym_index|
1704 self.symbol(sym_index).atom(elf_file).?.output_section_index
1706 self.symbol(sym_index).outputShndx(elf_file).?
17051707 else osec: {
17061708 const osec = try elf_file.addSection(.{
17071709 .name = try elf_file.insertShString(".rodata"),
......@@ -1710,7 +1712,7 @@ fn updateLazySymbol(
17101712 .flags = elf.SHF_ALLOC,
17111713 .offset = std.math.maxInt(u64),
17121714 });
1713 self.rodata_index = try self.addSectionSymbol(gpa, ".rodata", .@"1", osec);
1715 self.rodata_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".rodata"), osec);
17141716 break :osec osec;
17151717 },
17161718 };
......@@ -2011,20 +2013,10 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
20112013 }
20122014 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?);
20132015
2014 const sect_atom_ptr = for ([_]?Symbol.Index{
2015 self.text_index,
2016 self.rodata_index,
2017 self.data_relro_index,
2018 self.data_index,
2019 self.tdata_index,
2020 }) |maybe_sym_index| {
2021 const sect_sym_index = maybe_sym_index orelse continue;
2022 const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?;
2023 if (sect_atom_ptr.output_section_index == atom_ptr.output_section_index) break sect_atom_ptr;
2024 } else null;
2025 if (sect_atom_ptr) |sap| {
2026 sap.size = shdr.sh_size;
2027 sap.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);
2016 if (self.sectionSymbol(atom_ptr.output_section_index, elf_file)) |sym| {
2017 assert(sym.atom(elf_file) == null and sym.mergeSubsection(elf_file) == null);
2018 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
2019 esym.st_size += atom_ptr.size + Elf.padToIdeal(atom_ptr.size);
20282020 }
20292021
20302022 // This function can also reallocate an atom.
......@@ -2053,10 +2045,67 @@ fn growAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
20532045 }
20542046}
20552047
2048pub fn resetShdrIndexes(self: *ZigObject, backlinks: anytype) void {
2049 for (self.atoms_indexes.items) |atom_index| {
2050 const atom_ptr = self.atom(atom_index) orelse continue;
2051 atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];
2052 }
2053 inline for ([_]?Symbol.Index{
2054 self.text_index,
2055 self.rodata_index,
2056 self.data_relro_index,
2057 self.data_index,
2058 self.bss_index,
2059 self.tdata_index,
2060 self.tbss_index,
2061 self.eh_frame_index,
2062 self.debug_info_index,
2063 self.debug_abbrev_index,
2064 self.debug_aranges_index,
2065 self.debug_str_index,
2066 self.debug_line_index,
2067 self.debug_line_str_index,
2068 self.debug_loclists_index,
2069 self.debug_rnglists_index,
2070 }) |maybe_sym_index| {
2071 if (maybe_sym_index) |sym_index| {
2072 const sym = self.symbol(sym_index);
2073 sym.output_section_index = backlinks[sym.output_section_index];
2074 }
2075 }
2076}
2077
20562078pub fn asFile(self: *ZigObject) File {
20572079 return .{ .zig_object = self };
20582080}
20592081
2082pub fn sectionSymbol(self: *ZigObject, shndx: u32, elf_file: *Elf) ?*Symbol {
2083 inline for ([_]?Symbol.Index{
2084 self.text_index,
2085 self.rodata_index,
2086 self.data_relro_index,
2087 self.data_index,
2088 self.bss_index,
2089 self.tdata_index,
2090 self.tbss_index,
2091 self.eh_frame_index,
2092 self.debug_info_index,
2093 self.debug_abbrev_index,
2094 self.debug_aranges_index,
2095 self.debug_str_index,
2096 self.debug_line_index,
2097 self.debug_line_str_index,
2098 self.debug_loclists_index,
2099 self.debug_rnglists_index,
2100 }) |maybe_sym_index| {
2101 if (maybe_sym_index) |sym_index| {
2102 const sym = self.symbol(sym_index);
2103 if (sym.outputShndx(elf_file) == shndx) return sym;
2104 }
2105 }
2106 return null;
2107}
2108
20602109pub fn addString(self: *ZigObject, allocator: Allocator, string: []const u8) !u32 {
20612110 return self.strtab.insert(allocator, string);
20622111}