aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-02-10 14:41:07 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-02-11 10:52:13 +0100
commitb9b1ab024063105a9adfe3828692867c91015dc6 (patch)
treeae0c2e67953f9fbb308ecb17d5bdd8438747cca9 /src/codegen.zig
parent08e2f5d08390d41b58c92707693385e5e2968fc8 (diff)
downloadzig-b9b1ab024063105a9adfe3828692867c91015dc6.tar.gz
zig-b9b1ab024063105a9adfe3828692867c91015dc6.zip
elf: store pointer relocations indexed by containing atom
In `getDeclVAddr`, it may happen that the target `Decl` has not been allocated space in virtual memory. In this case, we store a relocation in the linker-global table which we will iterate over when flushing the module, and fill in any missing address in the final binary. Note that for optimisation, if the address was resolved at the time of a call to `getDeclVAddr`, we skip relocating this atom. This commit also adds the glue code for lowering const slices in the ARM backend.
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig30
1 files changed, 12 insertions, 18 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 389f38a020..fd4321fee9 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -142,6 +142,7 @@ pub fn generateFunction(
pub fn generateSymbol(
bin_file: *link.File,
+ parent_atom_index: u32,
src_loc: Module.SrcLoc,
typed_value: TypedValue,
code: *std.ArrayList(u8),
@@ -177,7 +178,7 @@ pub fn generateSymbol(
if (typed_value.ty.sentinel()) |sentinel| {
try code.ensureUnusedCapacity(payload.data.len + 1);
code.appendSliceAssumeCapacity(payload.data);
- switch (try generateSymbol(bin_file, src_loc, .{
+ switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
.ty = typed_value.ty.elemType(),
.val = sentinel,
}, code, debug_output)) {
@@ -197,7 +198,7 @@ pub fn generateSymbol(
const elem_vals = typed_value.val.castTag(.array).?.data;
const elem_ty = typed_value.ty.elemType();
for (elem_vals) |elem_val| {
- switch (try generateSymbol(bin_file, src_loc, .{
+ switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
.ty = elem_ty,
.val = elem_val,
}, code, debug_output)) {
@@ -223,11 +224,11 @@ pub fn generateSymbol(
.Pointer => switch (typed_value.val.tag()) {
.variable => {
const decl = typed_value.val.castTag(.variable).?.data.owner_decl;
- return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output);
+ return lowerDeclRef(bin_file, parent_atom_index, src_loc, typed_value, decl, code, debug_output);
},
.decl_ref => {
const decl = typed_value.val.castTag(.decl_ref).?.data;
- return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output);
+ return lowerDeclRef(bin_file, parent_atom_index, src_loc, typed_value, decl, code, debug_output);
},
.slice => {
const slice = typed_value.val.castTag(.slice).?.data;
@@ -235,7 +236,7 @@ pub fn generateSymbol(
// generate ptr
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
- switch (try generateSymbol(bin_file, src_loc, .{
+ switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
.ty = slice_ptr_field_type,
.val = slice.ptr,
}, code, debug_output)) {
@@ -247,7 +248,7 @@ pub fn generateSymbol(
}
// generate length
- switch (try generateSymbol(bin_file, src_loc, .{
+ switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
.ty = Type.initTag(.usize),
.val = slice.len,
}, code, debug_output)) {
@@ -391,7 +392,7 @@ pub fn generateSymbol(
const field_ty = typed_value.ty.structFieldType(index);
if (!field_ty.hasRuntimeBits()) continue;
- switch (try generateSymbol(bin_file, src_loc, .{
+ switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
.ty = field_ty,
.val = field_val,
}, code, debug_output)) {
@@ -446,6 +447,7 @@ pub fn generateSymbol(
fn lowerDeclRef(
bin_file: *link.File,
+ parent_atom_index: u32,
src_loc: Module.SrcLoc,
typed_value: TypedValue,
decl: *Module.Decl,
@@ -456,7 +458,7 @@ fn lowerDeclRef(
// generate ptr
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
- switch (try generateSymbol(bin_file, src_loc, .{
+ switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
.ty = slice_ptr_field_type,
.val = typed_value.val,
}, code, debug_output)) {
@@ -472,7 +474,7 @@ fn lowerDeclRef(
.base = .{ .tag = .int_u64 },
.data = typed_value.val.sliceLen(),
};
- switch (try generateSymbol(bin_file, src_loc, .{
+ switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
.ty = Type.initTag(.usize),
.val = Value.initPayload(&slice_len.base),
}, code, debug_output)) {
@@ -495,15 +497,7 @@ fn lowerDeclRef(
}
decl.markAlive();
- const vaddr = vaddr: {
- if (bin_file.cast(link.File.MachO)) |macho_file| {
- break :vaddr try macho_file.getDeclVAddrWithReloc(decl, code.items.len);
- }
- // TODO handle the dependency of this symbol on the decl's vaddr.
- // If the decl changes vaddr, then this symbol needs to get regenerated.
- break :vaddr bin_file.getDeclVAddr(decl);
- };
-
+ const vaddr = try bin_file.getDeclVAddr(decl, parent_atom_index, code.items.len);
const endian = target.cpu.arch.endian();
switch (ptr_width) {
16 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(u16, vaddr), endian),