| ... | @@ -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(); |
| 1544 | | 1544 | |
| 1545 | try self.allocateNonAllocSections(); | 1545 | try self.allocateNonAllocSections(); |
| 1546 | | 1546 | |
| 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 | } |
| 4062 | | 4062 | |
| 4063 | try self.updateSymtabSize(); | 4063 | self.updateSymtabSize(); |
| 4064 | self.updateShStrtabSize(); | 4064 | self.updateShStrtabSize(); |
| 4065 | } | 4065 | } |
| 4066 | | 4066 | |
| ... | @@ -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 | } |
| 4485 | | 4485 | |
| 4486 | fn updateSymtabSize(self: *Elf) !void { | 4486 | fn updateSymtabSize(self: *Elf) void { |
| 4487 | var sizes = SymtabSize{}; | 4487 | var sizes = SymtabSize{}; |
| 4488 | | 4488 | |
| 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 | } |
| 4546 | | 4546 | |
| | 4547 | fn 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 | |
| 4547 | fn writeSyntheticSections(self: *Elf) !void { | 4566 | fn writeSyntheticSections(self: *Elf) !void { |
| 4548 | const gpa = self.base.allocator; | 4567 | const gpa = self.base.allocator; |
| 4549 | | 4568 | |
| ... | @@ -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 | } |
| 4790 | | 4809 | |
| | 4810 | fn 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. |
| 4792 | fn ptrWidthBytes(self: Elf) u8 { | 4859 | fn ptrWidthBytes(self: Elf) u8 { |
| 4793 | return switch (self.ptr_width) { | 4860 | return switch (self.ptr_width) { |