mirror of
https://github.com/ziglang/zig.git
synced 2026-02-16 14:28:57 +00:00
elf: actually track output symtab index of symbols
This commit is contained in:
parent
ecf6ed7d9b
commit
5e78600f0f
251
src/link/Elf.zig
251
src/link/Elf.zig
@ -24,6 +24,7 @@ shdr_table_offset: ?u64 = null,
|
||||
/// Table of lists of atoms per output section.
|
||||
/// This table is not used to track incrementally generated atoms.
|
||||
output_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom.Index)) = .{},
|
||||
output_rela_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom.Index)) = .{},
|
||||
|
||||
/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
|
||||
/// Same order as in the file.
|
||||
@ -105,11 +106,8 @@ zig_got: ZigGotSection = .{},
|
||||
/// Tracked section headers with incremental updates to Zig object.
|
||||
/// .rela.* sections are only used when emitting a relocatable object file.
|
||||
zig_text_section_index: ?u16 = null,
|
||||
zig_text_rela_section_index: ?u16 = null,
|
||||
zig_data_rel_ro_section_index: ?u16 = null,
|
||||
zig_data_rel_ro_rela_section_index: ?u16 = null,
|
||||
zig_data_section_index: ?u16 = null,
|
||||
zig_data_rela_section_index: ?u16 = null,
|
||||
zig_bss_section_index: ?u16 = null,
|
||||
zig_got_section_index: ?u16 = null,
|
||||
|
||||
@ -357,6 +355,10 @@ pub fn deinit(self: *Elf) void {
|
||||
list.deinit(gpa);
|
||||
}
|
||||
self.output_sections.deinit(gpa);
|
||||
for (self.output_rela_sections.values()) |*list| {
|
||||
list.deinit(gpa);
|
||||
}
|
||||
self.output_rela_sections.deinit(gpa);
|
||||
self.shstrtab.deinit(gpa);
|
||||
self.symtab.deinit(gpa);
|
||||
self.strtab.deinit(gpa);
|
||||
@ -597,10 +599,8 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
const shdr = &self.shdrs.items[self.zig_text_section_index.?];
|
||||
fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index);
|
||||
if (self.isRelocatable()) {
|
||||
self.zig_text_rela_section_index = try self.addRelaShdr(
|
||||
".rela.text.zig",
|
||||
self.zig_text_section_index.?,
|
||||
);
|
||||
const rela_shndx = try self.addRelaShdr(".rela.text.zig", self.zig_text_section_index.?);
|
||||
try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{});
|
||||
} else {
|
||||
try self.phdr_to_shdr_table.putNoClobber(
|
||||
gpa,
|
||||
@ -644,10 +644,11 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?];
|
||||
fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index);
|
||||
if (self.isRelocatable()) {
|
||||
self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr(
|
||||
const rela_shndx = try self.addRelaShdr(
|
||||
".rela.data.rel.ro.zig",
|
||||
self.zig_data_rel_ro_section_index.?,
|
||||
);
|
||||
try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{});
|
||||
} else {
|
||||
try self.phdr_to_shdr_table.putNoClobber(
|
||||
gpa,
|
||||
@ -670,10 +671,11 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
const shdr = &self.shdrs.items[self.zig_data_section_index.?];
|
||||
fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index);
|
||||
if (self.isRelocatable()) {
|
||||
self.zig_data_rela_section_index = try self.addRelaShdr(
|
||||
const rela_shndx = try self.addRelaShdr(
|
||||
".rela.data.zig",
|
||||
self.zig_data_section_index.?,
|
||||
);
|
||||
try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{});
|
||||
} else {
|
||||
try self.phdr_to_shdr_table.putNoClobber(
|
||||
gpa,
|
||||
@ -1514,16 +1516,13 @@ pub fn flushStaticLib(self: *Elf) link.File.FlushError!void {
|
||||
try self.initSymtab();
|
||||
try self.initShStrtab();
|
||||
try self.sortShdrs();
|
||||
zig_object.updateRelaSectionsSizes(self);
|
||||
self.updateSymtabSizeZigObject(zig_object);
|
||||
self.updateShStrtabSize();
|
||||
try zig_object.addAtomsToRelaSections(self);
|
||||
try self.updateSectionSizesObject();
|
||||
|
||||
try self.allocateNonAllocSections();
|
||||
|
||||
try self.writeShdrTable();
|
||||
try zig_object.writeRelaSections(self);
|
||||
try self.writeSymtabZigObject(zig_object);
|
||||
try self.writeShStrtab();
|
||||
try self.writeSyntheticSectionsObject();
|
||||
try self.writeElfHeader();
|
||||
}
|
||||
|
||||
@ -1620,7 +1619,9 @@ pub fn flushObject(self: *Elf) link.File.FlushError!void {
|
||||
try self.initSectionsObject();
|
||||
try self.sortShdrs();
|
||||
for (self.objects.items) |index| {
|
||||
try self.file(index).?.object.addAtomsToOutputSections(self);
|
||||
const object = self.file(index).?.object;
|
||||
try object.addAtomsToOutputSections(self);
|
||||
try object.addAtomsToRelaSections(self);
|
||||
}
|
||||
try self.updateSectionSizesObject();
|
||||
|
||||
@ -3452,7 +3453,7 @@ fn initSectionsObject(self: *Elf) !void {
|
||||
.addralign = ptr_size,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
_ = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?);
|
||||
// _ = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?);
|
||||
}
|
||||
|
||||
try self.initSymtab();
|
||||
@ -3841,12 +3842,9 @@ fn sortShdrs(self: *Elf) !void {
|
||||
&self.versym_section_index,
|
||||
&self.verneed_section_index,
|
||||
&self.zig_text_section_index,
|
||||
&self.zig_text_rela_section_index,
|
||||
&self.zig_got_section_index,
|
||||
&self.zig_data_rel_ro_section_index,
|
||||
&self.zig_data_rel_ro_rela_section_index,
|
||||
&self.zig_data_section_index,
|
||||
&self.zig_data_rela_section_index,
|
||||
&self.zig_bss_section_index,
|
||||
&self.debug_str_section_index,
|
||||
&self.debug_info_section_index,
|
||||
@ -4066,7 +4064,7 @@ fn updateSectionSizes(self: *Elf) !void {
|
||||
self.shdrs.items[index].sh_size = self.verneed.size();
|
||||
}
|
||||
|
||||
self.updateSymtabSize();
|
||||
try self.updateSymtabSize();
|
||||
self.updateShStrtabSize();
|
||||
}
|
||||
|
||||
@ -4084,19 +4082,21 @@ fn updateSectionSizesObject(self: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
zig_object.updateRelaSectionsSizes(self);
|
||||
}
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
self.file(index).?.object.updateRelaSectionsSizes(self);
|
||||
for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, atom_list| {
|
||||
const shdr = &self.shdrs.items[shndx];
|
||||
for (atom_list.items) |atom_index| {
|
||||
const atom_ptr = self.atom(atom_index) orelse continue;
|
||||
if (!atom_ptr.flags.alive) continue;
|
||||
const relocs = atom_ptr.relocs(self);
|
||||
shdr.sh_size += shdr.sh_entsize * relocs.len;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.eh_frame_section_index) |index| {
|
||||
self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self);
|
||||
}
|
||||
|
||||
self.updateSymtabSize();
|
||||
try self.updateSymtabSize();
|
||||
self.updateShStrtabSize();
|
||||
}
|
||||
|
||||
@ -4597,96 +4597,123 @@ fn writeAtomsObject(self: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn updateSymtabSize(self: *Elf) void {
|
||||
var sizes = SymtabSize{};
|
||||
fn updateSymtabSize(self: *Elf) !void {
|
||||
var nlocals: u32 = 0;
|
||||
var nglobals: u32 = 0;
|
||||
var strsize: u32 = 0;
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
zig_object.asFile().updateSymtabSize(self);
|
||||
sizes.add(zig_object.output_symtab_size);
|
||||
}
|
||||
const gpa = self.base.allocator;
|
||||
var files = std.ArrayList(File.Index).init(gpa);
|
||||
defer files.deinit();
|
||||
try files.ensureTotalCapacityPrecise(self.objects.items.len + self.shared_objects.items.len + 1);
|
||||
|
||||
if (self.zig_object_index) |index| files.appendAssumeCapacity(index);
|
||||
for (self.objects.items) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
file_ptr.updateSymtabSize(self);
|
||||
sizes.add(file_ptr.object.output_symtab_size);
|
||||
files.appendAssumeCapacity(index);
|
||||
}
|
||||
for (self.shared_objects.items) |index| {
|
||||
files.appendAssumeCapacity(index);
|
||||
}
|
||||
|
||||
for (self.shared_objects.items) |index| {
|
||||
// Section symbols
|
||||
for (self.output_sections.keys()) |_| {
|
||||
nlocals += 1;
|
||||
}
|
||||
|
||||
for (files.items) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
file_ptr.updateSymtabSize(self);
|
||||
sizes.add(file_ptr.shared_object.output_symtab_size);
|
||||
const ctx = switch (file_ptr) {
|
||||
inline else => |x| &x.output_symtab_ctx,
|
||||
};
|
||||
ctx.ilocal = nlocals + 1;
|
||||
ctx.iglobal = nglobals + 1;
|
||||
try file_ptr.updateSymtabSize(self);
|
||||
nlocals += ctx.nlocals;
|
||||
nglobals += ctx.nglobals;
|
||||
strsize += ctx.strsize;
|
||||
}
|
||||
|
||||
if (self.zig_got_section_index) |_| {
|
||||
self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
|
||||
self.zig_got.updateSymtabSize(self);
|
||||
sizes.add(self.zig_got.output_symtab_size);
|
||||
nlocals += self.zig_got.output_symtab_ctx.nlocals;
|
||||
strsize += self.zig_got.output_symtab_ctx.strsize;
|
||||
}
|
||||
|
||||
if (self.got_section_index) |_| {
|
||||
self.got.output_symtab_ctx.ilocal = nlocals + 1;
|
||||
self.got.updateSymtabSize(self);
|
||||
sizes.add(self.got.output_symtab_size);
|
||||
nlocals += self.got.output_symtab_ctx.nlocals;
|
||||
strsize += self.got.output_symtab_ctx.strsize;
|
||||
}
|
||||
|
||||
if (self.plt_section_index) |_| {
|
||||
self.plt.output_symtab_ctx.ilocal = nlocals + 1;
|
||||
self.plt.updateSymtabSize(self);
|
||||
sizes.add(self.plt.output_symtab_size);
|
||||
nlocals += self.plt.output_symtab_ctx.nlocals;
|
||||
strsize += self.plt.output_symtab_ctx.strsize;
|
||||
}
|
||||
|
||||
if (self.plt_got_section_index) |_| {
|
||||
self.plt_got.output_symtab_ctx.ilocal = nlocals + 1;
|
||||
self.plt_got.updateSymtabSize(self);
|
||||
sizes.add(self.plt_got.output_symtab_size);
|
||||
nlocals += self.plt_got.output_symtab_ctx.nlocals;
|
||||
strsize += self.plt_got.output_symtab_ctx.strsize;
|
||||
}
|
||||
|
||||
if (self.linker_defined_index) |index| {
|
||||
for (files.items) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
file_ptr.updateSymtabSize(self);
|
||||
sizes.add(file_ptr.linker_defined.output_symtab_size);
|
||||
}
|
||||
|
||||
// Section symbols
|
||||
for (self.output_sections.keys()) |_| {
|
||||
sizes.nlocals += 1;
|
||||
const ctx = switch (file_ptr) {
|
||||
inline else => |x| &x.output_symtab_ctx,
|
||||
};
|
||||
ctx.iglobal += nlocals;
|
||||
}
|
||||
|
||||
const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];
|
||||
symtab_shdr.sh_info = sizes.nlocals + 1;
|
||||
symtab_shdr.sh_info = 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;
|
||||
const needed_size = (nlocals + 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;
|
||||
strtab.sh_size = strsize + 1;
|
||||
}
|
||||
|
||||
fn updateSymtabSizeZigObject(self: *Elf, zig_object: *ZigObject) void {
|
||||
var sizes = SymtabSize{};
|
||||
|
||||
zig_object.asFile().updateSymtabSize(self);
|
||||
sizes.add(zig_object.output_symtab_size);
|
||||
var nlocals: u32 = 0;
|
||||
var nglobals: u32 = 0;
|
||||
var strsize: u32 = 0;
|
||||
|
||||
// Section symbols
|
||||
for (self.output_sections.keys()) |_| {
|
||||
sizes.nlocals += 1;
|
||||
nlocals += 1;
|
||||
}
|
||||
|
||||
zig_object.output_symtab_ctx.ilocal = nlocals + 1;
|
||||
try zig_object.asFile().updateSymtabSize(self);
|
||||
nlocals += zig_object.output_symtab_ctx.nlocals;
|
||||
nglobals += zig_object.output_symtab_ctx.nglobals;
|
||||
strsize += zig_object.output_symtab_ctx.strsize;
|
||||
zig_object.output_symtab_ctx.iglobal = nlocals + 1;
|
||||
|
||||
const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];
|
||||
symtab_shdr.sh_info = sizes.nlocals + 1;
|
||||
symtab_shdr.sh_info = 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;
|
||||
const needed_size = (nlocals + 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;
|
||||
strtab.sh_size = strsize + 1;
|
||||
}
|
||||
|
||||
fn writeSyntheticSections(self: *Elf) !void {
|
||||
@ -4822,12 +4849,31 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
fn writeSyntheticSectionsObject(self: *Elf) !void {
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
try zig_object.writeRelaSections(self);
|
||||
}
|
||||
for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, atom_list| {
|
||||
if (atom_list.items.len == 0) continue;
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
try self.file(index).?.object.writeRelaSections(self);
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
|
||||
const num_relocs = @divExact(shdr.sh_size, shdr.sh_entsize);
|
||||
var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs);
|
||||
defer relocs.deinit();
|
||||
|
||||
for (atom_list.items) |atom_index| {
|
||||
const atom_ptr = self.atom(atom_index) orelse continue;
|
||||
if (!atom_ptr.flags.alive) continue;
|
||||
try atom_ptr.writeRelocs(self, &relocs);
|
||||
}
|
||||
|
||||
const SortRelocs = struct {
|
||||
pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool {
|
||||
_ = ctx;
|
||||
return lhs.r_offset < rhs.r_offset;
|
||||
}
|
||||
};
|
||||
|
||||
mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan);
|
||||
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset);
|
||||
}
|
||||
|
||||
if (self.eh_frame_section_index) |shndx| {
|
||||
@ -4836,7 +4882,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
try eh_frame.writeEhFrame(self, buffer.writer());
|
||||
// try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
|
||||
try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
|
||||
}
|
||||
|
||||
try self.writeSymtab();
|
||||
@ -4850,16 +4896,6 @@ fn writeShStrtab(self: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const WriteSymtabCtx = struct {
|
||||
ilocal: usize,
|
||||
iglobal: usize,
|
||||
|
||||
fn incr(this: *@This(), ss: SymtabSize) void {
|
||||
this.ilocal += ss.nlocals;
|
||||
this.iglobal += ss.nglobals;
|
||||
}
|
||||
};
|
||||
|
||||
fn writeSymtab(self: *Elf) !void {
|
||||
const gpa = self.base.allocator;
|
||||
const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
|
||||
@ -4876,54 +4912,41 @@ fn writeSymtab(self: *Elf) !void {
|
||||
const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
|
||||
try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);
|
||||
|
||||
var ctx: WriteSymtabCtx = .{
|
||||
.ilocal = 1,
|
||||
.iglobal = symtab_shdr.sh_info,
|
||||
};
|
||||
|
||||
ctx.incr(self.writeSectionSymbols(ctx));
|
||||
self.writeSectionSymbols();
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
zig_object.asFile().writeSymtab(self, ctx);
|
||||
ctx.incr(zig_object.output_symtab_size);
|
||||
zig_object.asFile().writeSymtab(self);
|
||||
}
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
file_ptr.writeSymtab(self, ctx);
|
||||
ctx.incr(file_ptr.object.output_symtab_size);
|
||||
file_ptr.writeSymtab(self);
|
||||
}
|
||||
|
||||
for (self.shared_objects.items) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
file_ptr.writeSymtab(self, ctx);
|
||||
ctx.incr(file_ptr.shared_object.output_symtab_size);
|
||||
file_ptr.writeSymtab(self);
|
||||
}
|
||||
|
||||
if (self.zig_got_section_index) |_| {
|
||||
self.zig_got.writeSymtab(self, ctx);
|
||||
ctx.incr(self.zig_got.output_symtab_size);
|
||||
self.zig_got.writeSymtab(self);
|
||||
}
|
||||
|
||||
if (self.got_section_index) |_| {
|
||||
self.got.writeSymtab(self, ctx);
|
||||
ctx.incr(self.got.output_symtab_size);
|
||||
self.got.writeSymtab(self);
|
||||
}
|
||||
|
||||
if (self.plt_section_index) |_| {
|
||||
self.plt.writeSymtab(self, ctx);
|
||||
ctx.incr(self.plt.output_symtab_size);
|
||||
self.plt.writeSymtab(self);
|
||||
}
|
||||
|
||||
if (self.plt_got_section_index) |_| {
|
||||
self.plt_got.writeSymtab(self, ctx);
|
||||
ctx.incr(self.plt_got.output_symtab_size);
|
||||
self.plt_got.writeSymtab(self);
|
||||
}
|
||||
|
||||
if (self.linker_defined_index) |index| {
|
||||
const file_ptr = self.file(index).?;
|
||||
file_ptr.writeSymtab(self, ctx);
|
||||
ctx.incr(file_ptr.linker_defined.output_symtab_size);
|
||||
file_ptr.writeSymtab(self);
|
||||
}
|
||||
|
||||
const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
|
||||
@ -4972,15 +4995,8 @@ fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void {
|
||||
const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
|
||||
try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);
|
||||
|
||||
var ctx: WriteSymtabCtx = .{
|
||||
.ilocal = 1,
|
||||
.iglobal = symtab_shdr.sh_info,
|
||||
};
|
||||
|
||||
ctx.incr(self.writeSectionSymbols(ctx));
|
||||
|
||||
zig_object.asFile().writeSymtab(self, ctx);
|
||||
ctx.incr(zig_object.output_symtab_size);
|
||||
self.writeSectionSymbols();
|
||||
zig_object.asFile().writeSymtab(self);
|
||||
|
||||
const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
|
||||
switch (self.ptr_width) {
|
||||
@ -5012,8 +5028,8 @@ fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void {
|
||||
try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
|
||||
}
|
||||
|
||||
fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize {
|
||||
var ilocal = ctx.ilocal;
|
||||
fn writeSectionSymbols(self: *Elf) void {
|
||||
var ilocal: u32 = 1;
|
||||
for (self.output_sections.keys()) |shndx| {
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
const out_sym = &self.symtab.items[ilocal];
|
||||
@ -5027,7 +5043,6 @@ fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize {
|
||||
};
|
||||
ilocal += 1;
|
||||
}
|
||||
return .{ .nlocals = @intCast(ilocal - ctx.ilocal) };
|
||||
}
|
||||
|
||||
/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.
|
||||
@ -6056,16 +6071,12 @@ pub const ComdatGroup = struct {
|
||||
pub const Index = u32;
|
||||
};
|
||||
|
||||
pub const SymtabSize = struct {
|
||||
pub const SymtabCtx = struct {
|
||||
ilocal: u32 = 0,
|
||||
iglobal: u32 = 0,
|
||||
nlocals: u32 = 0,
|
||||
nglobals: u32 = 0,
|
||||
strsize: u32 = 0,
|
||||
|
||||
fn add(ss: *SymtabSize, other: SymtabSize) void {
|
||||
ss.nlocals += other.nlocals;
|
||||
ss.nglobals += other.nglobals;
|
||||
ss.strsize += other.strsize;
|
||||
}
|
||||
};
|
||||
|
||||
pub const null_sym = elf.Elf64_Sym{
|
||||
|
||||
@ -293,6 +293,32 @@ pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void {
|
||||
const file_ptr = self.file(elf_file).?;
|
||||
for (self.relocs(elf_file)) |rel| {
|
||||
const target_index = switch (file_ptr) {
|
||||
.zig_object => |x| x.symbol(rel.r_sym()),
|
||||
.object => |x| x.symbols.items[rel.r_sym()],
|
||||
else => unreachable,
|
||||
};
|
||||
const target = elf_file.symbol(target_index);
|
||||
const r_sym = target.outputSymtabIndex(elf_file);
|
||||
const r_offset = self.value + rel.r_offset;
|
||||
const r_addend = rel.r_addend;
|
||||
const r_type = switch (rel.r_type()) {
|
||||
Elf.R_X86_64_ZIG_GOT32,
|
||||
Elf.R_X86_64_ZIG_GOTPCREL,
|
||||
=> unreachable, // Sanity check if we accidentally emitted those.
|
||||
else => |r_type| r_type,
|
||||
};
|
||||
out_relocs.appendAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
.r_info = (@as(u64, @intCast(r_sym)) << 32) | r_type,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fdes(self: Atom, elf_file: *Elf) []Fde {
|
||||
if (self.fde_start == self.fde_end) return &[0]Fde{};
|
||||
const object = self.file(elf_file).?.object;
|
||||
|
||||
@ -3,7 +3,7 @@ symtab: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
|
||||
strtab: std.ArrayListUnmanaged(u8) = .{},
|
||||
symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
|
||||
pub fn deinit(self: *LinkerDefined, allocator: Allocator) void {
|
||||
self.symtab.deinit(allocator);
|
||||
|
||||
@ -19,7 +19,7 @@ cies: std.ArrayListUnmanaged(Cie) = .{},
|
||||
alive: bool = true,
|
||||
num_dynrelocs: u32 = 0,
|
||||
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
output_ar_state: Archive.ArState = .{},
|
||||
|
||||
pub fn isObject(path: []const u8) !bool {
|
||||
@ -672,22 +672,19 @@ pub fn initRelaSections(self: Object, elf_file: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateRelaSectionsSizes(self: Object, elf_file: *Elf) void {
|
||||
pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void {
|
||||
for (self.atoms.items) |atom_index| {
|
||||
const atom = elf_file.atom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
const shndx = atom.relocsShndx() orelse continue;
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
const out_shndx = self.initOutputSection(elf_file, shdr) catch unreachable;
|
||||
const out_shdr = &elf_file.shdrs.items[out_shndx];
|
||||
const relocs = atom.relocs(elf_file);
|
||||
out_shdr.sh_size += out_shdr.sh_entsize * relocs.len;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeRelaSections(self: Object, elf_file: *Elf) !void {
|
||||
_ = self;
|
||||
_ = elf_file;
|
||||
const gpa = elf_file.base.allocator;
|
||||
const gop = try elf_file.output_rela_sections.getOrPut(gpa, out_shndx);
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
try gop.value_ptr.append(gpa, atom_index);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {
|
||||
|
||||
@ -21,7 +21,7 @@ verdef_sect_index: ?u16 = null,
|
||||
needed: bool,
|
||||
alive: bool,
|
||||
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
|
||||
pub fn isSharedObject(path: []const u8) !bool {
|
||||
const file = try std.fs.cwd().openFile(path, .{});
|
||||
|
||||
@ -107,6 +107,24 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true }, elf_file: *Elf
|
||||
return symbol.value;
|
||||
}
|
||||
|
||||
pub fn outputSymtabIndex(symbol: Symbol, elf_file: *Elf) u32 {
|
||||
assert(symbol.flags.output_symtab);
|
||||
const file_ptr = symbol.file(elf_file).?;
|
||||
const symtab_ctx = switch (file_ptr) {
|
||||
inline else => |x| x.output_symtab_ctx,
|
||||
};
|
||||
const idx = symbol.extra(elf_file).?.symtab;
|
||||
return if (symbol.isLocal(elf_file)) idx + symtab_ctx.ilocal else idx + symtab_ctx.iglobal;
|
||||
}
|
||||
|
||||
pub fn setOutputSymtabIndex(symbol: *Symbol, index: u32, elf_file: *Elf) !void {
|
||||
if (symbol.extra(elf_file)) |extras| {
|
||||
var new_extras = extras;
|
||||
new_extras.symtab = index;
|
||||
symbol.setExtra(new_extras, elf_file);
|
||||
} else try symbol.addExtra(.{ .symtab = index }, elf_file);
|
||||
}
|
||||
|
||||
pub fn gotAddress(symbol: Symbol, elf_file: *Elf) u64 {
|
||||
if (!symbol.flags.has_got) return 0;
|
||||
const extras = symbol.extra(elf_file).?;
|
||||
@ -388,6 +406,7 @@ pub const Extra = struct {
|
||||
plt: u32 = 0,
|
||||
plt_got: u32 = 0,
|
||||
dynamic: u32 = 0,
|
||||
symtab: u32 = 0,
|
||||
copy_rel: u32 = 0,
|
||||
tlsgd: u32 = 0,
|
||||
gottp: u32 = 0,
|
||||
|
||||
@ -18,7 +18,7 @@ relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{},
|
||||
|
||||
num_dynrelocs: u32 = 0,
|
||||
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
output_ar_state: Archive.ArState = .{},
|
||||
|
||||
dwarf: ?Dwarf = null,
|
||||
@ -533,94 +533,17 @@ pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void {
|
||||
try writer.writeAll(contents);
|
||||
}
|
||||
|
||||
pub fn updateRelaSectionsSizes(self: ZigObject, elf_file: *Elf) void {
|
||||
_ = self;
|
||||
pub fn addAtomsToRelaSections(self: ZigObject, elf_file: *Elf) !void {
|
||||
for (self.atoms.items) |atom_index| {
|
||||
const atom = elf_file.atom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
_ = atom.relocsShndx() orelse continue;
|
||||
const out_shndx = atom.outputShndx().?;
|
||||
|
||||
for (&[_]?u16{
|
||||
elf_file.zig_text_rela_section_index,
|
||||
elf_file.zig_data_rel_ro_rela_section_index,
|
||||
elf_file.zig_data_rela_section_index,
|
||||
}) |maybe_index| {
|
||||
const index = maybe_index orelse continue;
|
||||
const shdr = &elf_file.shdrs.items[index];
|
||||
const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?;
|
||||
const last_atom_index = meta.last_atom_index;
|
||||
|
||||
var atom = elf_file.atom(last_atom_index) orelse continue;
|
||||
while (true) {
|
||||
const relocs = atom.relocs(elf_file);
|
||||
shdr.sh_size += relocs.len * shdr.sh_entsize;
|
||||
if (elf_file.atom(atom.prev_index)) |prev| {
|
||||
atom = prev;
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
|
||||
for (&[_]?u16{
|
||||
elf_file.zig_text_rela_section_index,
|
||||
elf_file.zig_data_rel_ro_rela_section_index,
|
||||
elf_file.zig_data_rela_section_index,
|
||||
}) |maybe_index| {
|
||||
const index = maybe_index orelse continue;
|
||||
const shdr = &elf_file.shdrs.items[index];
|
||||
if (shdr.sh_size == 0) shdr.sh_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.allocator;
|
||||
|
||||
for (&[_]?u16{
|
||||
elf_file.zig_text_rela_section_index,
|
||||
elf_file.zig_data_rel_ro_rela_section_index,
|
||||
elf_file.zig_data_rela_section_index,
|
||||
}) |maybe_index| {
|
||||
const index = maybe_index orelse continue;
|
||||
const shdr = elf_file.shdrs.items[index];
|
||||
const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?;
|
||||
const last_atom_index = meta.last_atom_index;
|
||||
|
||||
var atom = elf_file.atom(last_atom_index) orelse continue;
|
||||
|
||||
var relocs = std.ArrayList(elf.Elf64_Rela).init(gpa);
|
||||
defer relocs.deinit();
|
||||
try relocs.ensureTotalCapacityPrecise(@intCast(@divExact(shdr.sh_size, shdr.sh_entsize)));
|
||||
|
||||
while (true) {
|
||||
for (atom.relocs(elf_file)) |rel| {
|
||||
const target = elf_file.symbol(self.symbol(rel.r_sym()));
|
||||
const r_offset = atom.value + rel.r_offset;
|
||||
const r_sym: u32 = if (target.flags.global)
|
||||
(target.esym_index & symbol_mask) + @as(u32, @intCast(self.local_esyms.slice().len))
|
||||
else
|
||||
target.esym_index;
|
||||
const r_type = switch (rel.r_type()) {
|
||||
Elf.R_X86_64_ZIG_GOT32,
|
||||
Elf.R_X86_64_ZIG_GOTPCREL,
|
||||
=> unreachable, // Sanity check if we accidentally emitted those.
|
||||
else => |r_type| r_type,
|
||||
};
|
||||
relocs.appendAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = rel.r_addend,
|
||||
.r_info = (@as(u64, @intCast(r_sym + 1)) << 32) | r_type,
|
||||
});
|
||||
}
|
||||
if (elf_file.atom(atom.prev_index)) |prev| {
|
||||
atom = prev;
|
||||
} else break;
|
||||
}
|
||||
|
||||
const SortRelocs = struct {
|
||||
pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool {
|
||||
_ = ctx;
|
||||
return lhs.r_offset < rhs.r_offset;
|
||||
}
|
||||
};
|
||||
|
||||
mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan);
|
||||
|
||||
try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset);
|
||||
const gpa = elf_file.base.allocator;
|
||||
const gop = try elf_file.output_rela_sections.getOrPut(gpa, out_shndx);
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
try gop.value_ptr.append(gpa, atom_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -127,9 +127,9 @@ pub const File = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn updateSymtabSize(file: File, elf_file: *Elf) void {
|
||||
const output_symtab_size = switch (file) {
|
||||
inline else => |x| &x.output_symtab_size,
|
||||
pub fn updateSymtabSize(file: File, elf_file: *Elf) !void {
|
||||
const output_symtab_ctx = switch (file) {
|
||||
inline else => |x| &x.output_symtab_ctx,
|
||||
};
|
||||
for (file.locals()) |local_index| {
|
||||
const local = elf_file.symbol(local_index);
|
||||
@ -140,8 +140,9 @@ pub const File = union(enum) {
|
||||
else => {},
|
||||
}
|
||||
local.flags.output_symtab = true;
|
||||
output_symtab_size.nlocals += 1;
|
||||
output_symtab_size.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
|
||||
try local.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file);
|
||||
output_symtab_ctx.nlocals += 1;
|
||||
output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
|
||||
}
|
||||
|
||||
for (file.globals()) |global_index| {
|
||||
@ -151,28 +152,28 @@ pub const File = union(enum) {
|
||||
if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
|
||||
global.flags.output_symtab = true;
|
||||
if (global.isLocal(elf_file)) {
|
||||
output_symtab_size.nlocals += 1;
|
||||
try global.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file);
|
||||
output_symtab_ctx.nlocals += 1;
|
||||
} else {
|
||||
output_symtab_size.nglobals += 1;
|
||||
try global.setOutputSymtabIndex(output_symtab_ctx.nglobals, elf_file);
|
||||
output_symtab_ctx.nglobals += 1;
|
||||
}
|
||||
output_symtab_size.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
|
||||
output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(file: File, elf_file: *Elf, ctx: anytype) void {
|
||||
var ilocal: usize = ctx.ilocal;
|
||||
pub fn writeSymtab(file: File, elf_file: *Elf) void {
|
||||
for (file.locals()) |local_index| {
|
||||
const local = elf_file.symbol(local_index);
|
||||
if (!local.flags.output_symtab) continue;
|
||||
const out_sym = &elf_file.symtab.items[ilocal];
|
||||
const idx = local.outputSymtabIndex(elf_file);
|
||||
const out_sym = &elf_file.symtab.items[idx];
|
||||
out_sym.st_name = @intCast(elf_file.strtab.items.len);
|
||||
elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file));
|
||||
elf_file.strtab.appendAssumeCapacity(0);
|
||||
local.setOutputSym(elf_file, out_sym);
|
||||
ilocal += 1;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -181,17 +182,10 @@ pub const File = union(enum) {
|
||||
const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
|
||||
elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
|
||||
elf_file.strtab.appendAssumeCapacity(0);
|
||||
if (global.isLocal(elf_file)) {
|
||||
const out_sym = &elf_file.symtab.items[ilocal];
|
||||
out_sym.st_name = st_name;
|
||||
global.setOutputSym(elf_file, out_sym);
|
||||
ilocal += 1;
|
||||
} else {
|
||||
const out_sym = &elf_file.symtab.items[iglobal];
|
||||
out_sym.st_name = st_name;
|
||||
global.setOutputSym(elf_file, out_sym);
|
||||
iglobal += 1;
|
||||
}
|
||||
const idx = global.outputSymtabIndex(elf_file);
|
||||
const out_sym = &elf_file.symtab.items[idx];
|
||||
out_sym.st_name = st_name;
|
||||
global.setOutputSym(elf_file, out_sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -222,7 +222,7 @@ pub const DynamicSection = struct {
|
||||
|
||||
pub const ZigGotSection = struct {
|
||||
entries: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
flags: Flags = .{},
|
||||
|
||||
const Flags = packed struct {
|
||||
@ -359,15 +359,15 @@ pub const ZigGotSection = struct {
|
||||
}
|
||||
|
||||
pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {
|
||||
zig_got.output_symtab_size.nlocals = @as(u32, @intCast(zig_got.entries.items.len));
|
||||
zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len));
|
||||
for (zig_got.entries.items) |entry| {
|
||||
const name = elf_file.symbol(entry).name(elf_file);
|
||||
zig_got.output_symtab_size.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1;
|
||||
zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf, ctx: anytype) void {
|
||||
for (zig_got.entries.items, ctx.ilocal.., 0..) |entry, ilocal, index| {
|
||||
pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void {
|
||||
for (zig_got.entries.items, zig_got.output_symtab_ctx.ilocal.., 0..) |entry, ilocal, index| {
|
||||
const symbol = elf_file.symbol(entry);
|
||||
const symbol_name = symbol.name(elf_file);
|
||||
const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
|
||||
@ -420,7 +420,7 @@ pub const ZigGotSection = struct {
|
||||
|
||||
pub const GotSection = struct {
|
||||
entries: std.ArrayListUnmanaged(Entry) = .{},
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
tlsld_index: ?u32 = null,
|
||||
flags: Flags = .{},
|
||||
|
||||
@ -760,18 +760,18 @@ pub const GotSection = struct {
|
||||
}
|
||||
|
||||
pub fn updateSymtabSize(got: *GotSection, elf_file: *Elf) void {
|
||||
got.output_symtab_size.nlocals = @as(u32, @intCast(got.entries.items.len));
|
||||
got.output_symtab_ctx.nlocals = @as(u32, @intCast(got.entries.items.len));
|
||||
for (got.entries.items) |entry| {
|
||||
const symbol_name = switch (entry.tag) {
|
||||
.tlsld => "",
|
||||
inline else => elf_file.symbol(entry.symbol_index).name(elf_file),
|
||||
};
|
||||
got.output_symtab_size.strsize += @as(u32, @intCast(symbol_name.len + @tagName(entry.tag).len)) + 1 + 1;
|
||||
got.output_symtab_ctx.strsize += @as(u32, @intCast(symbol_name.len + @tagName(entry.tag).len)) + 1 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(got: GotSection, elf_file: *Elf, ctx: anytype) void {
|
||||
for (got.entries.items, ctx.ilocal..) |entry, ilocal| {
|
||||
pub fn writeSymtab(got: GotSection, elf_file: *Elf) void {
|
||||
for (got.entries.items, got.output_symtab_ctx.ilocal..) |entry, ilocal| {
|
||||
const symbol = switch (entry.tag) {
|
||||
.tlsld => null,
|
||||
inline else => elf_file.symbol(entry.symbol_index),
|
||||
@ -831,7 +831,7 @@ pub const GotSection = struct {
|
||||
|
||||
pub const PltSection = struct {
|
||||
symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
|
||||
pub const preamble_size = 32;
|
||||
|
||||
@ -909,15 +909,15 @@ pub const PltSection = struct {
|
||||
}
|
||||
|
||||
pub fn updateSymtabSize(plt: *PltSection, elf_file: *Elf) void {
|
||||
plt.output_symtab_size.nlocals = @as(u32, @intCast(plt.symbols.items.len));
|
||||
plt.output_symtab_ctx.nlocals = @as(u32, @intCast(plt.symbols.items.len));
|
||||
for (plt.symbols.items) |sym_index| {
|
||||
const name = elf_file.symbol(sym_index).name(elf_file);
|
||||
plt.output_symtab_size.strsize += @as(u32, @intCast(name.len + "$plt".len)) + 1;
|
||||
plt.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$plt".len)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(plt: PltSection, elf_file: *Elf, ctx: anytype) void {
|
||||
var ilocal = ctx.ilocal;
|
||||
pub fn writeSymtab(plt: PltSection, elf_file: *Elf) void {
|
||||
var ilocal = plt.output_symtab_ctx.ilocal;
|
||||
for (plt.symbols.items) |sym_index| {
|
||||
const sym = elf_file.symbol(sym_index);
|
||||
const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
|
||||
@ -968,7 +968,7 @@ pub const GotPltSection = struct {
|
||||
|
||||
pub const PltGotSection = struct {
|
||||
symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
output_symtab_ctx: Elf.SymtabCtx = .{},
|
||||
|
||||
pub fn deinit(plt_got: *PltGotSection, allocator: Allocator) void {
|
||||
plt_got.symbols.deinit(allocator);
|
||||
@ -1008,15 +1008,15 @@ pub const PltGotSection = struct {
|
||||
}
|
||||
|
||||
pub fn updateSymtabSize(plt_got: *PltGotSection, elf_file: *Elf) void {
|
||||
plt_got.output_symtab_size.nlocals = @as(u32, @intCast(plt_got.symbols.items.len));
|
||||
plt_got.output_symtab_ctx.nlocals = @as(u32, @intCast(plt_got.symbols.items.len));
|
||||
for (plt_got.symbols.items) |sym_index| {
|
||||
const name = elf_file.symbol(sym_index).name(elf_file);
|
||||
plt_got.output_symtab_size.strsize += @as(u32, @intCast(name.len + "$pltgot".len)) + 1;
|
||||
plt_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$pltgot".len)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(plt_got: PltGotSection, elf_file: *Elf, ctx: anytype) void {
|
||||
var ilocal = ctx.ilocal;
|
||||
pub fn writeSymtab(plt_got: PltGotSection, elf_file: *Elf) void {
|
||||
var ilocal = plt_got.output_symtab_ctx.ilocal;
|
||||
for (plt_got.symbols.items) |sym_index| {
|
||||
const sym = elf_file.symbol(sym_index);
|
||||
const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user