aboutsummaryrefslogtreecommitdiff
path: root/src/link/Wasm/Atom.zig
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-02-19 21:25:50 +0100
committerLuuk de Gram <luuk@degram.dev>2022-02-23 16:07:36 +0100
commit0a48a763fd3548a7b8609555cecbafc21ebe1fc3 (patch)
treeefcb52976b8182f51b7c1d80ce88bb5b6997c5a7 /src/link/Wasm/Atom.zig
parent2b0431a8d3933a46fecba2bf064bf45df54a111d (diff)
downloadzig-0a48a763fd3548a7b8609555cecbafc21ebe1fc3.tar.gz
zig-0a48a763fd3548a7b8609555cecbafc21ebe1fc3.zip
wasm-linker: Emit relocations for object files
When generating a relocatable object file, we now emit a custom "reloc.CODE" and "reloc.DATA" section which will contain the relocations for each section. Using a new symbol location -> Atom mapping, we can now easily find the corresponding `Atom` from a symbol. This can be used to construct the symbol table, as well as easier access to a target atom when performing a relocation for a data symbol.
Diffstat (limited to 'src/link/Wasm/Atom.zig')
-rw-r--r--src/link/Wasm/Atom.zig21
1 files changed, 8 insertions, 13 deletions
diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig
index ec68901045..151f6a7f6a 100644
--- a/src/link/Wasm/Atom.zig
+++ b/src/link/Wasm/Atom.zig
@@ -94,12 +94,16 @@ pub fn symbolAtom(self: *Atom, symbol_index: u32) *Atom {
} else unreachable; // Used a symbol index not present in this atom or its children.
}
+/// Returns the location of the symbol that represents this `Atom`
+pub fn symbolLoc(self: Atom) Wasm.SymbolLoc {
+ return .{ .file = self.file, .index = self.sym_index };
+}
+
/// Resolves the relocations within the atom, writing the new value
/// at the calculated offset.
pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {
if (self.relocs.items.len == 0) return;
- const loc: Wasm.SymbolLoc = .{ .file = self.file, .index = self.sym_index };
- const symbol = loc.getSymbol(wasm_bin).*;
+ const symbol = self.symbolLoc().getSymbol(wasm_bin).*;
log.debug("Resolving relocs in atom '{s}' count({d})", .{
symbol.name,
self.relocs.items.len,
@@ -169,20 +173,11 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa
if (symbol.isUndefined() and (symbol.tag == .data or symbol.isWeak())) {
return 0;
}
+
const merge_segment = wasm_bin.base.options.output_mode != .Obj;
const segment_name = wasm_bin.segment_info.items[symbol.index].outputName(merge_segment);
const atom_index = wasm_bin.data_segments.get(segment_name).?;
- var target_atom = wasm_bin.atoms.getPtr(atom_index).?.*.getFirst();
- while (true) {
- // TODO: Can we simplify this by providing the ability to find an atom
- // based on a symbol location.
- if (target_atom.sym_index == relocation.index) {
- if (target_atom.file) |file| {
- if (self.file != null and self.file.? == file) break;
- } else if (self.file == null) break;
- }
- target_atom = target_atom.next orelse break;
- }
+ const target_atom = wasm_bin.symbol_atom.get(target_loc).?;
const segment = wasm_bin.segments.items[atom_index];
return target_atom.offset + segment.offset + (relocation.addend orelse 0);
},