authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-09 18:12:37+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-09 18:12:37+01:00
log2d3914213378f560fafb9a952cb1ad03a11aa634
tree0366b7da81517db151e2b20490cd787e0479ec45
parent4d1e5ef730630badf92a613cdc57a42d2321df12
parentec3e638b97c638a6d292902b18a6a685854d60b4
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10843 from ziglang/fix-1914

stage2: handle decl ref to void types

5 files changed, 66 insertions(+), 30 deletions(-)

lib/std/special/c.zig+20
...@@ -6,7 +6,9 @@...@@ -6,7 +6,9 @@
66
7const std = @import("std");7const std = @import("std");
8const builtin = @import("builtin");8const builtin = @import("builtin");
9const math = std.math;
9const native_os = builtin.os.tag;10const native_os = builtin.os.tag;
11const long_double_is_f128 = builtin.target.longDoubleIsF128();
1012
11comptime {13comptime {
12 // When the self-hosted compiler is further along, all the logic from c_stage1.zig will14 // When the self-hosted compiler is further along, all the logic from c_stage1.zig will
...@@ -15,6 +17,9 @@ comptime {...@@ -15,6 +17,9 @@ comptime {
15 if (builtin.zig_backend != .stage1) {17 if (builtin.zig_backend != .stage1) {
16 @export(memset, .{ .name = "memset", .linkage = .Strong });18 @export(memset, .{ .name = "memset", .linkage = .Strong });
17 @export(memcpy, .{ .name = "memcpy", .linkage = .Strong });19 @export(memcpy, .{ .name = "memcpy", .linkage = .Strong });
20 @export(trunc, .{ .name = "trunc", .linkage = .Strong });
21 @export(truncf, .{ .name = "truncf", .linkage = .Strong });
22 @export(truncl, .{ .name = "truncl", .linkage = .Strong });
18 } else {23 } else {
19 _ = @import("c_stage1.zig");24 _ = @import("c_stage1.zig");
20 }25 }
...@@ -74,3 +79,18 @@ fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, len: usize) callconv(...@@ -74,3 +79,18 @@ fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, len: usize) callconv(
7479
75 return dest;80 return dest;
76}81}
82
83fn trunc(a: f64) f64 {
84 return math.trunc(a);
85}
86
87fn truncf(a: f32) f32 {
88 return math.trunc(a);
89}
90
91fn truncl(a: c_longdouble) c_longdouble {
92 if (!long_double_is_f128) {
93 @panic("TODO implement this");
94 }
95 return math.trunc(a);
96}
src/Sema.zig+1
...@@ -13647,6 +13647,7 @@ fn structFieldPtr(...@@ -13647,6 +13647,7 @@ fn structFieldPtr(
13647 assert(unresolved_struct_ty.zigTypeTag() == .Struct);13647 assert(unresolved_struct_ty.zigTypeTag() == .Struct);
1364813648
13649 const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty);13649 const struct_ty = try sema.resolveTypeFields(block, src, unresolved_struct_ty);
13650 try sema.resolveStructLayout(block, src, struct_ty);
13650 const struct_obj = struct_ty.castTag(.@"struct").?.data;13651 const struct_obj = struct_ty.castTag(.@"struct").?.data;
1365113652
13652 const field_index_big = struct_obj.fields.getIndex(field_name) orelse13653 const field_index_big = struct_obj.fields.getIndex(field_name) orelse
src/codegen.zig+6-11
...@@ -487,19 +487,14 @@ fn lowerDeclRef(...@@ -487,19 +487,14 @@ fn lowerDeclRef(
487 return Result{ .appended = {} };487 return Result{ .appended = {} };
488 }488 }
489489
490 const target = bin_file.options.target;
491 const ptr_width = target.cpu.arch.ptrBitWidth();
490 const is_fn_body = decl.ty.zigTypeTag() == .Fn;492 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
491 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {493 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {
492 return Result{494 try code.writer().writeByteNTimes(0xaa, @divExact(ptr_width, 8));
493 .fail = try ErrorMsg.create(495 return Result{ .appended = {} };
494 bin_file.allocator,
495 src_loc,
496 "TODO handle void types when lowering decl ref",
497 .{},
498 ),
499 };
500 }496 }
501497
502 if (decl.analysis != .complete) return error.AnalysisFail;
503 decl.markAlive();498 decl.markAlive();
504 const vaddr = vaddr: {499 const vaddr = vaddr: {
505 if (bin_file.cast(link.File.MachO)) |macho_file| {500 if (bin_file.cast(link.File.MachO)) |macho_file| {
...@@ -510,8 +505,8 @@ fn lowerDeclRef(...@@ -510,8 +505,8 @@ fn lowerDeclRef(
510 break :vaddr bin_file.getDeclVAddr(decl);505 break :vaddr bin_file.getDeclVAddr(decl);
511 };506 };
512507
513 const endian = bin_file.options.target.cpu.arch.endian();508 const endian = target.cpu.arch.endian();
514 switch (bin_file.options.target.cpu.arch.ptrBitWidth()) {509 switch (ptr_width) {
515 16 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(u16, vaddr), endian),510 16 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(u16, vaddr), endian),
516 32 => mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, vaddr), endian),511 32 => mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, vaddr), endian),
517 64 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),512 64 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
src/link/Elf.zig+39-15
...@@ -2,6 +2,7 @@ const Elf = @This();...@@ -2,6 +2,7 @@ const Elf = @This();
22
3const std = @import("std");3const std = @import("std");
4const builtin = @import("builtin");4const builtin = @import("builtin");
5const math = std.math;
5const mem = std.mem;6const mem = std.mem;
6const assert = std.debug.assert;7const assert = std.debug.assert;
7const Allocator = std.mem.Allocator;8const Allocator = std.mem.Allocator;
...@@ -64,6 +65,7 @@ phdr_load_rw_index: ?u16 = null,...@@ -64,6 +65,7 @@ phdr_load_rw_index: ?u16 = null,
64phdr_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},65phdr_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},
6566
66entry_addr: ?u64 = null,67entry_addr: ?u64 = null,
68page_size: u16,
6769
68debug_strtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){},70debug_strtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){},
69shstrtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){},71shstrtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){},
...@@ -334,6 +336,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {...@@ -334,6 +336,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
334 };336 };
335 const self = try gpa.create(Elf);337 const self = try gpa.create(Elf);
336 errdefer gpa.destroy(self);338 errdefer gpa.destroy(self);
339 const page_size: u16 = 0x1000; // TODO ppc64le requires 64KB
337340
338 self.* = .{341 self.* = .{
339 .base = .{342 .base = .{
...@@ -343,6 +346,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {...@@ -343,6 +346,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
343 .file = null,346 .file = null,
344 },347 },
345 .ptr_width = ptr_width,348 .ptr_width = ptr_width,
349 .page_size = page_size,
346 };350 };
347 const use_llvm = build_options.have_llvm and options.use_llvm;351 const use_llvm = build_options.have_llvm and options.use_llvm;
348 const use_stage1 = build_options.is_stage1 and options.use_stage1;352 const use_stage1 = build_options.is_stage1 and options.use_stage1;
...@@ -523,10 +527,11 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -523,10 +527,11 @@ pub fn populateMissingMetadata(self: *Elf) !void {
523 .p64 => false,527 .p64 => false,
524 };528 };
525 const ptr_size: u8 = self.ptrWidthBytes();529 const ptr_size: u8 = self.ptrWidthBytes();
530
526 if (self.phdr_load_re_index == null) {531 if (self.phdr_load_re_index == null) {
527 self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len);532 self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len);
528 const file_size = self.base.options.program_code_size_hint;533 const file_size = self.base.options.program_code_size_hint;
529 const p_align = 0x1000;534 const p_align = self.page_size;
530 const off = self.findFreeSpace(file_size, p_align);535 const off = self.findFreeSpace(file_size, p_align);
531 log.debug("found PT_LOAD RE free space 0x{x} to 0x{x}", .{ off, off + file_size });536 log.debug("found PT_LOAD RE free space 0x{x} to 0x{x}", .{ off, off + file_size });
532 const entry_addr: u64 = self.entry_addr orelse if (self.base.options.target.cpu.arch == .spu_2) @as(u64, 0) else default_entry_addr;537 const entry_addr: u64 = self.entry_addr orelse if (self.base.options.target.cpu.arch == .spu_2) @as(u64, 0) else default_entry_addr;
...@@ -544,12 +549,13 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -544,12 +549,13 @@ pub fn populateMissingMetadata(self: *Elf) !void {
544 self.entry_addr = null;549 self.entry_addr = null;
545 self.phdr_table_dirty = true;550 self.phdr_table_dirty = true;
546 }551 }
552
547 if (self.phdr_got_index == null) {553 if (self.phdr_got_index == null) {
548 self.phdr_got_index = @intCast(u16, self.program_headers.items.len);554 self.phdr_got_index = @intCast(u16, self.program_headers.items.len);
549 const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint;555 const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
550 // We really only need ptr alignment but since we are using PROGBITS, linux requires556 // We really only need ptr alignment but since we are using PROGBITS, linux requires
551 // page align.557 // page align.
552 const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size);558 const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size);
553 const off = self.findFreeSpace(file_size, p_align);559 const off = self.findFreeSpace(file_size, p_align);
554 log.debug("found PT_LOAD GOT free space 0x{x} to 0x{x}", .{ off, off + file_size });560 log.debug("found PT_LOAD GOT free space 0x{x} to 0x{x}", .{ off, off + file_size });
555 // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at.561 // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at.
...@@ -568,16 +574,17 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -568,16 +574,17 @@ pub fn populateMissingMetadata(self: *Elf) !void {
568 });574 });
569 self.phdr_table_dirty = true;575 self.phdr_table_dirty = true;
570 }576 }
577
571 if (self.phdr_load_ro_index == null) {578 if (self.phdr_load_ro_index == null) {
572 self.phdr_load_ro_index = @intCast(u16, self.program_headers.items.len);579 self.phdr_load_ro_index = @intCast(u16, self.program_headers.items.len);
573 // TODO Find a hint about how much data need to be in rodata ?580 // TODO Find a hint about how much data need to be in rodata ?
574 const file_size = 1024;581 const file_size = 1024;
575 // Same reason as for GOT582 // Same reason as for GOT
576 const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size);583 const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size);
577 const off = self.findFreeSpace(file_size, p_align);584 const off = self.findFreeSpace(file_size, p_align);
578 log.debug("found PT_LOAD RO free space 0x{x} to 0x{x}\n", .{ off, off + file_size });585 log.debug("found PT_LOAD RO free space 0x{x} to 0x{x}", .{ off, off + file_size });
579 // TODO Same as for GOT586 // TODO Same as for GOT
580 const rodata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x5000000 else 0xa000;587 const rodata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0xc000000 else 0xa000;
581 try self.program_headers.append(self.base.allocator, .{588 try self.program_headers.append(self.base.allocator, .{
582 .p_type = elf.PT_LOAD,589 .p_type = elf.PT_LOAD,
583 .p_offset = off,590 .p_offset = off,
...@@ -591,16 +598,17 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -591,16 +598,17 @@ pub fn populateMissingMetadata(self: *Elf) !void {
591 try self.atom_free_lists.putNoClobber(self.base.allocator, self.phdr_load_ro_index.?, .{});598 try self.atom_free_lists.putNoClobber(self.base.allocator, self.phdr_load_ro_index.?, .{});
592 self.phdr_table_dirty = true;599 self.phdr_table_dirty = true;
593 }600 }
601
594 if (self.phdr_load_rw_index == null) {602 if (self.phdr_load_rw_index == null) {
595 self.phdr_load_rw_index = @intCast(u16, self.program_headers.items.len);603 self.phdr_load_rw_index = @intCast(u16, self.program_headers.items.len);
596 // TODO Find a hint about how much data need to be in data ?604 // TODO Find a hint about how much data need to be in data ?
597 const file_size = 1024;605 const file_size = 1024;
598 // Same reason as for GOT606 // Same reason as for GOT
599 const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size);607 const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size);
600 const off = self.findFreeSpace(file_size, p_align);608 const off = self.findFreeSpace(file_size, p_align);
601 log.debug("found PT_LOAD RW free space 0x{x} to 0x{x}\n", .{ off, off + file_size });609 log.debug("found PT_LOAD RW free space 0x{x} to 0x{x}", .{ off, off + file_size });
602 // TODO Same as for GOT610 // TODO Same as for GOT
603 const rwdata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x6000000 else 0xc000;611 const rwdata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x10000000 else 0xc000;
604 try self.program_headers.append(self.base.allocator, .{612 try self.program_headers.append(self.base.allocator, .{
605 .p_type = elf.PT_LOAD,613 .p_type = elf.PT_LOAD,
606 .p_offset = off,614 .p_offset = off,
...@@ -614,6 +622,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -614,6 +622,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
614 try self.atom_free_lists.putNoClobber(self.base.allocator, self.phdr_load_rw_index.?, .{});622 try self.atom_free_lists.putNoClobber(self.base.allocator, self.phdr_load_rw_index.?, .{});
615 self.phdr_table_dirty = true;623 self.phdr_table_dirty = true;
616 }624 }
625
617 if (self.shstrtab_index == null) {626 if (self.shstrtab_index == null) {
618 self.shstrtab_index = @intCast(u16, self.sections.items.len);627 self.shstrtab_index = @intCast(u16, self.sections.items.len);
619 assert(self.shstrtab.items.len == 0);628 assert(self.shstrtab.items.len == 0);
...@@ -635,6 +644,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -635,6 +644,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
635 self.shstrtab_dirty = true;644 self.shstrtab_dirty = true;
636 self.shdr_table_dirty = true;645 self.shdr_table_dirty = true;
637 }646 }
647
638 if (self.text_section_index == null) {648 if (self.text_section_index == null) {
639 self.text_section_index = @intCast(u16, self.sections.items.len);649 self.text_section_index = @intCast(u16, self.sections.items.len);
640 const phdr = &self.program_headers.items[self.phdr_load_re_index.?];650 const phdr = &self.program_headers.items[self.phdr_load_re_index.?];
...@@ -648,7 +658,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -648,7 +658,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
648 .sh_size = phdr.p_filesz,658 .sh_size = phdr.p_filesz,
649 .sh_link = 0,659 .sh_link = 0,
650 .sh_info = 0,660 .sh_info = 0,
651 .sh_addralign = phdr.p_align,661 .sh_addralign = 1,
652 .sh_entsize = 0,662 .sh_entsize = 0,
653 });663 });
654 try self.phdr_shdr_table.putNoClobber(664 try self.phdr_shdr_table.putNoClobber(
...@@ -658,6 +668,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -658,6 +668,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
658 );668 );
659 self.shdr_table_dirty = true;669 self.shdr_table_dirty = true;
660 }670 }
671
661 if (self.got_section_index == null) {672 if (self.got_section_index == null) {
662 self.got_section_index = @intCast(u16, self.sections.items.len);673 self.got_section_index = @intCast(u16, self.sections.items.len);
663 const phdr = &self.program_headers.items[self.phdr_got_index.?];674 const phdr = &self.program_headers.items[self.phdr_got_index.?];
...@@ -671,7 +682,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -671,7 +682,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
671 .sh_size = phdr.p_filesz,682 .sh_size = phdr.p_filesz,
672 .sh_link = 0,683 .sh_link = 0,
673 .sh_info = 0,684 .sh_info = 0,
674 .sh_addralign = phdr.p_align,685 .sh_addralign = @as(u16, ptr_size),
675 .sh_entsize = 0,686 .sh_entsize = 0,
676 });687 });
677 try self.phdr_shdr_table.putNoClobber(688 try self.phdr_shdr_table.putNoClobber(
...@@ -681,6 +692,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -681,6 +692,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
681 );692 );
682 self.shdr_table_dirty = true;693 self.shdr_table_dirty = true;
683 }694 }
695
684 if (self.rodata_section_index == null) {696 if (self.rodata_section_index == null) {
685 self.rodata_section_index = @intCast(u16, self.sections.items.len);697 self.rodata_section_index = @intCast(u16, self.sections.items.len);
686 const phdr = &self.program_headers.items[self.phdr_load_ro_index.?];698 const phdr = &self.program_headers.items[self.phdr_load_ro_index.?];
...@@ -694,7 +706,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -694,7 +706,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
694 .sh_size = phdr.p_filesz,706 .sh_size = phdr.p_filesz,
695 .sh_link = 0,707 .sh_link = 0,
696 .sh_info = 0,708 .sh_info = 0,
697 .sh_addralign = phdr.p_align,709 .sh_addralign = 1,
698 .sh_entsize = 0,710 .sh_entsize = 0,
699 });711 });
700 try self.phdr_shdr_table.putNoClobber(712 try self.phdr_shdr_table.putNoClobber(
...@@ -704,6 +716,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -704,6 +716,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
704 );716 );
705 self.shdr_table_dirty = true;717 self.shdr_table_dirty = true;
706 }718 }
719
707 if (self.data_section_index == null) {720 if (self.data_section_index == null) {
708 self.data_section_index = @intCast(u16, self.sections.items.len);721 self.data_section_index = @intCast(u16, self.sections.items.len);
709 const phdr = &self.program_headers.items[self.phdr_load_rw_index.?];722 const phdr = &self.program_headers.items[self.phdr_load_rw_index.?];
...@@ -717,7 +730,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -717,7 +730,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
717 .sh_size = phdr.p_filesz,730 .sh_size = phdr.p_filesz,
718 .sh_link = 0,731 .sh_link = 0,
719 .sh_info = 0,732 .sh_info = 0,
720 .sh_addralign = phdr.p_align,733 .sh_addralign = @as(u16, ptr_size),
721 .sh_entsize = 0,734 .sh_entsize = 0,
722 });735 });
723 try self.phdr_shdr_table.putNoClobber(736 try self.phdr_shdr_table.putNoClobber(
...@@ -727,6 +740,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -727,6 +740,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
727 );740 );
728 self.shdr_table_dirty = true;741 self.shdr_table_dirty = true;
729 }742 }
743
730 if (self.symtab_section_index == null) {744 if (self.symtab_section_index == null) {
731 self.symtab_section_index = @intCast(u16, self.sections.items.len);745 self.symtab_section_index = @intCast(u16, self.sections.items.len);
732 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);746 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);
...@@ -751,6 +765,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -751,6 +765,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
751 self.shdr_table_dirty = true;765 self.shdr_table_dirty = true;
752 try self.writeSymbol(0);766 try self.writeSymbol(0);
753 }767 }
768
754 if (self.debug_str_section_index == null) {769 if (self.debug_str_section_index == null) {
755 self.debug_str_section_index = @intCast(u16, self.sections.items.len);770 self.debug_str_section_index = @intCast(u16, self.sections.items.len);
756 assert(self.debug_strtab.items.len == 0);771 assert(self.debug_strtab.items.len == 0);
...@@ -769,6 +784,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -769,6 +784,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
769 self.debug_strtab_dirty = true;784 self.debug_strtab_dirty = true;
770 self.shdr_table_dirty = true;785 self.shdr_table_dirty = true;
771 }786 }
787
772 if (self.debug_info_section_index == null) {788 if (self.debug_info_section_index == null) {
773 self.debug_info_section_index = @intCast(u16, self.sections.items.len);789 self.debug_info_section_index = @intCast(u16, self.sections.items.len);
774790
...@@ -794,6 +810,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -794,6 +810,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
794 self.shdr_table_dirty = true;810 self.shdr_table_dirty = true;
795 self.debug_info_header_dirty = true;811 self.debug_info_header_dirty = true;
796 }812 }
813
797 if (self.debug_abbrev_section_index == null) {814 if (self.debug_abbrev_section_index == null) {
798 self.debug_abbrev_section_index = @intCast(u16, self.sections.items.len);815 self.debug_abbrev_section_index = @intCast(u16, self.sections.items.len);
799816
...@@ -819,6 +836,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -819,6 +836,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
819 self.shdr_table_dirty = true;836 self.shdr_table_dirty = true;
820 self.debug_abbrev_section_dirty = true;837 self.debug_abbrev_section_dirty = true;
821 }838 }
839
822 if (self.debug_aranges_section_index == null) {840 if (self.debug_aranges_section_index == null) {
823 self.debug_aranges_section_index = @intCast(u16, self.sections.items.len);841 self.debug_aranges_section_index = @intCast(u16, self.sections.items.len);
824842
...@@ -844,6 +862,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -844,6 +862,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
844 self.shdr_table_dirty = true;862 self.shdr_table_dirty = true;
845 self.debug_aranges_section_dirty = true;863 self.debug_aranges_section_dirty = true;
846 }864 }
865
847 if (self.debug_line_section_index == null) {866 if (self.debug_line_section_index == null) {
848 self.debug_line_section_index = @intCast(u16, self.sections.items.len);867 self.debug_line_section_index = @intCast(u16, self.sections.items.len);
849868
...@@ -869,6 +888,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -869,6 +888,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
869 self.shdr_table_dirty = true;888 self.shdr_table_dirty = true;
870 self.debug_line_header_dirty = true;889 self.debug_line_header_dirty = true;
871 }890 }
891
872 const shsize: u64 = switch (self.ptr_width) {892 const shsize: u64 = switch (self.ptr_width) {
873 .p32 => @sizeOf(elf.Elf32_Shdr),893 .p32 => @sizeOf(elf.Elf32_Shdr),
874 .p64 => @sizeOf(elf.Elf64_Shdr),894 .p64 => @sizeOf(elf.Elf64_Shdr),
...@@ -881,6 +901,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -881,6 +901,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
881 self.shdr_table_offset = self.findFreeSpace(self.sections.items.len * shsize, shalign);901 self.shdr_table_offset = self.findFreeSpace(self.sections.items.len * shsize, shalign);
882 self.shdr_table_dirty = true;902 self.shdr_table_dirty = true;
883 }903 }
904
884 const phsize: u64 = switch (self.ptr_width) {905 const phsize: u64 = switch (self.ptr_width) {
885 .p32 => @sizeOf(elf.Elf32_Phdr),906 .p32 => @sizeOf(elf.Elf32_Phdr),
886 .p64 => @sizeOf(elf.Elf64_Phdr),907 .p64 => @sizeOf(elf.Elf64_Phdr),
...@@ -893,6 +914,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -893,6 +914,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
893 self.phdr_table_offset = self.findFreeSpace(self.program_headers.items.len * phsize, phalign);914 self.phdr_table_offset = self.findFreeSpace(self.program_headers.items.len * phsize, phalign);
894 self.phdr_table_dirty = true;915 self.phdr_table_dirty = true;
895 }916 }
917
896 {918 {
897 // Iterate over symbols, populating free_list and last_text_block.919 // Iterate over symbols, populating free_list and last_text_block.
898 if (self.local_symbols.items.len != 1) {920 if (self.local_symbols.items.len != 1) {
...@@ -2378,12 +2400,13 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al...@@ -2378,12 +2400,13 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
2378 const text_capacity = self.allocatedSize(shdr.sh_offset);2400 const text_capacity = self.allocatedSize(shdr.sh_offset);
2379 const needed_size = (vaddr + new_block_size) - phdr.p_vaddr;2401 const needed_size = (vaddr + new_block_size) - phdr.p_vaddr;
2380 if (needed_size > text_capacity) {2402 if (needed_size > text_capacity) {
2381 // Must move the entire text section.2403 // Must move the entire section.
2382 const new_offset = self.findFreeSpace(needed_size, 0x1000);2404 const new_offset = self.findFreeSpace(needed_size, self.page_size);
2383 const text_size = if (self.atoms.get(phdr_index)) |last| blk: {2405 const text_size = if (self.atoms.get(phdr_index)) |last| blk: {
2384 const sym = self.local_symbols.items[last.local_sym_index];2406 const sym = self.local_symbols.items[last.local_sym_index];
2385 break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr;2407 break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr;
2386 } else 0;2408 } else 0;
2409 log.debug("new PT_LOAD file offset 0x{x} to 0x{x}", .{ new_offset, new_offset + text_size });
2387 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, text_size);2410 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, text_size);
2388 if (amt != text_size) return error.InputOutput;2411 if (amt != text_size) return error.InputOutput;
2389 shdr.sh_offset = new_offset;2412 shdr.sh_offset = new_offset;
...@@ -2407,6 +2430,7 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al...@@ -2407,6 +2430,7 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
2407 self.phdr_table_dirty = true; // TODO look into making only the one program header dirty2430 self.phdr_table_dirty = true; // TODO look into making only the one program header dirty
2408 self.shdr_table_dirty = true; // TODO look into making only the one section dirty2431 self.shdr_table_dirty = true; // TODO look into making only the one section dirty
2409 }2432 }
2433 shdr.sh_addralign = math.max(shdr.sh_addralign, alignment);
24102434
2411 // This function can also reallocate a text block.2435 // This function can also reallocate a text block.
2412 // In this case we need to "unplug" it from its previous location before2436 // In this case we need to "unplug" it from its previous location before
...@@ -3478,7 +3502,7 @@ fn writeOffsetTableEntry(self: *Elf, index: usize) !void {...@@ -3478,7 +3502,7 @@ fn writeOffsetTableEntry(self: *Elf, index: usize) !void {
3478 const needed_size = self.offset_table.items.len * entry_size;3502 const needed_size = self.offset_table.items.len * entry_size;
3479 if (needed_size > allocated_size) {3503 if (needed_size > allocated_size) {
3480 // Must move the entire got section.3504 // Must move the entire got section.
3481 const new_offset = self.findFreeSpace(needed_size, entry_size);3505 const new_offset = self.findFreeSpace(needed_size, self.page_size);
3482 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, shdr.sh_size);3506 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, shdr.sh_size);
3483 if (amt != shdr.sh_size) return error.InputOutput;3507 if (amt != shdr.sh_size) return error.InputOutput;
3484 shdr.sh_offset = new_offset;3508 shdr.sh_offset = new_offset;
test/behavior/bugs/1914.zig-4
...@@ -13,8 +13,6 @@ const a = A{ .b_list_pointer = &b_list };...@@ -13,8 +13,6 @@ const a = A{ .b_list_pointer = &b_list };
1313
14test "segfault bug" {14test "segfault bug" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
17 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
18 const assert = std.debug.assert;16 const assert = std.debug.assert;
19 const obj = B{ .a_pointer = &a };17 const obj = B{ .a_pointer = &a };
20 assert(obj.a_pointer == &a); // this makes zig crash18 assert(obj.a_pointer == &a); // this makes zig crash
...@@ -31,8 +29,6 @@ pub const B2 = struct {...@@ -31,8 +29,6 @@ pub const B2 = struct {
31var b_value = B2{ .pointer_array = &[_]*A2{} };29var b_value = B2{ .pointer_array = &[_]*A2{} };
3230
33test "basic stuff" {31test "basic stuff" {
34 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
35 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
36 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO32 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
37 std.debug.assert(&b_value == &b_value);33 std.debug.assert(&b_value == &b_value);
38}34}