| ... | @@ -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 | } |
| 313 | | 313 | |
| 314 | fn 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 | | | |
| 366 | fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool { | 314 | fn 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 | } |
| 991 | | 943 | |
| ... | @@ -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; |
| 998 | | 954 | |
| 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]; |