authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-06 14:26:35+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-06 14:26:35+01:00
log1b69b0c621568b1b36b6cf946967aaf9e2a596fa
tree581d23152143c84fbe1f9fc2ba858b61fbe1ba2c
parent281dabaa880a8099b0fff752c8e1f4bdd5eec423

elf: clearly separate updating and writing symtab from only ZigObject


2 files changed, 73 insertions(+), 6 deletions(-)

src/link/Elf.zig+71-4
...@@ -1539,14 +1539,14 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void...@@ -1539,14 +1539,14 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
1539 try self.initShStrtab();1539 try self.initShStrtab();
1540 try self.sortShdrs();1540 try self.sortShdrs();
1541 zig_object.updateRelaSectionSizes(self);1541 zig_object.updateRelaSectionSizes(self);
1542 try self.updateSymtabSize();1542 self.updateSymtabSizeObject(zig_object);
1543 self.updateShStrtabSize();1543 self.updateShStrtabSize();
15441544
1545 try self.allocateNonAllocSections();1545 try self.allocateNonAllocSections();
15461546
1547 try self.writeShdrTable();1547 try self.writeShdrTable();
1548 try zig_object.writeRelaSections(self);1548 try zig_object.writeRelaSections(self);
1549 try self.writeSymtab();1549 try self.writeSymtabObject(zig_object);
1550 try self.writeShStrtab();1550 try self.writeShStrtab();
1551 try self.writeElfHeader();1551 try self.writeElfHeader();
1552 }1552 }
...@@ -4060,7 +4060,7 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -4060,7 +4060,7 @@ fn updateSectionSizes(self: *Elf) !void {
4060 self.shdrs.items[index].sh_size = self.verneed.size();4060 self.shdrs.items[index].sh_size = self.verneed.size();
4061 }4061 }
40624062
4063 try self.updateSymtabSize();4063 self.updateSymtabSize();
4064 self.updateShStrtabSize();4064 self.updateShStrtabSize();
4065}4065}
40664066
...@@ -4483,7 +4483,7 @@ fn writeAtoms(self: *Elf) !void {...@@ -4483,7 +4483,7 @@ fn writeAtoms(self: *Elf) !void {
4483 try self.reportUndefined(&undefs);4483 try self.reportUndefined(&undefs);
4484}4484}
44854485
4486fn updateSymtabSize(self: *Elf) !void {4486fn updateSymtabSize(self: *Elf) void {
4487 var sizes = SymtabSize{};4487 var sizes = SymtabSize{};
44884488
4489 if (self.zigObjectPtr()) |zig_object| {4489 if (self.zigObjectPtr()) |zig_object| {
...@@ -4544,6 +4544,25 @@ fn updateSymtabSize(self: *Elf) !void {...@@ -4544,6 +4544,25 @@ fn updateSymtabSize(self: *Elf) !void {
4544 strtab.sh_size = sizes.strsize + 1;4544 strtab.sh_size = sizes.strsize + 1;
4545}4545}
45464546
4547fn updateSymtabSizeObject(self: *Elf, zig_object: *ZigObject) void {
4548 zig_object.asFile().updateSymtabSize(self);
4549 const sizes = zig_object.output_symtab_size;
4550
4551 const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];
4552 symtab_shdr.sh_info = sizes.nlocals + 1;
4553 symtab_shdr.sh_link = self.strtab_section_index.?;
4554
4555 const sym_size: u64 = switch (self.ptr_width) {
4556 .p32 => @sizeOf(elf.Elf32_Sym),
4557 .p64 => @sizeOf(elf.Elf64_Sym),
4558 };
4559 const needed_size = (sizes.nlocals + sizes.nglobals + 1) * sym_size;
4560 symtab_shdr.sh_size = needed_size;
4561
4562 const strtab = &self.shdrs.items[self.strtab_section_index.?];
4563 strtab.sh_size = sizes.strsize + 1;
4564}
4565
4547fn writeSyntheticSections(self: *Elf) !void {4566fn writeSyntheticSections(self: *Elf) !void {
4548 const gpa = self.base.allocator;4567 const gpa = self.base.allocator;
45494568
...@@ -4788,6 +4807,54 @@ fn writeSymtab(self: *Elf) !void {...@@ -4788,6 +4807,54 @@ fn writeSymtab(self: *Elf) !void {
4788 try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);4807 try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
4789}4808}
47904809
4810fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void {
4811 const gpa = self.base.allocator;
4812 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
4813 const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];
4814 const sym_size: u64 = switch (self.ptr_width) {
4815 .p32 => @sizeOf(elf.Elf32_Sym),
4816 .p64 => @sizeOf(elf.Elf64_Sym),
4817 };
4818 const nsyms = math.cast(usize, @divExact(symtab_shdr.sh_size, sym_size)) orelse return error.Overflow;
4819
4820 log.debug("writing {d} symbols at 0x{x}", .{ nsyms, symtab_shdr.sh_offset });
4821
4822 try self.symtab.resize(gpa, nsyms);
4823 const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
4824 try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);
4825
4826 zig_object.asFile().writeSymtab(self, .{ .ilocal = 1, .iglobal = symtab_shdr.sh_info });
4827
4828 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
4829 switch (self.ptr_width) {
4830 .p32 => {
4831 const buf = try gpa.alloc(elf.Elf32_Sym, self.symtab.items.len);
4832 defer gpa.free(buf);
4833
4834 for (buf, self.symtab.items) |*out, sym| {
4835 out.* = .{
4836 .st_name = sym.st_name,
4837 .st_info = sym.st_info,
4838 .st_other = sym.st_other,
4839 .st_shndx = sym.st_shndx,
4840 .st_value = @as(u32, @intCast(sym.st_value)),
4841 .st_size = @as(u32, @intCast(sym.st_size)),
4842 };
4843 if (foreign_endian) mem.byteSwapAllFields(elf.Elf32_Sym, out);
4844 }
4845 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), symtab_shdr.sh_offset);
4846 },
4847 .p64 => {
4848 if (foreign_endian) {
4849 for (self.symtab.items) |*sym| mem.byteSwapAllFields(elf.Elf64_Sym, sym);
4850 }
4851 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), symtab_shdr.sh_offset);
4852 },
4853 }
4854
4855 try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
4856}
4857
4791/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.4858/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.
4792fn ptrWidthBytes(self: Elf) u8 {4859fn ptrWidthBytes(self: Elf) u8 {
4793 return switch (self.ptr_width) {4860 return switch (self.ptr_width) {
src/link/Elf/file.zig+2-2
...@@ -161,7 +161,7 @@ pub const File = union(enum) {...@@ -161,7 +161,7 @@ pub const File = union(enum) {
161 }161 }
162162
163 pub fn writeSymtab(file: File, elf_file: *Elf, ctx: anytype) void {163 pub fn writeSymtab(file: File, elf_file: *Elf, ctx: anytype) void {
164 var ilocal = ctx.ilocal;164 var ilocal: usize = ctx.ilocal;
165 for (file.locals()) |local_index| {165 for (file.locals()) |local_index| {
166 const local = elf_file.symbol(local_index);166 const local = elf_file.symbol(local_index);
167 if (!local.flags.output_symtab) continue;167 if (!local.flags.output_symtab) continue;
...@@ -173,7 +173,7 @@ pub const File = union(enum) {...@@ -173,7 +173,7 @@ pub const File = union(enum) {
173 ilocal += 1;173 ilocal += 1;
174 }174 }
175175
176 var iglobal = ctx.iglobal;176 var iglobal: usize = ctx.iglobal;
177 for (file.globals()) |global_index| {177 for (file.globals()) |global_index| {
178 const global = elf_file.symbol(global_index);178 const global = elf_file.symbol(global_index);
179 const file_ptr = global.file(elf_file) orelse continue;179 const file_ptr = global.file(elf_file) orelse continue;