mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 17:35:12 +00:00
plan9: implement linking anon decls
This commit is contained in:
parent
de78caf9c4
commit
d634e02d33
@ -82,6 +82,8 @@ unnamed_const_atoms: UnnamedConstTable = .{},
|
||||
|
||||
lazy_syms: LazySymbolTable = .{},
|
||||
|
||||
anon_decls: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
|
||||
|
||||
relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{},
|
||||
hdr: aout.ExecHdr = undefined,
|
||||
|
||||
@ -166,6 +168,9 @@ pub const Atom = struct {
|
||||
code_len: usize,
|
||||
decl_index: Module.Decl.Index,
|
||||
},
|
||||
fn fromSlice(slice: []u8) CodePtr {
|
||||
return .{ .code_ptr = slice.ptr, .other = .{ .code_len = slice.len } };
|
||||
}
|
||||
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: {
|
||||
@ -608,8 +613,9 @@ fn atomCount(self: *Plan9) usize {
|
||||
while (it_lazy.next()) |kv| {
|
||||
lazy_atom_count += kv.value_ptr.numberOfAtoms();
|
||||
}
|
||||
const anon_atom_count = self.anon_decls.count();
|
||||
const extern_atom_count = self.externCount();
|
||||
return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count;
|
||||
return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count;
|
||||
}
|
||||
|
||||
pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
|
||||
@ -804,6 +810,27 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
self.syms.items[atom.sym_index.?].value = off;
|
||||
}
|
||||
}
|
||||
// the anon decls
|
||||
{
|
||||
var it_anon = self.anon_decls.iterator();
|
||||
while (it_anon.next()) |kv| {
|
||||
const atom = self.getAtomPtr(kv.value_ptr.*);
|
||||
const code = atom.code.getOwnedCode().?;
|
||||
log.debug("write anon decl: {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;
|
||||
atom.offset = off;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[atom.sym_index.?].value = off;
|
||||
}
|
||||
}
|
||||
// the lazy data symbols
|
||||
var it_lazy = self.lazy_syms.iterator();
|
||||
while (it_lazy.next()) |kv| {
|
||||
@ -1196,6 +1223,11 @@ pub fn deinit(self: *Plan9) void {
|
||||
while (itd.next()) |entry| {
|
||||
gpa.free(entry.value_ptr.*);
|
||||
}
|
||||
var it_anon = self.anon_decls.iterator();
|
||||
while (it_anon.next()) |entry| {
|
||||
const sym_index = self.getAtom(entry.value_ptr.*).sym_index.?;
|
||||
gpa.free(self.syms.items[sym_index].name);
|
||||
}
|
||||
self.data_decl_table.deinit(gpa);
|
||||
self.syms.deinit(gpa);
|
||||
self.got_index_free_list.deinit(gpa);
|
||||
@ -1428,17 +1460,51 @@ pub fn lowerAnonDecl(self: *Plan9, decl_val: InternPool.Index, src_loc: Module.S
|
||||
// be used by more than one function, however, its address is being used so we need
|
||||
// to put it in some location.
|
||||
// ...
|
||||
_ = self;
|
||||
_ = decl_val;
|
||||
_ = src_loc;
|
||||
_ = @panic("TODO: link/Plan9 lowerAnonDecl");
|
||||
const gpa = self.base.allocator;
|
||||
var gop = try self.anon_decls.getOrPut(gpa, decl_val);
|
||||
const mod = self.base.options.module.?;
|
||||
if (!gop.found_existing) {
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
|
||||
const index = try self.createAtom();
|
||||
const got_index = self.allocateGotIndex();
|
||||
gop.value_ptr.* = index;
|
||||
// we need to free name latex
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
const atom_ptr = self.getAtomPtr(index);
|
||||
atom_ptr.* = .{
|
||||
.type = .d,
|
||||
.offset = undefined,
|
||||
.sym_index = null,
|
||||
.got_index = got_index,
|
||||
.code = Atom.CodePtr.fromSlice(code),
|
||||
};
|
||||
_ = try atom_ptr.getOrCreateSymbolTableEntry(self);
|
||||
self.syms.items[atom_ptr.sym_index.?] = .{
|
||||
.type = .d,
|
||||
.value = undefined,
|
||||
.name = name,
|
||||
};
|
||||
}
|
||||
return .ok;
|
||||
}
|
||||
|
||||
pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
|
||||
_ = self;
|
||||
_ = decl_val;
|
||||
_ = reloc_info;
|
||||
_ = @panic("TODO: link/Plan9 getAnonDeclVAddr");
|
||||
const atom_index = self.anon_decls.get(decl_val).?;
|
||||
try self.addReloc(reloc_info.parent_atom_index, .{
|
||||
.target = atom_index,
|
||||
.offset = reloc_info.offset,
|
||||
.addend = reloc_info.addend,
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
|
||||
pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user