diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-10 14:41:07 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-11 10:52:13 +0100 |
| commit | b9b1ab024063105a9adfe3828692867c91015dc6 (patch) | |
| tree | ae0c2e67953f9fbb308ecb17d5bdd8438747cca9 /src/codegen.zig | |
| parent | 08e2f5d08390d41b58c92707693385e5e2968fc8 (diff) | |
| download | zig-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.zig | 30 |
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), |
