| ... | ... | @@ -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 | 314 | fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool { |
| 367 | 315 | const comp = elf_file.base.comp; |
| 368 | 316 | const shdr = self.shdrs.items[index]; |
| ... | ... | @@ -985,7 +933,11 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void { |
| 985 | 933 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 986 | 934 | if (!atom_ptr.alive) continue; |
| 987 | 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 | 946 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 995 | 947 | if (!atom_ptr.alive) continue; |
| 996 | 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 | 955 | const comp = elf_file.base.comp; |
| 1000 | 956 | const gpa = comp.gpa; |
| ... | ... | @@ -1009,7 +965,11 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1009 | 965 | if (!atom_ptr.alive) continue; |
| 1010 | 966 | const shndx = atom_ptr.relocsShndx() orelse continue; |
| 1011 | 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 | 973 | const out_shdr = &elf_file.sections.items(.shdr)[out_shndx]; |
| 1014 | 974 | out_shdr.sh_type = elf.SHT_RELA; |
| 1015 | 975 | out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela); |
| ... | ... | @@ -1025,7 +985,11 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1025 | 985 | const shndx = blk: { |
| 1026 | 986 | const shndx = atom_ptr.relocsShndx() orelse continue; |
| 1027 | 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 | 994 | const slice = elf_file.sections.slice(); |
| 1031 | 995 | const shdr = &slice.items(.shdr)[shndx]; |