| ... | ... | @@ -30,6 +30,7 @@ const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 30 | 30 | const Module = @import("../Module.zig"); |
| 31 | 31 | const Package = @import("../Package.zig"); |
| 32 | 32 | const StringTable = @import("strtab.zig").StringTable; |
| 33 | const TableSection = @import("table_section.zig").TableSection; |
| 33 | 34 | const Type = @import("../type.zig").Type; |
| 34 | 35 | const TypedValue = @import("../TypedValue.zig"); |
| 35 | 36 | const Value = @import("../value.zig").Value; |
| ... | ... | @@ -63,88 +64,6 @@ const Section = struct { |
| 63 | 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 | 67 | const LazySymbolMetadata = struct { |
| 149 | 68 | text_atom: ?Atom.Index = null, |
| 150 | 69 | rodata_atom: ?Atom.Index = null, |
| ... | ... | @@ -231,7 +150,7 @@ global_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, |
| 231 | 150 | local_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 232 | 151 | global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 233 | 152 | |
| 234 | | got_table: SectionTable = .{}, |
| 153 | got_table: TableSection(u32) = .{}, |
| 235 | 154 | |
| 236 | 155 | phdr_table_dirty: bool = false, |
| 237 | 156 | shdr_table_dirty: bool = false, |
| ... | ... | @@ -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 | 2970 | const entry_size: u16 = self.archPtrWidthBytes(); |
| 3052 | 2971 | if (self.got_table_count_dirty) { |
| 3053 | 2972 | const needed_size = self.got_table.entries.items.len * entry_size; |