diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-02-03 12:49:40 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-02-03 12:49:40 -0700 |
| commit | fab9b7110ed1fa7bb082aad5e095047441db2b24 (patch) | |
| tree | 81fef60aa45e7980dab8f3e23e5b5e92b40ee0a9 /src/link/Coff | |
| parent | d20d69b59e6b65a99f45cb6a45c14e887034dd18 (diff) | |
| parent | 60935decd318498529a016eeb1379d943a7e830d (diff) | |
| download | zig-fab9b7110ed1fa7bb082aad5e095047441db2b24.tar.gz zig-fab9b7110ed1fa7bb082aad5e095047441db2b24.zip | |
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'src/link/Coff')
| -rw-r--r-- | src/link/Coff/Atom.zig | 59 | ||||
| -rw-r--r-- | src/link/Coff/Relocation.zig | 18 |
2 files changed, 47 insertions, 30 deletions
diff --git a/src/link/Coff/Atom.zig b/src/link/Coff/Atom.zig index b1bb292c62..80c04a8fa1 100644 --- a/src/link/Coff/Atom.zig +++ b/src/link/Coff/Atom.zig @@ -27,42 +27,44 @@ alignment: u32, /// Points to the previous and next neighbors, based on the `text_offset`. /// This can be used to find, for example, the capacity of this `Atom`. -prev: ?*Atom, -next: ?*Atom, - -pub const empty = Atom{ - .sym_index = 0, - .file = null, - .size = 0, - .alignment = 0, - .prev = null, - .next = null, -}; +prev_index: ?Index, +next_index: ?Index, + +pub const Index = u32; + +pub fn getSymbolIndex(self: Atom) ?u32 { + if (self.sym_index == 0) return null; + return self.sym_index; +} /// Returns symbol referencing this atom. pub fn getSymbol(self: Atom, coff_file: *const Coff) *const coff.Symbol { + const sym_index = self.getSymbolIndex().?; return coff_file.getSymbol(.{ - .sym_index = self.sym_index, + .sym_index = sym_index, .file = self.file, }); } /// Returns pointer-to-symbol referencing this atom. pub fn getSymbolPtr(self: Atom, coff_file: *Coff) *coff.Symbol { + const sym_index = self.getSymbolIndex().?; return coff_file.getSymbolPtr(.{ - .sym_index = self.sym_index, + .sym_index = sym_index, .file = self.file, }); } pub fn getSymbolWithLoc(self: Atom) SymbolWithLoc { - return .{ .sym_index = self.sym_index, .file = self.file }; + const sym_index = self.getSymbolIndex().?; + return .{ .sym_index = sym_index, .file = self.file }; } /// Returns the name of this atom. pub fn getName(self: Atom, coff_file: *const Coff) []const u8 { + const sym_index = self.getSymbolIndex().?; return coff_file.getSymbolName(.{ - .sym_index = self.sym_index, + .sym_index = sym_index, .file = self.file, }); } @@ -70,7 +72,8 @@ pub fn getName(self: Atom, coff_file: *const Coff) []const u8 { /// Returns how much room there is to grow in virtual address space. pub fn capacity(self: Atom, coff_file: *const Coff) u32 { const self_sym = self.getSymbol(coff_file); - if (self.next) |next| { + if (self.next_index) |next_index| { + const next = coff_file.getAtom(next_index); const next_sym = next.getSymbol(coff_file); return next_sym.value - self_sym.value; } else { @@ -82,7 +85,8 @@ pub fn capacity(self: Atom, coff_file: *const Coff) u32 { pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool { // No need to keep a free list node for the last atom. - const next = self.next orelse return false; + const next_index = self.next_index orelse return false; + const next = coff_file.getAtom(next_index); const self_sym = self.getSymbol(coff_file); const next_sym = next.getSymbol(coff_file); const cap = next_sym.value - self_sym.value; @@ -92,22 +96,33 @@ pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool { return surplus >= Coff.min_text_capacity; } -pub fn addRelocation(self: *Atom, coff_file: *Coff, reloc: Relocation) !void { +pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !void { const gpa = coff_file.base.allocator; log.debug(" (adding reloc of type {s} to target %{d})", .{ @tagName(reloc.type), reloc.target.sym_index }); - const gop = try coff_file.relocs.getOrPut(gpa, self); + const gop = try coff_file.relocs.getOrPut(gpa, atom_index); if (!gop.found_existing) { gop.value_ptr.* = .{}; } try gop.value_ptr.append(gpa, reloc); } -pub fn addBaseRelocation(self: *Atom, coff_file: *Coff, offset: u32) !void { +pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void { const gpa = coff_file.base.allocator; - log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{ offset, self.sym_index }); - const gop = try coff_file.base_relocs.getOrPut(gpa, self); + log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{ + offset, + coff_file.getAtom(atom_index).getSymbolIndex().?, + }); + const gop = try coff_file.base_relocs.getOrPut(gpa, atom_index); if (!gop.found_existing) { gop.value_ptr.* = .{}; } try gop.value_ptr.append(gpa, offset); } + +pub fn freeRelocations(coff_file: *Coff, atom_index: Index) void { + const gpa = coff_file.base.allocator; + var removed_relocs = coff_file.relocs.fetchRemove(atom_index); + if (removed_relocs) |*relocs| relocs.value.deinit(gpa); + var removed_base_relocs = coff_file.base_relocs.fetchRemove(atom_index); + if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(gpa); +} diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index 12a34b332d..1ba1d7a1c1 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -46,33 +46,35 @@ length: u2, dirty: bool = true, /// Returns an Atom which is the target node of this relocation edge (if any). -pub fn getTargetAtom(self: Relocation, coff_file: *Coff) ?*Atom { +pub fn getTargetAtomIndex(self: Relocation, coff_file: *const Coff) ?Atom.Index { switch (self.type) { .got, .got_page, .got_pageoff, - => return coff_file.getGotAtomForSymbol(self.target), + => return coff_file.getGotAtomIndexForSymbol(self.target), .direct, .page, .pageoff, - => return coff_file.getAtomForSymbol(self.target), + => return coff_file.getAtomIndexForSymbol(self.target), .import, .import_page, .import_pageoff, - => return coff_file.getImportAtomForSymbol(self.target), + => return coff_file.getImportAtomIndexForSymbol(self.target), } } -pub fn resolve(self: *Relocation, atom: *Atom, coff_file: *Coff) !void { +pub fn resolve(self: *Relocation, atom_index: Atom.Index, coff_file: *Coff) !void { + const atom = coff_file.getAtom(atom_index); const source_sym = atom.getSymbol(coff_file); const source_section = coff_file.sections.get(@enumToInt(source_sym.section_number) - 1).header; const source_vaddr = source_sym.value + self.offset; const file_offset = source_section.pointer_to_raw_data + source_sym.value - source_section.virtual_address; - const target_atom = self.getTargetAtom(coff_file) orelse return; + const target_atom_index = self.getTargetAtomIndex(coff_file) orelse return; + const target_atom = coff_file.getAtom(target_atom_index); const target_vaddr = target_atom.getSymbol(coff_file).value; const target_vaddr_with_addend = target_vaddr + self.addend; @@ -107,7 +109,7 @@ const Context = struct { image_base: u64, }; -fn resolveAarch64(self: *Relocation, ctx: Context, coff_file: *Coff) !void { +fn resolveAarch64(self: Relocation, ctx: Context, coff_file: *Coff) !void { var buffer: [@sizeOf(u64)]u8 = undefined; switch (self.length) { 2 => { @@ -197,7 +199,7 @@ fn resolveAarch64(self: *Relocation, ctx: Context, coff_file: *Coff) !void { } } -fn resolveX86(self: *Relocation, ctx: Context, coff_file: *Coff) !void { +fn resolveX86(self: Relocation, ctx: Context, coff_file: *Coff) !void { switch (self.type) { .got_page => unreachable, .got_pageoff => unreachable, |
