mirror of
https://github.com/ziglang/zig.git
synced 2026-02-19 07:48:31 +00:00
plan9: revamp the relocation system to allow decl refs
This commit is contained in:
parent
4dac9f54dd
commit
5343a2f566
@ -130,6 +130,8 @@ const Owner = union(enum) {
|
||||
} else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
|
||||
return coff_file.getAtom(atom).getSymbolIndex().?;
|
||||
} else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| {
|
||||
return p9_file.seeDecl(decl_index);
|
||||
} else unreachable;
|
||||
},
|
||||
.lazy_sym => |lazy_sym| {
|
||||
@ -141,6 +143,9 @@ const Owner = union(enum) {
|
||||
const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
|
||||
return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
return coff_file.getAtom(atom).getSymbolIndex().?;
|
||||
} else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| {
|
||||
return p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
|
||||
return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
} else unreachable;
|
||||
},
|
||||
}
|
||||
|
||||
@ -118,6 +118,14 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.pcrel = true,
|
||||
.length = 2,
|
||||
});
|
||||
} else if (emit.bin_file.cast(link.File.Plan9)) |p9_file| {
|
||||
const atom_index = symbol.atom_index;
|
||||
try p9_file.addReloc(atom_index, .{ // TODO we may need to add a .type field to the relocs if they are .linker_got instead of just .linker_direct
|
||||
.target = symbol.sym_index, // we set sym_index to just be the atom index
|
||||
.offset = @intCast(u32, end_offset - 4),
|
||||
.addend = 0,
|
||||
.pcrel = true,
|
||||
});
|
||||
} else return emit.fail("TODO implement linker reloc for {s}", .{
|
||||
@tagName(emit.bin_file.tag),
|
||||
}),
|
||||
|
||||
@ -879,12 +879,9 @@ fn genUnnamedConst(
|
||||
return GenResult.mcv(.{ .load_direct = local_sym_index });
|
||||
} else if (bin_file.cast(link.File.Coff)) |_| {
|
||||
return GenResult.mcv(.{ .load_direct = local_sym_index });
|
||||
} else if (bin_file.cast(link.File.Plan9)) |p9| {
|
||||
const ptr_bits = target.ptrBitWidth();
|
||||
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
|
||||
const got_index = local_sym_index; // the plan9 backend returns the got_index
|
||||
const got_addr = p9.bases.data + got_index * ptr_bytes;
|
||||
return GenResult.mcv(.{ .memory = got_addr });
|
||||
} else if (bin_file.cast(link.File.Plan9)) |_| {
|
||||
const atom_index = local_sym_index; // plan9 returns the atom_index
|
||||
return GenResult.mcv(.{ .load_direct = atom_index });
|
||||
} else {
|
||||
return GenResult.fail(bin_file.allocator, src_loc, "TODO genUnnamedConst for target {}", .{target});
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ unnamed_const_atoms: UnnamedConstTable = .{},
|
||||
|
||||
lazy_syms: LazySymbolTable = .{},
|
||||
|
||||
relocs: std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Reloc)) = .{},
|
||||
relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{},
|
||||
hdr: aout.ExecHdr = undefined,
|
||||
|
||||
// relocs: std.
|
||||
@ -100,9 +100,10 @@ atoms: std.ArrayListUnmanaged(Atom) = .{},
|
||||
decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
|
||||
|
||||
const Reloc = struct {
|
||||
target: Module.Decl.Index,
|
||||
target: Atom.Index,
|
||||
offset: u64,
|
||||
addend: u32,
|
||||
pcrel: bool = false,
|
||||
};
|
||||
|
||||
const Bases = struct {
|
||||
@ -111,7 +112,7 @@ const Bases = struct {
|
||||
data: u64,
|
||||
};
|
||||
|
||||
const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(struct { info: Atom, code: []const u8 }));
|
||||
const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));
|
||||
|
||||
const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
|
||||
|
||||
@ -140,12 +141,36 @@ pub const Atom = struct {
|
||||
sym_index: ?usize,
|
||||
/// offset into got
|
||||
got_index: ?usize,
|
||||
/// We can optionally store code with the atom
|
||||
/// It is still owned by whatever created it
|
||||
/// This can be useful so that we don't need
|
||||
/// to setup so much infrastructure just to store code
|
||||
/// for stuff like LazySymbols.
|
||||
code: ?[]const u8 = null,
|
||||
/// We include the code here to be use in relocs
|
||||
/// In the case of unnamed_const_atoms and lazy_syms, this atom owns the code.
|
||||
/// But, in the case of function and data decls, they own the code and this field
|
||||
/// is just a pointer for convience.
|
||||
code: CodePtr,
|
||||
|
||||
const CodePtr = struct {
|
||||
code_ptr: ?[*]u8,
|
||||
other: union {
|
||||
code_len: usize,
|
||||
decl_index: Module.Decl.Index,
|
||||
},
|
||||
fn getCode(self: CodePtr, plan9: *const Plan9) []u8 {
|
||||
const mod = plan9.base.options.module.?;
|
||||
return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {
|
||||
const decl_index = self.other.decl_index;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (decl.ty.zigTypeTag(mod) == .Fn) {
|
||||
const table = plan9.fn_decl_table.get(decl.getFileScope(mod)).?.functions;
|
||||
const output = table.get(decl_index).?;
|
||||
break :blk output.code;
|
||||
} else {
|
||||
break :blk plan9.data_decl_table.get(decl_index).?;
|
||||
}
|
||||
};
|
||||
}
|
||||
fn getOwnedCode(self: CodePtr) ?[]u8 {
|
||||
return if (self.code_ptr) |p| p[0..self.other.code_len] else null;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Index = u32;
|
||||
|
||||
@ -329,7 +354,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: Module.Fn.Index, air:
|
||||
const decl = mod.declPtr(decl_index);
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
|
||||
_ = try self.seeDecl(decl_index);
|
||||
const atom_idx = try self.seeDecl(decl_index);
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
@ -363,6 +388,10 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: Module.Fn.Index, air:
|
||||
return;
|
||||
},
|
||||
};
|
||||
self.getAtomPtr(atom_idx).code = .{
|
||||
.code_ptr = null,
|
||||
.other = .{ .decl_index = decl_index },
|
||||
};
|
||||
const out: FnDeclOutput = .{
|
||||
.code = code,
|
||||
.lineinfo = try dbg_line_buffer.toOwnedSlice(),
|
||||
@ -394,12 +423,13 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
|
||||
const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl_name, index });
|
||||
|
||||
const sym_index = try self.allocateSymbolIndex();
|
||||
|
||||
const info: Atom = .{
|
||||
const new_atom_idx = try self.createAtom();
|
||||
var info: Atom = .{
|
||||
.type = .d,
|
||||
.offset = null,
|
||||
.sym_index = sym_index,
|
||||
.got_index = self.allocateGotIndex(),
|
||||
.code = undefined, // filled in later
|
||||
};
|
||||
const sym: aout.Sym = .{
|
||||
.value = undefined,
|
||||
@ -411,7 +441,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), tv, &code_buffer, .{
|
||||
.none = {},
|
||||
}, .{
|
||||
.parent_atom_index = @enumToInt(decl_index),
|
||||
.parent_atom_index = new_atom_idx,
|
||||
});
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
@ -425,9 +455,12 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
|
||||
// duped_code is freed when the unnamed const is freed
|
||||
var duped_code = try self.base.allocator.dupe(u8, code);
|
||||
errdefer self.base.allocator.free(duped_code);
|
||||
try unnamed_consts.append(self.base.allocator, .{ .info = info, .code = duped_code });
|
||||
// we return the got_index to codegen so that it can reference to the place of the data in the got
|
||||
return @intCast(u32, info.got_index.?);
|
||||
const new_atom = self.getAtomPtr(new_atom_idx);
|
||||
new_atom.* = info;
|
||||
new_atom.code = .{ .code_ptr = duped_code.ptr, .other = .{ .code_len = duped_code.len } };
|
||||
try unnamed_consts.append(self.base.allocator, new_atom_idx);
|
||||
// we return the new_atom_idx to codegen
|
||||
return new_atom_idx;
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !void {
|
||||
@ -442,7 +475,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !vo
|
||||
}
|
||||
}
|
||||
|
||||
_ = try self.seeDecl(decl_index);
|
||||
const atom_idx = try self.seeDecl(decl_index);
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
@ -452,7 +485,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !vo
|
||||
.ty = decl.ty,
|
||||
.val = decl_val,
|
||||
}, &code_buffer, .{ .none = {} }, .{
|
||||
.parent_atom_index = @enumToInt(decl_index),
|
||||
.parent_atom_index = @intCast(Atom.Index, atom_idx),
|
||||
});
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
@ -464,6 +497,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !vo
|
||||
};
|
||||
try self.data_decl_table.ensureUnusedCapacity(self.base.allocator, 1);
|
||||
const duped_code = try self.base.allocator.dupe(u8, code);
|
||||
self.getAtomPtr(self.decls.get(decl_index).?.index).code = .{ .code_ptr = null, .other = .{ .decl_index = decl_index } };
|
||||
if (self.data_decl_table.fetchPutAssumeCapacity(decl_index, duped_code)) |old_entry| {
|
||||
self.base.allocator.free(old_entry.value);
|
||||
}
|
||||
@ -636,6 +670,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
var it = fentry.value_ptr.functions.iterator();
|
||||
while (it.next()) |entry| {
|
||||
const decl_index = entry.key_ptr.*;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);
|
||||
const out = entry.value_ptr.*;
|
||||
{
|
||||
@ -655,6 +690,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
const off = self.getAddr(text_i, .t);
|
||||
text_i += out.code.len;
|
||||
atom.offset = off;
|
||||
log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @intCast(u32, off), self.base.options.target.cpu.arch.endian());
|
||||
} else {
|
||||
@ -677,7 +713,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
while (it.next()) |kv| {
|
||||
const meta = kv.value_ptr;
|
||||
const text_atom = if (meta.text_state != .unused) self.getAtomPtr(meta.text_atom) else continue;
|
||||
const code = text_atom.code.?;
|
||||
const code = text_atom.code.getOwnedCode().?;
|
||||
foff += code.len;
|
||||
iovecs[iovecs_i] = .{ .iov_base = code.ptr, .iov_len = code.len };
|
||||
iovecs_i += 1;
|
||||
@ -725,21 +761,22 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
// write the unnamed constants after the other data decls
|
||||
var it_unc = self.unnamed_const_atoms.iterator();
|
||||
while (it_unc.next()) |unnamed_consts| {
|
||||
for (unnamed_consts.value_ptr.items) |*unnamed_const| {
|
||||
const code = unnamed_const.code;
|
||||
log.debug("write unnamed const: ({s})", .{self.syms.items[unnamed_const.info.sym_index.?].name});
|
||||
for (unnamed_consts.value_ptr.items) |atom_idx| {
|
||||
const atom = self.getAtomPtr(atom_idx);
|
||||
const code = atom.code.getOwnedCode().?; // unnamed consts must own their code
|
||||
log.debug("write unnamed const: ({s})", .{self.syms.items[atom.sym_index.?].name});
|
||||
foff += code.len;
|
||||
iovecs[iovecs_i] = .{ .iov_base = code.ptr, .iov_len = code.len };
|
||||
iovecs_i += 1;
|
||||
const off = self.getAddr(data_i, .d);
|
||||
data_i += code.len;
|
||||
unnamed_const.info.offset = off;
|
||||
atom.offset = off;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[unnamed_const.info.got_index.? * 4 ..][0..4], @intCast(u32, off), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @intCast(u32, off), self.base.options.target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[unnamed_const.info.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[unnamed_const.info.sym_index.?].value = off;
|
||||
self.syms.items[atom.sym_index.?].value = off;
|
||||
}
|
||||
}
|
||||
// the lazy data symbols
|
||||
@ -747,7 +784,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
while (it_lazy.next()) |kv| {
|
||||
const meta = kv.value_ptr;
|
||||
const data_atom = if (meta.rodata_state != .unused) self.getAtomPtr(meta.rodata_atom) else continue;
|
||||
const code = data_atom.code.?;
|
||||
const code = data_atom.code.getOwnedCode().?; // lazy symbols must own their code
|
||||
foff += code.len;
|
||||
iovecs[iovecs_i] = .{ .iov_base = code.ptr, .iov_len = code.len };
|
||||
iovecs_i += 1;
|
||||
@ -795,35 +832,31 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
{
|
||||
var it = self.relocs.iterator();
|
||||
while (it.next()) |kv| {
|
||||
const source_decl_index = kv.key_ptr.*;
|
||||
const source_decl = mod.declPtr(source_decl_index);
|
||||
const source_atom_index = kv.key_ptr.*;
|
||||
const source_atom = self.getAtom(source_atom_index);
|
||||
const source_atom_symbol = self.syms.items[source_atom.sym_index.?];
|
||||
for (kv.value_ptr.items) |reloc| {
|
||||
const target_decl_index = reloc.target;
|
||||
const target_decl = mod.declPtr(target_decl_index);
|
||||
_ = target_decl;
|
||||
const target_atom = self.getAtom(self.decls.get(target_decl_index).?.index);
|
||||
const target_decl_offset = target_atom.offset.?;
|
||||
const target_atom_index = reloc.target;
|
||||
const target_atom = self.getAtomPtr(target_atom_index);
|
||||
const target_symbol = self.syms.items[target_atom.sym_index.?];
|
||||
const target_offset = target_atom.offset.?;
|
||||
|
||||
const offset = reloc.offset;
|
||||
const addend = reloc.addend;
|
||||
|
||||
const code = blk: {
|
||||
const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;
|
||||
if (is_fn) {
|
||||
const table = self.fn_decl_table.get(source_decl.getFileScope(mod)).?.functions;
|
||||
const output = table.get(source_decl_index).?;
|
||||
break :blk output.code;
|
||||
} else {
|
||||
const code = self.data_decl_table.get(source_decl_index).?;
|
||||
break :blk code;
|
||||
}
|
||||
};
|
||||
const code = source_atom.code.getCode(self);
|
||||
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, code[@intCast(usize, offset)..][0..4], @intCast(u32, target_decl_offset + addend), self.base.options.target.cpu.arch.endian());
|
||||
if (reloc.pcrel) {
|
||||
const disp = @intCast(i32, target_offset) - @intCast(i32, source_atom.offset.?) - 4 - @intCast(i32, offset);
|
||||
mem.writeInt(i32, code[@intCast(usize, offset)..][0..4], @intCast(i32, disp), self.base.options.target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, code[@intCast(usize, offset)..][0..8], target_decl_offset + addend, self.base.options.target.cpu.arch.endian());
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, code[@intCast(usize, offset)..][0..4], @intCast(u32, target_offset + addend), self.base.options.target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, code[@intCast(usize, offset)..][0..8], target_offset + addend, self.base.options.target.cpu.arch.endian());
|
||||
}
|
||||
}
|
||||
log.debug("relocating the address of '{s}' + {d} into '{s}' + {d} (({s}[{d}] = 0x{x} + 0x{x})", .{ target_symbol.name, addend, source_atom_symbol.name, offset, source_atom_symbol.name, offset, target_offset, addend });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -908,18 +941,19 @@ pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void {
|
||||
}
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
{
|
||||
const relocs = self.relocs.getPtr(decl_index) orelse return;
|
||||
const atom_index = self.decls.get(decl_index).?.index;
|
||||
const relocs = self.relocs.getPtr(atom_index) orelse return;
|
||||
relocs.clearAndFree(self.base.allocator);
|
||||
assert(self.relocs.remove(decl_index));
|
||||
assert(self.relocs.remove(atom_index));
|
||||
}
|
||||
}
|
||||
fn freeUnnamedConsts(self: *Plan9, decl_index: Module.Decl.Index) void {
|
||||
const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
|
||||
for (unnamed_consts.items) |c| {
|
||||
self.base.allocator.free(self.syms.items[c.info.sym_index.?].name);
|
||||
self.base.allocator.free(c.code);
|
||||
self.syms.items[c.info.sym_index.?] = aout.Sym.undefined_symbol;
|
||||
self.syms_index_free_list.append(self.base.allocator, c.info.sym_index.?) catch {};
|
||||
for (unnamed_consts.items) |atom_idx| {
|
||||
const atom = self.getAtom(atom_idx);
|
||||
self.base.allocator.free(self.syms.items[atom.sym_index.?].name);
|
||||
self.syms.items[atom.sym_index.?] = aout.Sym.undefined_symbol;
|
||||
self.syms_index_free_list.append(self.base.allocator, atom.sym_index.?) catch {};
|
||||
}
|
||||
unnamed_consts.clearAndFree(self.base.allocator);
|
||||
}
|
||||
@ -933,6 +967,7 @@ fn createAtom(self: *Plan9) !Atom.Index {
|
||||
.offset = null,
|
||||
.sym_index = null,
|
||||
.got_index = null,
|
||||
.code = undefined,
|
||||
};
|
||||
return index;
|
||||
}
|
||||
@ -992,9 +1027,6 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
|
||||
const atom = self.getAtomPtr(atom_index);
|
||||
const local_sym_index = atom.sym_index.?;
|
||||
|
||||
var required_alignment: u32 = undefined;
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
@ -1010,7 +1042,7 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
|
||||
.type = if (sym.kind == .code) .t else .d,
|
||||
.name = name,
|
||||
};
|
||||
self.syms.items[atom.sym_index.?] = symbol;
|
||||
self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol;
|
||||
|
||||
// generate the code
|
||||
const src = if (sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
|
||||
@ -1028,7 +1060,7 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
|
||||
&required_alignment,
|
||||
&code_buffer,
|
||||
.none,
|
||||
.{ .parent_atom_index = @intCast(u32, local_sym_index) },
|
||||
.{ .parent_atom_index = @intCast(Atom.Index, atom_index) },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
@ -1040,8 +1072,10 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
|
||||
// duped_code is freed when the atom is freed
|
||||
var duped_code = try self.base.allocator.dupe(u8, code);
|
||||
errdefer self.base.allocator.free(duped_code);
|
||||
|
||||
atom.code = duped_code;
|
||||
self.getAtomPtr(atom_index).code = .{
|
||||
.code_ptr = duped_code.ptr,
|
||||
.other = .{ .code_len = duped_code.len },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Plan9) void {
|
||||
@ -1089,8 +1123,8 @@ pub fn deinit(self: *Plan9) void {
|
||||
self.syms_index_free_list.deinit(gpa);
|
||||
self.file_segments.deinit(gpa);
|
||||
self.path_arena.deinit();
|
||||
for (self.atoms.items) |atom| {
|
||||
if (atom.code) |c| {
|
||||
for (self.atoms.items) |a| {
|
||||
if (a.code.getOwnedCode()) |c| {
|
||||
gpa.free(c);
|
||||
}
|
||||
}
|
||||
@ -1151,7 +1185,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
|
||||
}
|
||||
|
||||
pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {
|
||||
log.debug("write sym{{name: {s}, value: {x}}}", .{ sym.name, sym.value });
|
||||
// log.debug("write sym{{name: {s}, value: {x}}}", .{ sym.name, sym.value });
|
||||
if (sym.type == .bad) return; // we don't want to write free'd symbols
|
||||
if (!self.sixtyfour_bit) {
|
||||
try w.writeIntBig(u32, @intCast(u32, sym.value));
|
||||
@ -1210,6 +1244,17 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
|
||||
try self.writeSym(writer, sym);
|
||||
}
|
||||
}
|
||||
// unnamed consts
|
||||
{
|
||||
var it = self.unnamed_const_atoms.iterator();
|
||||
while (it.next()) |kv| {
|
||||
const consts = kv.value_ptr;
|
||||
for (consts.items) |atom_index| {
|
||||
const sym = self.syms.items[self.getAtom(atom_index).sym_index.?];
|
||||
try self.writeSym(writer, sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
// text symbols are the hardest:
|
||||
// the file of a text symbol is the .z symbol before it
|
||||
// so we have to write everything in the right order
|
||||
@ -1266,6 +1311,7 @@ pub fn getDeclVAddr(
|
||||
) !u64 {
|
||||
const mod = self.base.options.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
// we might already know the vaddr
|
||||
if (decl.ty.zigTypeTag(mod) == .Fn) {
|
||||
var start = self.bases.text;
|
||||
var it_file = self.fn_decl_table.iterator();
|
||||
@ -1285,17 +1331,22 @@ pub fn getDeclVAddr(
|
||||
start += kv.value_ptr.len;
|
||||
}
|
||||
}
|
||||
const atom_index = try self.seeDecl(decl_index);
|
||||
// the parent_atom_index in this case is just the decl_index of the parent
|
||||
const gop = try self.relocs.getOrPut(self.base.allocator, @intToEnum(Module.Decl.Index, reloc_info.parent_atom_index));
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
try gop.value_ptr.append(self.base.allocator, .{
|
||||
.target = decl_index,
|
||||
try self.addReloc(reloc_info.parent_atom_index, .{
|
||||
.target = atom_index,
|
||||
.offset = reloc_info.offset,
|
||||
.addend = reloc_info.addend,
|
||||
});
|
||||
return 0;
|
||||
return 0xcafebabe;
|
||||
}
|
||||
|
||||
pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void {
|
||||
const gop = try self.relocs.getOrPut(self.base.allocator, parent_index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
try gop.value_ptr.append(self.base.allocator, reloc);
|
||||
}
|
||||
|
||||
pub fn getAtom(self: *const Plan9, index: Atom.Index) Atom {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user