aboutsummaryrefslogtreecommitdiff
path: root/src/link/Coff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-02-03 12:49:40 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-02-03 12:49:40 -0700
commitfab9b7110ed1fa7bb082aad5e095047441db2b24 (patch)
tree81fef60aa45e7980dab8f3e23e5b5e92b40ee0a9 /src/link/Coff
parentd20d69b59e6b65a99f45cb6a45c14e887034dd18 (diff)
parent60935decd318498529a016eeb1379d943a7e830d (diff)
downloadzig-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.zig59
-rw-r--r--src/link/Coff/Relocation.zig18
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,