| ... | ... | @@ -715,7 +715,13 @@ fn initHeaders( |
| 715 | 715 | break :phndx phnum; |
| 716 | 716 | } else undefined; |
| 717 | 717 | |
| 718 | | const expected_nodes_len = 5 + phnum * 2 + @as(usize, 2) * @intFromBool(have_dynamic_section); |
| 718 | const expected_nodes_len = expected_nodes_len: { |
| 719 | const expected_nodes_len = 5 + phnum * 2 + @as(usize, 2) * @intFromBool(have_dynamic_section); |
| 720 | if (@"type" != .REL) break :expected_nodes_len expected_nodes_len; |
| 721 | phnum = 0; |
| 722 | break :expected_nodes_len expected_nodes_len - |
| 723 | @intFromBool(comp.config.any_non_single_threaded); |
| 724 | }; |
| 719 | 725 | try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len); |
| 720 | 726 | try elf.phdrs.resize(gpa, phnum); |
| 721 | 727 | elf.nodes.appendAssumeCapacity(.file); |
| ... | ... | @@ -767,37 +773,37 @@ fn initHeaders( |
| 767 | 773 | |
| 768 | 774 | assert(elf.ni.rodata == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 769 | 775 | .alignment = elf.mf.flags.block_size, |
| 770 | | .moved = true, |
| 776 | .moved = @"type" != .REL, |
| 771 | 777 | .bubbles_moved = false, |
| 772 | 778 | })); |
| 773 | 779 | elf.nodes.appendAssumeCapacity(.{ .segment = rodata_phndx }); |
| 774 | | elf.phdrs.items[rodata_phndx] = elf.ni.rodata; |
| 780 | if (@"type" != .REL) elf.phdrs.items[rodata_phndx] = elf.ni.rodata; |
| 775 | 781 | |
| 776 | 782 | assert(elf.ni.phdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{ |
| 777 | 783 | .size = elf.ehdrField(.phentsize) * elf.ehdrField(.phnum), |
| 778 | 784 | .alignment = addr_align, |
| 779 | | .moved = true, |
| 780 | | .resized = true, |
| 785 | .moved = @"type" != .REL, |
| 786 | .resized = @"type" != .REL, |
| 781 | 787 | .bubbles_moved = false, |
| 782 | 788 | })); |
| 783 | 789 | elf.nodes.appendAssumeCapacity(.{ .segment = phdr_phndx }); |
| 784 | | elf.phdrs.items[phdr_phndx] = elf.ni.phdr; |
| 790 | if (@"type" != .REL) elf.phdrs.items[phdr_phndx] = elf.ni.phdr; |
| 785 | 791 | |
| 786 | 792 | assert(elf.ni.text == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 787 | 793 | .alignment = elf.mf.flags.block_size, |
| 788 | | .moved = true, |
| 794 | .moved = @"type" != .REL, |
| 789 | 795 | .bubbles_moved = false, |
| 790 | 796 | })); |
| 791 | 797 | elf.nodes.appendAssumeCapacity(.{ .segment = text_phndx }); |
| 792 | | elf.phdrs.items[text_phndx] = elf.ni.text; |
| 798 | if (@"type" != .REL) elf.phdrs.items[text_phndx] = elf.ni.text; |
| 793 | 799 | |
| 794 | 800 | assert(elf.ni.data == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 795 | 801 | .alignment = elf.mf.flags.block_size, |
| 796 | | .moved = true, |
| 802 | .moved = @"type" != .REL, |
| 797 | 803 | .bubbles_moved = false, |
| 798 | 804 | })); |
| 799 | 805 | elf.nodes.appendAssumeCapacity(.{ .segment = data_phndx }); |
| 800 | | elf.phdrs.items[data_phndx] = elf.ni.data; |
| 806 | if (@"type" != .REL) elf.phdrs.items[data_phndx] = elf.ni.data; |
| 801 | 807 | |
| 802 | 808 | var ph_vaddr: u32 = switch (elf.ehdrField(.type)) { |
| 803 | 809 | else => 0, |
| ... | ... | @@ -816,108 +822,110 @@ fn initHeaders( |
| 816 | 822 | const ElfN = ct_class.ElfN(); |
| 817 | 823 | const target_endian = elf.targetEndian(); |
| 818 | 824 | |
| 819 | | const phdr: []ElfN.Phdr = @ptrCast(@alignCast(elf.ni.phdr.slice(&elf.mf))); |
| 820 | | const ph_phdr = &phdr[phdr_phndx]; |
| 821 | | ph_phdr.* = .{ |
| 822 | | .type = std.elf.PT_PHDR, |
| 823 | | .offset = 0, |
| 824 | | .vaddr = 0, |
| 825 | | .paddr = 0, |
| 826 | | .filesz = 0, |
| 827 | | .memsz = 0, |
| 828 | | .flags = .{ .R = true }, |
| 829 | | .@"align" = @intCast(elf.ni.phdr.alignment(&elf.mf).toByteUnits()), |
| 830 | | }; |
| 831 | | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_phdr); |
| 832 | | |
| 833 | | if (maybe_interp) |_| { |
| 834 | | const ph_interp = &phdr[interp_phndx]; |
| 835 | | ph_interp.* = .{ |
| 836 | | .type = std.elf.PT_INTERP, |
| 825 | if (@"type" != .REL) { |
| 826 | const phdr: []ElfN.Phdr = @ptrCast(@alignCast(elf.ni.phdr.slice(&elf.mf))); |
| 827 | const ph_phdr = &phdr[phdr_phndx]; |
| 828 | ph_phdr.* = .{ |
| 829 | .type = std.elf.PT_PHDR, |
| 837 | 830 | .offset = 0, |
| 838 | 831 | .vaddr = 0, |
| 839 | 832 | .paddr = 0, |
| 840 | 833 | .filesz = 0, |
| 841 | 834 | .memsz = 0, |
| 842 | 835 | .flags = .{ .R = true }, |
| 843 | | .@"align" = 1, |
| 836 | .@"align" = @intCast(elf.ni.phdr.alignment(&elf.mf).toByteUnits()), |
| 844 | 837 | }; |
| 845 | | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_interp); |
| 846 | | } |
| 847 | | |
| 848 | | _, const rodata_size = elf.ni.rodata.location(&elf.mf).resolve(&elf.mf); |
| 849 | | const ph_rodata = &phdr[rodata_phndx]; |
| 850 | | ph_rodata.* = .{ |
| 851 | | .type = std.elf.PT_NULL, |
| 852 | | .offset = 0, |
| 853 | | .vaddr = ph_vaddr, |
| 854 | | .paddr = ph_vaddr, |
| 855 | | .filesz = @intCast(rodata_size), |
| 856 | | .memsz = @intCast(rodata_size), |
| 857 | | .flags = .{ .R = true }, |
| 858 | | .@"align" = @intCast(elf.ni.rodata.alignment(&elf.mf).toByteUnits()), |
| 859 | | }; |
| 860 | | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_rodata); |
| 861 | | ph_vaddr += @intCast(rodata_size); |
| 862 | | |
| 863 | | _, const text_size = elf.ni.text.location(&elf.mf).resolve(&elf.mf); |
| 864 | | const ph_text = &phdr[text_phndx]; |
| 865 | | ph_text.* = .{ |
| 866 | | .type = std.elf.PT_NULL, |
| 867 | | .offset = 0, |
| 868 | | .vaddr = ph_vaddr, |
| 869 | | .paddr = ph_vaddr, |
| 870 | | .filesz = @intCast(text_size), |
| 871 | | .memsz = @intCast(text_size), |
| 872 | | .flags = .{ .R = true, .X = true }, |
| 873 | | .@"align" = @intCast(elf.ni.text.alignment(&elf.mf).toByteUnits()), |
| 874 | | }; |
| 875 | | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_text); |
| 876 | | ph_vaddr += @intCast(text_size); |
| 838 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_phdr); |
| 839 | |
| 840 | if (maybe_interp) |_| { |
| 841 | const ph_interp = &phdr[interp_phndx]; |
| 842 | ph_interp.* = .{ |
| 843 | .type = std.elf.PT_INTERP, |
| 844 | .offset = 0, |
| 845 | .vaddr = 0, |
| 846 | .paddr = 0, |
| 847 | .filesz = 0, |
| 848 | .memsz = 0, |
| 849 | .flags = .{ .R = true }, |
| 850 | .@"align" = 1, |
| 851 | }; |
| 852 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_interp); |
| 853 | } |
| 877 | 854 | |
| 878 | | _, const data_size = elf.ni.data.location(&elf.mf).resolve(&elf.mf); |
| 879 | | const ph_data = &phdr[data_phndx]; |
| 880 | | ph_data.* = .{ |
| 881 | | .type = std.elf.PT_NULL, |
| 882 | | .offset = 0, |
| 883 | | .vaddr = ph_vaddr, |
| 884 | | .paddr = ph_vaddr, |
| 885 | | .filesz = @intCast(data_size), |
| 886 | | .memsz = @intCast(data_size), |
| 887 | | .flags = .{ .R = true, .W = true }, |
| 888 | | .@"align" = @intCast(elf.ni.data.alignment(&elf.mf).toByteUnits()), |
| 889 | | }; |
| 890 | | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_data); |
| 891 | | ph_vaddr += @intCast(data_size); |
| 855 | _, const rodata_size = elf.ni.rodata.location(&elf.mf).resolve(&elf.mf); |
| 856 | const ph_rodata = &phdr[rodata_phndx]; |
| 857 | ph_rodata.* = .{ |
| 858 | .type = std.elf.PT_NULL, |
| 859 | .offset = 0, |
| 860 | .vaddr = ph_vaddr, |
| 861 | .paddr = ph_vaddr, |
| 862 | .filesz = @intCast(rodata_size), |
| 863 | .memsz = @intCast(rodata_size), |
| 864 | .flags = .{ .R = true }, |
| 865 | .@"align" = @intCast(elf.ni.rodata.alignment(&elf.mf).toByteUnits()), |
| 866 | }; |
| 867 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_rodata); |
| 868 | ph_vaddr += @intCast(rodata_size); |
| 892 | 869 | |
| 893 | | if (have_dynamic_section) { |
| 894 | | const ph_dynamic = &phdr[dynamic_phndx]; |
| 895 | | ph_dynamic.* = .{ |
| 896 | | .type = std.elf.PT_DYNAMIC, |
| 870 | _, const text_size = elf.ni.text.location(&elf.mf).resolve(&elf.mf); |
| 871 | const ph_text = &phdr[text_phndx]; |
| 872 | ph_text.* = .{ |
| 873 | .type = std.elf.PT_NULL, |
| 897 | 874 | .offset = 0, |
| 898 | | .vaddr = 0, |
| 899 | | .paddr = 0, |
| 900 | | .filesz = 0, |
| 901 | | .memsz = 0, |
| 902 | | .flags = .{ .R = true, .W = true }, |
| 903 | | .@"align" = @intCast(addr_align.toByteUnits()), |
| 875 | .vaddr = ph_vaddr, |
| 876 | .paddr = ph_vaddr, |
| 877 | .filesz = @intCast(text_size), |
| 878 | .memsz = @intCast(text_size), |
| 879 | .flags = .{ .R = true, .X = true }, |
| 880 | .@"align" = @intCast(elf.ni.text.alignment(&elf.mf).toByteUnits()), |
| 904 | 881 | }; |
| 905 | | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_dynamic); |
| 906 | | } |
| 882 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_text); |
| 883 | ph_vaddr += @intCast(text_size); |
| 907 | 884 | |
| 908 | | if (comp.config.any_non_single_threaded) { |
| 909 | | const ph_tls = &phdr[tls_phndx]; |
| 910 | | ph_tls.* = .{ |
| 911 | | .type = std.elf.PT_TLS, |
| 885 | _, const data_size = elf.ni.data.location(&elf.mf).resolve(&elf.mf); |
| 886 | const ph_data = &phdr[data_phndx]; |
| 887 | ph_data.* = .{ |
| 888 | .type = std.elf.PT_NULL, |
| 912 | 889 | .offset = 0, |
| 913 | | .vaddr = 0, |
| 914 | | .paddr = 0, |
| 915 | | .filesz = 0, |
| 916 | | .memsz = 0, |
| 917 | | .flags = .{ .R = true }, |
| 918 | | .@"align" = @intCast(elf.mf.flags.block_size.toByteUnits()), |
| 890 | .vaddr = ph_vaddr, |
| 891 | .paddr = ph_vaddr, |
| 892 | .filesz = @intCast(data_size), |
| 893 | .memsz = @intCast(data_size), |
| 894 | .flags = .{ .R = true, .W = true }, |
| 895 | .@"align" = @intCast(elf.ni.data.alignment(&elf.mf).toByteUnits()), |
| 919 | 896 | }; |
| 920 | | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_tls); |
| 897 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_data); |
| 898 | ph_vaddr += @intCast(data_size); |
| 899 | |
| 900 | if (have_dynamic_section) { |
| 901 | const ph_dynamic = &phdr[dynamic_phndx]; |
| 902 | ph_dynamic.* = .{ |
| 903 | .type = std.elf.PT_DYNAMIC, |
| 904 | .offset = 0, |
| 905 | .vaddr = 0, |
| 906 | .paddr = 0, |
| 907 | .filesz = 0, |
| 908 | .memsz = 0, |
| 909 | .flags = .{ .R = true, .W = true }, |
| 910 | .@"align" = @intCast(addr_align.toByteUnits()), |
| 911 | }; |
| 912 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_dynamic); |
| 913 | } |
| 914 | |
| 915 | if (comp.config.any_non_single_threaded) { |
| 916 | const ph_tls = &phdr[tls_phndx]; |
| 917 | ph_tls.* = .{ |
| 918 | .type = std.elf.PT_TLS, |
| 919 | .offset = 0, |
| 920 | .vaddr = 0, |
| 921 | .paddr = 0, |
| 922 | .filesz = 0, |
| 923 | .memsz = 0, |
| 924 | .flags = .{ .R = true }, |
| 925 | .@"align" = @intCast(elf.mf.flags.block_size.toByteUnits()), |
| 926 | }; |
| 927 | if (target_endian != native_endian) std.mem.byteSwapAllFields(ElfN.Phdr, ph_tls); |
| 928 | } |
| 921 | 929 | } |
| 922 | 930 | |
| 923 | 931 | const sh_null: *ElfN.Shdr = @ptrCast(@alignCast(elf.ni.shdr.slice(&elf.mf))); |
| ... | ... | @@ -982,17 +990,17 @@ fn initHeaders( |
| 982 | 990 | try elf.linkSections(.symtab, .strtab); |
| 983 | 991 | elf.si.strtab.node(elf).slice(&elf.mf)[0] = 0; |
| 984 | 992 | |
| 985 | | assert(elf.si.rodata == try elf.addSection(elf.ni.rodata, .{ |
| 993 | assert(elf.si.rodata == try elf.addSection(if (@"type" != .REL) elf.ni.rodata else elf.ni.file, .{ |
| 986 | 994 | .name = ".rodata", |
| 987 | 995 | .flags = .{ .ALLOC = true }, |
| 988 | 996 | .addralign = elf.mf.flags.block_size, |
| 989 | 997 | })); |
| 990 | | assert(elf.si.text == try elf.addSection(elf.ni.text, .{ |
| 998 | assert(elf.si.text == try elf.addSection(if (@"type" != .REL) elf.ni.text else elf.ni.file, .{ |
| 991 | 999 | .name = ".text", |
| 992 | 1000 | .flags = .{ .ALLOC = true, .EXECINSTR = true }, |
| 993 | 1001 | .addralign = elf.mf.flags.block_size, |
| 994 | 1002 | })); |
| 995 | | assert(elf.si.data == try elf.addSection(elf.ni.data, .{ |
| 1003 | assert(elf.si.data == try elf.addSection(if (@"type" != .REL) elf.ni.data else elf.ni.file, .{ |
| 996 | 1004 | .name = ".data", |
| 997 | 1005 | .flags = .{ .WRITE = true, .ALLOC = true }, |
| 998 | 1006 | .addralign = elf.mf.flags.block_size, |
| ... | ... | @@ -1064,15 +1072,17 @@ fn initHeaders( |
| 1064 | 1072 | try elf.linkSections(elf.si.dynsym, elf.si.dynstr); |
| 1065 | 1073 | } |
| 1066 | 1074 | if (comp.config.any_non_single_threaded) { |
| 1067 | | elf.ni.tls = try elf.mf.addLastChildNode(gpa, elf.ni.rodata, .{ |
| 1068 | | .alignment = elf.mf.flags.block_size, |
| 1069 | | .moved = true, |
| 1070 | | .bubbles_moved = false, |
| 1071 | | }); |
| 1072 | | elf.nodes.appendAssumeCapacity(.{ .segment = tls_phndx }); |
| 1073 | | elf.phdrs.items[tls_phndx] = elf.ni.tls; |
| 1075 | if (@"type" != .REL) { |
| 1076 | elf.ni.tls = try elf.mf.addLastChildNode(gpa, elf.ni.rodata, .{ |
| 1077 | .alignment = elf.mf.flags.block_size, |
| 1078 | .moved = true, |
| 1079 | .bubbles_moved = false, |
| 1080 | }); |
| 1081 | elf.nodes.appendAssumeCapacity(.{ .segment = tls_phndx }); |
| 1082 | elf.phdrs.items[tls_phndx] = elf.ni.tls; |
| 1083 | } |
| 1074 | 1084 | |
| 1075 | | elf.si.tdata = try elf.addSection(elf.ni.tls, .{ |
| 1085 | elf.si.tdata = try elf.addSection(if (@"type" != .REL) elf.ni.tls else elf.ni.file, .{ |
| 1076 | 1086 | .name = ".tdata", |
| 1077 | 1087 | .flags = .{ .WRITE = true, .ALLOC = true, .TLS = true }, |
| 1078 | 1088 | .addralign = elf.mf.flags.block_size, |