| ... | ... | @@ -3645,77 +3645,22 @@ fn initHeaders( |
| 3645 | 3645 | |
| 3646 | 3646 | const entsize: struct { ph: u32, sh: u32 } = switch (class) { |
| 3647 | 3647 | .NONE, _ => unreachable, |
| 3648 | | inline else => |ct_class| entsize: { |
| 3649 | | const ElfN = ct_class.ElfN(); |
| 3650 | | elf.ni.ehdr = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3651 | | .size = @sizeOf(ElfN.Ehdr), |
| 3652 | | .alignment = addr_align, |
| 3653 | | .fixed = true, |
| 3654 | | }); |
| 3655 | | elf.nodes.appendAssumeCapacity(.ehdr); |
| 3656 | | |
| 3657 | | const ehdr: *ElfN.Ehdr = @ptrCast(@alignCast(elf.ni.ehdr.slice(&elf.mf))); |
| 3658 | | ehdr.ident = .{ |
| 3659 | | .class = class, |
| 3660 | | .data = data, |
| 3661 | | .version = 1, |
| 3662 | | .osabi = osabi, |
| 3663 | | .abiversion = 0, |
| 3664 | | }; |
| 3665 | | ehdr.type = @"type".toElf(); |
| 3666 | | ehdr.machine = machine.toElf(); |
| 3667 | | ehdr.version = 1; |
| 3668 | | ehdr.entry = 0; |
| 3669 | | ehdr.phoff = 0; |
| 3670 | | ehdr.shoff = 0; |
| 3671 | | ehdr.flags = switch (machine) { |
| 3672 | | .LOONGARCH => .{ .loongarch = .{ |
| 3673 | | .base_abi_modifier = mod: { |
| 3674 | | const cpu = comp.getTarget().cpu; |
| 3675 | | if (cpu.has(.loongarch, .d)) break :mod .d; |
| 3676 | | if (cpu.has(.loongarch, .f)) break :mod .f; |
| 3677 | | break :mod .s; |
| 3678 | | }, |
| 3679 | | .abi_extension = .base, |
| 3680 | | .abi_version = 1, |
| 3681 | | } }, |
| 3682 | | .SPARCV9 => .{ .sparc = .{ |
| 3683 | | .mm = .rmo, |
| 3684 | | .ext = .{ |
| 3685 | | .@"32plus" = false, |
| 3686 | | .sun_us1 = false, |
| 3687 | | .hal_r1 = false, |
| 3688 | | .sun_us3 = false, |
| 3689 | | .le_data = false, |
| 3690 | | }, |
| 3691 | | } }, |
| 3692 | | .X86_64 => .{ .int = 0 }, |
| 3693 | | .AARCH64, .PPC64, .RISCV => @panic(@tagName(machine)), |
| 3694 | | }; |
| 3695 | | ehdr.ehsize = @sizeOf(ElfN.Ehdr); |
| 3696 | | ehdr.phentsize = @sizeOf(ElfN.Phdr); |
| 3697 | | ehdr.phnum = @min(phnum, std.elf.PN_XNUM); |
| 3698 | | ehdr.shentsize = @sizeOf(ElfN.Shdr); |
| 3699 | | ehdr.shnum = 1; // Only the null shdr initially---will be incremented by `addSection` |
| 3700 | | ehdr.shstrndx = std.elf.SHN_UNDEF; |
| 3701 | | if (elf.targetEndian() != native_endian) std.mem.byteSwapAllFields(ElfN.Ehdr, ehdr); |
| 3702 | | |
| 3703 | | break :entsize .{ .ph = @sizeOf(ElfN.Phdr), .sh = @sizeOf(ElfN.Shdr) }; |
| 3648 | inline else => |ct_class| .{ |
| 3649 | .ph = @sizeOf(ct_class.ElfN().Phdr), |
| 3650 | .sh = @sizeOf(ct_class.ElfN().Shdr), |
| 3704 | 3651 | }, |
| 3705 | 3652 | }; |
| 3706 | 3653 | |
| 3707 | | elf.ni.shdr = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3708 | | .size = 1 * entsize.sh, // as above, only the null shdr initially |
| 3709 | | .alignment = addr_align.max(node_block_align), |
| 3710 | | .moved = true, |
| 3711 | | .resized = true, |
| 3712 | | }); |
| 3713 | | elf.nodes.appendAssumeCapacity(.shdr); |
| 3714 | | |
| 3654 | // We want to create the segment nodes *before* the ehdr, because the ehdr should go inside of |
| 3655 | // the rodata segment. Although to my knowledge neither ELF nor any ELF-based OS strictly |
| 3656 | // requires this, it is highly conventional and therefore sometimes relied upon. |
| 3715 | 3657 | if (@"type" != .REL) { |
| 3716 | | elf.ni.rodata = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3658 | elf.ni.rodata = try elf.mf.addOnlyChildNode(gpa, elf.ni.elf, .{ |
| 3717 | 3659 | // Must be at least `addr_align` for `elf.ni.phdr` to be placed inside this node |
| 3718 | 3660 | .alignment = node_block_align.max(addr_align), |
| 3661 | // This node will contain the ehdr, which must be at the start of the ELF file, so this |
| 3662 | // node must itself be fixed. |
| 3663 | .fixed = true, |
| 3719 | 3664 | .moved = true, |
| 3720 | 3665 | .bubbles_moved = false, |
| 3721 | 3666 | }); |
| ... | ... | @@ -3781,6 +3726,79 @@ fn initHeaders( |
| 3781 | 3726 | |
| 3782 | 3727 | elf.phdrs.items[phndx.gnu_stack] = .none; |
| 3783 | 3728 | } |
| 3729 | |
| 3730 | switch (class) { |
| 3731 | .NONE, _ => unreachable, |
| 3732 | inline else => |ct_class| { |
| 3733 | const ElfN = ct_class.ElfN(); |
| 3734 | // In loadable modules, the ehdr goes in the rodata segment, as described above. |
| 3735 | const parent_ni = switch (@"type") { |
| 3736 | .REL => elf.ni.elf, |
| 3737 | .DYN, .EXEC => elf.ni.rodata, |
| 3738 | }; |
| 3739 | elf.ni.ehdr = try elf.mf.addFirstChildNode(gpa, parent_ni, .{ |
| 3740 | .size = @sizeOf(ElfN.Ehdr), |
| 3741 | .alignment = addr_align, |
| 3742 | .fixed = true, |
| 3743 | }); |
| 3744 | elf.nodes.appendAssumeCapacity(.ehdr); |
| 3745 | |
| 3746 | const ehdr: *ElfN.Ehdr = @ptrCast(@alignCast(elf.ni.ehdr.slice(&elf.mf))); |
| 3747 | ehdr.ident = .{ |
| 3748 | .class = class, |
| 3749 | .data = data, |
| 3750 | .version = 1, |
| 3751 | .osabi = osabi, |
| 3752 | .abiversion = 0, |
| 3753 | }; |
| 3754 | ehdr.type = @"type".toElf(); |
| 3755 | ehdr.machine = machine.toElf(); |
| 3756 | ehdr.version = 1; |
| 3757 | ehdr.entry = 0; |
| 3758 | ehdr.phoff = 0; |
| 3759 | ehdr.shoff = 0; |
| 3760 | ehdr.flags = switch (machine) { |
| 3761 | .LOONGARCH => .{ .loongarch = .{ |
| 3762 | .base_abi_modifier = mod: { |
| 3763 | const cpu = comp.getTarget().cpu; |
| 3764 | if (cpu.has(.loongarch, .d)) break :mod .d; |
| 3765 | if (cpu.has(.loongarch, .f)) break :mod .f; |
| 3766 | break :mod .s; |
| 3767 | }, |
| 3768 | .abi_extension = .base, |
| 3769 | .abi_version = 1, |
| 3770 | } }, |
| 3771 | .SPARCV9 => .{ .sparc = .{ |
| 3772 | .mm = .rmo, |
| 3773 | .ext = .{ |
| 3774 | .@"32plus" = false, |
| 3775 | .sun_us1 = false, |
| 3776 | .hal_r1 = false, |
| 3777 | .sun_us3 = false, |
| 3778 | .le_data = false, |
| 3779 | }, |
| 3780 | } }, |
| 3781 | .X86_64 => .{ .int = 0 }, |
| 3782 | .AARCH64, .PPC64, .RISCV => @panic(@tagName(machine)), |
| 3783 | }; |
| 3784 | ehdr.ehsize = @sizeOf(ElfN.Ehdr); |
| 3785 | ehdr.phentsize = @sizeOf(ElfN.Phdr); |
| 3786 | ehdr.phnum = @min(phnum, std.elf.PN_XNUM); |
| 3787 | ehdr.shentsize = @sizeOf(ElfN.Shdr); |
| 3788 | ehdr.shnum = 1; // Only the null shdr initially---will be incremented by `addSection` |
| 3789 | ehdr.shstrndx = std.elf.SHN_UNDEF; |
| 3790 | if (elf.targetEndian() != native_endian) std.mem.byteSwapAllFields(ElfN.Ehdr, ehdr); |
| 3791 | }, |
| 3792 | } |
| 3793 | |
| 3794 | elf.ni.shdr = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3795 | .size = 1 * entsize.sh, // as above, only the null shdr initially |
| 3796 | .alignment = addr_align.max(node_block_align), |
| 3797 | .moved = true, |
| 3798 | .resized = true, |
| 3799 | }); |
| 3800 | elf.nodes.appendAssumeCapacity(.shdr); |
| 3801 | |
| 3784 | 3802 | switch (class) { |
| 3785 | 3803 | .NONE, _ => unreachable, |
| 3786 | 3804 | inline else => |ct_class| { |
| ... | ... | @@ -3818,7 +3836,9 @@ fn initHeaders( |
| 3818 | 3836 | // actually `PT_NULL` for now, because we initialize `filesz` and `memsz` to zero. |
| 3819 | 3837 | // Any which end up non-empty will have their size populated (and their type set to |
| 3820 | 3838 | // `PT_LOAD`) by the segment virtual address space allocation logic. |
| 3821 | | const phdr: []ElfN.Phdr = @ptrCast(@alignCast(elf.ni.phdr.slice(&elf.mf))); |
| 3839 | const phdr: []ElfN.Phdr = @ptrCast(@alignCast( |
| 3840 | elf.ni.phdr.slice(&elf.mf)[0 .. phnum * @sizeOf(ElfN.Phdr)], |
| 3841 | )); |
| 3822 | 3842 | |
| 3823 | 3843 | const ph_phdr = &phdr[phndx.phdr]; |
| 3824 | 3844 | ph_phdr.* = .{ |
| ... | ... | @@ -4900,14 +4920,11 @@ const PhdrSlice = union(std.elf.CLASS) { |
| 4900 | 4920 | }; |
| 4901 | 4921 | fn phdrSlice(elf: *Elf) PhdrSlice { |
| 4902 | 4922 | assert(elf.ehdrType() != .REL); |
| 4903 | | const slice = elf.ni.phdr.slice(&elf.mf); |
| 4904 | 4923 | return switch (elf.identClass()) { |
| 4905 | 4924 | .NONE, _ => unreachable, |
| 4906 | | inline else => |class| @unionInit( |
| 4907 | | PhdrSlice, |
| 4908 | | @tagName(class), |
| 4909 | | @ptrCast(@alignCast(slice)), |
| 4910 | | ), |
| 4925 | inline else => |class| @unionInit(PhdrSlice, @tagName(class), @ptrCast(@alignCast( |
| 4926 | elf.ni.phdr.slice(&elf.mf)[0 .. elf.phdrs.items.len * @sizeOf(class.ElfN().Phdr)], |
| 4927 | ))), |
| 4911 | 4928 | }; |
| 4912 | 4929 | } |
| 4913 | 4930 | |