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(
715715 break :phndx phnum;
716716 } 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 };
719725 try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len);
720726 try elf.phdrs.resize(gpa, phnum);
721727 elf.nodes.appendAssumeCapacity(.file);
......@@ -767,37 +773,37 @@ fn initHeaders(
767773
768774 assert(elf.ni.rodata == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
769775 .alignment = elf.mf.flags.block_size,
770 .moved = true,
776 .moved = @"type" != .REL,
771777 .bubbles_moved = false,
772778 }));
773779 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
776782 assert(elf.ni.phdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{
777783 .size = elf.ehdrField(.phentsize) * elf.ehdrField(.phnum),
778784 .alignment = addr_align,
779 .moved = true,
780 .resized = true,
785 .moved = @"type" != .REL,
786 .resized = @"type" != .REL,
781787 .bubbles_moved = false,
782788 }));
783789 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
786792 assert(elf.ni.text == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
787793 .alignment = elf.mf.flags.block_size,
788 .moved = true,
794 .moved = @"type" != .REL,
789795 .bubbles_moved = false,
790796 }));
791797 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
794800 assert(elf.ni.data == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{
795801 .alignment = elf.mf.flags.block_size,
796 .moved = true,
802 .moved = @"type" != .REL,
797803 .bubbles_moved = false,
798804 }));
799805 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
802808 var ph_vaddr: u32 = switch (elf.ehdrField(.type)) {
803809 else => 0,
......@@ -816,108 +822,110 @@ fn initHeaders(
816822 const ElfN = ct_class.ElfN();
817823 const target_endian = elf.targetEndian();
818824
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,
837830 .offset = 0,
838831 .vaddr = 0,
839832 .paddr = 0,
840833 .filesz = 0,
841834 .memsz = 0,
842835 .flags = .{ .R = true },
843 .@"align" = 1,
836 .@"align" = @intCast(elf.ni.phdr.alignment(&elf.mf).toByteUnits()),
844837 };
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 }
877854
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);
892869
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,
897874 .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()),
904881 };
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);
907884
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,
912889 .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()),
919896 };
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 }
921929 }
922930
923931 const sh_null: *ElfN.Shdr = @ptrCast(@alignCast(elf.ni.shdr.slice(&elf.mf)));
......@@ -982,17 +990,17 @@ fn initHeaders(
982990 try elf.linkSections(.symtab, .strtab);
983991 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, .{
986994 .name = ".rodata",
987995 .flags = .{ .ALLOC = true },
988996 .addralign = elf.mf.flags.block_size,
989997 }));
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, .{
991999 .name = ".text",
9921000 .flags = .{ .ALLOC = true, .EXECINSTR = true },
9931001 .addralign = elf.mf.flags.block_size,
9941002 }));
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, .{
9961004 .name = ".data",
9971005 .flags = .{ .WRITE = true, .ALLOC = true },
9981006 .addralign = elf.mf.flags.block_size,
......@@ -1064,15 +1072,17 @@ fn initHeaders(
10641072 try elf.linkSections(elf.si.dynsym, elf.si.dynstr);
10651073 }
10661074 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 }
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, .{
10761086 .name = ".tdata",
10771087 .flags = .{ .WRITE = true, .ALLOC = true, .TLS = true },
10781088 .addralign = elf.mf.flags.block_size,