link: make Elf atoms fully owned by the linker
This commit is contained in:
@@ -5275,7 +5275,7 @@ pub fn clearDecl(
|
||||
// and allow it to be variably sized.
|
||||
decl.link = switch (mod.comp.bin_file.tag) {
|
||||
.coff => .{ .coff = link.File.Coff.Atom.empty },
|
||||
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
|
||||
.elf => .{ .elf = {} },
|
||||
.macho => .{ .macho = {} },
|
||||
.plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
|
||||
.c => .{ .c = {} },
|
||||
@@ -5381,7 +5381,7 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void
|
||||
}
|
||||
}
|
||||
if (mod.comp.bin_file.cast(link.File.Elf)) |elf| {
|
||||
elf.deleteExport(exp.link.elf);
|
||||
elf.deleteDeclExport(decl_index, exp.options.name);
|
||||
}
|
||||
if (mod.comp.bin_file.cast(link.File.MachO)) |macho| {
|
||||
try macho.deleteDeclExport(decl_index, exp.options.name);
|
||||
@@ -5695,7 +5695,7 @@ pub fn allocateNewDecl(
|
||||
.src_scope = src_scope,
|
||||
.link = switch (mod.comp.bin_file.tag) {
|
||||
.coff => .{ .coff = link.File.Coff.Atom.empty },
|
||||
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
|
||||
.elf => .{ .elf = {} },
|
||||
.macho => .{ .macho = {} },
|
||||
.plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
|
||||
.c => .{ .c = {} },
|
||||
|
||||
@@ -5566,7 +5566,7 @@ pub fn analyzeExport(
|
||||
.src = src,
|
||||
.link = switch (mod.comp.bin_file.tag) {
|
||||
.coff => .{ .coff = .{} },
|
||||
.elf => .{ .elf = .{} },
|
||||
.elf => .{ .elf = {} },
|
||||
.macho => .{ .macho = {} },
|
||||
.plan9 => .{ .plan9 = null },
|
||||
.c => .{ .c = {} },
|
||||
|
||||
@@ -4308,8 +4308,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try fn_owner_decl.link.elf.ensureInitialized(elf_file);
|
||||
const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file));
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file));
|
||||
try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = got_addr });
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
@@ -6138,8 +6139,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
|
||||
mod.markDeclAlive(decl);
|
||||
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try decl.link.elf.ensureInitialized(elf_file);
|
||||
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
|
||||
const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
@@ -6168,8 +6170,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
|
||||
return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
|
||||
};
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
const vaddr = elf_file.local_symbols.items[local_sym_index].st_value;
|
||||
return MCValue{ .memory = vaddr };
|
||||
return MCValue{ .memory = elf_file.getSymbol(local_sym_index).st_value };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
return MCValue{ .linker_load = .{
|
||||
.type = .direct,
|
||||
|
||||
@@ -4256,12 +4256,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
||||
if (self.air.value(callee)) |func_value| {
|
||||
if (func_value.castTag(.function)) |func_payload| {
|
||||
const func = func_payload.data;
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try fn_owner_decl.link.elf.ensureInitialized(elf_file);
|
||||
const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file));
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file));
|
||||
try self.genSetReg(Type.initTag(.usize), .lr, .{ .memory = got_addr });
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
unreachable; // unsupported architecture for MachO
|
||||
@@ -6084,8 +6083,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
|
||||
mod.markDeclAlive(decl);
|
||||
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try decl.link.elf.ensureInitialized(elf_file);
|
||||
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
unreachable; // unsupported architecture for MachO
|
||||
} else if (self.bin_file.cast(link.File.Coff)) |_| {
|
||||
@@ -6106,8 +6106,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
|
||||
return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
|
||||
};
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
const vaddr = elf_file.local_symbols.items[local_sym_index].st_value;
|
||||
return MCValue{ .memory = vaddr };
|
||||
return MCValue{ .memory = elf_file.getSymbol(local_sym_index).st_value };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
unreachable;
|
||||
} else if (self.bin_file.cast(link.File.Coff)) |_| {
|
||||
|
||||
@@ -1721,12 +1721,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
||||
if (self.air.value(callee)) |func_value| {
|
||||
if (func_value.castTag(.function)) |func_payload| {
|
||||
const func = func_payload.data;
|
||||
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
try fn_owner_decl.link.elf.ensureInitialized(elf_file);
|
||||
const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file));
|
||||
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file));
|
||||
try self.genSetReg(Type.initTag(.usize), .ra, .{ .memory = got_addr });
|
||||
_ = try self.addInst(.{
|
||||
.tag = .jalr,
|
||||
@@ -2553,8 +2550,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
|
||||
const decl = mod.declPtr(decl_index);
|
||||
mod.markDeclAlive(decl);
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try decl.link.elf.ensureInitialized(elf_file);
|
||||
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
unreachable;
|
||||
} else if (self.bin_file.cast(link.File.Coff)) |_| {
|
||||
|
||||
@@ -1216,11 +1216,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
||||
if (self.bin_file.tag == link.File.Elf.base_tag) {
|
||||
if (func_value.castTag(.function)) |func_payload| {
|
||||
const func = func_payload.data;
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
|
||||
try fn_owner_decl.link.elf.ensureInitialized(elf_file);
|
||||
break :blk @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file));
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
break :blk @intCast(u32, atom.getOffsetTableAddress(elf_file));
|
||||
} else unreachable;
|
||||
|
||||
try self.genSetReg(Type.initTag(.usize), .o7, .{ .memory = got_addr });
|
||||
@@ -4205,8 +4204,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
|
||||
|
||||
mod.markDeclAlive(decl);
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try decl.link.elf.ensureInitialized(elf_file);
|
||||
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) };
|
||||
} else {
|
||||
return self.fail("TODO codegen non-ELF const Decl pointer", .{});
|
||||
}
|
||||
|
||||
@@ -4000,8 +4000,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try fn_owner_decl.link.elf.ensureInitialized(elf_file);
|
||||
const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file));
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file));
|
||||
_ = try self.addInst(.{
|
||||
.tag = .call,
|
||||
.ops = Mir.Inst.Ops.encode(.{ .flags = 0b01 }),
|
||||
@@ -6721,8 +6722,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
|
||||
module.markDeclAlive(decl);
|
||||
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
try decl.link.elf.ensureInitialized(elf_file);
|
||||
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
|
||||
const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
|
||||
@@ -6751,8 +6753,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
|
||||
return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
|
||||
};
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
const vaddr = elf_file.local_symbols.items[local_sym_index].st_value;
|
||||
return MCValue{ .memory = vaddr };
|
||||
return MCValue{ .memory = elf_file.getSymbol(local_sym_index).st_value };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
return MCValue{ .linker_load = .{
|
||||
.type = .direct,
|
||||
|
||||
@@ -262,7 +262,7 @@ pub const File = struct {
|
||||
lock: ?Cache.Lock = null,
|
||||
|
||||
pub const LinkBlock = union {
|
||||
elf: Elf.TextBlock,
|
||||
elf: void,
|
||||
coff: Coff.Atom,
|
||||
macho: void,
|
||||
plan9: Plan9.DeclBlock,
|
||||
@@ -284,7 +284,7 @@ pub const File = struct {
|
||||
};
|
||||
|
||||
pub const Export = union {
|
||||
elf: Elf.Export,
|
||||
elf: void,
|
||||
coff: Coff.Export,
|
||||
macho: void,
|
||||
plan9: Plan9.Export,
|
||||
|
||||
@@ -1099,7 +1099,7 @@ pub fn commitDeclState(
|
||||
switch (self.bin_file.tag) {
|
||||
.elf => {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const debug_line_sect = &elf_file.sections.items[elf_file.debug_line_section_index.?];
|
||||
const debug_line_sect = &elf_file.sections.items(.shdr)[elf_file.debug_line_section_index.?];
|
||||
const file_pos = debug_line_sect.sh_offset + src_fn.off;
|
||||
try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
|
||||
},
|
||||
@@ -1152,7 +1152,7 @@ pub fn commitDeclState(
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const shdr_index = elf_file.debug_line_section_index.?;
|
||||
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
|
||||
const debug_line_sect = elf_file.sections.items[shdr_index];
|
||||
const debug_line_sect = elf_file.sections.items(.shdr)[shdr_index];
|
||||
const file_pos = debug_line_sect.sh_offset + src_fn.off;
|
||||
try pwriteDbgLineNops(
|
||||
elf_file.base.file.?,
|
||||
@@ -1332,7 +1332,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void {
|
||||
switch (self.bin_file.tag) {
|
||||
.elf => {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];
|
||||
const debug_info_sect = &elf_file.sections.items(.shdr)[elf_file.debug_info_section_index.?];
|
||||
const file_pos = debug_info_sect.sh_offset + atom.off;
|
||||
try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
|
||||
},
|
||||
@@ -1399,7 +1399,7 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const shdr_index = elf_file.debug_info_section_index.?;
|
||||
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
|
||||
const debug_info_sect = elf_file.sections.items[shdr_index];
|
||||
const debug_info_sect = elf_file.sections.items(.shdr)[shdr_index];
|
||||
const file_pos = debug_info_sect.sh_offset + atom.off;
|
||||
try pwriteDbgInfoNops(
|
||||
elf_file.base.file.?,
|
||||
@@ -1475,7 +1475,7 @@ pub fn updateDeclLineNumber(self: *Dwarf, decl: *const Module.Decl) !void {
|
||||
switch (self.bin_file.tag) {
|
||||
.elf => {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const shdr = elf_file.sections.items[elf_file.debug_line_section_index.?];
|
||||
const shdr = elf_file.sections.items(.shdr)[elf_file.debug_line_section_index.?];
|
||||
const file_pos = shdr.sh_offset + decl.fn_link.elf.off + self.getRelocDbgLineOff();
|
||||
try elf_file.base.file.?.pwriteAll(&data, file_pos);
|
||||
},
|
||||
@@ -1690,7 +1690,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const shdr_index = elf_file.debug_abbrev_section_index.?;
|
||||
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, false);
|
||||
const debug_abbrev_sect = elf_file.sections.items[shdr_index];
|
||||
const debug_abbrev_sect = elf_file.sections.items(.shdr)[shdr_index];
|
||||
const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;
|
||||
try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
|
||||
},
|
||||
@@ -1805,7 +1805,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
|
||||
switch (self.bin_file.tag) {
|
||||
.elf => {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const debug_info_sect = elf_file.sections.items[elf_file.debug_info_section_index.?];
|
||||
const debug_info_sect = elf_file.sections.items(.shdr)[elf_file.debug_info_section_index.?];
|
||||
const file_pos = debug_info_sect.sh_offset;
|
||||
try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
|
||||
},
|
||||
@@ -2124,7 +2124,7 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const shdr_index = elf_file.debug_aranges_section_index.?;
|
||||
try elf_file.growNonAllocSection(shdr_index, needed_size, 16, false);
|
||||
const debug_aranges_sect = elf_file.sections.items[shdr_index];
|
||||
const debug_aranges_sect = elf_file.sections.items(.shdr)[shdr_index];
|
||||
const file_pos = debug_aranges_sect.sh_offset;
|
||||
try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);
|
||||
},
|
||||
@@ -2285,9 +2285,9 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
|
||||
.elf => {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const shdr_index = elf_file.debug_line_section_index.?;
|
||||
const needed_size = elf_file.sections.items[shdr_index].sh_size + delta;
|
||||
const needed_size = elf_file.sections.items(.shdr)[shdr_index].sh_size + delta;
|
||||
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
|
||||
const file_pos = elf_file.sections.items[shdr_index].sh_offset + src_fn.off;
|
||||
const file_pos = elf_file.sections.items(.shdr)[shdr_index].sh_offset + src_fn.off;
|
||||
|
||||
const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);
|
||||
if (amt != buffer.len) return error.InputOutput;
|
||||
@@ -2346,7 +2346,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
|
||||
switch (self.bin_file.tag) {
|
||||
.elf => {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const debug_line_sect = elf_file.sections.items[elf_file.debug_line_section_index.?];
|
||||
const debug_line_sect = elf_file.sections.items(.shdr)[elf_file.debug_line_section_index.?];
|
||||
const file_pos = debug_line_sect.sh_offset;
|
||||
try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
|
||||
},
|
||||
@@ -2487,7 +2487,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
|
||||
switch (self.bin_file.tag) {
|
||||
.elf => {
|
||||
const elf_file = self.bin_file.cast(File.Elf).?;
|
||||
const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];
|
||||
const debug_info_sect = &elf_file.sections.items(.shdr)[elf_file.debug_info_section_index.?];
|
||||
break :blk debug_info_sect.sh_offset;
|
||||
},
|
||||
.macho => {
|
||||
@@ -2638,7 +2638,7 @@ fn addDbgInfoErrorSet(
|
||||
fn getDbgInfoAtom(tag: File.Tag, mod: *Module, decl_index: Module.Decl.Index) *Atom {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
return switch (tag) {
|
||||
.elf => &decl.link.elf.dbg_info_atom,
|
||||
.elf => unreachable,
|
||||
.macho => unreachable,
|
||||
.wasm => &decl.link.wasm.dbg_info_atom,
|
||||
else => unreachable,
|
||||
|
||||
1535
src/link/Elf.zig
1535
src/link/Elf.zig
File diff suppressed because it is too large
Load Diff
@@ -20,44 +20,35 @@ offset_table_index: u32,
|
||||
|
||||
/// Points to the previous and next neighbors, based on the `text_offset`.
|
||||
/// This can be used to find, for example, the capacity of this `TextBlock`.
|
||||
prev: ?*Atom,
|
||||
next: ?*Atom,
|
||||
prev_index: ?Atom.Index,
|
||||
next_index: ?Atom.Index,
|
||||
|
||||
dbg_info_atom: Dwarf.Atom,
|
||||
|
||||
pub const empty = Atom{
|
||||
.local_sym_index = 0,
|
||||
.offset_table_index = undefined,
|
||||
.prev = null,
|
||||
.next = null,
|
||||
.dbg_info_atom = undefined,
|
||||
};
|
||||
pub const Index = u32;
|
||||
|
||||
pub fn ensureInitialized(self: *Atom, elf_file: *Elf) !void {
|
||||
if (self.getSymbolIndex() != null) return; // Already initialized
|
||||
self.local_sym_index = try elf_file.allocateLocalSymbol();
|
||||
self.offset_table_index = try elf_file.allocateGotOffset();
|
||||
try elf_file.atom_by_index_table.putNoClobber(elf_file.base.allocator, self.local_sym_index, self);
|
||||
}
|
||||
pub const Reloc = struct {
|
||||
target: u32,
|
||||
offset: u64,
|
||||
addend: u32,
|
||||
prev_vaddr: u64,
|
||||
};
|
||||
|
||||
pub fn getSymbolIndex(self: Atom) ?u32 {
|
||||
if (self.local_sym_index == 0) return null;
|
||||
return self.local_sym_index;
|
||||
}
|
||||
|
||||
pub fn getSymbol(self: Atom, elf_file: *Elf) elf.Elf64_Sym {
|
||||
const sym_index = self.getSymbolIndex().?;
|
||||
return elf_file.local_symbols.items[sym_index];
|
||||
pub fn getSymbol(self: Atom, elf_file: *const Elf) elf.Elf64_Sym {
|
||||
return elf_file.getSymbol(self.getSymbolIndex().?);
|
||||
}
|
||||
|
||||
pub fn getSymbolPtr(self: Atom, elf_file: *Elf) *elf.Elf64_Sym {
|
||||
const sym_index = self.getSymbolIndex().?;
|
||||
return &elf_file.local_symbols.items[sym_index];
|
||||
return elf_file.getSymbolPtr(self.getSymbolIndex().?);
|
||||
}
|
||||
|
||||
pub fn getName(self: Atom, elf_file: *Elf) []const u8 {
|
||||
const sym = self.getSymbol();
|
||||
return elf_file.getString(sym.st_name);
|
||||
pub fn getName(self: Atom, elf_file: *const Elf) []const u8 {
|
||||
return elf_file.getSymbolName(self.getSymbolIndex().?);
|
||||
}
|
||||
|
||||
pub fn getOffsetTableAddress(self: Atom, elf_file: *Elf) u64 {
|
||||
@@ -72,9 +63,10 @@ pub fn getOffsetTableAddress(self: Atom, elf_file: *Elf) u64 {
|
||||
/// Returns how much room there is to grow in virtual address space.
|
||||
/// File offset relocation happens transparently, so it is not included in
|
||||
/// this calculation.
|
||||
pub fn capacity(self: Atom, elf_file: *Elf) u64 {
|
||||
pub fn capacity(self: Atom, elf_file: *const Elf) u64 {
|
||||
const self_sym = self.getSymbol(elf_file);
|
||||
if (self.next) |next| {
|
||||
if (self.next_index) |next_index| {
|
||||
const next = elf_file.getAtom(next_index);
|
||||
const next_sym = next.getSymbol(elf_file);
|
||||
return next_sym.st_value - self_sym.st_value;
|
||||
} else {
|
||||
@@ -83,9 +75,10 @@ pub fn capacity(self: Atom, elf_file: *Elf) u64 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {
|
||||
pub fn freeListEligible(self: Atom, elf_file: *const Elf) bool {
|
||||
// No need to keep a free list node for the last block.
|
||||
const next = self.next orelse return false;
|
||||
const next_index = self.next_index orelse return false;
|
||||
const next = elf_file.getAtom(next_index);
|
||||
const self_sym = self.getSymbol(elf_file);
|
||||
const next_sym = next.getSymbol(elf_file);
|
||||
const cap = next_sym.st_value - self_sym.st_value;
|
||||
@@ -94,3 +87,17 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {
|
||||
const surplus = cap - ideal_cap;
|
||||
return surplus >= Elf.min_text_capacity;
|
||||
}
|
||||
|
||||
pub fn addRelocation(elf_file: *Elf, atom_index: Index, reloc: Reloc) !void {
|
||||
const gpa = elf_file.base.allocator;
|
||||
const gop = try elf_file.relocs.getOrPut(gpa, atom_index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
try gop.value_ptr.append(gpa, reloc);
|
||||
}
|
||||
|
||||
pub fn freeRelocations(elf_file: *Elf, atom_index: Index) void {
|
||||
var removed_relocs = elf_file.relocs.fetchRemove(atom_index);
|
||||
if (removed_relocs) |*relocs| relocs.value.deinit(elf_file.base.allocator);
|
||||
}
|
||||
|
||||
@@ -2604,9 +2604,11 @@ pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void {
|
||||
|
||||
log.debug("freeDecl {*}", .{decl});
|
||||
|
||||
if (self.decls.fetchSwapRemove(decl_index)) |kv| {
|
||||
if (self.decls.fetchSwapRemove(decl_index)) |const_kv| {
|
||||
var kv = const_kv;
|
||||
self.freeAtom(kv.value.atom);
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
kv.value.exports.deinit(self.base.allocator);
|
||||
}
|
||||
|
||||
// if (self.d_sym) |*d_sym| {
|
||||
|
||||
Reference in New Issue
Block a user