| ... | ... | @@ -91,7 +91,7 @@ pub fn openBinFile(allocator: *Allocator, file: fs.File, options: Options) !ElfF |
| 91 | 91 | |
| 92 | 92 | pub const ElfFile = struct { |
| 93 | 93 | allocator: *Allocator, |
| 94 | | file: fs.File, |
| 94 | file: ?fs.File, |
| 95 | 95 | owns_file_handle: bool, |
| 96 | 96 | options: Options, |
| 97 | 97 | ptr_width: enum { p32, p64 }, |
| ... | ... | @@ -170,8 +170,27 @@ pub const ElfFile = struct { |
| 170 | 170 | self.local_symbols.deinit(self.allocator); |
| 171 | 171 | self.global_symbols.deinit(self.allocator); |
| 172 | 172 | self.offset_table.deinit(self.allocator); |
| 173 | | if (self.owns_file_handle) |
| 174 | | self.file.close(); |
| 173 | if (self.owns_file_handle) { |
| 174 | if (self.file) |f| f.close(); |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | pub fn makeExecutable(self: *ElfFile) !void { |
| 179 | assert(self.owns_file_handle); |
| 180 | if (self.file) |f| { |
| 181 | f.close(); |
| 182 | self.file = null; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | pub fn makeWritable(self: *ElfFile, dir: fs.Dir, sub_path: []const u8) !void { |
| 187 | assert(self.owns_file_handle); |
| 188 | if (self.file != null) return; |
| 189 | self.file = try dir.createFile(sub_path, .{ |
| 190 | .truncate = false, |
| 191 | .read = true, |
| 192 | .mode = determineMode(self.options), |
| 193 | }); |
| 175 | 194 | } |
| 176 | 195 | |
| 177 | 196 | // `alloc_num / alloc_den` is the factor of padding when allocation |
| ... | ... | @@ -467,7 +486,7 @@ pub const ElfFile = struct { |
| 467 | 486 | bswapAllFields(elf.Elf32_Phdr, phdr); |
| 468 | 487 | } |
| 469 | 488 | } |
| 470 | | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| 489 | try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| 471 | 490 | }, |
| 472 | 491 | .p64 => { |
| 473 | 492 | const buf = try self.allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| ... | ... | @@ -479,7 +498,7 @@ pub const ElfFile = struct { |
| 479 | 498 | bswapAllFields(elf.Elf64_Phdr, phdr); |
| 480 | 499 | } |
| 481 | 500 | } |
| 482 | | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| 501 | try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| 483 | 502 | }, |
| 484 | 503 | } |
| 485 | 504 | self.phdr_table_dirty = false; |
| ... | ... | @@ -498,7 +517,7 @@ pub const ElfFile = struct { |
| 498 | 517 | shstrtab_sect.sh_size = needed_size; |
| 499 | 518 | //std.debug.warn("shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size }); |
| 500 | 519 | |
| 501 | | try self.file.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset); |
| 520 | try self.file.?.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset); |
| 502 | 521 | if (!self.shdr_table_dirty) { |
| 503 | 522 | // Then it won't get written with the others and we need to do it. |
| 504 | 523 | try self.writeSectHeader(self.shstrtab_index.?); |
| ... | ... | @@ -534,7 +553,7 @@ pub const ElfFile = struct { |
| 534 | 553 | bswapAllFields(elf.Elf32_Shdr, shdr); |
| 535 | 554 | } |
| 536 | 555 | } |
| 537 | | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 556 | try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 538 | 557 | }, |
| 539 | 558 | .p64 => { |
| 540 | 559 | const buf = try self.allocator.alloc(elf.Elf64_Shdr, self.sections.items.len); |
| ... | ... | @@ -547,7 +566,7 @@ pub const ElfFile = struct { |
| 547 | 566 | bswapAllFields(elf.Elf64_Shdr, shdr); |
| 548 | 567 | } |
| 549 | 568 | } |
| 550 | | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 569 | try self.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 551 | 570 | }, |
| 552 | 571 | } |
| 553 | 572 | self.shdr_table_dirty = false; |
| ... | ... | @@ -687,7 +706,7 @@ pub const ElfFile = struct { |
| 687 | 706 | |
| 688 | 707 | assert(index == e_ehsize); |
| 689 | 708 | |
| 690 | | try self.file.pwriteAll(hdr_buf[0..index], 0); |
| 709 | try self.file.?.pwriteAll(hdr_buf[0..index], 0); |
| 691 | 710 | } |
| 692 | 711 | |
| 693 | 712 | const AllocatedBlock = struct { |
| ... | ... | @@ -718,7 +737,7 @@ pub const ElfFile = struct { |
| 718 | 737 | // Must move the entire text section. |
| 719 | 738 | const new_offset = self.findFreeSpace(needed_size, 0x1000); |
| 720 | 739 | const text_size = (last_start + last_size) - phdr.p_vaddr; |
| 721 | | const amt = try self.file.copyRangeAll(shdr.sh_offset, self.file, new_offset, text_size); |
| 740 | const amt = try self.file.?.copyRangeAll(shdr.sh_offset, self.file.?, new_offset, text_size); |
| 722 | 741 | if (amt != text_size) return error.InputOutput; |
| 723 | 742 | shdr.sh_offset = new_offset; |
| 724 | 743 | } |
| ... | ... | @@ -876,7 +895,7 @@ pub const ElfFile = struct { |
| 876 | 895 | } |
| 877 | 896 | }; |
| 878 | 897 | |
| 879 | | try self.file.pwriteAll(code, file_offset); |
| 898 | try self.file.?.pwriteAll(code, file_offset); |
| 880 | 899 | |
| 881 | 900 | // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. |
| 882 | 901 | const decl_exports = module.decl_exports.getValue(decl) orelse &[0]*Module.Export{}; |
| ... | ... | @@ -962,14 +981,14 @@ pub const ElfFile = struct { |
| 962 | 981 | if (foreign_endian) { |
| 963 | 982 | bswapAllFields(elf.Elf32_Phdr, &phdr[0]); |
| 964 | 983 | } |
| 965 | | return self.file.pwriteAll(mem.sliceAsBytes(&phdr), offset); |
| 984 | return self.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); |
| 966 | 985 | }, |
| 967 | 986 | 64 => { |
| 968 | 987 | var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]}; |
| 969 | 988 | if (foreign_endian) { |
| 970 | 989 | bswapAllFields(elf.Elf64_Phdr, &phdr[0]); |
| 971 | 990 | } |
| 972 | | return self.file.pwriteAll(mem.sliceAsBytes(&phdr), offset); |
| 991 | return self.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); |
| 973 | 992 | }, |
| 974 | 993 | else => return error.UnsupportedArchitecture, |
| 975 | 994 | } |
| ... | ... | @@ -985,14 +1004,14 @@ pub const ElfFile = struct { |
| 985 | 1004 | if (foreign_endian) { |
| 986 | 1005 | bswapAllFields(elf.Elf32_Shdr, &shdr[0]); |
| 987 | 1006 | } |
| 988 | | return self.file.pwriteAll(mem.sliceAsBytes(&shdr), offset); |
| 1007 | return self.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); |
| 989 | 1008 | }, |
| 990 | 1009 | 64 => { |
| 991 | 1010 | var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]}; |
| 992 | 1011 | if (foreign_endian) { |
| 993 | 1012 | bswapAllFields(elf.Elf64_Shdr, &shdr[0]); |
| 994 | 1013 | } |
| 995 | | return self.file.pwriteAll(mem.sliceAsBytes(&shdr), offset); |
| 1014 | return self.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); |
| 996 | 1015 | }, |
| 997 | 1016 | else => return error.UnsupportedArchitecture, |
| 998 | 1017 | } |
| ... | ... | @@ -1012,7 +1031,7 @@ pub const ElfFile = struct { |
| 1012 | 1031 | if (needed_size > allocated_size) { |
| 1013 | 1032 | // Must move the entire got section. |
| 1014 | 1033 | const new_offset = self.findFreeSpace(needed_size, entry_size); |
| 1015 | | const amt = try self.file.copyRangeAll(shdr.sh_offset, self.file, new_offset, shdr.sh_size); |
| 1034 | const amt = try self.file.?.copyRangeAll(shdr.sh_offset, self.file.?, new_offset, shdr.sh_size); |
| 1016 | 1035 | if (amt != shdr.sh_size) return error.InputOutput; |
| 1017 | 1036 | shdr.sh_offset = new_offset; |
| 1018 | 1037 | } |
| ... | ... | @@ -1031,12 +1050,12 @@ pub const ElfFile = struct { |
| 1031 | 1050 | .p32 => { |
| 1032 | 1051 | var buf: [4]u8 = undefined; |
| 1033 | 1052 | mem.writeInt(u32, &buf, @intCast(u32, self.offset_table.items[index]), endian); |
| 1034 | | try self.file.pwriteAll(&buf, off); |
| 1053 | try self.file.?.pwriteAll(&buf, off); |
| 1035 | 1054 | }, |
| 1036 | 1055 | .p64 => { |
| 1037 | 1056 | var buf: [8]u8 = undefined; |
| 1038 | 1057 | mem.writeInt(u64, &buf, self.offset_table.items[index], endian); |
| 1039 | | try self.file.pwriteAll(&buf, off); |
| 1058 | try self.file.?.pwriteAll(&buf, off); |
| 1040 | 1059 | }, |
| 1041 | 1060 | } |
| 1042 | 1061 | } |
| ... | ... | @@ -1059,7 +1078,7 @@ pub const ElfFile = struct { |
| 1059 | 1078 | // Move all the symbols to a new file location. |
| 1060 | 1079 | const new_offset = self.findFreeSpace(needed_size, sym_align); |
| 1061 | 1080 | const existing_size = @as(u64, syms_sect.sh_info) * sym_size; |
| 1062 | | const amt = try self.file.copyRangeAll(syms_sect.sh_offset, self.file, new_offset, existing_size); |
| 1081 | const amt = try self.file.?.copyRangeAll(syms_sect.sh_offset, self.file.?, new_offset, existing_size); |
| 1063 | 1082 | if (amt != existing_size) return error.InputOutput; |
| 1064 | 1083 | syms_sect.sh_offset = new_offset; |
| 1065 | 1084 | } |
| ... | ... | @@ -1084,7 +1103,7 @@ pub const ElfFile = struct { |
| 1084 | 1103 | bswapAllFields(elf.Elf32_Sym, &sym[0]); |
| 1085 | 1104 | } |
| 1086 | 1105 | const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index; |
| 1087 | | try self.file.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); |
| 1106 | try self.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); |
| 1088 | 1107 | }, |
| 1089 | 1108 | .p64 => { |
| 1090 | 1109 | var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]}; |
| ... | ... | @@ -1092,7 +1111,7 @@ pub const ElfFile = struct { |
| 1092 | 1111 | bswapAllFields(elf.Elf64_Sym, &sym[0]); |
| 1093 | 1112 | } |
| 1094 | 1113 | const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index; |
| 1095 | | try self.file.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); |
| 1114 | try self.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); |
| 1096 | 1115 | }, |
| 1097 | 1116 | } |
| 1098 | 1117 | } |
| ... | ... | @@ -1124,7 +1143,7 @@ pub const ElfFile = struct { |
| 1124 | 1143 | bswapAllFields(elf.Elf32_Sym, sym); |
| 1125 | 1144 | } |
| 1126 | 1145 | } |
| 1127 | | try self.file.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); |
| 1146 | try self.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); |
| 1128 | 1147 | }, |
| 1129 | 1148 | .p64 => { |
| 1130 | 1149 | const buf = try self.allocator.alloc(elf.Elf64_Sym, self.global_symbols.items.len); |
| ... | ... | @@ -1143,7 +1162,7 @@ pub const ElfFile = struct { |
| 1143 | 1162 | bswapAllFields(elf.Elf64_Sym, sym); |
| 1144 | 1163 | } |
| 1145 | 1164 | } |
| 1146 | | try self.file.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); |
| 1165 | try self.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); |
| 1147 | 1166 | }, |
| 1148 | 1167 | } |
| 1149 | 1168 | } |