authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-27 15:22:33+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-04 13:34:25+02:00
logd32af9ea2ade7c447ac8b882076dba337a10dc51
treec514a34fdfe5c3e13e973b6c0e252bccc4002371
parentb44dd599ad4a0f8a6684acd6e3c5a02f3c7b8f04

elf: move initOutputSection into Elf from Object


2 files changed, 73 insertions(+), 56 deletions(-)

src/link/Elf.zig+53
...@@ -1827,6 +1827,59 @@ fn scanRelocs(self: *Elf) !void {...@@ -1827,6 +1827,59 @@ fn scanRelocs(self: *Elf) !void {
1827 }1827 }
1828}1828}
18291829
1830pub fn initOutputSection(self: *Elf, args: struct {
1831 name: [:0]const u8,
1832 flags: u64,
1833 type: u32,
1834}) error{OutOfMemory}!u32 {
1835 const name = blk: {
1836 if (self.base.isRelocatable()) break :blk args.name;
1837 if (args.flags & elf.SHF_MERGE != 0) break :blk args.name;
1838 const name_prefixes: []const [:0]const u8 = &.{
1839 ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
1840 ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", ".ctors",
1841 ".dtors", ".gnu.warning",
1842 };
1843 inline for (name_prefixes) |prefix| {
1844 if (std.mem.eql(u8, args.name, prefix) or std.mem.startsWith(u8, args.name, prefix ++ ".")) {
1845 break :blk prefix;
1846 }
1847 }
1848 break :blk args.name;
1849 };
1850 const @"type" = tt: {
1851 if (self.getTarget().cpu.arch == .x86_64 and
1852 args.type == elf.SHT_X86_64_UNWIND) break :tt elf.SHT_PROGBITS;
1853 switch (args.type) {
1854 elf.SHT_NULL => unreachable,
1855 elf.SHT_PROGBITS => {
1856 if (std.mem.eql(u8, args.name, ".init_array") or std.mem.startsWith(u8, args.name, ".init_array."))
1857 break :tt elf.SHT_INIT_ARRAY;
1858 if (std.mem.eql(u8, args.name, ".fini_array") or std.mem.startsWith(u8, args.name, ".fini_array."))
1859 break :tt elf.SHT_FINI_ARRAY;
1860 break :tt args.type;
1861 },
1862 else => break :tt args.type,
1863 }
1864 };
1865 const flags = blk: {
1866 var flags = args.flags;
1867 if (!self.base.isRelocatable()) {
1868 flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN);
1869 }
1870 break :blk switch (@"type") {
1871 elf.SHT_INIT_ARRAY, elf.SHT_FINI_ARRAY => flags | elf.SHF_WRITE,
1872 else => flags,
1873 };
1874 };
1875 const out_shndx = self.sectionByName(name) orelse try self.addSection(.{
1876 .type = @"type",
1877 .flags = flags,
1878 .name = try self.insertShString(name),
1879 });
1880 return out_shndx;
1881}
1882
1830fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {1883fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
1831 dev.check(.lld_linker);1884 dev.check(.lld_linker);
18321885
src/link/Elf/Object.zig+20-56
...@@ -311,58 +311,6 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -311,58 +311,6 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
311 };311 };
312}312}
313313
314fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u32 {
315 const name = blk: {
316 const name = self.getString(shdr.sh_name);
317 if (elf_file.base.isRelocatable()) break :blk name;
318 if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name;
319 const sh_name_prefixes: []const [:0]const u8 = &.{
320 ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
321 ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", ".ctors",
322 ".dtors", ".gnu.warning",
323 };
324 inline for (sh_name_prefixes) |prefix| {
325 if (std.mem.eql(u8, name, prefix) or std.mem.startsWith(u8, name, prefix ++ ".")) {
326 break :blk prefix;
327 }
328 }
329 break :blk name;
330 };
331 const @"type" = tt: {
332 if (elf_file.getTarget().cpu.arch == .x86_64 and
333 shdr.sh_type == elf.SHT_X86_64_UNWIND) break :tt elf.SHT_PROGBITS;
334
335 const @"type" = switch (shdr.sh_type) {
336 elf.SHT_NULL => unreachable,
337 elf.SHT_PROGBITS => blk: {
338 if (std.mem.eql(u8, name, ".init_array") or std.mem.startsWith(u8, name, ".init_array."))
339 break :blk elf.SHT_INIT_ARRAY;
340 if (std.mem.eql(u8, name, ".fini_array") or std.mem.startsWith(u8, name, ".fini_array."))
341 break :blk elf.SHT_FINI_ARRAY;
342 break :blk shdr.sh_type;
343 },
344 else => shdr.sh_type,
345 };
346 break :tt @"type";
347 };
348 const flags = blk: {
349 var flags = shdr.sh_flags;
350 if (!elf_file.base.isRelocatable()) {
351 flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN);
352 }
353 break :blk switch (@"type") {
354 elf.SHT_INIT_ARRAY, elf.SHT_FINI_ARRAY => flags | elf.SHF_WRITE,
355 else => flags,
356 };
357 };
358 const out_shndx = elf_file.sectionByName(name) orelse try elf_file.addSection(.{
359 .type = @"type",
360 .flags = flags,
361 .name = try elf_file.insertShString(name),
362 });
363 return out_shndx;
364}
365
366fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool {314fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool {
367 const comp = elf_file.base.comp;315 const comp = elf_file.base.comp;
368 const shdr = self.shdrs.items[index];316 const shdr = self.shdrs.items[index];
...@@ -985,7 +933,11 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void {...@@ -985,7 +933,11 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void {
985 const atom_ptr = self.atom(atom_index) orelse continue;933 const atom_ptr = self.atom(atom_index) orelse continue;
986 if (!atom_ptr.alive) continue;934 if (!atom_ptr.alive) continue;
987 const shdr = atom_ptr.inputShdr(elf_file);935 const shdr = atom_ptr.inputShdr(elf_file);
988 _ = try self.initOutputSection(elf_file, shdr);936 _ = try elf_file.initOutputSection(.{
937 .name = self.getString(shdr.sh_name),
938 .flags = shdr.sh_flags,
939 .type = shdr.sh_type,
940 });
989 }941 }
990}942}
991943
...@@ -994,7 +946,11 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {...@@ -994,7 +946,11 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
994 const atom_ptr = self.atom(atom_index) orelse continue;946 const atom_ptr = self.atom(atom_index) orelse continue;
995 if (!atom_ptr.alive) continue;947 if (!atom_ptr.alive) continue;
996 const shdr = atom_ptr.inputShdr(elf_file);948 const shdr = atom_ptr.inputShdr(elf_file);
997 atom_ptr.output_section_index = self.initOutputSection(elf_file, shdr) catch unreachable;949 atom_ptr.output_section_index = elf_file.initOutputSection(.{
950 .name = self.getString(shdr.sh_name),
951 .flags = shdr.sh_flags,
952 .type = shdr.sh_type,
953 }) catch unreachable;
998954
999 const comp = elf_file.base.comp;955 const comp = elf_file.base.comp;
1000 const gpa = comp.gpa;956 const gpa = comp.gpa;
...@@ -1009,7 +965,11 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {...@@ -1009,7 +965,11 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {
1009 if (!atom_ptr.alive) continue;965 if (!atom_ptr.alive) continue;
1010 const shndx = atom_ptr.relocsShndx() orelse continue;966 const shndx = atom_ptr.relocsShndx() orelse continue;
1011 const shdr = self.shdrs.items[shndx];967 const shdr = self.shdrs.items[shndx];
1012 const out_shndx = try self.initOutputSection(elf_file, shdr);968 const out_shndx = try elf_file.initOutputSection(.{
969 .name = self.getString(shdr.sh_name),
970 .flags = shdr.sh_flags,
971 .type = shdr.sh_type,
972 });
1013 const out_shdr = &elf_file.sections.items(.shdr)[out_shndx];973 const out_shdr = &elf_file.sections.items(.shdr)[out_shndx];
1014 out_shdr.sh_type = elf.SHT_RELA;974 out_shdr.sh_type = elf.SHT_RELA;
1015 out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);975 out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);
...@@ -1025,7 +985,11 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {...@@ -1025,7 +985,11 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
1025 const shndx = blk: {985 const shndx = blk: {
1026 const shndx = atom_ptr.relocsShndx() orelse continue;986 const shndx = atom_ptr.relocsShndx() orelse continue;
1027 const shdr = self.shdrs.items[shndx];987 const shdr = self.shdrs.items[shndx];
1028 break :blk self.initOutputSection(elf_file, shdr) catch unreachable;988 break :blk elf_file.initOutputSection(.{
989 .name = self.getString(shdr.sh_name),
990 .flags = shdr.sh_flags,
991 .type = shdr.sh_type,
992 }) catch unreachable;
1029 };993 };
1030 const slice = elf_file.sections.slice();994 const slice = elf_file.sections.slice();
1031 const shdr = &slice.items(.shdr)[shndx];995 const shdr = &slice.items(.shdr)[shndx];