authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-11-05 05:17:40-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-11-09 03:31:26-05:00
log7bcefe5a221fc9f0f277f9e909c1b63fbe0b830b
tree4699b2e1540e7a06201608f77bcdc98326627627
parent5358af7ba4cf16bef1734729646b99842e439916

Elf2: emit object files that are slightly more object-like


1 files changed, 119 insertions(+), 109 deletions(-)

src/link/Elf2.zig+119-109
...@@ -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;
717717
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(
767773
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;
775781
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;
785791
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;
793799
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;
801807
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();
818824
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
847840 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);
877854
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);
892869
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);
907884
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 }
922930
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;
984992
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 }
10741084
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,