| ... | @@ -30,6 +30,7 @@ const LlvmObject = @import("../codegen/llvm.zig").Object; | ... | @@ -30,6 +30,7 @@ const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 30 | const Module = @import("../Module.zig"); | 30 | const Module = @import("../Module.zig"); |
| 31 | const Package = @import("../Package.zig"); | 31 | const Package = @import("../Package.zig"); |
| 32 | const StringTable = @import("strtab.zig").StringTable; | 32 | const StringTable = @import("strtab.zig").StringTable; |
| | 33 | const TableSection = @import("table_section.zig").TableSection; |
| 33 | const Type = @import("../type.zig").Type; | 34 | const Type = @import("../type.zig").Type; |
| 34 | const TypedValue = @import("../TypedValue.zig"); | 35 | const TypedValue = @import("../TypedValue.zig"); |
| 35 | const Value = @import("../value.zig").Value; | 36 | const Value = @import("../value.zig").Value; |
| ... | @@ -63,88 +64,6 @@ const Section = struct { | ... | @@ -63,88 +64,6 @@ const Section = struct { |
| 63 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, | 64 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 64 | }; | 65 | }; |
| 65 | | 66 | |
| 66 | const SectionTable = struct { | | |
| 67 | entries: std.ArrayListUnmanaged(SymIndex) = .{}, | | |
| 68 | free_list: std.ArrayListUnmanaged(Index) = .{}, | | |
| 69 | lookup: std.AutoHashMapUnmanaged(SymIndex, Index) = .{}, | | |
| 70 | | | |
| 71 | const SymIndex = u32; | | |
| 72 | const Index = u32; | | |
| 73 | | | |
| 74 | pub fn deinit(st: *ST, allocator: Allocator) void { | | |
| 75 | st.entries.deinit(allocator); | | |
| 76 | st.free_list.deinit(allocator); | | |
| 77 | st.lookup.deinit(allocator); | | |
| 78 | } | | |
| 79 | | | |
| 80 | pub fn allocateEntry(st: *ST, allocator: Allocator, target: SymIndex) !Index { | | |
| 81 | try st.entries.ensureUnusedCapacity(allocator, 1); | | |
| 82 | const index = blk: { | | |
| 83 | if (st.free_list.popOrNull()) |index| { | | |
| 84 | log.debug(" (reusing entry index {d})", .{index}); | | |
| 85 | break :blk index; | | |
| 86 | } else { | | |
| 87 | log.debug(" (allocating entry at index {d})", .{st.entries.items.len}); | | |
| 88 | const index = @intCast(u32, st.entries.items.len); | | |
| 89 | _ = st.entries.addOneAssumeCapacity(); | | |
| 90 | break :blk index; | | |
| 91 | } | | |
| 92 | }; | | |
| 93 | st.entries.items[index] = target; | | |
| 94 | try st.lookup.putNoClobber(allocator, target, index); | | |
| 95 | return index; | | |
| 96 | } | | |
| 97 | | | |
| 98 | pub fn freeEntry(st: *ST, allocator: Allocator, target: SymIndex) void { | | |
| 99 | const index = st.lookup.get(target) orelse return; | | |
| 100 | st.free_list.append(allocator, index) catch {}; | | |
| 101 | st.entries.items[index] = 0; | | |
| 102 | _ = st.lookup.remove(target); | | |
| 103 | } | | |
| 104 | | | |
| 105 | const FormatContext = struct { | | |
| 106 | ctx: *Elf, | | |
| 107 | st: *const ST, | | |
| 108 | }; | | |
| 109 | | | |
| 110 | fn fmt( | | |
| 111 | ctx: FormatContext, | | |
| 112 | comptime unused_format_string: []const u8, | | |
| 113 | options: std.fmt.FormatOptions, | | |
| 114 | writer: anytype, | | |
| 115 | ) @TypeOf(writer).Error!void { | | |
| 116 | _ = options; | | |
| 117 | comptime assert(unused_format_string.len == 0); | | |
| 118 | | | |
| 119 | const base_addr = ctx.ctx.program_headers.items[ctx.ctx.phdr_got_index.?].p_vaddr; | | |
| 120 | const target = ctx.ctx.base.options.target; | | |
| 121 | const ptr_bits = target.cpu.arch.ptrBitWidth(); | | |
| 122 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); | | |
| 123 | | | |
| 124 | try writer.writeAll("SectionTable:\n"); | | |
| 125 | for (ctx.st.entries.items, 0..) |entry, i| { | | |
| 126 | try writer.print(" {d}@{x} => local(%{d})\n", .{ i, base_addr + i * ptr_bytes, entry }); | | |
| 127 | } | | |
| 128 | } | | |
| 129 | | | |
| 130 | fn format(st: ST, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | | |
| 131 | _ = st; | | |
| 132 | _ = unused_format_string; | | |
| 133 | _ = options; | | |
| 134 | _ = writer; | | |
| 135 | @compileError("do not format SectionTable directly; use st.fmtDebug()"); | | |
| 136 | } | | |
| 137 | | | |
| 138 | pub fn fmtDebug(st: ST, ctx: *Elf) std.fmt.Formatter(fmt) { | | |
| 139 | return .{ .data = .{ | | |
| 140 | .ctx = ctx, | | |
| 141 | .st = st, | | |
| 142 | } }; | | |
| 143 | } | | |
| 144 | | | |
| 145 | const ST = @This(); | | |
| 146 | }; | | |
| 147 | | | |
| 148 | const LazySymbolMetadata = struct { | 67 | const LazySymbolMetadata = struct { |
| 149 | text_atom: ?Atom.Index = null, | 68 | text_atom: ?Atom.Index = null, |
| 150 | rodata_atom: ?Atom.Index = null, | 69 | rodata_atom: ?Atom.Index = null, |
| ... | @@ -231,7 +150,7 @@ global_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, | ... | @@ -231,7 +150,7 @@ global_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, |
| 231 | local_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, | 150 | local_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 232 | global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, | 151 | global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 233 | | 152 | |
| 234 | got_table: SectionTable = .{}, | 153 | got_table: TableSection(u32) = .{}, |
| 235 | | 154 | |
| 236 | phdr_table_dirty: bool = false, | 155 | phdr_table_dirty: bool = false, |
| 237 | shdr_table_dirty: bool = false, | 156 | shdr_table_dirty: bool = false, |
| ... | @@ -3047,7 +2966,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void { | ... | @@ -3047,7 +2966,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void { |
| 3047 | } | 2966 | } |
| 3048 | } | 2967 | } |
| 3049 | | 2968 | |
| 3050 | fn writeOffsetTableEntry(self: *Elf, index: usize) !void { | 2969 | fn writeOffsetTableEntry(self: *Elf, index: @TypeOf(self.got_table).Index) !void { |
| 3051 | const entry_size: u16 = self.archPtrWidthBytes(); | 2970 | const entry_size: u16 = self.archPtrWidthBytes(); |
| 3052 | if (self.got_table_count_dirty) { | 2971 | if (self.got_table_count_dirty) { |
| 3053 | const needed_size = self.got_table.entries.items.len * entry_size; | 2972 | const needed_size = self.got_table.entries.items.len * entry_size; |