| ... | ... | @@ -462,7 +462,7 @@ pub const Reloc = extern struct { |
| 462 | 462 | .TPOFF32 => { |
| 463 | 463 | const phdr = @field(elf.phdrSlice(), @tagName(class)); |
| 464 | 464 | const ph = &phdr[elf.getNode(elf.ni.tls).segment]; |
| 465 | | assert(elf.targetLoad(&ph.type) == std.elf.PT_TLS); |
| 465 | assert(elf.targetLoad(&ph.type) == .TLS); |
| 466 | 466 | std.mem.writeInt( |
| 467 | 467 | i32, |
| 468 | 468 | loc_slice[0..4], |
| ... | ... | @@ -715,12 +715,15 @@ fn initHeaders( |
| 715 | 715 | break :phndx phnum; |
| 716 | 716 | } else undefined; |
| 717 | 717 | |
| 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); |
| 718 | const expected_nodes_len = expected_nodes_len: switch (@"type") { |
| 719 | .NONE => unreachable, |
| 720 | .REL => { |
| 721 | defer phnum = 0; |
| 722 | break :expected_nodes_len 5 + phnum; |
| 723 | }, |
| 724 | .EXEC, .DYN => break :expected_nodes_len 5 + phnum * 2 + |
| 725 | @as(usize, 2) * @intFromBool(have_dynamic_section), |
| 726 | .CORE, _ => unreachable, |
| 724 | 727 | }; |
| 725 | 728 | try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len); |
| 726 | 729 | try elf.phdrs.resize(gpa, phnum); |
| ... | ... | @@ -771,51 +774,53 @@ fn initHeaders( |
| 771 | 774 | })); |
| 772 | 775 | elf.nodes.appendAssumeCapacity(.shdr); |
| 773 | 776 | |
| 774 | | assert(elf.ni.rodata == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 775 | | .alignment = elf.mf.flags.block_size, |
| 776 | | .moved = @"type" != .REL, |
| 777 | | .bubbles_moved = false, |
| 778 | | })); |
| 779 | | elf.nodes.appendAssumeCapacity(.{ .segment = rodata_phndx }); |
| 780 | | if (@"type" != .REL) elf.phdrs.items[rodata_phndx] = elf.ni.rodata; |
| 777 | var ph_vaddr: u32 = if (@"type" != .REL) ph_vaddr: { |
| 778 | assert(elf.ni.rodata == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 779 | .alignment = elf.mf.flags.block_size, |
| 780 | .moved = true, |
| 781 | .bubbles_moved = false, |
| 782 | })); |
| 783 | elf.nodes.appendAssumeCapacity(.{ .segment = rodata_phndx }); |
| 784 | elf.phdrs.items[rodata_phndx] = elf.ni.rodata; |
| 781 | 785 | |
| 782 | | assert(elf.ni.phdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{ |
| 783 | | .size = elf.ehdrField(.phentsize) * elf.ehdrField(.phnum), |
| 784 | | .alignment = addr_align, |
| 785 | | .moved = @"type" != .REL, |
| 786 | | .resized = @"type" != .REL, |
| 787 | | .bubbles_moved = false, |
| 788 | | })); |
| 789 | | elf.nodes.appendAssumeCapacity(.{ .segment = phdr_phndx }); |
| 790 | | if (@"type" != .REL) elf.phdrs.items[phdr_phndx] = elf.ni.phdr; |
| 786 | assert(elf.ni.phdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{ |
| 787 | .size = elf.ehdrField(.phentsize) * elf.ehdrField(.phnum), |
| 788 | .alignment = addr_align, |
| 789 | .moved = true, |
| 790 | .resized = true, |
| 791 | .bubbles_moved = false, |
| 792 | })); |
| 793 | elf.nodes.appendAssumeCapacity(.{ .segment = phdr_phndx }); |
| 794 | elf.phdrs.items[phdr_phndx] = elf.ni.phdr; |
| 791 | 795 | |
| 792 | | assert(elf.ni.text == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 793 | | .alignment = elf.mf.flags.block_size, |
| 794 | | .moved = @"type" != .REL, |
| 795 | | .bubbles_moved = false, |
| 796 | | })); |
| 797 | | elf.nodes.appendAssumeCapacity(.{ .segment = text_phndx }); |
| 798 | | if (@"type" != .REL) elf.phdrs.items[text_phndx] = elf.ni.text; |
| 796 | assert(elf.ni.text == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 797 | .alignment = elf.mf.flags.block_size, |
| 798 | .moved = true, |
| 799 | .bubbles_moved = false, |
| 800 | })); |
| 801 | elf.nodes.appendAssumeCapacity(.{ .segment = text_phndx }); |
| 802 | elf.phdrs.items[text_phndx] = elf.ni.text; |
| 799 | 803 | |
| 800 | | assert(elf.ni.data == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 801 | | .alignment = elf.mf.flags.block_size, |
| 802 | | .moved = @"type" != .REL, |
| 803 | | .bubbles_moved = false, |
| 804 | | })); |
| 805 | | elf.nodes.appendAssumeCapacity(.{ .segment = data_phndx }); |
| 806 | | if (@"type" != .REL) elf.phdrs.items[data_phndx] = elf.ni.data; |
| 807 | | |
| 808 | | var ph_vaddr: u32 = switch (elf.ehdrField(.type)) { |
| 809 | | else => 0, |
| 810 | | .EXEC => switch (elf.ehdrField(.machine)) { |
| 811 | | .@"386" => 0x400000, |
| 812 | | .AARCH64, .X86_64 => 0x200000, |
| 813 | | .PPC, .PPC64 => 0x10000000, |
| 814 | | .S390, .S390_OLD => 0x1000000, |
| 815 | | .OLD_SPARCV9, .SPARCV9 => 0x100000, |
| 816 | | else => 0x10000, |
| 817 | | }, |
| 818 | | }; |
| 804 | assert(elf.ni.data == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ |
| 805 | .alignment = elf.mf.flags.block_size, |
| 806 | .moved = true, |
| 807 | .bubbles_moved = false, |
| 808 | })); |
| 809 | elf.nodes.appendAssumeCapacity(.{ .segment = data_phndx }); |
| 810 | elf.phdrs.items[data_phndx] = elf.ni.data; |
| 811 | |
| 812 | break :ph_vaddr switch (elf.ehdrField(.type)) { |
| 813 | else => 0, |
| 814 | .EXEC => switch (elf.ehdrField(.machine)) { |
| 815 | .@"386" => 0x400000, |
| 816 | .AARCH64, .X86_64 => 0x200000, |
| 817 | .PPC, .PPC64 => 0x10000000, |
| 818 | .S390, .S390_OLD => 0x1000000, |
| 819 | .OLD_SPARCV9, .SPARCV9 => 0x100000, |
| 820 | else => 0x10000, |
| 821 | }, |
| 822 | }; |
| 823 | } else undefined; |
| 819 | 824 | switch (class) { |
| 820 | 825 | .NONE, _ => unreachable, |
| 821 | 826 | inline else => |ct_class| { |
| ... | ... | @@ -826,7 +831,7 @@ fn initHeaders( |
| 826 | 831 | const phdr: []ElfN.Phdr = @ptrCast(@alignCast(elf.ni.phdr.slice(&elf.mf))); |
| 827 | 832 | const ph_phdr = &phdr[phdr_phndx]; |
| 828 | 833 | ph_phdr.* = .{ |
| 829 | | .type = std.elf.PT_PHDR, |
| 834 | .type = .PHDR, |
| 830 | 835 | .offset = 0, |
| 831 | 836 | .vaddr = 0, |
| 832 | 837 | .paddr = 0, |
| ... | ... | @@ -840,7 +845,7 @@ fn initHeaders( |
| 840 | 845 | if (maybe_interp) |_| { |
| 841 | 846 | const ph_interp = &phdr[interp_phndx]; |
| 842 | 847 | ph_interp.* = .{ |
| 843 | | .type = std.elf.PT_INTERP, |
| 848 | .type = .INTERP, |
| 844 | 849 | .offset = 0, |
| 845 | 850 | .vaddr = 0, |
| 846 | 851 | .paddr = 0, |
| ... | ... | @@ -855,7 +860,7 @@ fn initHeaders( |
| 855 | 860 | _, const rodata_size = elf.ni.rodata.location(&elf.mf).resolve(&elf.mf); |
| 856 | 861 | const ph_rodata = &phdr[rodata_phndx]; |
| 857 | 862 | ph_rodata.* = .{ |
| 858 | | .type = std.elf.PT_NULL, |
| 863 | .type = if (rodata_size == 0) .NULL else .LOAD, |
| 859 | 864 | .offset = 0, |
| 860 | 865 | .vaddr = ph_vaddr, |
| 861 | 866 | .paddr = ph_vaddr, |
| ... | ... | @@ -870,7 +875,7 @@ fn initHeaders( |
| 870 | 875 | _, const text_size = elf.ni.text.location(&elf.mf).resolve(&elf.mf); |
| 871 | 876 | const ph_text = &phdr[text_phndx]; |
| 872 | 877 | ph_text.* = .{ |
| 873 | | .type = std.elf.PT_NULL, |
| 878 | .type = if (text_size == 0) .NULL else .LOAD, |
| 874 | 879 | .offset = 0, |
| 875 | 880 | .vaddr = ph_vaddr, |
| 876 | 881 | .paddr = ph_vaddr, |
| ... | ... | @@ -885,7 +890,7 @@ fn initHeaders( |
| 885 | 890 | _, const data_size = elf.ni.data.location(&elf.mf).resolve(&elf.mf); |
| 886 | 891 | const ph_data = &phdr[data_phndx]; |
| 887 | 892 | ph_data.* = .{ |
| 888 | | .type = std.elf.PT_NULL, |
| 893 | .type = if (data_size == 0) .NULL else .LOAD, |
| 889 | 894 | .offset = 0, |
| 890 | 895 | .vaddr = ph_vaddr, |
| 891 | 896 | .paddr = ph_vaddr, |
| ... | ... | @@ -900,7 +905,7 @@ fn initHeaders( |
| 900 | 905 | if (have_dynamic_section) { |
| 901 | 906 | const ph_dynamic = &phdr[dynamic_phndx]; |
| 902 | 907 | ph_dynamic.* = .{ |
| 903 | | .type = std.elf.PT_DYNAMIC, |
| 908 | .type = .DYNAMIC, |
| 904 | 909 | .offset = 0, |
| 905 | 910 | .vaddr = 0, |
| 906 | 911 | .paddr = 0, |
| ... | ... | @@ -915,7 +920,7 @@ fn initHeaders( |
| 915 | 920 | if (comp.config.any_non_single_threaded) { |
| 916 | 921 | const ph_tls = &phdr[tls_phndx]; |
| 917 | 922 | ph_tls.* = .{ |
| 918 | | .type = std.elf.PT_TLS, |
| 923 | .type = .TLS, |
| 919 | 924 | .offset = 0, |
| 920 | 925 | .vaddr = 0, |
| 921 | 926 | .paddr = 0, |
| ... | ... | @@ -931,7 +936,7 @@ fn initHeaders( |
| 931 | 936 | const sh_null: *ElfN.Shdr = @ptrCast(@alignCast(elf.ni.shdr.slice(&elf.mf))); |
| 932 | 937 | sh_null.* = .{ |
| 933 | 938 | .name = try elf.string(.shstrtab, ""), |
| 934 | | .type = std.elf.SHT_NULL, |
| 939 | .type = .NULL, |
| 935 | 940 | .flags = .{ .shf = .{} }, |
| 936 | 941 | .addr = 0, |
| 937 | 942 | .offset = 0, |
| ... | ... | @@ -951,7 +956,7 @@ fn initHeaders( |
| 951 | 956 | .unused = 0, |
| 952 | 957 | }; |
| 953 | 958 | assert(elf.si.symtab == try elf.addSection(elf.ni.file, .{ |
| 954 | | .type = std.elf.SHT_SYMTAB, |
| 959 | .type = .SYMTAB, |
| 955 | 960 | .size = @sizeOf(ElfN.Sym) * 1, |
| 956 | 961 | .addralign = addr_align, |
| 957 | 962 | .entsize = @sizeOf(ElfN.Sym), |
| ... | ... | @@ -972,7 +977,7 @@ fn initHeaders( |
| 972 | 977 | }, |
| 973 | 978 | } |
| 974 | 979 | assert(elf.si.shstrtab == try elf.addSection(elf.ni.file, .{ |
| 975 | | .type = std.elf.SHT_STRTAB, |
| 980 | .type = .STRTAB, |
| 976 | 981 | .addralign = elf.mf.flags.block_size, |
| 977 | 982 | .entsize = 1, |
| 978 | 983 | })); |
| ... | ... | @@ -982,7 +987,7 @@ fn initHeaders( |
| 982 | 987 | |
| 983 | 988 | assert(elf.si.strtab == try elf.addSection(elf.ni.file, .{ |
| 984 | 989 | .name = ".strtab", |
| 985 | | .type = std.elf.SHT_STRTAB, |
| 990 | .type = .STRTAB, |
| 986 | 991 | .size = 1, |
| 987 | 992 | .addralign = elf.mf.flags.block_size, |
| 988 | 993 | .entsize = 1, |
| ... | ... | @@ -1016,6 +1021,7 @@ fn initHeaders( |
| 1016 | 1021 | elf.phdrs.items[interp_phndx] = interp_ni; |
| 1017 | 1022 | |
| 1018 | 1023 | const sec_interp_si = try elf.addSection(interp_ni, .{ |
| 1024 | .type = .PROGBITS, |
| 1019 | 1025 | .name = ".interp", |
| 1020 | 1026 | .flags = .{ .ALLOC = true }, |
| 1021 | 1027 | .size = @intCast(interp.len + 1), |
| ... | ... | @@ -1038,7 +1044,7 @@ fn initHeaders( |
| 1038 | 1044 | const ElfN = ct_class.ElfN(); |
| 1039 | 1045 | elf.si.dynsym = try elf.addSection(elf.ni.rodata, .{ |
| 1040 | 1046 | .name = ".dynsym", |
| 1041 | | .type = std.elf.SHT_DYNSYM, |
| 1047 | .type = .DYNSYM, |
| 1042 | 1048 | .size = @sizeOf(ElfN.Sym) * 1, |
| 1043 | 1049 | .addralign = addr_align, |
| 1044 | 1050 | .entsize = @sizeOf(ElfN.Sym), |
| ... | ... | @@ -1057,14 +1063,14 @@ fn initHeaders( |
| 1057 | 1063 | } |
| 1058 | 1064 | elf.si.dynstr = try elf.addSection(elf.ni.rodata, .{ |
| 1059 | 1065 | .name = ".dynstr", |
| 1060 | | .type = std.elf.SHT_STRTAB, |
| 1066 | .type = .STRTAB, |
| 1061 | 1067 | .size = 1, |
| 1062 | 1068 | .addralign = elf.mf.flags.block_size, |
| 1063 | 1069 | .entsize = 1, |
| 1064 | 1070 | }); |
| 1065 | 1071 | elf.si.dynamic = try elf.addSection(dynamic_ni, .{ |
| 1066 | 1072 | .name = ".dynamic", |
| 1067 | | .type = std.elf.SHT_DYNAMIC, |
| 1073 | .type = .DYNAMIC, |
| 1068 | 1074 | .flags = .{ .ALLOC = true, .WRITE = true }, |
| 1069 | 1075 | .addralign = addr_align, |
| 1070 | 1076 | }); |
| ... | ... | @@ -1126,7 +1132,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 1126 | 1132 | .file => return 0, |
| 1127 | 1133 | .ehdr, .shdr => unreachable, |
| 1128 | 1134 | .segment => |phndx| break :parent_vaddr switch (elf.phdrSlice()) { |
| 1129 | | inline else => |ph| elf.targetLoad(&ph[phndx].vaddr), |
| 1135 | inline else => |phdr| elf.targetLoad(&phdr[phndx].vaddr), |
| 1130 | 1136 | }, |
| 1131 | 1137 | .section => |si| si, |
| 1132 | 1138 | .input_section => unreachable, |
| ... | ... | @@ -1581,7 +1587,7 @@ fn loadObject( |
| 1581 | 1587 | }; |
| 1582 | 1588 | try r.discardAll(ehdr.shentsize); |
| 1583 | 1589 | switch (section.shdr.type) { |
| 1584 | | std.elf.SHT_NULL, std.elf.SHT_NOBITS => {}, |
| 1590 | .NULL, .NOBITS => {}, |
| 1585 | 1591 | else => if (section.shdr.offset + section.shdr.size > fl.size) |
| 1586 | 1592 | return diags.failParse(path, "bad section location", .{}), |
| 1587 | 1593 | } |
| ... | ... | @@ -1590,8 +1596,7 @@ fn loadObject( |
| 1590 | 1596 | if (ehdr.shstrndx == std.elf.SHN_UNDEF or ehdr.shstrndx >= ehdr.shnum) |
| 1591 | 1597 | return diags.failParse(path, "missing section names", .{}); |
| 1592 | 1598 | const shdr = &sections[ehdr.shstrndx].shdr; |
| 1593 | | if (shdr.type != std.elf.SHT_STRTAB) |
| 1594 | | return diags.failParse(path, "invalid shstrtab type", .{}); |
| 1599 | if (shdr.type != .STRTAB) return diags.failParse(path, "invalid shstrtab type", .{}); |
| 1595 | 1600 | const shstrtab = try gpa.alloc(u8, @intCast(shdr.size)); |
| 1596 | 1601 | errdefer gpa.free(shstrtab); |
| 1597 | 1602 | try fr.seekTo(fl.offset + shdr.offset); |
| ... | ... | @@ -1604,7 +1609,7 @@ fn loadObject( |
| 1604 | 1609 | try elf.input_sections.ensureUnusedCapacity(gpa, ehdr.shnum - 1); |
| 1605 | 1610 | for (sections[1..]) |*section| switch (section.shdr.type) { |
| 1606 | 1611 | else => {}, |
| 1607 | | std.elf.SHT_PROGBITS, std.elf.SHT_NOBITS => { |
| 1612 | .PROGBITS, .NOBITS => { |
| 1608 | 1613 | if (section.shdr.name >= shstrtab.len) continue; |
| 1609 | 1614 | const name = std.mem.sliceTo(shstrtab[section.shdr.name..], 0); |
| 1610 | 1615 | const parent_si = elf.namedSection(name) orelse continue; |
| ... | ... | @@ -1639,14 +1644,14 @@ fn loadObject( |
| 1639 | 1644 | defer symmap.deinit(gpa); |
| 1640 | 1645 | for (sections[1..], 1..) |*symtab, symtab_shndx| switch (symtab.shdr.type) { |
| 1641 | 1646 | else => {}, |
| 1642 | | std.elf.SHT_SYMTAB => { |
| 1647 | .SYMTAB => { |
| 1643 | 1648 | if (symtab.shdr.entsize < @sizeOf(ElfN.Sym)) |
| 1644 | 1649 | return diags.failParse(path, "unsupported symtab entsize", .{}); |
| 1645 | 1650 | const strtab = strtab: { |
| 1646 | 1651 | if (symtab.shdr.link == std.elf.SHN_UNDEF or symtab.shdr.link >= ehdr.shnum) |
| 1647 | 1652 | return diags.failParse(path, "missing symbol names", .{}); |
| 1648 | 1653 | const shdr = &sections[symtab.shdr.link].shdr; |
| 1649 | | if (shdr.type != std.elf.SHT_STRTAB) |
| 1654 | if (shdr.type != .STRTAB) |
| 1650 | 1655 | return diags.failParse(path, "invalid strtab type", .{}); |
| 1651 | 1656 | const strtab = try gpa.alloc(u8, @intCast(shdr.size)); |
| 1652 | 1657 | errdefer gpa.free(strtab); |
| ... | ... | @@ -1729,13 +1734,13 @@ fn loadObject( |
| 1729 | 1734 | } |
| 1730 | 1735 | for (sections[1..]) |*rels| switch (rels.shdr.type) { |
| 1731 | 1736 | else => {}, |
| 1732 | | inline std.elf.SHT_REL, std.elf.SHT_RELA => |sht| { |
| 1737 | inline .REL, .RELA => |sht| { |
| 1733 | 1738 | if (rels.shdr.link != symtab_shndx or rels.shdr.info == std.elf.SHN_UNDEF or |
| 1734 | 1739 | rels.shdr.info >= ehdr.shnum) continue; |
| 1735 | 1740 | const Rel = switch (sht) { |
| 1736 | 1741 | else => comptime unreachable, |
| 1737 | | std.elf.SHT_REL => ElfN.Rel, |
| 1738 | | std.elf.SHT_RELA => ElfN.Rela, |
| 1742 | .REL => ElfN.Rel, |
| 1743 | .RELA => ElfN.Rela, |
| 1739 | 1744 | }; |
| 1740 | 1745 | if (rels.shdr.entsize < @sizeOf(Rel)) |
| 1741 | 1746 | return diags.failParse(path, "unsupported rel entsize", .{}); |
| ... | ... | @@ -1810,7 +1815,7 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *std.Io.File.Reader) !void |
| 1810 | 1815 | try r.discardAll(ehdr.phentsize); |
| 1811 | 1816 | switch (ph.type) { |
| 1812 | 1817 | else => {}, |
| 1813 | | std.elf.PT_DYNAMIC => break ph, |
| 1818 | .DYNAMIC => break ph, |
| 1814 | 1819 | } |
| 1815 | 1820 | } else return diags.failParse(path, "no dynamic segment", .{}); |
| 1816 | 1821 | const dynnum = std.math.divExact( |
| ... | ... | @@ -1846,7 +1851,7 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *std.Io.File.Reader) !void |
| 1846 | 1851 | try r.discardAll(ehdr.phentsize); |
| 1847 | 1852 | switch (ph.type) { |
| 1848 | 1853 | else => {}, |
| 1849 | | std.elf.PT_LOAD => if (strtab.? >= ph.vaddr and |
| 1854 | .LOAD => if (strtab.? >= ph.vaddr and |
| 1850 | 1855 | strtab.? + (strsz orelse 0) <= ph.vaddr + ph.filesz) break ph, |
| 1851 | 1856 | } |
| 1852 | 1857 | } else return diags.failParse(path, "strtab not part of a loaded segment", .{}); |
| ... | ... | @@ -1982,15 +1987,15 @@ pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target_si: Symbol.In |
| 1982 | 1987 | |
| 1983 | 1988 | fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 1984 | 1989 | name: []const u8 = "", |
| 1985 | | type: std.elf.Word = std.elf.SHT_NULL, |
| 1990 | type: std.elf.SHT = .NULL, |
| 1986 | 1991 | flags: std.elf.SHF = .{}, |
| 1987 | 1992 | size: std.elf.Word = 0, |
| 1988 | 1993 | addralign: std.mem.Alignment = .@"1", |
| 1989 | 1994 | entsize: std.elf.Word = 0, |
| 1990 | 1995 | }) !Symbol.Index { |
| 1991 | 1996 | switch (opts.type) { |
| 1992 | | std.elf.SHT_NULL => assert(opts.size == 0), |
| 1993 | | std.elf.SHT_PROGBITS => assert(opts.size > 0), |
| 1997 | .NULL => assert(opts.size == 0), |
| 1998 | .PROGBITS => assert(opts.size > 0), |
| 1994 | 1999 | else => {}, |
| 1995 | 2000 | } |
| 1996 | 2001 | const gpa = elf.base.comp.gpa; |
| ... | ... | @@ -2626,10 +2631,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 2626 | 2631 | const ph = &phdr[phndx]; |
| 2627 | 2632 | switch (elf.targetLoad(&ph.type)) { |
| 2628 | 2633 | else => unreachable, |
| 2629 | | std.elf.PT_NULL, std.elf.PT_LOAD => return, |
| 2630 | | std.elf.PT_DYNAMIC, std.elf.PT_INTERP => {}, |
| 2631 | | std.elf.PT_PHDR => @field(elf.ehdrPtr(), @tagName(class)).phoff = ph.offset, |
| 2632 | | std.elf.PT_TLS => {}, |
| 2634 | .NULL, .LOAD => return, |
| 2635 | .DYNAMIC, .INTERP => {}, |
| 2636 | .PHDR => @field(elf.ehdrPtr(), @tagName(class)).phoff = ph.offset, |
| 2637 | .TLS => {}, |
| 2633 | 2638 | } |
| 2634 | 2639 | elf.targetStore(&ph.vaddr, @intCast(elf.computeNodeVAddr(ni))); |
| 2635 | 2640 | ph.paddr = ph.vaddr; |
| ... | ... | @@ -2694,22 +2699,18 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 2694 | 2699 | elf.targetStore(&ph.memsz, @intCast(memsz)); |
| 2695 | 2700 | switch (elf.targetLoad(&ph.type)) { |
| 2696 | 2701 | else => unreachable, |
| 2697 | | std.elf.PT_NULL => if (size > 0) elf.targetStore(&ph.type, std.elf.PT_LOAD), |
| 2698 | | std.elf.PT_LOAD => if (size == 0) elf.targetStore(&ph.type, std.elf.PT_NULL), |
| 2699 | | std.elf.PT_DYNAMIC, std.elf.PT_INTERP, std.elf.PT_PHDR => return, |
| 2700 | | std.elf.PT_TLS => return ni.childrenMoved(elf.base.comp.gpa, &elf.mf), |
| 2702 | .NULL => if (size > 0) elf.targetStore(&ph.type, .LOAD), |
| 2703 | .LOAD => if (size == 0) elf.targetStore(&ph.type, .NULL), |
| 2704 | .DYNAMIC, .INTERP, .PHDR => return, |
| 2705 | .TLS => return ni.childrenMoved(elf.base.comp.gpa, &elf.mf), |
| 2701 | 2706 | } |
| 2702 | 2707 | var vaddr = elf.targetLoad(&ph.vaddr); |
| 2703 | 2708 | var new_phndx = phndx; |
| 2704 | 2709 | for (phdr[phndx + 1 ..], phndx + 1..) |*next_ph, next_phndx| { |
| 2705 | 2710 | switch (elf.targetLoad(&next_ph.type)) { |
| 2706 | 2711 | else => unreachable, |
| 2707 | | std.elf.PT_NULL, std.elf.PT_LOAD => {}, |
| 2708 | | std.elf.PT_DYNAMIC, |
| 2709 | | std.elf.PT_INTERP, |
| 2710 | | std.elf.PT_PHDR, |
| 2711 | | std.elf.PT_TLS, |
| 2712 | | => break, |
| 2712 | .NULL, .LOAD => {}, |
| 2713 | .DYNAMIC, .INTERP, .PHDR, .TLS => break, |
| 2713 | 2714 | } |
| 2714 | 2715 | const next_vaddr = elf.targetLoad(&next_ph.vaddr); |
| 2715 | 2716 | if (vaddr + memsz <= next_vaddr) break; |
| ... | ... | @@ -2737,13 +2738,13 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 2737 | 2738 | elf.targetStore(&sh.size, @intCast(size)); |
| 2738 | 2739 | switch (elf.targetLoad(&sh.type)) { |
| 2739 | 2740 | else => unreachable, |
| 2740 | | std.elf.SHT_NULL => if (size > 0) elf.targetStore(&sh.type, std.elf.SHT_PROGBITS), |
| 2741 | | std.elf.SHT_PROGBITS => if (size == 0) elf.targetStore(&sh.type, std.elf.SHT_NULL), |
| 2742 | | std.elf.SHT_SYMTAB, std.elf.SHT_DYNSYM => elf.targetStore( |
| 2741 | .NULL => if (size > 0) elf.targetStore(&sh.type, .PROGBITS), |
| 2742 | .PROGBITS => if (size == 0) elf.targetStore(&sh.type, .NULL), |
| 2743 | .SYMTAB, .DYNSYM => elf.targetStore( |
| 2743 | 2744 | &sh.info, |
| 2744 | 2745 | @intCast(@divExact(size, elf.targetLoad(&sh.entsize))), |
| 2745 | 2746 | ), |
| 2746 | | std.elf.SHT_STRTAB, std.elf.SHT_DYNAMIC => {}, |
| 2747 | .STRTAB, .DYNAMIC => {}, |
| 2747 | 2748 | } |
| 2748 | 2749 | }, |
| 2749 | 2750 | }, |
| ... | ... | @@ -2870,6 +2871,26 @@ pub fn printNode( |
| 2870 | 2871 | try w.writeAll(@tagName(node)); |
| 2871 | 2872 | switch (node) { |
| 2872 | 2873 | else => {}, |
| 2874 | .segment => |phndx| switch (elf.phdrSlice()) { |
| 2875 | inline else => |phdr| { |
| 2876 | const ph = &phdr[phndx]; |
| 2877 | try w.writeByte('('); |
| 2878 | const pt = elf.targetLoad(&ph.type); |
| 2879 | if (std.enums.tagName(std.elf.PT, pt)) |pt_name| |
| 2880 | try w.writeAll(pt_name) |
| 2881 | else inline for (@typeInfo(std.elf.PT).@"enum".decls) |decl| { |
| 2882 | const decl_val = @field(std.elf.PT, decl.name); |
| 2883 | if (@TypeOf(decl_val) != std.elf.PT) continue; |
| 2884 | if (pt == @field(std.elf.PT, decl.name)) break try w.writeAll(decl.name); |
| 2885 | } else try w.print("0x{x}", .{pt}); |
| 2886 | try w.writeAll(", "); |
| 2887 | const pf = elf.targetLoad(&ph.flags); |
| 2888 | if (pf.R) try w.writeByte('R'); |
| 2889 | if (pf.W) try w.writeByte('W'); |
| 2890 | if (pf.X) try w.writeByte('X'); |
| 2891 | try w.writeByte(')'); |
| 2892 | }, |
| 2893 | }, |
| 2873 | 2894 | .section => |si| try w.print("({s})", .{elf.sectionName(si)}), |
| 2874 | 2895 | .input_section => |isi| { |
| 2875 | 2896 | const ii = isi.input(elf); |