mirror of
https://github.com/ziglang/zig.git
synced 2024-11-16 17:15:37 +00:00
elf: clearly separate updating and writing symtab from only ZigObject
This commit is contained in:
parent
281dabaa88
commit
1b69b0c621
@ -1539,14 +1539,14 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
|
||||
try self.initShStrtab();
|
||||
try self.sortShdrs();
|
||||
zig_object.updateRelaSectionSizes(self);
|
||||
try self.updateSymtabSize();
|
||||
self.updateSymtabSizeObject(zig_object);
|
||||
self.updateShStrtabSize();
|
||||
|
||||
try self.allocateNonAllocSections();
|
||||
|
||||
try self.writeShdrTable();
|
||||
try zig_object.writeRelaSections(self);
|
||||
try self.writeSymtab();
|
||||
try self.writeSymtabObject(zig_object);
|
||||
try self.writeShStrtab();
|
||||
try self.writeElfHeader();
|
||||
}
|
||||
@ -4060,7 +4060,7 @@ fn updateSectionSizes(self: *Elf) !void {
|
||||
self.shdrs.items[index].sh_size = self.verneed.size();
|
||||
}
|
||||
|
||||
try self.updateSymtabSize();
|
||||
self.updateSymtabSize();
|
||||
self.updateShStrtabSize();
|
||||
}
|
||||
|
||||
@ -4483,7 +4483,7 @@ fn writeAtoms(self: *Elf) !void {
|
||||
try self.reportUndefined(&undefs);
|
||||
}
|
||||
|
||||
fn updateSymtabSize(self: *Elf) !void {
|
||||
fn updateSymtabSize(self: *Elf) void {
|
||||
var sizes = SymtabSize{};
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
@ -4544,6 +4544,25 @@ fn updateSymtabSize(self: *Elf) !void {
|
||||
strtab.sh_size = sizes.strsize + 1;
|
||||
}
|
||||
|
||||
fn updateSymtabSizeObject(self: *Elf, zig_object: *ZigObject) void {
|
||||
zig_object.asFile().updateSymtabSize(self);
|
||||
const sizes = zig_object.output_symtab_size;
|
||||
|
||||
const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];
|
||||
symtab_shdr.sh_info = sizes.nlocals + 1;
|
||||
symtab_shdr.sh_link = self.strtab_section_index.?;
|
||||
|
||||
const sym_size: u64 = switch (self.ptr_width) {
|
||||
.p32 => @sizeOf(elf.Elf32_Sym),
|
||||
.p64 => @sizeOf(elf.Elf64_Sym),
|
||||
};
|
||||
const needed_size = (sizes.nlocals + sizes.nglobals + 1) * sym_size;
|
||||
symtab_shdr.sh_size = needed_size;
|
||||
|
||||
const strtab = &self.shdrs.items[self.strtab_section_index.?];
|
||||
strtab.sh_size = sizes.strsize + 1;
|
||||
}
|
||||
|
||||
fn writeSyntheticSections(self: *Elf) !void {
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
@ -4788,6 +4807,54 @@ fn writeSymtab(self: *Elf) !void {
|
||||
try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
|
||||
}
|
||||
|
||||
fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void {
|
||||
const gpa = self.base.allocator;
|
||||
const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
|
||||
const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];
|
||||
const sym_size: u64 = switch (self.ptr_width) {
|
||||
.p32 => @sizeOf(elf.Elf32_Sym),
|
||||
.p64 => @sizeOf(elf.Elf64_Sym),
|
||||
};
|
||||
const nsyms = math.cast(usize, @divExact(symtab_shdr.sh_size, sym_size)) orelse return error.Overflow;
|
||||
|
||||
log.debug("writing {d} symbols at 0x{x}", .{ nsyms, symtab_shdr.sh_offset });
|
||||
|
||||
try self.symtab.resize(gpa, nsyms);
|
||||
const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
|
||||
try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);
|
||||
|
||||
zig_object.asFile().writeSymtab(self, .{ .ilocal = 1, .iglobal = symtab_shdr.sh_info });
|
||||
|
||||
const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
|
||||
switch (self.ptr_width) {
|
||||
.p32 => {
|
||||
const buf = try gpa.alloc(elf.Elf32_Sym, self.symtab.items.len);
|
||||
defer gpa.free(buf);
|
||||
|
||||
for (buf, self.symtab.items) |*out, sym| {
|
||||
out.* = .{
|
||||
.st_name = sym.st_name,
|
||||
.st_info = sym.st_info,
|
||||
.st_other = sym.st_other,
|
||||
.st_shndx = sym.st_shndx,
|
||||
.st_value = @as(u32, @intCast(sym.st_value)),
|
||||
.st_size = @as(u32, @intCast(sym.st_size)),
|
||||
};
|
||||
if (foreign_endian) mem.byteSwapAllFields(elf.Elf32_Sym, out);
|
||||
}
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), symtab_shdr.sh_offset);
|
||||
},
|
||||
.p64 => {
|
||||
if (foreign_endian) {
|
||||
for (self.symtab.items) |*sym| mem.byteSwapAllFields(elf.Elf64_Sym, sym);
|
||||
}
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), symtab_shdr.sh_offset);
|
||||
},
|
||||
}
|
||||
|
||||
try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
|
||||
}
|
||||
|
||||
/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.
|
||||
fn ptrWidthBytes(self: Elf) u8 {
|
||||
return switch (self.ptr_width) {
|
||||
|
@ -161,7 +161,7 @@ pub const File = union(enum) {
|
||||
}
|
||||
|
||||
pub fn writeSymtab(file: File, elf_file: *Elf, ctx: anytype) void {
|
||||
var ilocal = ctx.ilocal;
|
||||
var ilocal: usize = ctx.ilocal;
|
||||
for (file.locals()) |local_index| {
|
||||
const local = elf_file.symbol(local_index);
|
||||
if (!local.flags.output_symtab) continue;
|
||||
@ -173,7 +173,7 @@ pub const File = union(enum) {
|
||||
ilocal += 1;
|
||||
}
|
||||
|
||||
var iglobal = ctx.iglobal;
|
||||
var iglobal: usize = ctx.iglobal;
|
||||
for (file.globals()) |global_index| {
|
||||
const global = elf_file.symbol(global_index);
|
||||
const file_ptr = global.file(elf_file) orelse continue;
|
||||
|
Loading…
Reference in New Issue
Block a user