mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 23:52:31 +00:00
elf: make TableSection a generic construct
This commit is contained in:
parent
8a3ad3f620
commit
8e3100ae02
@ -30,6 +30,7 @@ const LlvmObject = @import("../codegen/llvm.zig").Object;
|
||||
const Module = @import("../Module.zig");
|
||||
const Package = @import("../Package.zig");
|
||||
const StringTable = @import("strtab.zig").StringTable;
|
||||
const TableSection = @import("table_section.zig").TableSection;
|
||||
const Type = @import("../type.zig").Type;
|
||||
const TypedValue = @import("../TypedValue.zig");
|
||||
const Value = @import("../value.zig").Value;
|
||||
@ -63,88 +64,6 @@ const Section = struct {
|
||||
free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
|
||||
};
|
||||
|
||||
const SectionTable = struct {
|
||||
entries: std.ArrayListUnmanaged(SymIndex) = .{},
|
||||
free_list: std.ArrayListUnmanaged(Index) = .{},
|
||||
lookup: std.AutoHashMapUnmanaged(SymIndex, Index) = .{},
|
||||
|
||||
const SymIndex = u32;
|
||||
const Index = u32;
|
||||
|
||||
pub fn deinit(st: *ST, allocator: Allocator) void {
|
||||
st.entries.deinit(allocator);
|
||||
st.free_list.deinit(allocator);
|
||||
st.lookup.deinit(allocator);
|
||||
}
|
||||
|
||||
pub fn allocateEntry(st: *ST, allocator: Allocator, target: SymIndex) !Index {
|
||||
try st.entries.ensureUnusedCapacity(allocator, 1);
|
||||
const index = blk: {
|
||||
if (st.free_list.popOrNull()) |index| {
|
||||
log.debug(" (reusing entry index {d})", .{index});
|
||||
break :blk index;
|
||||
} else {
|
||||
log.debug(" (allocating entry at index {d})", .{st.entries.items.len});
|
||||
const index = @intCast(u32, st.entries.items.len);
|
||||
_ = st.entries.addOneAssumeCapacity();
|
||||
break :blk index;
|
||||
}
|
||||
};
|
||||
st.entries.items[index] = target;
|
||||
try st.lookup.putNoClobber(allocator, target, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn freeEntry(st: *ST, allocator: Allocator, target: SymIndex) void {
|
||||
const index = st.lookup.get(target) orelse return;
|
||||
st.free_list.append(allocator, index) catch {};
|
||||
st.entries.items[index] = 0;
|
||||
_ = st.lookup.remove(target);
|
||||
}
|
||||
|
||||
const FormatContext = struct {
|
||||
ctx: *Elf,
|
||||
st: *const ST,
|
||||
};
|
||||
|
||||
fn fmt(
|
||||
ctx: FormatContext,
|
||||
comptime unused_format_string: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
_ = options;
|
||||
comptime assert(unused_format_string.len == 0);
|
||||
|
||||
const base_addr = ctx.ctx.program_headers.items[ctx.ctx.phdr_got_index.?].p_vaddr;
|
||||
const target = ctx.ctx.base.options.target;
|
||||
const ptr_bits = target.cpu.arch.ptrBitWidth();
|
||||
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
|
||||
|
||||
try writer.writeAll("SectionTable:\n");
|
||||
for (ctx.st.entries.items, 0..) |entry, i| {
|
||||
try writer.print(" {d}@{x} => local(%{d})\n", .{ i, base_addr + i * ptr_bytes, entry });
|
||||
}
|
||||
}
|
||||
|
||||
fn format(st: ST, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = st;
|
||||
_ = unused_format_string;
|
||||
_ = options;
|
||||
_ = writer;
|
||||
@compileError("do not format SectionTable directly; use st.fmtDebug()");
|
||||
}
|
||||
|
||||
pub fn fmtDebug(st: ST, ctx: *Elf) std.fmt.Formatter(fmt) {
|
||||
return .{ .data = .{
|
||||
.ctx = ctx,
|
||||
.st = st,
|
||||
} };
|
||||
}
|
||||
|
||||
const ST = @This();
|
||||
};
|
||||
|
||||
const LazySymbolMetadata = struct {
|
||||
text_atom: ?Atom.Index = null,
|
||||
rodata_atom: ?Atom.Index = null,
|
||||
@ -231,7 +150,7 @@ global_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
|
||||
local_symbol_free_list: std.ArrayListUnmanaged(u32) = .{},
|
||||
global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{},
|
||||
|
||||
got_table: SectionTable = .{},
|
||||
got_table: TableSection(u32) = .{},
|
||||
|
||||
phdr_table_dirty: bool = false,
|
||||
shdr_table_dirty: bool = false,
|
||||
@ -3047,7 +2966,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeOffsetTableEntry(self: *Elf, index: usize) !void {
|
||||
fn writeOffsetTableEntry(self: *Elf, index: @TypeOf(self.got_table).Index) !void {
|
||||
const entry_size: u16 = self.archPtrWidthBytes();
|
||||
if (self.got_table_count_dirty) {
|
||||
const needed_size = self.got_table.entries.items.len * entry_size;
|
||||
|
65
src/link/table_section.zig
Normal file
65
src/link/table_section.zig
Normal file
@ -0,0 +1,65 @@
|
||||
pub fn TableSection(comptime Entry: type) type {
|
||||
return struct {
|
||||
entries: std.ArrayListUnmanaged(Entry) = .{},
|
||||
free_list: std.ArrayListUnmanaged(Index) = .{},
|
||||
lookup: std.AutoHashMapUnmanaged(Entry, Index) = .{},
|
||||
|
||||
pub fn deinit(self: *Self, allocator: Allocator) void {
|
||||
self.entries.deinit(allocator);
|
||||
self.free_list.deinit(allocator);
|
||||
self.lookup.deinit(allocator);
|
||||
}
|
||||
|
||||
pub fn allocateEntry(self: *Self, allocator: Allocator, entry: Entry) Allocator.Error!Index {
|
||||
try self.entries.ensureUnusedCapacity(allocator, 1);
|
||||
const index = blk: {
|
||||
if (self.free_list.popOrNull()) |index| {
|
||||
log.debug(" (reusing entry index {d})", .{index});
|
||||
break :blk index;
|
||||
} else {
|
||||
log.debug(" (allocating entry at index {d})", .{self.entries.items.len});
|
||||
const index = @intCast(u32, self.entries.items.len);
|
||||
_ = self.entries.addOneAssumeCapacity();
|
||||
break :blk index;
|
||||
}
|
||||
};
|
||||
self.entries.items[index] = entry;
|
||||
try self.lookup.putNoClobber(allocator, entry, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn freeEntry(self: *Self, allocator: Allocator, entry: Entry) void {
|
||||
const index = self.lookup.get(entry) orelse return;
|
||||
self.free_list.append(allocator, index) catch {};
|
||||
self.entries.items[index] = undefined;
|
||||
_ = self.lookup.remove(entry);
|
||||
}
|
||||
|
||||
pub fn count(self: Self) usize {
|
||||
return self.entries.items.len;
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
self: Self,
|
||||
comptime unused_format_string: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
_ = options;
|
||||
comptime assert(unused_format_string.len == 0);
|
||||
try writer.writeAll("SectionTable:\n");
|
||||
for (self.entries.items, 0..) |entry, i| {
|
||||
try writer.print(" {d} => {}\n", .{ i, entry });
|
||||
}
|
||||
}
|
||||
|
||||
const Self = @This();
|
||||
pub const Index = u32;
|
||||
};
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const log = std.log.scoped(.link);
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
Loading…
Reference in New Issue
Block a user