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