elf: write $got symbols into the symtab

This commit is contained in:
Jakub Konka
2023-09-08 22:53:53 +02:00
parent 69738a07c2
commit 465431807b
2 changed files with 21 additions and 47 deletions

View File

@@ -2736,6 +2736,11 @@ fn updateSymtabSize(self: *Elf) !void {
sizes.nglobals += zig_module.output_symtab_size.nglobals;
}
if (self.got_section_index) |_| {
self.got.updateSymtabSize(self);
sizes.nlocals += self.got.output_symtab_size.nlocals;
}
const shdr = &self.sections.items(.shdr)[self.symtab_section_index.?];
shdr.sh_info = sizes.nlocals + 1;
self.markDirty(self.symtab_section_index.?, null);
@@ -2780,6 +2785,11 @@ fn writeSymtab(self: *Elf) !void {
ctx.iglobal += zig_module.output_symtab_size.nglobals;
}
if (self.got_section_index) |_| {
try self.got.writeSymtab(self, ctx);
ctx.ilocal += self.got.output_symtab_size.nlocals;
}
const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
switch (self.ptr_width) {
.p32 => {

View File

@@ -356,52 +356,30 @@ pub const GotSection = struct {
// return num;
// }
pub fn calcSymtabSize(got: *GotSection, elf_file: *Elf) !void {
got.output_symtab_size.nlocals = @as(u32, @intCast(got.symbols.items.len));
for (got.symbols.items) |sym| {
const suffix_len = switch (sym) {
.tlsgd => "$tlsgd".len,
.got => "$got".len,
.gottp => "$gottp".len,
.tlsdesc => "$tlsdesc".len,
};
const symbol = elf_file.getSymbol(sym.getIndex());
const name_len = symbol.getName(elf_file).len;
got.output_symtab_size.strsize += @as(u32, @intCast(name_len + suffix_len + 1));
}
if (got.emit_tlsld) {
got.output_symtab_size.nlocals += 1;
got.output_symtab_size.strsize += @as(u32, @intCast("$tlsld".len + 1));
}
pub fn updateSymtabSize(got: *GotSection, elf_file: *Elf) void {
_ = elf_file;
got.output_symtab_size.nlocals = @as(u32, @intCast(got.entries.items.len));
}
pub fn writeSymtab(got: GotSection, elf_file: *Elf, ctx: anytype) !void {
const gpa = elf_file.base.allocator;
var ilocal = ctx.ilocal;
for (got.symbols.items) |sym| {
const suffix = switch (sym) {
for (got.entries.items, ctx.ilocal..) |entry, ilocal| {
const suffix = switch (entry.tag) {
.tlsld => "$tlsld",
.tlsgd => "$tlsgd",
.got => "$got",
.gottp => "$gottp",
.tlsdesc => "$tlsdesc",
};
const symbol = elf_file.getSymbol(sym.getIndex());
const name = try std.fmt.allocPrint(gpa, "{s}{s}", .{ symbol.getName(elf_file), suffix });
const symbol = elf_file.symbol(entry.symbol_index);
const name = try std.fmt.allocPrint(gpa, "{s}{s}", .{ symbol.name(elf_file), suffix });
defer gpa.free(name);
const st_name = try ctx.strtab.insert(gpa, name);
const st_value = switch (sym) {
// .tlsgd => symbol.tlsGdAddress(elf_file),
const st_name = try elf_file.strtab.insert(gpa, name);
const st_value = switch (entry.tag) {
.got => symbol.gotAddress(elf_file),
// .gottp => symbol.gotTpAddress(elf_file),
// .tlsdesc => symbol.tlsDescAddress(elf_file),
else => unreachable,
};
const st_size: u64 = switch (sym) {
.tlsgd, .tlsdesc => 16,
.got, .gottp => 8,
};
const st_size: u64 = entry.len() * elf_file.archPtrWidthBytes();
ctx.symtab[ilocal] = .{
.st_name = st_name,
.st_info = elf.STT_OBJECT,
@@ -410,21 +388,7 @@ pub const GotSection = struct {
.st_value = st_value,
.st_size = st_size,
};
ilocal += 1;
}
// if (got.emit_tlsld) {
// const st_name = try ctx.strtab.insert(gpa, "$tlsld");
// ctx.symtab[ilocal] = .{
// .st_name = st_name,
// .st_info = elf.STT_OBJECT,
// .st_other = 0,
// .st_shndx = elf_file.got_sect_index.?,
// .st_value = elf_file.getTlsLdAddress(),
// .st_size = 16,
// };
// ilocal += 1;
// }
}
const FormatCtx = struct {