| ... | ... | @@ -36,9 +36,12 @@ pub const Options = struct { |
| 36 | 36 | program_code_size_hint: u64 = 256 * 1024, |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | |
| 39 | 40 | pub const File = struct { |
| 40 | 41 | tag: Tag, |
| 41 | 42 | options: Options, |
| 43 | file: ?fs.File, |
| 44 | allocator: *Allocator, |
| 42 | 45 | |
| 43 | 46 | /// Attempts incremental linking, if the file already exists. If |
| 44 | 47 | /// incremental linking fails, falls back to truncating the file and |
| ... | ... | @@ -66,15 +69,23 @@ pub const File = struct { |
| 66 | 69 | |
| 67 | 70 | pub fn makeWritable(base: *File, dir: fs.Dir, sub_path: []const u8) !void { |
| 68 | 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 | 80 | .c => {}, |
| 71 | 81 | } |
| 72 | 82 | } |
| 73 | 83 | |
| 74 | 84 | pub fn makeExecutable(base: *File) !void { |
| 75 | | switch (base.tag) { |
| 76 | | .elf => return @fieldParentPtr(Elf, "base", base).makeExecutable(), |
| 77 | | .c => unreachable, |
| 85 | std.debug.assert(base.tag != .c); |
| 86 | if (base.file) |f| { |
| 87 | f.close(); |
| 88 | base.file = null; |
| 78 | 89 | } |
| 79 | 90 | } |
| 80 | 91 | |
| ... | ... | @@ -100,6 +111,7 @@ pub const File = struct { |
| 100 | 111 | } |
| 101 | 112 | |
| 102 | 113 | pub fn deinit(base: *File) void { |
| 114 | if (base.file) |f| f.close(); |
| 103 | 115 | switch (base.tag) { |
| 104 | 116 | .elf => @fieldParentPtr(Elf, "base", base).deinit(), |
| 105 | 117 | .c => @fieldParentPtr(C, "base", base).deinit(), |
| ... | ... | @@ -111,12 +123,12 @@ pub const File = struct { |
| 111 | 123 | .elf => { |
| 112 | 124 | const parent = @fieldParentPtr(Elf, "base", base); |
| 113 | 125 | parent.deinit(); |
| 114 | | parent.allocator.destroy(parent); |
| 126 | base.allocator.destroy(parent); |
| 115 | 127 | }, |
| 116 | 128 | .c => { |
| 117 | 129 | const parent = @fieldParentPtr(C, "base", base); |
| 118 | 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 | 184 | |
| 173 | 185 | base: File, |
| 174 | 186 | |
| 175 | | allocator: *Allocator, |
| 176 | 187 | header: std.ArrayList(u8), |
| 177 | 188 | constants: std.ArrayList(u8), |
| 178 | 189 | main: std.ArrayList(u8), |
| 179 | | file: ?fs.File, |
| 190 | |
| 180 | 191 | called: std.StringHashMap(void), |
| 181 | 192 | need_stddef: bool = false, |
| 182 | 193 | need_stdint: bool = false, |
| ... | ... | @@ -196,9 +207,9 @@ pub const File = struct { |
| 196 | 207 | .base = .{ |
| 197 | 208 | .tag = .c, |
| 198 | 209 | .options = options, |
| 210 | .file = file, |
| 211 | .allocator = allocator, |
| 199 | 212 | }, |
| 200 | | .allocator = allocator, |
| 201 | | .file = file, |
| 202 | 213 | .main = std.ArrayList(u8).init(allocator), |
| 203 | 214 | .header = std.ArrayList(u8).init(allocator), |
| 204 | 215 | .constants = std.ArrayList(u8).init(allocator), |
| ... | ... | @@ -209,7 +220,7 @@ pub const File = struct { |
| 209 | 220 | } |
| 210 | 221 | |
| 211 | 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 | 224 | return error.AnalysisFail; |
| 214 | 225 | } |
| 215 | 226 | |
| ... | ... | @@ -218,8 +229,6 @@ pub const File = struct { |
| 218 | 229 | self.header.deinit(); |
| 219 | 230 | self.constants.deinit(); |
| 220 | 231 | self.called.deinit(); |
| 221 | | if (self.file) |f| |
| 222 | | f.close(); |
| 223 | 232 | } |
| 224 | 233 | |
| 225 | 234 | pub fn updateDecl(self: *File.C, module: *Module, decl: *Module.Decl) !void { |
| ... | ... | @@ -232,7 +241,7 @@ pub const File = struct { |
| 232 | 241 | } |
| 233 | 242 | |
| 234 | 243 | pub fn flush(self: *File.C) !void { |
| 235 | | const writer = self.file.?.writer(); |
| 244 | const writer = self.base.file.?.writer(); |
| 236 | 245 | try writer.writeAll(@embedFile("cbe.h")); |
| 237 | 246 | var includes = false; |
| 238 | 247 | if (self.need_stddef) { |
| ... | ... | @@ -259,8 +268,8 @@ pub const File = struct { |
| 259 | 268 | } |
| 260 | 269 | } |
| 261 | 270 | try writer.writeAll(self.main.items); |
| 262 | | self.file.?.close(); |
| 263 | | self.file = null; |
| 271 | self.base.file.?.close(); |
| 272 | self.base.file = null; |
| 264 | 273 | } |
| 265 | 274 | }; |
| 266 | 275 | |
| ... | ... | @@ -269,9 +278,6 @@ pub const File = struct { |
| 269 | 278 | |
| 270 | 279 | base: File, |
| 271 | 280 | |
| 272 | | allocator: *Allocator, |
| 273 | | file: ?fs.File, |
| 274 | | owns_file_handle: bool, |
| 275 | 281 | ptr_width: enum { p32, p64 }, |
| 276 | 282 | |
| 277 | 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 | 460 | else => |e| return e, |
| 455 | 461 | }; |
| 456 | 462 | |
| 457 | | elf_file.owns_file_handle = true; |
| 458 | 463 | return &elf_file.base; |
| 459 | 464 | } |
| 460 | 465 | |
| ... | ... | @@ -467,12 +472,11 @@ pub const File = struct { |
| 467 | 472 | } |
| 468 | 473 | var self: Elf = .{ |
| 469 | 474 | .base = .{ |
| 475 | .file = file, |
| 470 | 476 | .tag = .elf, |
| 471 | 477 | .options = options, |
| 478 | .allocator = allocator, |
| 472 | 479 | }, |
| 473 | | .allocator = allocator, |
| 474 | | .file = file, |
| 475 | | .owns_file_handle = false, |
| 476 | 480 | .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) { |
| 477 | 481 | 32 => .p32, |
| 478 | 482 | 64 => .p64, |
| ... | ... | @@ -499,16 +503,15 @@ pub const File = struct { |
| 499 | 503 | .base = .{ |
| 500 | 504 | .tag = .elf, |
| 501 | 505 | .options = options, |
| 506 | .allocator = allocator, |
| 507 | .file = file, |
| 502 | 508 | }, |
| 503 | | .allocator = allocator, |
| 504 | | .file = file, |
| 505 | 509 | .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) { |
| 506 | 510 | 32 => .p32, |
| 507 | 511 | 64 => .p64, |
| 508 | 512 | else => return error.UnsupportedELFArchitecture, |
| 509 | 513 | }, |
| 510 | 514 | .shdr_table_dirty = true, |
| 511 | | .owns_file_handle = false, |
| 512 | 515 | }; |
| 513 | 516 | errdefer self.deinit(); |
| 514 | 517 | |
| ... | ... | @@ -542,39 +545,18 @@ pub const File = struct { |
| 542 | 545 | } |
| 543 | 546 | |
| 544 | 547 | pub fn deinit(self: *Elf) void { |
| 545 | | self.sections.deinit(self.allocator); |
| 546 | | self.program_headers.deinit(self.allocator); |
| 547 | | self.shstrtab.deinit(self.allocator); |
| 548 | | self.debug_strtab.deinit(self.allocator); |
| 549 | | self.local_symbols.deinit(self.allocator); |
| 550 | | self.global_symbols.deinit(self.allocator); |
| 551 | | self.global_symbol_free_list.deinit(self.allocator); |
| 552 | | self.local_symbol_free_list.deinit(self.allocator); |
| 553 | | self.offset_table_free_list.deinit(self.allocator); |
| 554 | | self.text_block_free_list.deinit(self.allocator); |
| 555 | | self.dbg_line_fn_free_list.deinit(self.allocator); |
| 556 | | self.offset_table.deinit(self.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 | | }); |
| 548 | self.sections.deinit(self.base.allocator); |
| 549 | self.program_headers.deinit(self.base.allocator); |
| 550 | self.shstrtab.deinit(self.base.allocator); |
| 551 | self.debug_strtab.deinit(self.base.allocator); |
| 552 | self.local_symbols.deinit(self.base.allocator); |
| 553 | self.global_symbols.deinit(self.base.allocator); |
| 554 | self.global_symbol_free_list.deinit(self.base.allocator); |
| 555 | self.local_symbol_free_list.deinit(self.base.allocator); |
| 556 | self.offset_table_free_list.deinit(self.base.allocator); |
| 557 | self.text_block_free_list.deinit(self.base.allocator); |
| 558 | self.dbg_line_fn_free_list.deinit(self.base.allocator); |
| 559 | self.offset_table.deinit(self.base.allocator); |
| 578 | 560 | } |
| 579 | 561 | |
| 580 | 562 | fn getDebugLineProgramOff(self: Elf) u32 { |
| ... | ... | @@ -662,7 +644,7 @@ pub const File = struct { |
| 662 | 644 | |
| 663 | 645 | /// TODO Improve this to use a table. |
| 664 | 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 | 648 | const result = self.shstrtab.items.len; |
| 667 | 649 | self.shstrtab.appendSliceAssumeCapacity(bytes); |
| 668 | 650 | self.shstrtab.appendAssumeCapacity(0); |
| ... | ... | @@ -671,7 +653,7 @@ pub const File = struct { |
| 671 | 653 | |
| 672 | 654 | /// TODO Improve this to use a table. |
| 673 | 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 | 657 | const result = self.debug_strtab.items.len; |
| 676 | 658 | self.debug_strtab.appendSliceAssumeCapacity(bytes); |
| 677 | 659 | self.debug_strtab.appendAssumeCapacity(0); |
| ... | ... | @@ -703,7 +685,7 @@ pub const File = struct { |
| 703 | 685 | const p_align = 0x1000; |
| 704 | 686 | const off = self.findFreeSpace(file_size, p_align); |
| 705 | 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 | 689 | .p_type = elf.PT_LOAD, |
| 708 | 690 | .p_offset = off, |
| 709 | 691 | .p_filesz = file_size, |
| ... | ... | @@ -721,14 +703,14 @@ pub const File = struct { |
| 721 | 703 | const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; |
| 722 | 704 | // We really only need ptr alignment but since we are using PROGBITS, linux requires |
| 723 | 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 | 707 | const off = self.findFreeSpace(file_size, p_align); |
| 726 | 708 | log.debug(.link, "found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 727 | 709 | // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at. |
| 728 | 710 | // we'll need to re-use that function anyway, in case the GOT grows and overlaps something |
| 729 | 711 | // else in virtual memory. |
| 730 | | const default_got_addr = 0x4000000; |
| 731 | | try self.program_headers.append(self.allocator, .{ |
| 712 | const default_got_addr = if (ptr_size == 2) @as(u32, 0x8000) else 0x4000000; |
| 713 | try self.program_headers.append(self.base.allocator, .{ |
| 732 | 714 | .p_type = elf.PT_LOAD, |
| 733 | 715 | .p_offset = off, |
| 734 | 716 | .p_filesz = file_size, |
| ... | ... | @@ -743,10 +725,10 @@ pub const File = struct { |
| 743 | 725 | if (self.shstrtab_index == null) { |
| 744 | 726 | self.shstrtab_index = @intCast(u16, self.sections.items.len); |
| 745 | 727 | assert(self.shstrtab.items.len == 0); |
| 746 | | try self.shstrtab.append(self.allocator, 0); // need a 0 at position 0 |
| 728 | try self.shstrtab.append(self.base.allocator, 0); // need a 0 at position 0 |
| 747 | 729 | const off = self.findFreeSpace(self.shstrtab.items.len, 1); |
| 748 | 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 | 732 | .sh_name = try self.makeString(".shstrtab"), |
| 751 | 733 | .sh_type = elf.SHT_STRTAB, |
| 752 | 734 | .sh_flags = 0, |
| ... | ... | @@ -765,7 +747,7 @@ pub const File = struct { |
| 765 | 747 | self.text_section_index = @intCast(u16, self.sections.items.len); |
| 766 | 748 | const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 767 | 749 | |
| 768 | | try self.sections.append(self.allocator, .{ |
| 750 | try self.sections.append(self.base.allocator, .{ |
| 769 | 751 | .sh_name = try self.makeString(".text"), |
| 770 | 752 | .sh_type = elf.SHT_PROGBITS, |
| 771 | 753 | .sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, |
| ... | ... | @@ -783,7 +765,7 @@ pub const File = struct { |
| 783 | 765 | self.got_section_index = @intCast(u16, self.sections.items.len); |
| 784 | 766 | const phdr = &self.program_headers.items[self.phdr_got_index.?]; |
| 785 | 767 | |
| 786 | | try self.sections.append(self.allocator, .{ |
| 768 | try self.sections.append(self.base.allocator, .{ |
| 787 | 769 | .sh_name = try self.makeString(".got"), |
| 788 | 770 | .sh_type = elf.SHT_PROGBITS, |
| 789 | 771 | .sh_flags = elf.SHF_ALLOC, |
| ... | ... | @@ -805,7 +787,7 @@ pub const File = struct { |
| 805 | 787 | const off = self.findFreeSpace(file_size, min_align); |
| 806 | 788 | log.debug(.link, "found symtab free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| 807 | 789 | |
| 808 | | try self.sections.append(self.allocator, .{ |
| 790 | try self.sections.append(self.base.allocator, .{ |
| 809 | 791 | .sh_name = try self.makeString(".symtab"), |
| 810 | 792 | .sh_type = elf.SHT_SYMTAB, |
| 811 | 793 | .sh_flags = 0, |
| ... | ... | @@ -824,7 +806,7 @@ pub const File = struct { |
| 824 | 806 | if (self.debug_str_section_index == null) { |
| 825 | 807 | self.debug_str_section_index = @intCast(u16, self.sections.items.len); |
| 826 | 808 | assert(self.debug_strtab.items.len == 0); |
| 827 | | try self.sections.append(self.allocator, .{ |
| 809 | try self.sections.append(self.base.allocator, .{ |
| 828 | 810 | .sh_name = try self.makeString(".debug_str"), |
| 829 | 811 | .sh_type = elf.SHT_PROGBITS, |
| 830 | 812 | .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS, |
| ... | ... | @@ -849,7 +831,7 @@ pub const File = struct { |
| 849 | 831 | off, |
| 850 | 832 | off + file_size_hint, |
| 851 | 833 | }); |
| 852 | | try self.sections.append(self.allocator, .{ |
| 834 | try self.sections.append(self.base.allocator, .{ |
| 853 | 835 | .sh_name = try self.makeString(".debug_info"), |
| 854 | 836 | .sh_type = elf.SHT_PROGBITS, |
| 855 | 837 | .sh_flags = 0, |
| ... | ... | @@ -874,7 +856,7 @@ pub const File = struct { |
| 874 | 856 | off, |
| 875 | 857 | off + file_size_hint, |
| 876 | 858 | }); |
| 877 | | try self.sections.append(self.allocator, .{ |
| 859 | try self.sections.append(self.base.allocator, .{ |
| 878 | 860 | .sh_name = try self.makeString(".debug_abbrev"), |
| 879 | 861 | .sh_type = elf.SHT_PROGBITS, |
| 880 | 862 | .sh_flags = 0, |
| ... | ... | @@ -899,7 +881,7 @@ pub const File = struct { |
| 899 | 881 | off, |
| 900 | 882 | off + file_size_hint, |
| 901 | 883 | }); |
| 902 | | try self.sections.append(self.allocator, .{ |
| 884 | try self.sections.append(self.base.allocator, .{ |
| 903 | 885 | .sh_name = try self.makeString(".debug_aranges"), |
| 904 | 886 | .sh_type = elf.SHT_PROGBITS, |
| 905 | 887 | .sh_flags = 0, |
| ... | ... | @@ -924,7 +906,7 @@ pub const File = struct { |
| 924 | 906 | off, |
| 925 | 907 | off + file_size_hint, |
| 926 | 908 | }); |
| 927 | | try self.sections.append(self.allocator, .{ |
| 909 | try self.sections.append(self.base.allocator, .{ |
| 928 | 910 | .sh_name = try self.makeString(".debug_line"), |
| 929 | 911 | .sh_type = elf.SHT_PROGBITS, |
| 930 | 912 | .sh_flags = 0, |
| ... | ... | @@ -1019,7 +1001,7 @@ pub const File = struct { |
| 1019 | 1001 | |
| 1020 | 1002 | const abbrev_offset = 0; |
| 1021 | 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 | 1005 | if (!self.shdr_table_dirty) { |
| 1024 | 1006 | // Then it won't get written with the others and we need to do it. |
| 1025 | 1007 | try self.writeSectHeader(self.debug_abbrev_section_index.?); |
| ... | ... | @@ -1030,7 +1012,7 @@ pub const File = struct { |
| 1030 | 1012 | if (self.debug_info_section_dirty) { |
| 1031 | 1013 | const debug_info_sect = &self.sections.items[self.debug_info_section_index.?]; |
| 1032 | 1014 | |
| 1033 | | var di_buf = std.ArrayList(u8).init(self.allocator); |
| 1015 | var di_buf = std.ArrayList(u8).init(self.base.allocator); |
| 1034 | 1016 | defer di_buf.deinit(); |
| 1035 | 1017 | |
| 1036 | 1018 | // Enough for a 64-bit header and main compilation unit without resizing. |
| ... | ... | @@ -1101,7 +1083,7 @@ pub const File = struct { |
| 1101 | 1083 | debug_info_sect.sh_offset + needed_size, |
| 1102 | 1084 | }); |
| 1103 | 1085 | |
| 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 | 1087 | if (!self.shdr_table_dirty) { |
| 1106 | 1088 | // Then it won't get written with the others and we need to do it. |
| 1107 | 1089 | try self.writeSectHeader(self.debug_info_section_index.?); |
| ... | ... | @@ -1112,7 +1094,7 @@ pub const File = struct { |
| 1112 | 1094 | if (self.debug_aranges_section_dirty) { |
| 1113 | 1095 | const debug_aranges_sect = &self.sections.items[self.debug_aranges_section_index.?]; |
| 1114 | 1096 | |
| 1115 | | var di_buf = std.ArrayList(u8).init(self.allocator); |
| 1097 | var di_buf = std.ArrayList(u8).init(self.base.allocator); |
| 1116 | 1098 | defer di_buf.deinit(); |
| 1117 | 1099 | |
| 1118 | 1100 | // Enough for all the data without resizing. When support for more compilation units |
| ... | ... | @@ -1172,7 +1154,7 @@ pub const File = struct { |
| 1172 | 1154 | debug_aranges_sect.sh_offset + needed_size, |
| 1173 | 1155 | }); |
| 1174 | 1156 | |
| 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 | 1158 | if (!self.shdr_table_dirty) { |
| 1177 | 1159 | // Then it won't get written with the others and we need to do it. |
| 1178 | 1160 | try self.writeSectHeader(self.debug_aranges_section_index.?); |
| ... | ... | @@ -1187,7 +1169,7 @@ pub const File = struct { |
| 1187 | 1169 | |
| 1188 | 1170 | const debug_line_sect = &self.sections.items[self.debug_line_section_index.?]; |
| 1189 | 1171 | |
| 1190 | | var di_buf = std.ArrayList(u8).init(self.allocator); |
| 1172 | var di_buf = std.ArrayList(u8).init(self.base.allocator); |
| 1191 | 1173 | defer di_buf.deinit(); |
| 1192 | 1174 | |
| 1193 | 1175 | // The size of this header is variable, depending on the number of directories, |
| ... | ... | @@ -1294,8 +1276,8 @@ pub const File = struct { |
| 1294 | 1276 | |
| 1295 | 1277 | switch (self.ptr_width) { |
| 1296 | 1278 | .p32 => { |
| 1297 | | const buf = try self.allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); |
| 1298 | | defer self.allocator.free(buf); |
| 1279 | const buf = try self.base.allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); |
| 1280 | defer self.base.allocator.free(buf); |
| 1299 | 1281 | |
| 1300 | 1282 | for (buf) |*phdr, i| { |
| 1301 | 1283 | phdr.* = progHeaderTo32(self.program_headers.items[i]); |
| ... | ... | @@ -1303,11 +1285,11 @@ pub const File = struct { |
| 1303 | 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 | 1290 | .p64 => { |
| 1309 | | const buf = try self.allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| 1310 | | defer self.allocator.free(buf); |
| 1291 | const buf = try self.base.allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| 1292 | defer self.base.allocator.free(buf); |
| 1311 | 1293 | |
| 1312 | 1294 | for (buf) |*phdr, i| { |
| 1313 | 1295 | phdr.* = self.program_headers.items[i]; |
| ... | ... | @@ -1315,7 +1297,7 @@ pub const File = struct { |
| 1315 | 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 | 1303 | self.phdr_table_dirty = false; |
| ... | ... | @@ -1334,7 +1316,7 @@ pub const File = struct { |
| 1334 | 1316 | shstrtab_sect.sh_size = needed_size; |
| 1335 | 1317 | log.debug(.link, "writing shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size }); |
| 1336 | 1318 | |
| 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 | 1320 | if (!self.shdr_table_dirty) { |
| 1339 | 1321 | // Then it won't get written with the others and we need to do it. |
| 1340 | 1322 | try self.writeSectHeader(self.shstrtab_index.?); |
| ... | ... | @@ -1355,7 +1337,7 @@ pub const File = struct { |
| 1355 | 1337 | debug_strtab_sect.sh_size = needed_size; |
| 1356 | 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 }); |
| 1357 | 1339 | |
| 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 | 1341 | if (!self.shdr_table_dirty) { |
| 1360 | 1342 | // Then it won't get written with the others and we need to do it. |
| 1361 | 1343 | try self.writeSectHeader(self.debug_str_section_index.?); |
| ... | ... | @@ -1382,20 +1364,21 @@ pub const File = struct { |
| 1382 | 1364 | |
| 1383 | 1365 | switch (self.ptr_width) { |
| 1384 | 1366 | .p32 => { |
| 1385 | | const buf = try self.allocator.alloc(elf.Elf32_Shdr, self.sections.items.len); |
| 1386 | | defer self.allocator.free(buf); |
| 1367 | const buf = try self.base.allocator.alloc(elf.Elf32_Shdr, self.sections.items.len); |
| 1368 | defer self.base.allocator.free(buf); |
| 1387 | 1369 | |
| 1388 | 1370 | for (buf) |*shdr, i| { |
| 1389 | 1371 | shdr.* = sectHeaderTo32(self.sections.items[i]); |
| 1372 | std.log.debug(.link, "writing section {}\n", .{shdr.*}); |
| 1390 | 1373 | if (foreign_endian) { |
| 1391 | 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 | 1379 | .p64 => { |
| 1397 | | const buf = try self.allocator.alloc(elf.Elf64_Shdr, self.sections.items.len); |
| 1398 | | defer self.allocator.free(buf); |
| 1380 | const buf = try self.base.allocator.alloc(elf.Elf64_Shdr, self.sections.items.len); |
| 1381 | defer self.base.allocator.free(buf); |
| 1399 | 1382 | |
| 1400 | 1383 | for (buf) |*shdr, i| { |
| 1401 | 1384 | shdr.* = self.sections.items[i]; |
| ... | ... | @@ -1404,7 +1387,7 @@ pub const File = struct { |
| 1404 | 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 | 1393 | self.shdr_table_dirty = false; |
| ... | ... | @@ -1557,7 +1540,7 @@ pub const File = struct { |
| 1557 | 1540 | |
| 1558 | 1541 | assert(index == e_ehsize); |
| 1559 | 1542 | |
| 1560 | | try self.file.?.pwriteAll(hdr_buf[0..index], 0); |
| 1543 | try self.base.file.?.pwriteAll(hdr_buf[0..index], 0); |
| 1561 | 1544 | } |
| 1562 | 1545 | |
| 1563 | 1546 | fn freeTextBlock(self: *Elf, text_block: *TextBlock) void { |
| ... | ... | @@ -1587,7 +1570,7 @@ pub const File = struct { |
| 1587 | 1570 | if (!already_have_free_list_node and prev.freeListEligible(self.*)) { |
| 1588 | 1571 | // The free list is heuristics, it doesn't have to be perfect, so we can |
| 1589 | 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 | 1575 | } else { |
| 1593 | 1576 | text_block.prev = null; |
| ... | ... | @@ -1688,7 +1671,7 @@ pub const File = struct { |
| 1688 | 1671 | const sym = self.local_symbols.items[last.local_sym_index]; |
| 1689 | 1672 | break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr; |
| 1690 | 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 | 1675 | if (amt != text_size) return error.InputOutput; |
| 1693 | 1676 | shdr.sh_offset = new_offset; |
| 1694 | 1677 | phdr.p_offset = new_offset; |
| ... | ... | @@ -1739,8 +1722,8 @@ pub const File = struct { |
| 1739 | 1722 | pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void { |
| 1740 | 1723 | if (decl.link.local_sym_index != 0) return; |
| 1741 | 1724 | |
| 1742 | | try self.local_symbols.ensureCapacity(self.allocator, self.local_symbols.items.len + 1); |
| 1743 | | try self.offset_table.ensureCapacity(self.allocator, self.offset_table.items.len + 1); |
| 1725 | try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1); |
| 1726 | try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1); |
| 1744 | 1727 | |
| 1745 | 1728 | if (self.local_symbol_free_list.popOrNull()) |i| { |
| 1746 | 1729 | log.debug(.link, "reusing symbol index {} for {}\n", .{ i, decl.name }); |
| ... | ... | @@ -1776,8 +1759,8 @@ pub const File = struct { |
| 1776 | 1759 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. |
| 1777 | 1760 | self.freeTextBlock(&decl.link); |
| 1778 | 1761 | if (decl.link.local_sym_index != 0) { |
| 1779 | | self.local_symbol_free_list.append(self.allocator, decl.link.local_sym_index) catch {}; |
| 1780 | | self.offset_table_free_list.append(self.allocator, decl.link.offset_table_index) catch {}; |
| 1762 | self.local_symbol_free_list.append(self.base.allocator, decl.link.local_sym_index) catch {}; |
| 1763 | self.offset_table_free_list.append(self.base.allocator, decl.link.offset_table_index) catch {}; |
| 1781 | 1764 | |
| 1782 | 1765 | self.local_symbols.items[decl.link.local_sym_index].st_info = 0; |
| 1783 | 1766 | |
| ... | ... | @@ -1787,7 +1770,7 @@ pub const File = struct { |
| 1787 | 1770 | // is desired for both. |
| 1788 | 1771 | _ = self.dbg_line_fn_free_list.remove(&decl.fn_link); |
| 1789 | 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 | 1774 | prev.next = decl.fn_link.next; |
| 1792 | 1775 | if (decl.fn_link.next) |next| { |
| 1793 | 1776 | next.prev = prev; |
| ... | ... | @@ -1810,10 +1793,10 @@ pub const File = struct { |
| 1810 | 1793 | const tracy = trace(@src()); |
| 1811 | 1794 | defer tracy.end(); |
| 1812 | 1795 | |
| 1813 | | var code_buffer = std.ArrayList(u8).init(self.allocator); |
| 1796 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 1814 | 1797 | defer code_buffer.deinit(); |
| 1815 | 1798 | |
| 1816 | | var dbg_line_buffer = std.ArrayList(u8).init(self.allocator); |
| 1799 | var dbg_line_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 1817 | 1800 | defer dbg_line_buffer.deinit(); |
| 1818 | 1801 | |
| 1819 | 1802 | const typed_value = decl.typed_value.most_recent.typed_value; |
| ... | ... | @@ -1936,7 +1919,7 @@ pub const File = struct { |
| 1936 | 1919 | |
| 1937 | 1920 | const section_offset = local_sym.st_value - self.program_headers.items[self.phdr_load_re_index.?].p_vaddr; |
| 1938 | 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); |
| 1940 | 1923 | |
| 1941 | 1924 | // If the Decl is a function, we need to update the .debug_line program. |
| 1942 | 1925 | if (is_fn) { |
| ... | ... | @@ -1966,7 +1949,7 @@ pub const File = struct { |
| 1966 | 1949 | if (src_fn.off + src_fn.len + min_nop_size > next.off) { |
| 1967 | 1950 | // It grew too big, so we move it to a new location. |
| 1968 | 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 | 1953 | prev.next = src_fn.next; |
| 1971 | 1954 | } |
| 1972 | 1955 | next.prev = src_fn.prev; |
| ... | ... | @@ -2009,7 +1992,7 @@ pub const File = struct { |
| 2009 | 1992 | debug_line_sect.sh_offset, |
| 2010 | 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 | 1996 | if (amt != existing_size) return error.InputOutput; |
| 2014 | 1997 | debug_line_sect.sh_offset = new_offset; |
| 2015 | 1998 | } |
| ... | ... | @@ -2041,7 +2024,7 @@ pub const File = struct { |
| 2041 | 2024 | const tracy = trace(@src()); |
| 2042 | 2025 | defer tracy.end(); |
| 2043 | 2026 | |
| 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 | 2028 | const typed_value = decl.typed_value.most_recent.typed_value; |
| 2046 | 2029 | if (decl.link.local_sym_index == 0) return; |
| 2047 | 2030 | const decl_sym = self.local_symbols.items[decl.link.local_sym_index]; |
| ... | ... | @@ -2052,7 +2035,7 @@ pub const File = struct { |
| 2052 | 2035 | try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); |
| 2053 | 2036 | module.failed_exports.putAssumeCapacityNoClobber( |
| 2054 | 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 | 2040 | continue; |
| 2058 | 2041 | } |
| ... | ... | @@ -2070,7 +2053,7 @@ pub const File = struct { |
| 2070 | 2053 | try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); |
| 2071 | 2054 | module.failed_exports.putAssumeCapacityNoClobber( |
| 2072 | 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 | 2058 | continue; |
| 2076 | 2059 | }, |
| ... | ... | @@ -2125,12 +2108,12 @@ pub const File = struct { |
| 2125 | 2108 | const file_pos = shdr.sh_offset + decl.fn_link.off + self.getRelocDbgLineOff(); |
| 2126 | 2109 | var data: [4]u8 = undefined; |
| 2127 | 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 | } |
| 2130 | 2113 | |
| 2131 | 2114 | pub fn deleteExport(self: *Elf, exp: Export) void { |
| 2132 | 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 | 2117 | self.global_symbols.items[sym_index].st_info = 0; |
| 2135 | 2118 | } |
| 2136 | 2119 | |
| ... | ... | @@ -2143,14 +2126,14 @@ pub const File = struct { |
| 2143 | 2126 | if (foreign_endian) { |
| 2144 | 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 | 2131 | 64 => { |
| 2149 | 2132 | var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]}; |
| 2150 | 2133 | if (foreign_endian) { |
| 2151 | 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 | 2138 | else => return error.UnsupportedArchitecture, |
| 2156 | 2139 | } |
| ... | ... | @@ -2166,7 +2149,7 @@ pub const File = struct { |
| 2166 | 2149 | bswapAllFields(elf.Elf32_Shdr, &shdr[0]); |
| 2167 | 2150 | } |
| 2168 | 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 | 2154 | 64 => { |
| 2172 | 2155 | var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]}; |
| ... | ... | @@ -2174,7 +2157,7 @@ pub const File = struct { |
| 2174 | 2157 | bswapAllFields(elf.Elf64_Shdr, &shdr[0]); |
| 2175 | 2158 | } |
| 2176 | 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 | 2162 | else => return error.UnsupportedArchitecture, |
| 2180 | 2163 | } |
| ... | ... | @@ -2191,7 +2174,7 @@ pub const File = struct { |
| 2191 | 2174 | if (needed_size > allocated_size) { |
| 2192 | 2175 | // Must move the entire got section. |
| 2193 | 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 | 2178 | if (amt != shdr.sh_size) return error.InputOutput; |
| 2196 | 2179 | shdr.sh_offset = new_offset; |
| 2197 | 2180 | phdr.p_offset = new_offset; |
| ... | ... | @@ -2211,12 +2194,12 @@ pub const File = struct { |
| 2211 | 2194 | .p32 => { |
| 2212 | 2195 | var buf: [4]u8 = undefined; |
| 2213 | 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 | 2199 | .p64 => { |
| 2217 | 2200 | var buf: [8]u8 = undefined; |
| 2218 | 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 | 2222 | // Move all the symbols to a new file location. |
| 2240 | 2223 | const new_offset = self.findFreeSpace(needed_size, sym_align); |
| 2241 | 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 | 2226 | if (amt != existing_size) return error.InputOutput; |
| 2244 | 2227 | syms_sect.sh_offset = new_offset; |
| 2245 | 2228 | } |
| ... | ... | @@ -2264,7 +2247,7 @@ pub const File = struct { |
| 2264 | 2247 | bswapAllFields(elf.Elf32_Sym, &sym[0]); |
| 2265 | 2248 | } |
| 2266 | 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 | 2252 | .p64 => { |
| 2270 | 2253 | var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]}; |
| ... | ... | @@ -2272,7 +2255,7 @@ pub const File = struct { |
| 2272 | 2255 | bswapAllFields(elf.Elf64_Sym, &sym[0]); |
| 2273 | 2256 | } |
| 2274 | 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 | 2270 | const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size; |
| 2288 | 2271 | switch (self.ptr_width) { |
| 2289 | 2272 | .p32 => { |
| 2290 | | const buf = try self.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len); |
| 2291 | | defer self.allocator.free(buf); |
| 2273 | const buf = try self.base.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len); |
| 2274 | defer self.base.allocator.free(buf); |
| 2292 | 2275 | |
| 2293 | 2276 | for (buf) |*sym, i| { |
| 2294 | 2277 | sym.* = .{ |
| ... | ... | @@ -2303,11 +2286,11 @@ pub const File = struct { |
| 2303 | 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 | 2291 | .p64 => { |
| 2309 | | const buf = try self.allocator.alloc(elf.Elf64_Sym, self.global_symbols.items.len); |
| 2310 | | defer self.allocator.free(buf); |
| 2292 | const buf = try self.base.allocator.alloc(elf.Elf64_Sym, self.global_symbols.items.len); |
| 2293 | defer self.base.allocator.free(buf); |
| 2311 | 2294 | |
| 2312 | 2295 | for (buf) |*sym, i| { |
| 2313 | 2296 | sym.* = .{ |
| ... | ... | @@ -2322,7 +2305,7 @@ pub const File = struct { |
| 2322 | 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 | 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 | } |
| 2442 | 2425 | |
| 2443 | 2426 | const min_nop_size = 2; |