authorgravatar for noam@pixelhero.devNoam Preil <noam@pixelhero.dev> 2020-08-02 20:46:06-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-05 11:25:08-07:00
loga5b76d2474c5d1cbbb1c08def6b30ad1836da3bc
tree8abd88d04d2393cefc77766a0992439d9572506d
parentcf4936bcb0d48df5578efe76156c5c7ffc0d7b1e

Stage2: minor File.ELF refactor


3 files changed, 130 insertions(+), 146 deletions(-)

src-self-hosted/codegen.zig+13-12
...@@ -134,7 +134,7 @@ pub fn generateSymbol(...@@ -134,7 +134,7 @@ pub fn generateSymbol(
134 }134 }
135 return Result{135 return Result{
136 .fail = try ErrorMsg.create(136 .fail = try ErrorMsg.create(
137 bin_file.allocator,137 bin_file.base.allocator,
138 src,138 src,
139 "TODO implement generateSymbol for more kinds of arrays",139 "TODO implement generateSymbol for more kinds of arrays",
140 .{},140 .{},
...@@ -150,21 +150,22 @@ pub fn generateSymbol(...@@ -150,21 +150,22 @@ pub fn generateSymbol(
150 // If the decl changes vaddr, then this symbol needs to get regenerated.150 // If the decl changes vaddr, then this symbol needs to get regenerated.
151 const vaddr = bin_file.local_symbols.items[decl.link.local_sym_index].st_value;151 const vaddr = bin_file.local_symbols.items[decl.link.local_sym_index].st_value;
152 const endian = bin_file.base.options.target.cpu.arch.endian();152 const endian = bin_file.base.options.target.cpu.arch.endian();
153 switch (bin_file.ptr_width) {153 switch (bin_file.base.options.target.cpu.arch.ptrBitWidth()) {
154 .p32 => {154 32 => {
155 try code.resize(4);155 try code.resize(4);
156 mem.writeInt(u32, code.items[0..4], @intCast(u32, vaddr), endian);156 mem.writeInt(u32, code.items[0..4], @intCast(u32, vaddr), endian);
157 },157 },
158 .p64 => {158 64 => {
159 try code.resize(8);159 try code.resize(8);
160 mem.writeInt(u64, code.items[0..8], vaddr, endian);160 mem.writeInt(u64, code.items[0..8], vaddr, endian);
161 },161 },
162 else => unreachable,
162 }163 }
163 return Result{ .appended = {} };164 return Result{ .appended = {} };
164 }165 }
165 return Result{166 return Result{
166 .fail = try ErrorMsg.create(167 .fail = try ErrorMsg.create(
167 bin_file.allocator,168 bin_file.base.allocator,
168 src,169 src,
169 "TODO implement generateSymbol for pointer {}",170 "TODO implement generateSymbol for pointer {}",
170 .{typed_value.val},171 .{typed_value.val},
...@@ -180,7 +181,7 @@ pub fn generateSymbol(...@@ -180,7 +181,7 @@ pub fn generateSymbol(
180 }181 }
181 return Result{182 return Result{
182 .fail = try ErrorMsg.create(183 .fail = try ErrorMsg.create(
183 bin_file.allocator,184 bin_file.base.allocator,
184 src,185 src,
185 "TODO implement generateSymbol for int type '{}'",186 "TODO implement generateSymbol for int type '{}'",
186 .{typed_value.ty},187 .{typed_value.ty},
...@@ -190,7 +191,7 @@ pub fn generateSymbol(...@@ -190,7 +191,7 @@ pub fn generateSymbol(
190 else => |t| {191 else => |t| {
191 return Result{192 return Result{
192 .fail = try ErrorMsg.create(193 .fail = try ErrorMsg.create(
193 bin_file.allocator,194 bin_file.base.allocator,
194 src,195 src,
195 "TODO implement generateSymbol for type '{}'",196 "TODO implement generateSymbol for type '{}'",
196 .{@tagName(t)},197 .{@tagName(t)},
...@@ -387,10 +388,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -387,10 +388,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
387388
388 const fn_type = module_fn.owner_decl.typed_value.most_recent.typed_value.ty;389 const fn_type = module_fn.owner_decl.typed_value.most_recent.typed_value.ty;
389390
390 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);391 var branch_stack = std.ArrayList(Branch).init(bin_file.base.allocator);
391 defer {392 defer {
392 assert(branch_stack.items.len == 1);393 assert(branch_stack.items.len == 1);
393 branch_stack.items[0].deinit(bin_file.allocator);394 branch_stack.items[0].deinit(bin_file.base.allocator);
394 branch_stack.deinit();395 branch_stack.deinit();
395 }396 }
396 const branch = try branch_stack.addOne();397 const branch = try branch_stack.addOne();
...@@ -413,7 +414,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -413,7 +414,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
413 };414 };
414415
415 var function = Self{416 var function = Self{
416 .gpa = bin_file.allocator,417 .gpa = bin_file.base.allocator,
417 .target = &bin_file.base.options.target,418 .target = &bin_file.base.options.target,
418 .bin_file = bin_file,419 .bin_file = bin_file,
419 .mod_fn = module_fn,420 .mod_fn = module_fn,
...@@ -432,7 +433,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -432,7 +433,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
432 .rbrace_src = src_data.rbrace_src,433 .rbrace_src = src_data.rbrace_src,
433 .source = src_data.source,434 .source = src_data.source,
434 };435 };
435 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);436 defer function.exitlude_jump_relocs.deinit(bin_file.base.allocator);
436437
437 var call_info = function.resolveCallingConventionValues(src, fn_type) catch |err| switch (err) {438 var call_info = function.resolveCallingConventionValues(src, fn_type) catch |err| switch (err) {
438 error.CodegenFail => return Result{ .fail = function.err_msg.? },439 error.CodegenFail => return Result{ .fail = function.err_msg.? },
...@@ -2054,7 +2055,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2054,7 +2055,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2054 fn fail(self: *Self, src: usize, comptime format: []const u8, args: anytype) error{ CodegenFail, OutOfMemory } {2055 fn fail(self: *Self, src: usize, comptime format: []const u8, args: anytype) error{ CodegenFail, OutOfMemory } {
2055 @setCold(true);2056 @setCold(true);
2056 assert(self.err_msg == null);2057 assert(self.err_msg == null);
2057 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, src, format, args);2058 self.err_msg = try ErrorMsg.create(self.bin_file.base.allocator, src, format, args);
2058 return error.CodegenFail;2059 return error.CodegenFail;
2059 }2060 }
20602061
src-self-hosted/codegen/c.zig+4-4
...@@ -44,8 +44,8 @@ fn renderType(file: *C, writer: std.ArrayList(u8).Writer, T: Type, src: usize) !...@@ -44,8 +44,8 @@ fn renderType(file: *C, writer: std.ArrayList(u8).Writer, T: Type, src: usize) !
44fn renderFunctionSignature(file: *C, writer: std.ArrayList(u8).Writer, decl: *Decl) !void {44fn renderFunctionSignature(file: *C, writer: std.ArrayList(u8).Writer, decl: *Decl) !void {
45 const tv = decl.typed_value.most_recent.typed_value;45 const tv = decl.typed_value.most_recent.typed_value;
46 try renderType(file, writer, tv.ty.fnReturnType(), decl.src());46 try renderType(file, writer, tv.ty.fnReturnType(), decl.src());
47 const name = try map(file.allocator, mem.spanZ(decl.name));47 const name = try map(file.base.allocator, mem.spanZ(decl.name));
48 defer file.allocator.free(name);48 defer file.base.allocator.free(name);
49 try writer.print(" {}(", .{name});49 try writer.print(" {}(", .{name});
50 if (tv.ty.fnParamLen() == 0)50 if (tv.ty.fnParamLen() == 0)
51 try writer.writeAll("void)")51 try writer.writeAll("void)")
...@@ -64,8 +64,8 @@ pub fn generate(file: *C, decl: *Decl) !void {...@@ -64,8 +64,8 @@ pub fn generate(file: *C, decl: *Decl) !void {
64fn genArray(file: *C, decl: *Decl) !void {64fn genArray(file: *C, decl: *Decl) !void {
65 const tv = decl.typed_value.most_recent.typed_value;65 const tv = decl.typed_value.most_recent.typed_value;
66 // TODO: prevent inline asm constants from being emitted66 // TODO: prevent inline asm constants from being emitted
67 const name = try map(file.allocator, mem.span(decl.name));67 const name = try map(file.base.allocator, mem.span(decl.name));
68 defer file.allocator.free(name);68 defer file.base.allocator.free(name);
69 if (tv.val.cast(Value.Payload.Bytes)) |payload|69 if (tv.val.cast(Value.Payload.Bytes)) |payload|
70 if (tv.ty.arraySentinel()) |sentinel|70 if (tv.ty.arraySentinel()) |sentinel|
71 if (sentinel.toUnsignedInt() == 0)71 if (sentinel.toUnsignedInt() == 0)
src-self-hosted/link.zig+113-130
...@@ -36,9 +36,12 @@ pub const Options = struct {...@@ -36,9 +36,12 @@ pub const Options = struct {
36 program_code_size_hint: u64 = 256 * 1024,36 program_code_size_hint: u64 = 256 * 1024,
37};37};
3838
39
39pub const File = struct {40pub const File = struct {
40 tag: Tag,41 tag: Tag,
41 options: Options,42 options: Options,
43 file: ?fs.File,
44 allocator: *Allocator,
4245
43 /// Attempts incremental linking, if the file already exists. If46 /// Attempts incremental linking, if the file already exists. If
44 /// incremental linking fails, falls back to truncating the file and47 /// incremental linking fails, falls back to truncating the file and
...@@ -66,15 +69,23 @@ pub const File = struct {...@@ -66,15 +69,23 @@ pub const File = struct {
6669
67 pub fn makeWritable(base: *File, dir: fs.Dir, sub_path: []const u8) !void {70 pub fn makeWritable(base: *File, dir: fs.Dir, sub_path: []const u8) !void {
68 switch (base.tag) {71 switch (base.tag) {
69 .elf => return @fieldParentPtr(Elf, "base", base).makeWritable(dir, sub_path),72 .elf => {
73 if (base.file != null) return;
74 base.file = try dir.createFile(sub_path, .{
75 .truncate = false,
76 .read = true,
77 .mode = determineMode(base.options),
78 });
79 },
70 .c => {},80 .c => {},
71 }81 }
72 }82 }
7383
74 pub fn makeExecutable(base: *File) !void {84 pub fn makeExecutable(base: *File) !void {
75 switch (base.tag) {85 std.debug.assert(base.tag != .c);
76 .elf => return @fieldParentPtr(Elf, "base", base).makeExecutable(),86 if (base.file) |f| {
77 .c => unreachable,87 f.close();
88 base.file = null;
78 }89 }
79 }90 }
8091
...@@ -100,6 +111,7 @@ pub const File = struct {...@@ -100,6 +111,7 @@ pub const File = struct {
100 }111 }
101112
102 pub fn deinit(base: *File) void {113 pub fn deinit(base: *File) void {
114 if (base.file) |f| f.close();
103 switch (base.tag) {115 switch (base.tag) {
104 .elf => @fieldParentPtr(Elf, "base", base).deinit(),116 .elf => @fieldParentPtr(Elf, "base", base).deinit(),
105 .c => @fieldParentPtr(C, "base", base).deinit(),117 .c => @fieldParentPtr(C, "base", base).deinit(),
...@@ -111,12 +123,12 @@ pub const File = struct {...@@ -111,12 +123,12 @@ pub const File = struct {
111 .elf => {123 .elf => {
112 const parent = @fieldParentPtr(Elf, "base", base);124 const parent = @fieldParentPtr(Elf, "base", base);
113 parent.deinit();125 parent.deinit();
114 parent.allocator.destroy(parent);126 base.allocator.destroy(parent);
115 },127 },
116 .c => {128 .c => {
117 const parent = @fieldParentPtr(C, "base", base);129 const parent = @fieldParentPtr(C, "base", base);
118 parent.deinit();130 parent.deinit();
119 parent.allocator.destroy(parent);131 base.allocator.destroy(parent);
120 },132 },
121 }133 }
122 }134 }
...@@ -172,11 +184,10 @@ pub const File = struct {...@@ -172,11 +184,10 @@ pub const File = struct {
172184
173 base: File,185 base: File,
174186
175 allocator: *Allocator,
176 header: std.ArrayList(u8),187 header: std.ArrayList(u8),
177 constants: std.ArrayList(u8),188 constants: std.ArrayList(u8),
178 main: std.ArrayList(u8),189 main: std.ArrayList(u8),
179 file: ?fs.File,190
180 called: std.StringHashMap(void),191 called: std.StringHashMap(void),
181 need_stddef: bool = false,192 need_stddef: bool = false,
182 need_stdint: bool = false,193 need_stdint: bool = false,
...@@ -196,9 +207,9 @@ pub const File = struct {...@@ -196,9 +207,9 @@ pub const File = struct {
196 .base = .{207 .base = .{
197 .tag = .c,208 .tag = .c,
198 .options = options,209 .options = options,
210 .file = file,
211 .allocator = allocator,
199 },212 },
200 .allocator = allocator,
201 .file = file,
202 .main = std.ArrayList(u8).init(allocator),213 .main = std.ArrayList(u8).init(allocator),
203 .header = std.ArrayList(u8).init(allocator),214 .header = std.ArrayList(u8).init(allocator),
204 .constants = std.ArrayList(u8).init(allocator),215 .constants = std.ArrayList(u8).init(allocator),
...@@ -209,7 +220,7 @@ pub const File = struct {...@@ -209,7 +220,7 @@ pub const File = struct {
209 }220 }
210221
211 pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) !void {222 pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) !void {
212 self.error_msg = try Module.ErrorMsg.create(self.allocator, src, format, args);223 self.error_msg = try Module.ErrorMsg.create(self.base.allocator, src, format, args);
213 return error.AnalysisFail;224 return error.AnalysisFail;
214 }225 }
215226
...@@ -218,8 +229,6 @@ pub const File = struct {...@@ -218,8 +229,6 @@ pub const File = struct {
218 self.header.deinit();229 self.header.deinit();
219 self.constants.deinit();230 self.constants.deinit();
220 self.called.deinit();231 self.called.deinit();
221 if (self.file) |f|
222 f.close();
223 }232 }
224233
225 pub fn updateDecl(self: *File.C, module: *Module, decl: *Module.Decl) !void {234 pub fn updateDecl(self: *File.C, module: *Module, decl: *Module.Decl) !void {
...@@ -232,7 +241,7 @@ pub const File = struct {...@@ -232,7 +241,7 @@ pub const File = struct {
232 }241 }
233242
234 pub fn flush(self: *File.C) !void {243 pub fn flush(self: *File.C) !void {
235 const writer = self.file.?.writer();244 const writer = self.base.file.?.writer();
236 try writer.writeAll(@embedFile("cbe.h"));245 try writer.writeAll(@embedFile("cbe.h"));
237 var includes = false;246 var includes = false;
238 if (self.need_stddef) {247 if (self.need_stddef) {
...@@ -259,8 +268,8 @@ pub const File = struct {...@@ -259,8 +268,8 @@ pub const File = struct {
259 }268 }
260 }269 }
261 try writer.writeAll(self.main.items);270 try writer.writeAll(self.main.items);
262 self.file.?.close();271 self.base.file.?.close();
263 self.file = null;272 self.base.file = null;
264 }273 }
265 };274 };
266275
...@@ -269,9 +278,6 @@ pub const File = struct {...@@ -269,9 +278,6 @@ pub const File = struct {
269278
270 base: File,279 base: File,
271280
272 allocator: *Allocator,
273 file: ?fs.File,
274 owns_file_handle: bool,
275 ptr_width: enum { p32, p64 },281 ptr_width: enum { p32, p64 },
276282
277 /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.283 /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
...@@ -454,7 +460,6 @@ pub const File = struct {...@@ -454,7 +460,6 @@ pub const File = struct {
454 else => |e| return e,460 else => |e| return e,
455 };461 };
456462
457 elf_file.owns_file_handle = true;
458 return &elf_file.base;463 return &elf_file.base;
459 }464 }
460465
...@@ -467,12 +472,11 @@ pub const File = struct {...@@ -467,12 +472,11 @@ pub const File = struct {
467 }472 }
468 var self: Elf = .{473 var self: Elf = .{
469 .base = .{474 .base = .{
475 .file = file,
470 .tag = .elf,476 .tag = .elf,
471 .options = options,477 .options = options,
478 .allocator = allocator,
472 },479 },
473 .allocator = allocator,
474 .file = file,
475 .owns_file_handle = false,
476 .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) {480 .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) {
477 32 => .p32,481 32 => .p32,
478 64 => .p64,482 64 => .p64,
...@@ -499,16 +503,15 @@ pub const File = struct {...@@ -499,16 +503,15 @@ pub const File = struct {
499 .base = .{503 .base = .{
500 .tag = .elf,504 .tag = .elf,
501 .options = options,505 .options = options,
506 .allocator = allocator,
507 .file = file,
502 },508 },
503 .allocator = allocator,
504 .file = file,
505 .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) {509 .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) {
506 32 => .p32,510 32 => .p32,
507 64 => .p64,511 64 => .p64,
508 else => return error.UnsupportedELFArchitecture,512 else => return error.UnsupportedELFArchitecture,
509 },513 },
510 .shdr_table_dirty = true,514 .shdr_table_dirty = true,
511 .owns_file_handle = false,
512 };515 };
513 errdefer self.deinit();516 errdefer self.deinit();
514517
...@@ -542,39 +545,18 @@ pub const File = struct {...@@ -542,39 +545,18 @@ pub const File = struct {
542 }545 }
543546
544 pub fn deinit(self: *Elf) void {547 pub fn deinit(self: *Elf) void {
545 self.sections.deinit(self.allocator);548 self.sections.deinit(self.base.allocator);
546 self.program_headers.deinit(self.allocator);549 self.program_headers.deinit(self.base.allocator);
547 self.shstrtab.deinit(self.allocator);550 self.shstrtab.deinit(self.base.allocator);
548 self.debug_strtab.deinit(self.allocator);551 self.debug_strtab.deinit(self.base.allocator);
549 self.local_symbols.deinit(self.allocator);552 self.local_symbols.deinit(self.base.allocator);
550 self.global_symbols.deinit(self.allocator);553 self.global_symbols.deinit(self.base.allocator);
551 self.global_symbol_free_list.deinit(self.allocator);554 self.global_symbol_free_list.deinit(self.base.allocator);
552 self.local_symbol_free_list.deinit(self.allocator);555 self.local_symbol_free_list.deinit(self.base.allocator);
553 self.offset_table_free_list.deinit(self.allocator);556 self.offset_table_free_list.deinit(self.base.allocator);
554 self.text_block_free_list.deinit(self.allocator);557 self.text_block_free_list.deinit(self.base.allocator);
555 self.dbg_line_fn_free_list.deinit(self.allocator);558 self.dbg_line_fn_free_list.deinit(self.base.allocator);
556 self.offset_table.deinit(self.allocator);559 self.offset_table.deinit(self.base.allocator);
557 if (self.owns_file_handle) {
558 if (self.file) |f| f.close();
559 }
560 }
561
562 pub fn makeExecutable(self: *Elf) !void {
563 assert(self.owns_file_handle);
564 if (self.file) |f| {
565 f.close();
566 self.file = null;
567 }
568 }
569
570 pub fn makeWritable(self: *Elf, dir: fs.Dir, sub_path: []const u8) !void {
571 assert(self.owns_file_handle);
572 if (self.file != null) return;
573 self.file = try dir.createFile(sub_path, .{
574 .truncate = false,
575 .read = true,
576 .mode = determineMode(self.base.options),
577 });
578 }560 }
579561
580 fn getDebugLineProgramOff(self: Elf) u32 {562 fn getDebugLineProgramOff(self: Elf) u32 {
...@@ -662,7 +644,7 @@ pub const File = struct {...@@ -662,7 +644,7 @@ pub const File = struct {
662644
663 /// TODO Improve this to use a table.645 /// TODO Improve this to use a table.
664 fn makeString(self: *Elf, bytes: []const u8) !u32 {646 fn makeString(self: *Elf, bytes: []const u8) !u32 {
665 try self.shstrtab.ensureCapacity(self.allocator, self.shstrtab.items.len + bytes.len + 1);647 try self.shstrtab.ensureCapacity(self.base.allocator, self.shstrtab.items.len + bytes.len + 1);
666 const result = self.shstrtab.items.len;648 const result = self.shstrtab.items.len;
667 self.shstrtab.appendSliceAssumeCapacity(bytes);649 self.shstrtab.appendSliceAssumeCapacity(bytes);
668 self.shstrtab.appendAssumeCapacity(0);650 self.shstrtab.appendAssumeCapacity(0);
...@@ -671,7 +653,7 @@ pub const File = struct {...@@ -671,7 +653,7 @@ pub const File = struct {
671653
672 /// TODO Improve this to use a table.654 /// TODO Improve this to use a table.
673 fn makeDebugString(self: *Elf, bytes: []const u8) !u32 {655 fn makeDebugString(self: *Elf, bytes: []const u8) !u32 {
674 try self.debug_strtab.ensureCapacity(self.allocator, self.debug_strtab.items.len + bytes.len + 1);656 try self.debug_strtab.ensureCapacity(self.base.allocator, self.debug_strtab.items.len + bytes.len + 1);
675 const result = self.debug_strtab.items.len;657 const result = self.debug_strtab.items.len;
676 self.debug_strtab.appendSliceAssumeCapacity(bytes);658 self.debug_strtab.appendSliceAssumeCapacity(bytes);
677 self.debug_strtab.appendAssumeCapacity(0);659 self.debug_strtab.appendAssumeCapacity(0);
...@@ -703,7 +685,7 @@ pub const File = struct {...@@ -703,7 +685,7 @@ pub const File = struct {
703 const p_align = 0x1000;685 const p_align = 0x1000;
704 const off = self.findFreeSpace(file_size, p_align);686 const off = self.findFreeSpace(file_size, p_align);
705 log.debug(.link, "found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });687 log.debug(.link, "found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
706 try self.program_headers.append(self.allocator, .{688 try self.program_headers.append(self.base.allocator, .{
707 .p_type = elf.PT_LOAD,689 .p_type = elf.PT_LOAD,
708 .p_offset = off,690 .p_offset = off,
709 .p_filesz = file_size,691 .p_filesz = file_size,
...@@ -721,14 +703,14 @@ pub const File = struct {...@@ -721,14 +703,14 @@ pub const File = struct {
721 const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint;703 const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
722 // We really only need ptr alignment but since we are using PROGBITS, linux requires704 // We really only need ptr alignment but since we are using PROGBITS, linux requires
723 // page align.705 // page align.
724 const p_align = 0x1000;706 const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size);
725 const off = self.findFreeSpace(file_size, p_align);707 const off = self.findFreeSpace(file_size, p_align);
726 log.debug(.link, "found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });708 log.debug(.link, "found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
727 // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at.709 // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at.
728 // we'll need to re-use that function anyway, in case the GOT grows and overlaps something710 // we'll need to re-use that function anyway, in case the GOT grows and overlaps something
729 // else in virtual memory.711 // else in virtual memory.
730 const default_got_addr = 0x4000000;712 const default_got_addr = if (ptr_size == 2) @as(u32, 0x8000) else 0x4000000;
731 try self.program_headers.append(self.allocator, .{713 try self.program_headers.append(self.base.allocator, .{
732 .p_type = elf.PT_LOAD,714 .p_type = elf.PT_LOAD,
733 .p_offset = off,715 .p_offset = off,
734 .p_filesz = file_size,716 .p_filesz = file_size,
...@@ -743,10 +725,10 @@ pub const File = struct {...@@ -743,10 +725,10 @@ pub const File = struct {
743 if (self.shstrtab_index == null) {725 if (self.shstrtab_index == null) {
744 self.shstrtab_index = @intCast(u16, self.sections.items.len);726 self.shstrtab_index = @intCast(u16, self.sections.items.len);
745 assert(self.shstrtab.items.len == 0);727 assert(self.shstrtab.items.len == 0);
746 try self.shstrtab.append(self.allocator, 0); // need a 0 at position 0728 try self.shstrtab.append(self.base.allocator, 0); // need a 0 at position 0
747 const off = self.findFreeSpace(self.shstrtab.items.len, 1);729 const off = self.findFreeSpace(self.shstrtab.items.len, 1);
748 log.debug(.link, "found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len });730 log.debug(.link, "found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len });
749 try self.sections.append(self.allocator, .{731 try self.sections.append(self.base.allocator, .{
750 .sh_name = try self.makeString(".shstrtab"),732 .sh_name = try self.makeString(".shstrtab"),
751 .sh_type = elf.SHT_STRTAB,733 .sh_type = elf.SHT_STRTAB,
752 .sh_flags = 0,734 .sh_flags = 0,
...@@ -765,7 +747,7 @@ pub const File = struct {...@@ -765,7 +747,7 @@ pub const File = struct {
765 self.text_section_index = @intCast(u16, self.sections.items.len);747 self.text_section_index = @intCast(u16, self.sections.items.len);
766 const phdr = &self.program_headers.items[self.phdr_load_re_index.?];748 const phdr = &self.program_headers.items[self.phdr_load_re_index.?];
767749
768 try self.sections.append(self.allocator, .{750 try self.sections.append(self.base.allocator, .{
769 .sh_name = try self.makeString(".text"),751 .sh_name = try self.makeString(".text"),
770 .sh_type = elf.SHT_PROGBITS,752 .sh_type = elf.SHT_PROGBITS,
771 .sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,753 .sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
...@@ -783,7 +765,7 @@ pub const File = struct {...@@ -783,7 +765,7 @@ pub const File = struct {
783 self.got_section_index = @intCast(u16, self.sections.items.len);765 self.got_section_index = @intCast(u16, self.sections.items.len);
784 const phdr = &self.program_headers.items[self.phdr_got_index.?];766 const phdr = &self.program_headers.items[self.phdr_got_index.?];
785767
786 try self.sections.append(self.allocator, .{768 try self.sections.append(self.base.allocator, .{
787 .sh_name = try self.makeString(".got"),769 .sh_name = try self.makeString(".got"),
788 .sh_type = elf.SHT_PROGBITS,770 .sh_type = elf.SHT_PROGBITS,
789 .sh_flags = elf.SHF_ALLOC,771 .sh_flags = elf.SHF_ALLOC,
...@@ -805,7 +787,7 @@ pub const File = struct {...@@ -805,7 +787,7 @@ pub const File = struct {
805 const off = self.findFreeSpace(file_size, min_align);787 const off = self.findFreeSpace(file_size, min_align);
806 log.debug(.link, "found symtab free space 0x{x} to 0x{x}\n", .{ off, off + file_size });788 log.debug(.link, "found symtab free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
807789
808 try self.sections.append(self.allocator, .{790 try self.sections.append(self.base.allocator, .{
809 .sh_name = try self.makeString(".symtab"),791 .sh_name = try self.makeString(".symtab"),
810 .sh_type = elf.SHT_SYMTAB,792 .sh_type = elf.SHT_SYMTAB,
811 .sh_flags = 0,793 .sh_flags = 0,
...@@ -824,7 +806,7 @@ pub const File = struct {...@@ -824,7 +806,7 @@ pub const File = struct {
824 if (self.debug_str_section_index == null) {806 if (self.debug_str_section_index == null) {
825 self.debug_str_section_index = @intCast(u16, self.sections.items.len);807 self.debug_str_section_index = @intCast(u16, self.sections.items.len);
826 assert(self.debug_strtab.items.len == 0);808 assert(self.debug_strtab.items.len == 0);
827 try self.sections.append(self.allocator, .{809 try self.sections.append(self.base.allocator, .{
828 .sh_name = try self.makeString(".debug_str"),810 .sh_name = try self.makeString(".debug_str"),
829 .sh_type = elf.SHT_PROGBITS,811 .sh_type = elf.SHT_PROGBITS,
830 .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,812 .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,
...@@ -849,7 +831,7 @@ pub const File = struct {...@@ -849,7 +831,7 @@ pub const File = struct {
849 off,831 off,
850 off + file_size_hint,832 off + file_size_hint,
851 });833 });
852 try self.sections.append(self.allocator, .{834 try self.sections.append(self.base.allocator, .{
853 .sh_name = try self.makeString(".debug_info"),835 .sh_name = try self.makeString(".debug_info"),
854 .sh_type = elf.SHT_PROGBITS,836 .sh_type = elf.SHT_PROGBITS,
855 .sh_flags = 0,837 .sh_flags = 0,
...@@ -874,7 +856,7 @@ pub const File = struct {...@@ -874,7 +856,7 @@ pub const File = struct {
874 off,856 off,
875 off + file_size_hint,857 off + file_size_hint,
876 });858 });
877 try self.sections.append(self.allocator, .{859 try self.sections.append(self.base.allocator, .{
878 .sh_name = try self.makeString(".debug_abbrev"),860 .sh_name = try self.makeString(".debug_abbrev"),
879 .sh_type = elf.SHT_PROGBITS,861 .sh_type = elf.SHT_PROGBITS,
880 .sh_flags = 0,862 .sh_flags = 0,
...@@ -899,7 +881,7 @@ pub const File = struct {...@@ -899,7 +881,7 @@ pub const File = struct {
899 off,881 off,
900 off + file_size_hint,882 off + file_size_hint,
901 });883 });
902 try self.sections.append(self.allocator, .{884 try self.sections.append(self.base.allocator, .{
903 .sh_name = try self.makeString(".debug_aranges"),885 .sh_name = try self.makeString(".debug_aranges"),
904 .sh_type = elf.SHT_PROGBITS,886 .sh_type = elf.SHT_PROGBITS,
905 .sh_flags = 0,887 .sh_flags = 0,
...@@ -924,7 +906,7 @@ pub const File = struct {...@@ -924,7 +906,7 @@ pub const File = struct {
924 off,906 off,
925 off + file_size_hint,907 off + file_size_hint,
926 });908 });
927 try self.sections.append(self.allocator, .{909 try self.sections.append(self.base.allocator, .{
928 .sh_name = try self.makeString(".debug_line"),910 .sh_name = try self.makeString(".debug_line"),
929 .sh_type = elf.SHT_PROGBITS,911 .sh_type = elf.SHT_PROGBITS,
930 .sh_flags = 0,912 .sh_flags = 0,
...@@ -1019,7 +1001,7 @@ pub const File = struct {...@@ -1019,7 +1001,7 @@ pub const File = struct {
10191001
1020 const abbrev_offset = 0;1002 const abbrev_offset = 0;
1021 self.debug_abbrev_table_offset = abbrev_offset;1003 self.debug_abbrev_table_offset = abbrev_offset;
1022 try self.file.?.pwriteAll(&abbrev_buf, debug_abbrev_sect.sh_offset + abbrev_offset);1004 try self.base.file.?.pwriteAll(&abbrev_buf, debug_abbrev_sect.sh_offset + abbrev_offset);
1023 if (!self.shdr_table_dirty) {1005 if (!self.shdr_table_dirty) {
1024 // Then it won't get written with the others and we need to do it.1006 // Then it won't get written with the others and we need to do it.
1025 try self.writeSectHeader(self.debug_abbrev_section_index.?);1007 try self.writeSectHeader(self.debug_abbrev_section_index.?);
...@@ -1030,7 +1012,7 @@ pub const File = struct {...@@ -1030,7 +1012,7 @@ pub const File = struct {
1030 if (self.debug_info_section_dirty) {1012 if (self.debug_info_section_dirty) {
1031 const debug_info_sect = &self.sections.items[self.debug_info_section_index.?];1013 const debug_info_sect = &self.sections.items[self.debug_info_section_index.?];
10321014
1033 var di_buf = std.ArrayList(u8).init(self.allocator);1015 var di_buf = std.ArrayList(u8).init(self.base.allocator);
1034 defer di_buf.deinit();1016 defer di_buf.deinit();
10351017
1036 // Enough for a 64-bit header and main compilation unit without resizing.1018 // Enough for a 64-bit header and main compilation unit without resizing.
...@@ -1101,7 +1083,7 @@ pub const File = struct {...@@ -1101,7 +1083,7 @@ pub const File = struct {
1101 debug_info_sect.sh_offset + needed_size,1083 debug_info_sect.sh_offset + needed_size,
1102 });1084 });
11031085
1104 try self.file.?.pwriteAll(di_buf.items, debug_info_sect.sh_offset);1086 try self.base.file.?.pwriteAll(di_buf.items, debug_info_sect.sh_offset);
1105 if (!self.shdr_table_dirty) {1087 if (!self.shdr_table_dirty) {
1106 // Then it won't get written with the others and we need to do it.1088 // Then it won't get written with the others and we need to do it.
1107 try self.writeSectHeader(self.debug_info_section_index.?);1089 try self.writeSectHeader(self.debug_info_section_index.?);
...@@ -1112,7 +1094,7 @@ pub const File = struct {...@@ -1112,7 +1094,7 @@ pub const File = struct {
1112 if (self.debug_aranges_section_dirty) {1094 if (self.debug_aranges_section_dirty) {
1113 const debug_aranges_sect = &self.sections.items[self.debug_aranges_section_index.?];1095 const debug_aranges_sect = &self.sections.items[self.debug_aranges_section_index.?];
11141096
1115 var di_buf = std.ArrayList(u8).init(self.allocator);1097 var di_buf = std.ArrayList(u8).init(self.base.allocator);
1116 defer di_buf.deinit();1098 defer di_buf.deinit();
11171099
1118 // Enough for all the data without resizing. When support for more compilation units1100 // Enough for all the data without resizing. When support for more compilation units
...@@ -1172,7 +1154,7 @@ pub const File = struct {...@@ -1172,7 +1154,7 @@ pub const File = struct {
1172 debug_aranges_sect.sh_offset + needed_size,1154 debug_aranges_sect.sh_offset + needed_size,
1173 });1155 });
11741156
1175 try self.file.?.pwriteAll(di_buf.items, debug_aranges_sect.sh_offset);1157 try self.base.file.?.pwriteAll(di_buf.items, debug_aranges_sect.sh_offset);
1176 if (!self.shdr_table_dirty) {1158 if (!self.shdr_table_dirty) {
1177 // Then it won't get written with the others and we need to do it.1159 // Then it won't get written with the others and we need to do it.
1178 try self.writeSectHeader(self.debug_aranges_section_index.?);1160 try self.writeSectHeader(self.debug_aranges_section_index.?);
...@@ -1187,7 +1169,7 @@ pub const File = struct {...@@ -1187,7 +1169,7 @@ pub const File = struct {
11871169
1188 const debug_line_sect = &self.sections.items[self.debug_line_section_index.?];1170 const debug_line_sect = &self.sections.items[self.debug_line_section_index.?];
11891171
1190 var di_buf = std.ArrayList(u8).init(self.allocator);1172 var di_buf = std.ArrayList(u8).init(self.base.allocator);
1191 defer di_buf.deinit();1173 defer di_buf.deinit();
11921174
1193 // The size of this header is variable, depending on the number of directories,1175 // The size of this header is variable, depending on the number of directories,
...@@ -1294,8 +1276,8 @@ pub const File = struct {...@@ -1294,8 +1276,8 @@ pub const File = struct {
12941276
1295 switch (self.ptr_width) {1277 switch (self.ptr_width) {
1296 .p32 => {1278 .p32 => {
1297 const buf = try self.allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len);1279 const buf = try self.base.allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len);
1298 defer self.allocator.free(buf);1280 defer self.base.allocator.free(buf);
12991281
1300 for (buf) |*phdr, i| {1282 for (buf) |*phdr, i| {
1301 phdr.* = progHeaderTo32(self.program_headers.items[i]);1283 phdr.* = progHeaderTo32(self.program_headers.items[i]);
...@@ -1303,11 +1285,11 @@ pub const File = struct {...@@ -1303,11 +1285,11 @@ pub const File = struct {
1303 bswapAllFields(elf.Elf32_Phdr, phdr);1285 bswapAllFields(elf.Elf32_Phdr, phdr);
1304 }1286 }
1305 }1287 }
1306 try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);1288 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
1307 },1289 },
1308 .p64 => {1290 .p64 => {
1309 const buf = try self.allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len);1291 const buf = try self.base.allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len);
1310 defer self.allocator.free(buf);1292 defer self.base.allocator.free(buf);
13111293
1312 for (buf) |*phdr, i| {1294 for (buf) |*phdr, i| {
1313 phdr.* = self.program_headers.items[i];1295 phdr.* = self.program_headers.items[i];
...@@ -1315,7 +1297,7 @@ pub const File = struct {...@@ -1315,7 +1297,7 @@ pub const File = struct {
1315 bswapAllFields(elf.Elf64_Phdr, phdr);1297 bswapAllFields(elf.Elf64_Phdr, phdr);
1316 }1298 }
1317 }1299 }
1318 try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);1300 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
1319 },1301 },
1320 }1302 }
1321 self.phdr_table_dirty = false;1303 self.phdr_table_dirty = false;
...@@ -1334,7 +1316,7 @@ pub const File = struct {...@@ -1334,7 +1316,7 @@ pub const File = struct {
1334 shstrtab_sect.sh_size = needed_size;1316 shstrtab_sect.sh_size = needed_size;
1335 log.debug(.link, "writing shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size });1317 log.debug(.link, "writing shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size });
13361318
1337 try self.file.?.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset);1319 try self.base.file.?.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset);
1338 if (!self.shdr_table_dirty) {1320 if (!self.shdr_table_dirty) {
1339 // Then it won't get written with the others and we need to do it.1321 // Then it won't get written with the others and we need to do it.
1340 try self.writeSectHeader(self.shstrtab_index.?);1322 try self.writeSectHeader(self.shstrtab_index.?);
...@@ -1355,7 +1337,7 @@ pub const File = struct {...@@ -1355,7 +1337,7 @@ pub const File = struct {
1355 debug_strtab_sect.sh_size = needed_size;1337 debug_strtab_sect.sh_size = needed_size;
1356 log.debug(.link, "debug_strtab start=0x{x} end=0x{x}\n", .{ debug_strtab_sect.sh_offset, debug_strtab_sect.sh_offset + needed_size });1338 log.debug(.link, "debug_strtab start=0x{x} end=0x{x}\n", .{ debug_strtab_sect.sh_offset, debug_strtab_sect.sh_offset + needed_size });
13571339
1358 try self.file.?.pwriteAll(self.debug_strtab.items, debug_strtab_sect.sh_offset);1340 try self.base.file.?.pwriteAll(self.debug_strtab.items, debug_strtab_sect.sh_offset);
1359 if (!self.shdr_table_dirty) {1341 if (!self.shdr_table_dirty) {
1360 // Then it won't get written with the others and we need to do it.1342 // Then it won't get written with the others and we need to do it.
1361 try self.writeSectHeader(self.debug_str_section_index.?);1343 try self.writeSectHeader(self.debug_str_section_index.?);
...@@ -1382,20 +1364,21 @@ pub const File = struct {...@@ -1382,20 +1364,21 @@ pub const File = struct {
13821364
1383 switch (self.ptr_width) {1365 switch (self.ptr_width) {
1384 .p32 => {1366 .p32 => {
1385 const buf = try self.allocator.alloc(elf.Elf32_Shdr, self.sections.items.len);1367 const buf = try self.base.allocator.alloc(elf.Elf32_Shdr, self.sections.items.len);
1386 defer self.allocator.free(buf);1368 defer self.base.allocator.free(buf);
13871369
1388 for (buf) |*shdr, i| {1370 for (buf) |*shdr, i| {
1389 shdr.* = sectHeaderTo32(self.sections.items[i]);1371 shdr.* = sectHeaderTo32(self.sections.items[i]);
1372 std.log.debug(.link, "writing section {}\n", .{shdr.*});
1390 if (foreign_endian) {1373 if (foreign_endian) {
1391 bswapAllFields(elf.Elf32_Shdr, shdr);1374 bswapAllFields(elf.Elf32_Shdr, shdr);
1392 }1375 }
1393 }1376 }
1394 try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);1377 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);
1395 },1378 },
1396 .p64 => {1379 .p64 => {
1397 const buf = try self.allocator.alloc(elf.Elf64_Shdr, self.sections.items.len);1380 const buf = try self.base.allocator.alloc(elf.Elf64_Shdr, self.sections.items.len);
1398 defer self.allocator.free(buf);1381 defer self.base.allocator.free(buf);
13991382
1400 for (buf) |*shdr, i| {1383 for (buf) |*shdr, i| {
1401 shdr.* = self.sections.items[i];1384 shdr.* = self.sections.items[i];
...@@ -1404,7 +1387,7 @@ pub const File = struct {...@@ -1404,7 +1387,7 @@ pub const File = struct {
1404 bswapAllFields(elf.Elf64_Shdr, shdr);1387 bswapAllFields(elf.Elf64_Shdr, shdr);
1405 }1388 }
1406 }1389 }
1407 try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);1390 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);
1408 },1391 },
1409 }1392 }
1410 self.shdr_table_dirty = false;1393 self.shdr_table_dirty = false;
...@@ -1557,7 +1540,7 @@ pub const File = struct {...@@ -1557,7 +1540,7 @@ pub const File = struct {
15571540
1558 assert(index == e_ehsize);1541 assert(index == e_ehsize);
15591542
1560 try self.file.?.pwriteAll(hdr_buf[0..index], 0);1543 try self.base.file.?.pwriteAll(hdr_buf[0..index], 0);
1561 }1544 }
15621545
1563 fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {1546 fn freeTextBlock(self: *Elf, text_block: *TextBlock) void {
...@@ -1587,7 +1570,7 @@ pub const File = struct {...@@ -1587,7 +1570,7 @@ pub const File = struct {
1587 if (!already_have_free_list_node and prev.freeListEligible(self.*)) {1570 if (!already_have_free_list_node and prev.freeListEligible(self.*)) {
1588 // The free list is heuristics, it doesn't have to be perfect, so we can1571 // The free list is heuristics, it doesn't have to be perfect, so we can
1589 // ignore the OOM here.1572 // ignore the OOM here.
1590 self.text_block_free_list.append(self.allocator, prev) catch {};1573 self.text_block_free_list.append(self.base.allocator, prev) catch {};
1591 }1574 }
1592 } else {1575 } else {
1593 text_block.prev = null;1576 text_block.prev = null;
...@@ -1688,7 +1671,7 @@ pub const File = struct {...@@ -1688,7 +1671,7 @@ pub const File = struct {
1688 const sym = self.local_symbols.items[last.local_sym_index];1671 const sym = self.local_symbols.items[last.local_sym_index];
1689 break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr;1672 break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr;
1690 } else 0;1673 } else 0;
1691 const amt = try self.file.?.copyRangeAll(shdr.sh_offset, self.file.?, new_offset, text_size);1674 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, text_size);
1692 if (amt != text_size) return error.InputOutput;1675 if (amt != text_size) return error.InputOutput;
1693 shdr.sh_offset = new_offset;1676 shdr.sh_offset = new_offset;
1694 phdr.p_offset = new_offset;1677 phdr.p_offset = new_offset;
...@@ -1739,8 +1722,8 @@ pub const File = struct {...@@ -1739,8 +1722,8 @@ pub const File = struct {
1739 pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {1722 pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void {
1740 if (decl.link.local_sym_index != 0) return;1723 if (decl.link.local_sym_index != 0) return;
17411724
1742 try self.local_symbols.ensureCapacity(self.allocator, self.local_symbols.items.len + 1);1725 try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1);
1743 try self.offset_table.ensureCapacity(self.allocator, self.offset_table.items.len + 1);1726 try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1);
17441727
1745 if (self.local_symbol_free_list.popOrNull()) |i| {1728 if (self.local_symbol_free_list.popOrNull()) |i| {
1746 log.debug(.link, "reusing symbol index {} for {}\n", .{ i, decl.name });1729 log.debug(.link, "reusing symbol index {} for {}\n", .{ i, decl.name });
...@@ -1776,8 +1759,8 @@ pub const File = struct {...@@ -1776,8 +1759,8 @@ pub const File = struct {
1776 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.1759 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
1777 self.freeTextBlock(&decl.link);1760 self.freeTextBlock(&decl.link);
1778 if (decl.link.local_sym_index != 0) {1761 if (decl.link.local_sym_index != 0) {
1779 self.local_symbol_free_list.append(self.allocator, decl.link.local_sym_index) catch {};1762 self.local_symbol_free_list.append(self.base.allocator, decl.link.local_sym_index) catch {};
1780 self.offset_table_free_list.append(self.allocator, decl.link.offset_table_index) catch {};1763 self.offset_table_free_list.append(self.base.allocator, decl.link.offset_table_index) catch {};
17811764
1782 self.local_symbols.items[decl.link.local_sym_index].st_info = 0;1765 self.local_symbols.items[decl.link.local_sym_index].st_info = 0;
17831766
...@@ -1787,7 +1770,7 @@ pub const File = struct {...@@ -1787,7 +1770,7 @@ pub const File = struct {
1787 // is desired for both.1770 // is desired for both.
1788 _ = self.dbg_line_fn_free_list.remove(&decl.fn_link);1771 _ = self.dbg_line_fn_free_list.remove(&decl.fn_link);
1789 if (decl.fn_link.prev) |prev| {1772 if (decl.fn_link.prev) |prev| {
1790 _ = self.dbg_line_fn_free_list.put(self.allocator, prev, {}) catch {};1773 _ = self.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {};
1791 prev.next = decl.fn_link.next;1774 prev.next = decl.fn_link.next;
1792 if (decl.fn_link.next) |next| {1775 if (decl.fn_link.next) |next| {
1793 next.prev = prev;1776 next.prev = prev;
...@@ -1810,10 +1793,10 @@ pub const File = struct {...@@ -1810,10 +1793,10 @@ pub const File = struct {
1810 const tracy = trace(@src());1793 const tracy = trace(@src());
1811 defer tracy.end();1794 defer tracy.end();
18121795
1813 var code_buffer = std.ArrayList(u8).init(self.allocator);1796 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
1814 defer code_buffer.deinit();1797 defer code_buffer.deinit();
18151798
1816 var dbg_line_buffer = std.ArrayList(u8).init(self.allocator);1799 var dbg_line_buffer = std.ArrayList(u8).init(self.base.allocator);
1817 defer dbg_line_buffer.deinit();1800 defer dbg_line_buffer.deinit();
18181801
1819 const typed_value = decl.typed_value.most_recent.typed_value;1802 const typed_value = decl.typed_value.most_recent.typed_value;
...@@ -1936,7 +1919,7 @@ pub const File = struct {...@@ -1936,7 +1919,7 @@ pub const File = struct {
19361919
1937 const section_offset = local_sym.st_value - self.program_headers.items[self.phdr_load_re_index.?].p_vaddr;1920 const section_offset = local_sym.st_value - self.program_headers.items[self.phdr_load_re_index.?].p_vaddr;
1938 const file_offset = self.sections.items[self.text_section_index.?].sh_offset + section_offset;1921 const file_offset = self.sections.items[self.text_section_index.?].sh_offset + section_offset;
1939 try self.file.?.pwriteAll(code, file_offset);1922 try self.base.file.?.pwriteAll(code, file_offset);
19401923
1941 // If the Decl is a function, we need to update the .debug_line program.1924 // If the Decl is a function, we need to update the .debug_line program.
1942 if (is_fn) {1925 if (is_fn) {
...@@ -1966,7 +1949,7 @@ pub const File = struct {...@@ -1966,7 +1949,7 @@ pub const File = struct {
1966 if (src_fn.off + src_fn.len + min_nop_size > next.off) {1949 if (src_fn.off + src_fn.len + min_nop_size > next.off) {
1967 // It grew too big, so we move it to a new location.1950 // It grew too big, so we move it to a new location.
1968 if (src_fn.prev) |prev| {1951 if (src_fn.prev) |prev| {
1969 _ = self.dbg_line_fn_free_list.put(self.allocator, prev, {}) catch {};1952 _ = self.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {};
1970 prev.next = src_fn.next;1953 prev.next = src_fn.next;
1971 }1954 }
1972 next.prev = src_fn.prev;1955 next.prev = src_fn.prev;
...@@ -2009,7 +1992,7 @@ pub const File = struct {...@@ -2009,7 +1992,7 @@ pub const File = struct {
2009 debug_line_sect.sh_offset,1992 debug_line_sect.sh_offset,
2010 new_offset,1993 new_offset,
2011 });1994 });
2012 const amt = try self.file.?.copyRangeAll(debug_line_sect.sh_offset, self.file.?, new_offset, existing_size);1995 const amt = try self.base.file.?.copyRangeAll(debug_line_sect.sh_offset, self.base.file.?, new_offset, existing_size);
2013 if (amt != existing_size) return error.InputOutput;1996 if (amt != existing_size) return error.InputOutput;
2014 debug_line_sect.sh_offset = new_offset;1997 debug_line_sect.sh_offset = new_offset;
2015 }1998 }
...@@ -2041,7 +2024,7 @@ pub const File = struct {...@@ -2041,7 +2024,7 @@ pub const File = struct {
2041 const tracy = trace(@src());2024 const tracy = trace(@src());
2042 defer tracy.end();2025 defer tracy.end();
20432026
2044 try self.global_symbols.ensureCapacity(self.allocator, self.global_symbols.items.len + exports.len);2027 try self.global_symbols.ensureCapacity(self.base.allocator, self.global_symbols.items.len + exports.len);
2045 const typed_value = decl.typed_value.most_recent.typed_value;2028 const typed_value = decl.typed_value.most_recent.typed_value;
2046 if (decl.link.local_sym_index == 0) return;2029 if (decl.link.local_sym_index == 0) return;
2047 const decl_sym = self.local_symbols.items[decl.link.local_sym_index];2030 const decl_sym = self.local_symbols.items[decl.link.local_sym_index];
...@@ -2052,7 +2035,7 @@ pub const File = struct {...@@ -2052,7 +2035,7 @@ pub const File = struct {
2052 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);2035 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);
2053 module.failed_exports.putAssumeCapacityNoClobber(2036 module.failed_exports.putAssumeCapacityNoClobber(
2054 exp,2037 exp,
2055 try Module.ErrorMsg.create(self.allocator, 0, "Unimplemented: ExportOptions.section", .{}),2038 try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: ExportOptions.section", .{}),
2056 );2039 );
2057 continue;2040 continue;
2058 }2041 }
...@@ -2070,7 +2053,7 @@ pub const File = struct {...@@ -2070,7 +2053,7 @@ pub const File = struct {
2070 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);2053 try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1);
2071 module.failed_exports.putAssumeCapacityNoClobber(2054 module.failed_exports.putAssumeCapacityNoClobber(
2072 exp,2055 exp,
2073 try Module.ErrorMsg.create(self.allocator, 0, "Unimplemented: GlobalLinkage.LinkOnce", .{}),2056 try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: GlobalLinkage.LinkOnce", .{}),
2074 );2057 );
2075 continue;2058 continue;
2076 },2059 },
...@@ -2125,12 +2108,12 @@ pub const File = struct {...@@ -2125,12 +2108,12 @@ pub const File = struct {
2125 const file_pos = shdr.sh_offset + decl.fn_link.off + self.getRelocDbgLineOff();2108 const file_pos = shdr.sh_offset + decl.fn_link.off + self.getRelocDbgLineOff();
2126 var data: [4]u8 = undefined;2109 var data: [4]u8 = undefined;
2127 leb128.writeUnsignedFixed(4, &data, casted_line_off);2110 leb128.writeUnsignedFixed(4, &data, casted_line_off);
2128 try self.file.?.pwriteAll(&data, file_pos);2111 try self.base.file.?.pwriteAll(&data, file_pos);
2129 }2112 }
21302113
2131 pub fn deleteExport(self: *Elf, exp: Export) void {2114 pub fn deleteExport(self: *Elf, exp: Export) void {
2132 const sym_index = exp.sym_index orelse return;2115 const sym_index = exp.sym_index orelse return;
2133 self.global_symbol_free_list.append(self.allocator, sym_index) catch {};2116 self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {};
2134 self.global_symbols.items[sym_index].st_info = 0;2117 self.global_symbols.items[sym_index].st_info = 0;
2135 }2118 }
21362119
...@@ -2143,14 +2126,14 @@ pub const File = struct {...@@ -2143,14 +2126,14 @@ pub const File = struct {
2143 if (foreign_endian) {2126 if (foreign_endian) {
2144 bswapAllFields(elf.Elf32_Phdr, &phdr[0]);2127 bswapAllFields(elf.Elf32_Phdr, &phdr[0]);
2145 }2128 }
2146 return self.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);2129 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);
2147 },2130 },
2148 64 => {2131 64 => {
2149 var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]};2132 var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]};
2150 if (foreign_endian) {2133 if (foreign_endian) {
2151 bswapAllFields(elf.Elf64_Phdr, &phdr[0]);2134 bswapAllFields(elf.Elf64_Phdr, &phdr[0]);
2152 }2135 }
2153 return self.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);2136 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);
2154 },2137 },
2155 else => return error.UnsupportedArchitecture,2138 else => return error.UnsupportedArchitecture,
2156 }2139 }
...@@ -2166,7 +2149,7 @@ pub const File = struct {...@@ -2166,7 +2149,7 @@ pub const File = struct {
2166 bswapAllFields(elf.Elf32_Shdr, &shdr[0]);2149 bswapAllFields(elf.Elf32_Shdr, &shdr[0]);
2167 }2150 }
2168 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf32_Shdr);2151 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf32_Shdr);
2169 return self.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);2152 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);
2170 },2153 },
2171 64 => {2154 64 => {
2172 var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]};2155 var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]};
...@@ -2174,7 +2157,7 @@ pub const File = struct {...@@ -2174,7 +2157,7 @@ pub const File = struct {
2174 bswapAllFields(elf.Elf64_Shdr, &shdr[0]);2157 bswapAllFields(elf.Elf64_Shdr, &shdr[0]);
2175 }2158 }
2176 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf64_Shdr);2159 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf64_Shdr);
2177 return self.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);2160 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);
2178 },2161 },
2179 else => return error.UnsupportedArchitecture,2162 else => return error.UnsupportedArchitecture,
2180 }2163 }
...@@ -2191,7 +2174,7 @@ pub const File = struct {...@@ -2191,7 +2174,7 @@ pub const File = struct {
2191 if (needed_size > allocated_size) {2174 if (needed_size > allocated_size) {
2192 // Must move the entire got section.2175 // Must move the entire got section.
2193 const new_offset = self.findFreeSpace(needed_size, entry_size);2176 const new_offset = self.findFreeSpace(needed_size, entry_size);
2194 const amt = try self.file.?.copyRangeAll(shdr.sh_offset, self.file.?, new_offset, shdr.sh_size);2177 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, shdr.sh_size);
2195 if (amt != shdr.sh_size) return error.InputOutput;2178 if (amt != shdr.sh_size) return error.InputOutput;
2196 shdr.sh_offset = new_offset;2179 shdr.sh_offset = new_offset;
2197 phdr.p_offset = new_offset;2180 phdr.p_offset = new_offset;
...@@ -2211,12 +2194,12 @@ pub const File = struct {...@@ -2211,12 +2194,12 @@ pub const File = struct {
2211 .p32 => {2194 .p32 => {
2212 var buf: [4]u8 = undefined;2195 var buf: [4]u8 = undefined;
2213 mem.writeInt(u32, &buf, @intCast(u32, self.offset_table.items[index]), endian);2196 mem.writeInt(u32, &buf, @intCast(u32, self.offset_table.items[index]), endian);
2214 try self.file.?.pwriteAll(&buf, off);2197 try self.base.file.?.pwriteAll(&buf, off);
2215 },2198 },
2216 .p64 => {2199 .p64 => {
2217 var buf: [8]u8 = undefined;2200 var buf: [8]u8 = undefined;
2218 mem.writeInt(u64, &buf, self.offset_table.items[index], endian);2201 mem.writeInt(u64, &buf, self.offset_table.items[index], endian);
2219 try self.file.?.pwriteAll(&buf, off);2202 try self.base.file.?.pwriteAll(&buf, off);
2220 },2203 },
2221 }2204 }
2222 }2205 }
...@@ -2239,7 +2222,7 @@ pub const File = struct {...@@ -2239,7 +2222,7 @@ pub const File = struct {
2239 // Move all the symbols to a new file location.2222 // Move all the symbols to a new file location.
2240 const new_offset = self.findFreeSpace(needed_size, sym_align);2223 const new_offset = self.findFreeSpace(needed_size, sym_align);
2241 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;2224 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;
2242 const amt = try self.file.?.copyRangeAll(syms_sect.sh_offset, self.file.?, new_offset, existing_size);2225 const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size);
2243 if (amt != existing_size) return error.InputOutput;2226 if (amt != existing_size) return error.InputOutput;
2244 syms_sect.sh_offset = new_offset;2227 syms_sect.sh_offset = new_offset;
2245 }2228 }
...@@ -2264,7 +2247,7 @@ pub const File = struct {...@@ -2264,7 +2247,7 @@ pub const File = struct {
2264 bswapAllFields(elf.Elf32_Sym, &sym[0]);2247 bswapAllFields(elf.Elf32_Sym, &sym[0]);
2265 }2248 }
2266 const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index;2249 const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index;
2267 try self.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);2250 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
2268 },2251 },
2269 .p64 => {2252 .p64 => {
2270 var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]};2253 var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]};
...@@ -2272,7 +2255,7 @@ pub const File = struct {...@@ -2272,7 +2255,7 @@ pub const File = struct {
2272 bswapAllFields(elf.Elf64_Sym, &sym[0]);2255 bswapAllFields(elf.Elf64_Sym, &sym[0]);
2273 }2256 }
2274 const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index;2257 const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index;
2275 try self.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);2258 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
2276 },2259 },
2277 }2260 }
2278 }2261 }
...@@ -2287,8 +2270,8 @@ pub const File = struct {...@@ -2287,8 +2270,8 @@ pub const File = struct {
2287 const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size;2270 const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size;
2288 switch (self.ptr_width) {2271 switch (self.ptr_width) {
2289 .p32 => {2272 .p32 => {
2290 const buf = try self.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len);2273 const buf = try self.base.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len);
2291 defer self.allocator.free(buf);2274 defer self.base.allocator.free(buf);
22922275
2293 for (buf) |*sym, i| {2276 for (buf) |*sym, i| {
2294 sym.* = .{2277 sym.* = .{
...@@ -2303,11 +2286,11 @@ pub const File = struct {...@@ -2303,11 +2286,11 @@ pub const File = struct {
2303 bswapAllFields(elf.Elf32_Sym, sym);2286 bswapAllFields(elf.Elf32_Sym, sym);
2304 }2287 }
2305 }2288 }
2306 try self.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);2289 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);
2307 },2290 },
2308 .p64 => {2291 .p64 => {
2309 const buf = try self.allocator.alloc(elf.Elf64_Sym, self.global_symbols.items.len);2292 const buf = try self.base.allocator.alloc(elf.Elf64_Sym, self.global_symbols.items.len);
2310 defer self.allocator.free(buf);2293 defer self.base.allocator.free(buf);
23112294
2312 for (buf) |*sym, i| {2295 for (buf) |*sym, i| {
2313 sym.* = .{2296 sym.* = .{
...@@ -2322,7 +2305,7 @@ pub const File = struct {...@@ -2322,7 +2305,7 @@ pub const File = struct {
2322 bswapAllFields(elf.Elf64_Sym, sym);2305 bswapAllFields(elf.Elf64_Sym, sym);
2323 }2306 }
2324 }2307 }
2325 try self.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);2308 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);
2326 },2309 },
2327 }2310 }
2328 }2311 }
...@@ -2437,7 +2420,7 @@ pub const File = struct {...@@ -2437,7 +2420,7 @@ pub const File = struct {
2437 vec_index += 1;2420 vec_index += 1;
2438 }2421 }
2439 }2422 }
2440 try self.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size);2423 try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size);
2441 }2424 }
24422425
2443 const min_nop_size = 2;2426 const min_nop_size = 2;