link: stub out getAnonDeclVAddr

This commit is contained in:
Andrew Kelley
2023-09-30 21:41:36 -07:00
parent c4b0b7a30b
commit 0483b4a512
7 changed files with 159 additions and 13 deletions

View File

@@ -643,19 +643,9 @@ fn lowerParentPtr(
const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr;
assert(ptr.len == .none);
return switch (ptr.addr) {
.decl, .mut_decl => try lowerDeclRef(
bin_file,
src_loc,
switch (ptr.addr) {
.decl => |decl| decl,
.mut_decl => |mut_decl| mut_decl.decl,
else => unreachable,
},
code,
debug_output,
reloc_info,
),
.anon_decl => @panic("TODO"),
.decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info),
.mut_decl => |md| try lowerDeclRef(bin_file, src_loc, md.decl, code, debug_output, reloc_info),
.anon_decl => |ad| try lowerAnonDeclRef(bin_file, src_loc, ad, code, debug_output, reloc_info),
.int => |int| try generateSymbol(bin_file, src_loc, .{
.ty = Type.usize,
.val = int.toValue(),
@@ -741,6 +731,43 @@ const RelocInfo = struct {
}
};
fn lowerAnonDeclRef(
bin_file: *link.File,
src_loc: Module.SrcLoc,
decl_val: InternPool.Index,
code: *std.ArrayList(u8),
debug_output: DebugInfoOutput,
reloc_info: RelocInfo,
) CodeGenError!Result {
_ = src_loc;
_ = debug_output;
const target = bin_file.options.target;
const mod = bin_file.options.module.?;
const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
const decl_ty = mod.intern_pool.typeOf(decl_val).toType();
const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
if (!is_fn_body and !decl_ty.hasRuntimeBits(mod)) {
try code.appendNTimes(0xaa, ptr_width_bytes);
return Result.ok;
}
const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{
.parent_atom_index = reloc_info.parent_atom_index,
.offset = code.items.len,
.addend = reloc_info.addend orelse 0,
});
const endian = target.cpu.arch.endian();
switch (ptr_width_bytes) {
2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian),
4 => mem.writeInt(u32, try code.addManyAsArray(4), @intCast(vaddr), endian),
8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
else => unreachable,
}
return Result.ok;
}
fn lowerDeclRef(
bin_file: *link.File,
src_loc: Module.SrcLoc,

View File

@@ -937,6 +937,20 @@ pub const File = struct {
}
}
pub fn getAnonDeclVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 {
if (build_options.only_c) unreachable;
switch (base.tag) {
.coff => return @fieldParentPtr(Coff, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
.elf => return @fieldParentPtr(Elf, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
.macho => return @fieldParentPtr(MachO, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
.plan9 => return @fieldParentPtr(Plan9, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
.c => unreachable,
.wasm => return @fieldParentPtr(Wasm, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
.spirv => unreachable,
.nvptx => unreachable,
}
}
/// This function is called by the frontend before flush(). It communicates that
/// `options.bin_file.emit` directory needs to be renamed from
/// `[zig-cache]/tmp/[random]` to `[zig-cache]/o/[digest]`.

View File

@@ -1727,6 +1727,27 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link
return 0;
}
pub fn getAnonDeclVAddr(
self: *Coff,
decl_val: InternPool.Index,
reloc_info: link.File.RelocInfo,
) !u64 {
// This is basically the same as lowerUnnamedConst except it needs
// to return the same thing as `getDeclVAddr`
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
// const val = decl_val.toValue();
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
// It doesn't have an owner decl because it's just an unnamed constant that might
// 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;
_ = reloc_info;
_ = @panic("TODO: link/Coff getAnonDeclVAddr");
}
pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name_name: ?[]const u8) !u32 {
const gop = try self.getOrPutGlobalPtr(name);
const global_index = self.getGlobalIndex(name).?;

View File

@@ -348,6 +348,27 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
return vaddr;
}
pub fn getAnonDeclVAddr(
self: *Elf,
decl_val: InternPool.Index,
reloc_info: link.File.RelocInfo,
) !u64 {
// This is basically the same as lowerUnnamedConst except it needs
// to return the same thing as `getDeclVAddr`
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
// const val = decl_val.toValue();
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
// It doesn't have an owner decl because it's just an unnamed constant that might
// 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;
_ = reloc_info;
_ = @panic("TODO: link/Elf getAnonDeclVAddr");
}
/// Returns end pos of collision, if any.
fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 {
const small_ptr = self.ptr_width == .p32;

View File

@@ -2840,6 +2840,27 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil
return 0;
}
pub fn getAnonDeclVAddr(
self: *MachO,
decl_val: InternPool.Index,
reloc_info: link.File.RelocInfo,
) !u64 {
// This is basically the same as lowerUnnamedConst except it needs
// to return the same thing as `getDeclVAddr`
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
// const val = decl_val.toValue();
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
// It doesn't have an owner decl because it's just an unnamed constant that might
// 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;
_ = reloc_info;
_ = @panic("TODO: link/MachO getAnonDeclVAddr");
}
fn populateMissingMetadata(self: *MachO) !void {
assert(self.mode == .incremental);

View File

@@ -1418,6 +1418,27 @@ pub fn getDeclVAddr(
return undefined;
}
pub fn getAnonDeclVAddr(
self: *Plan9,
decl_val: InternPool.Index,
reloc_info: link.File.RelocInfo,
) !u64 {
// This is basically the same as lowerUnnamedConst except it needs
// to return the same thing as `getDeclVAddr`
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
// const val = decl_val.toValue();
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
// It doesn't have an owner decl because it's just an unnamed constant that might
// 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;
_ = reloc_info;
_ = @panic("TODO: link/Plan9 getAnonDeclVAddr");
}
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) {

View File

@@ -1679,6 +1679,27 @@ pub fn getDeclVAddr(
return target_symbol_index;
}
pub fn getAnonDeclVAddr(
wasm: *Wasm,
decl_val: InternPool.Index,
reloc_info: link.File.RelocInfo,
) !u64 {
// This is basically the same as lowerUnnamedConst except it needs
// to return the same thing as `getDeclVAddr`
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
// const val = decl_val.toValue();
// The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
// It doesn't have an owner decl because it's just an unnamed constant that might
// be used by more than one function, however, its address is being used so we need
// to put it in some location.
// ...
_ = wasm;
_ = decl_val;
_ = reloc_info;
_ = @panic("TODO: link/Wasm getAnonDeclVAddr");
}
pub fn deleteDeclExport(wasm: *Wasm, decl_index: Module.Decl.Index) void {
if (wasm.llvm_object) |_| return;
const atom_index = wasm.decls.get(decl_index) orelse return;