| author | |
| committer | |
| log | f63cd9194c81459d113a57dc7e8ce357f8029728 |
| tree | 361f0305050a9049b06da4899a03eaf1c70988f6 |
| parent | 3071ba4272c2a89e892c6a48090496ec0ba46d8c |
| parent | 877d6df8f75a7fcfacea572d38f74ac66d045f32 |
| signature |
fix linker writing undefined memory to output file11 files changed, 66 insertions(+), 61 deletions(-)
lib/std/Io/Writer.zig+5| ... | ... | @@ -865,6 +865,11 @@ pub inline fn writeSliceEndian( |
| 865 | 865 | slice: []const Elem, |
| 866 | 866 | endian: std.builtin.Endian, |
| 867 | 867 | ) Error!void { |
| 868 | switch (@typeInfo(Elem)) { | |
| 869 | .@"struct" => |info| comptime assert(info.layout != .auto), | |
| 870 | .int, .@"enum" => {}, | |
| 871 | else => @compileError("ill-defined memory layout"), | |
| 872 | } | |
| 868 | 873 | if (native_endian == endian) { |
| 869 | 874 | return writeAll(w, @ptrCast(slice)); |
| 870 | 875 | } else { |
src/link/Coff.zig+36-37| ... | ... | @@ -1,4 +1,38 @@ |
| 1 | 1 | //! The main driver of the self-hosted COFF linker. |
| 2 | const Coff = @This(); | |
| 3 | ||
| 4 | const std = @import("std"); | |
| 5 | const build_options = @import("build_options"); | |
| 6 | const builtin = @import("builtin"); | |
| 7 | const assert = std.debug.assert; | |
| 8 | const coff_util = std.coff; | |
| 9 | const fmt = std.fmt; | |
| 10 | const fs = std.fs; | |
| 11 | const log = std.log.scoped(.link); | |
| 12 | const math = std.math; | |
| 13 | const mem = std.mem; | |
| 14 | ||
| 15 | const Allocator = std.mem.Allocator; | |
| 16 | const Path = std.Build.Cache.Path; | |
| 17 | const Directory = std.Build.Cache.Directory; | |
| 18 | const Cache = std.Build.Cache; | |
| 19 | ||
| 20 | const aarch64_util = link.aarch64; | |
| 21 | const allocPrint = std.fmt.allocPrint; | |
| 22 | const codegen = @import("../codegen.zig"); | |
| 23 | const link = @import("../link.zig"); | |
| 24 | const target_util = @import("../target.zig"); | |
| 25 | const trace = @import("../tracy.zig").trace; | |
| 26 | ||
| 27 | const Compilation = @import("../Compilation.zig"); | |
| 28 | const Zcu = @import("../Zcu.zig"); | |
| 29 | const InternPool = @import("../InternPool.zig"); | |
| 30 | const TableSection = @import("table_section.zig").TableSection; | |
| 31 | const StringTable = @import("StringTable.zig"); | |
| 32 | const Type = @import("../Type.zig"); | |
| 33 | const Value = @import("../Value.zig"); | |
| 34 | const AnalUnit = InternPool.AnalUnit; | |
| 35 | const dev = @import("../dev.zig"); | |
| 2 | 36 | |
| 3 | 37 | base: link.File, |
| 4 | 38 | image_base: u64, |
| ... | ... | @@ -2168,12 +2202,12 @@ fn writeStrtab(coff: *Coff) !void { |
| 2168 | 2202 | |
| 2169 | 2203 | fn writeSectionHeaders(coff: *Coff) !void { |
| 2170 | 2204 | const offset = coff.getSectionHeadersOffset(); |
| 2171 | try coff.pwriteAll(mem.sliceAsBytes(coff.sections.items(.header)), offset); | |
| 2205 | try coff.pwriteAll(@ptrCast(coff.sections.items(.header)), offset); | |
| 2172 | 2206 | } |
| 2173 | 2207 | |
| 2174 | 2208 | fn writeDataDirectoriesHeaders(coff: *Coff) !void { |
| 2175 | 2209 | const offset = coff.getDataDirectoryHeadersOffset(); |
| 2176 | try coff.pwriteAll(mem.sliceAsBytes(&coff.data_directories), offset); | |
| 2210 | try coff.pwriteAll(@ptrCast(&coff.data_directories), offset); | |
| 2177 | 2211 | } |
| 2178 | 2212 | |
| 2179 | 2213 | fn writeHeader(coff: *Coff) !void { |
| ... | ... | @@ -3068,41 +3102,6 @@ fn pwriteAll(coff: *Coff, bytes: []const u8, offset: u64) error{LinkFailure}!voi |
| 3068 | 3102 | }; |
| 3069 | 3103 | } |
| 3070 | 3104 | |
| 3071 | const Coff = @This(); | |
| 3072 | ||
| 3073 | const std = @import("std"); | |
| 3074 | const build_options = @import("build_options"); | |
| 3075 | const builtin = @import("builtin"); | |
| 3076 | const assert = std.debug.assert; | |
| 3077 | const coff_util = std.coff; | |
| 3078 | const fmt = std.fmt; | |
| 3079 | const fs = std.fs; | |
| 3080 | const log = std.log.scoped(.link); | |
| 3081 | const math = std.math; | |
| 3082 | const mem = std.mem; | |
| 3083 | ||
| 3084 | const Allocator = std.mem.Allocator; | |
| 3085 | const Path = std.Build.Cache.Path; | |
| 3086 | const Directory = std.Build.Cache.Directory; | |
| 3087 | const Cache = std.Build.Cache; | |
| 3088 | ||
| 3089 | const aarch64_util = link.aarch64; | |
| 3090 | const allocPrint = std.fmt.allocPrint; | |
| 3091 | const codegen = @import("../codegen.zig"); | |
| 3092 | const link = @import("../link.zig"); | |
| 3093 | const target_util = @import("../target.zig"); | |
| 3094 | const trace = @import("../tracy.zig").trace; | |
| 3095 | ||
| 3096 | const Compilation = @import("../Compilation.zig"); | |
| 3097 | const Zcu = @import("../Zcu.zig"); | |
| 3098 | const InternPool = @import("../InternPool.zig"); | |
| 3099 | const TableSection = @import("table_section.zig").TableSection; | |
| 3100 | const StringTable = @import("StringTable.zig"); | |
| 3101 | const Type = @import("../Type.zig"); | |
| 3102 | const Value = @import("../Value.zig"); | |
| 3103 | const AnalUnit = InternPool.AnalUnit; | |
| 3104 | const dev = @import("../dev.zig"); | |
| 3105 | ||
| 3106 | 3105 | /// This is the start of a Portable Executable (PE) file. |
| 3107 | 3106 | /// It starts with a MS-DOS header followed by a MS-DOS stub program. |
| 3108 | 3107 | /// This data does not change so we include it as follows in all binaries. |
src/link/Elf.zig+9-9| ... | ... | @@ -1465,7 +1465,7 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 1465 | 1465 | mem.byteSwapAllFields(elf.Elf32_Shdr, shdr); |
| 1466 | 1466 | } |
| 1467 | 1467 | } |
| 1468 | try self.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); | |
| 1468 | try self.pwriteAll(@ptrCast(buf), self.shdr_table_offset.?); | |
| 1469 | 1469 | }, |
| 1470 | 1470 | .p64 => { |
| 1471 | 1471 | const buf = try gpa.alloc(elf.Elf64_Shdr, self.sections.items(.shdr).len); |
| ... | ... | @@ -1478,7 +1478,7 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 1478 | 1478 | mem.byteSwapAllFields(elf.Elf64_Shdr, shdr); |
| 1479 | 1479 | } |
| 1480 | 1480 | } |
| 1481 | try self.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); | |
| 1481 | try self.pwriteAll(@ptrCast(buf), self.shdr_table_offset.?); | |
| 1482 | 1482 | }, |
| 1483 | 1483 | } |
| 1484 | 1484 | } |
| ... | ... | @@ -1505,7 +1505,7 @@ fn writePhdrTable(self: *Elf) !void { |
| 1505 | 1505 | mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); |
| 1506 | 1506 | } |
| 1507 | 1507 | } |
| 1508 | try self.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); | |
| 1508 | try self.pwriteAll(@ptrCast(buf), phdr_table.p_offset); | |
| 1509 | 1509 | }, |
| 1510 | 1510 | .p64 => { |
| 1511 | 1511 | const buf = try gpa.alloc(elf.Elf64_Phdr, self.phdrs.items.len); |
| ... | ... | @@ -1517,7 +1517,7 @@ fn writePhdrTable(self: *Elf) !void { |
| 1517 | 1517 | mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); |
| 1518 | 1518 | } |
| 1519 | 1519 | } |
| 1520 | try self.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); | |
| 1520 | try self.pwriteAll(@ptrCast(buf), phdr_table.p_offset); | |
| 1521 | 1521 | }, |
| 1522 | 1522 | } |
| 1523 | 1523 | } |
| ... | ... | @@ -3157,7 +3157,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3157 | 3157 | |
| 3158 | 3158 | if (self.section_indexes.versym) |shndx| { |
| 3159 | 3159 | const shdr = slice.items(.shdr)[shndx]; |
| 3160 | try self.pwriteAll(mem.sliceAsBytes(self.versym.items), shdr.sh_offset); | |
| 3160 | try self.pwriteAll(@ptrCast(self.versym.items), shdr.sh_offset); | |
| 3161 | 3161 | } |
| 3162 | 3162 | |
| 3163 | 3163 | if (self.section_indexes.verneed) |shndx| { |
| ... | ... | @@ -3226,7 +3226,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3226 | 3226 | try self.got.addRela(self); |
| 3227 | 3227 | try self.copy_rel.addRela(self); |
| 3228 | 3228 | self.sortRelaDyn(); |
| 3229 | try self.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset); | |
| 3229 | try self.pwriteAll(@ptrCast(self.rela_dyn.items), shdr.sh_offset); | |
| 3230 | 3230 | } |
| 3231 | 3231 | |
| 3232 | 3232 | if (self.section_indexes.plt) |shndx| { |
| ... | ... | @@ -3256,7 +3256,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3256 | 3256 | if (self.section_indexes.rela_plt) |shndx| { |
| 3257 | 3257 | const shdr = slice.items(.shdr)[shndx]; |
| 3258 | 3258 | try self.plt.addRela(self); |
| 3259 | try self.pwriteAll(mem.sliceAsBytes(self.rela_plt.items), shdr.sh_offset); | |
| 3259 | try self.pwriteAll(@ptrCast(self.rela_plt.items), shdr.sh_offset); | |
| 3260 | 3260 | } |
| 3261 | 3261 | |
| 3262 | 3262 | try self.writeSymtab(); |
| ... | ... | @@ -3364,13 +3364,13 @@ pub fn writeSymtab(self: *Elf) !void { |
| 3364 | 3364 | }; |
| 3365 | 3365 | if (foreign_endian) mem.byteSwapAllFields(elf.Elf32_Sym, out); |
| 3366 | 3366 | } |
| 3367 | try self.pwriteAll(mem.sliceAsBytes(buf), symtab_shdr.sh_offset); | |
| 3367 | try self.pwriteAll(@ptrCast(buf), symtab_shdr.sh_offset); | |
| 3368 | 3368 | }, |
| 3369 | 3369 | .p64 => { |
| 3370 | 3370 | if (foreign_endian) { |
| 3371 | 3371 | for (self.symtab.items) |*sym| mem.byteSwapAllFields(elf.Elf64_Sym, sym); |
| 3372 | 3372 | } |
| 3373 | try self.pwriteAll(mem.sliceAsBytes(self.symtab.items), symtab_shdr.sh_offset); | |
| 3373 | try self.pwriteAll(@ptrCast(self.symtab.items), symtab_shdr.sh_offset); | |
| 3374 | 3374 | }, |
| 3375 | 3375 | } |
| 3376 | 3376 |
src/link/Elf/eh_frame.zig+2-2| ... | ... | @@ -482,7 +482,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { |
| 482 | 482 | ); |
| 483 | 483 | try writer.writeInt(u32, num_fdes, .little); |
| 484 | 484 | |
| 485 | const Entry = struct { | |
| 485 | const Entry = extern struct { | |
| 486 | 486 | init_addr: u32, |
| 487 | 487 | fde_addr: u32, |
| 488 | 488 | |
| ... | ... | @@ -520,7 +520,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | std.mem.sort(Entry, entries.items, {}, Entry.lessThan); |
| 523 | try writer.writeAll(std.mem.sliceAsBytes(entries.items)); | |
| 523 | try writer.writeSliceEndian(Entry, entries.items, .little); | |
| 524 | 524 | } |
| 525 | 525 | |
| 526 | 526 | const eh_frame_hdr_header_size: usize = 12; |
src/link/Elf/relocatable.zig+2-2| ... | ... | @@ -397,7 +397,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 397 | 397 | shdr.sh_offset + shdr.sh_size, |
| 398 | 398 | }); |
| 399 | 399 | |
| 400 | try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); | |
| 400 | try elf_file.base.file.?.pwriteAll(@ptrCast(relocs.items), shdr.sh_offset); | |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | if (elf_file.section_indexes.eh_frame) |shndx| { |
| ... | ... | @@ -435,7 +435,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 435 | 435 | shdr.sh_offset, |
| 436 | 436 | shdr.sh_offset + shdr.sh_size, |
| 437 | 437 | }); |
| 438 | try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); | |
| 438 | try elf_file.base.file.?.pwriteAll(@ptrCast(relocs.items), shdr.sh_offset); | |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | 441 | try writeGroups(elf_file); |
src/link/Elf/synthetic_sections.zig+5-5| ... | ... | @@ -1265,7 +1265,7 @@ pub const GnuHashSection = struct { |
| 1265 | 1265 | bloom[idx] |= @as(u64, 1) << @as(u6, @intCast((h >> bloom_shift) % 64)); |
| 1266 | 1266 | } |
| 1267 | 1267 | |
| 1268 | try writer.writeAll(mem.sliceAsBytes(bloom)); | |
| 1268 | try writer.writeSliceEndian(u64, bloom, .little); | |
| 1269 | 1269 | |
| 1270 | 1270 | // Fill in the hash bucket indices |
| 1271 | 1271 | const buckets = try gpa.alloc(u32, hash.num_buckets); |
| ... | ... | @@ -1278,7 +1278,7 @@ pub const GnuHashSection = struct { |
| 1278 | 1278 | } |
| 1279 | 1279 | } |
| 1280 | 1280 | |
| 1281 | try writer.writeAll(mem.sliceAsBytes(buckets)); | |
| 1281 | try writer.writeSliceEndian(u32, buckets, .little); | |
| 1282 | 1282 | |
| 1283 | 1283 | // Finally, write the hash table |
| 1284 | 1284 | const table = try gpa.alloc(u32, hash.num_exports); |
| ... | ... | @@ -1294,7 +1294,7 @@ pub const GnuHashSection = struct { |
| 1294 | 1294 | } |
| 1295 | 1295 | } |
| 1296 | 1296 | |
| 1297 | try writer.writeAll(mem.sliceAsBytes(table)); | |
| 1297 | try writer.writeSliceEndian(u32, table, .little); | |
| 1298 | 1298 | } |
| 1299 | 1299 | |
| 1300 | 1300 | pub fn hasher(name: [:0]const u8) u32 { |
| ... | ... | @@ -1442,8 +1442,8 @@ pub const VerneedSection = struct { |
| 1442 | 1442 | } |
| 1443 | 1443 | |
| 1444 | 1444 | pub fn write(vern: VerneedSection, writer: *std.Io.Writer) !void { |
| 1445 | try writer.writeAll(mem.sliceAsBytes(vern.verneed.items)); | |
| 1446 | try writer.writeAll(mem.sliceAsBytes(vern.vernaux.items)); | |
| 1445 | try writer.writeSliceEndian(elf.Elf64_Verneed, vern.verneed.items, .little); | |
| 1446 | try writer.writeSliceEndian(elf.Vernaux, vern.vernaux.items, .little); | |
| 1447 | 1447 | } |
| 1448 | 1448 | }; |
| 1449 | 1449 |
src/link/MachO.zig+1-1| ... | ... | @@ -2711,7 +2711,7 @@ pub fn writeSymtabToFile(self: *MachO) !void { |
| 2711 | 2711 | const tracy = trace(@src()); |
| 2712 | 2712 | defer tracy.end(); |
| 2713 | 2713 | const cmd = self.symtab_cmd; |
| 2714 | try self.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff); | |
| 2714 | try self.pwriteAll(@ptrCast(self.symtab.items), cmd.symoff); | |
| 2715 | 2715 | try self.pwriteAll(self.strtab.items, cmd.stroff); |
| 2716 | 2716 | } |
| 2717 | 2717 |
src/link/MachO/DebugSymbols.zig+1-1| ... | ... | @@ -403,7 +403,7 @@ pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 { |
| 403 | 403 | internal.writeSymtab(macho_file, self); |
| 404 | 404 | } |
| 405 | 405 | |
| 406 | try self.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff); | |
| 406 | try self.file.?.pwriteAll(@ptrCast(self.symtab.items), cmd.symoff); | |
| 407 | 407 | |
| 408 | 408 | return off + cmd.nsyms * @sizeOf(macho.nlist_64); |
| 409 | 409 | } |
src/link/MachO/UnwindInfo.zig+1-1| ... | ... | @@ -311,7 +311,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { |
| 311 | 311 | .indexCount = indexes_count, |
| 312 | 312 | }), .little); |
| 313 | 313 | |
| 314 | try writer.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count])); | |
| 314 | try writer.writeSliceEndian(Encoding, info.common_encodings[0..info.common_encodings_count], .little); | |
| 315 | 315 | |
| 316 | 316 | for (info.personalities[0..info.personalities_count]) |ref| { |
| 317 | 317 | const sym = ref.getSymbol(macho_file).?; |
src/link/MachO/relocatable.zig+2-2| ... | ... | @@ -676,11 +676,11 @@ fn writeSectionsToFile(macho_file: *MachO) !void { |
| 676 | 676 | const slice = macho_file.sections.slice(); |
| 677 | 677 | for (slice.items(.header), slice.items(.out), slice.items(.relocs)) |header, out, relocs| { |
| 678 | 678 | try macho_file.pwriteAll(out.items, header.offset); |
| 679 | try macho_file.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff); | |
| 679 | try macho_file.pwriteAll(@ptrCast(relocs.items), header.reloff); | |
| 680 | 680 | } |
| 681 | 681 | |
| 682 | 682 | try macho_file.writeDataInCode(); |
| 683 | try macho_file.pwriteAll(mem.sliceAsBytes(macho_file.symtab.items), macho_file.symtab_cmd.symoff); | |
| 683 | try macho_file.pwriteAll(@ptrCast(macho_file.symtab.items), macho_file.symtab_cmd.symoff); | |
| 684 | 684 | try macho_file.pwriteAll(macho_file.strtab.items, macho_file.symtab_cmd.stroff); |
| 685 | 685 | } |
| 686 | 686 |
src/link/SpirV.zig+2-1| ... | ... | @@ -285,7 +285,8 @@ pub fn flush( |
| 285 | 285 | else => |other| return diags.fail("error while linking: {s}", .{@errorName(other)}), |
| 286 | 286 | }; |
| 287 | 287 | |
| 288 | linker.base.file.?.writeAll(std.mem.sliceAsBytes(linked_module)) catch |err| | |
| 288 | // TODO endianness bug. use file writer and call writeSliceEndian instead | |
| 289 | linker.base.file.?.writeAll(@ptrCast(linked_module)) catch |err| | |
| 289 | 290 | return diags.fail("failed to write: {s}", .{@errorName(err)}); |
| 290 | 291 | } |
| 291 | 292 |