Commit d32af9ea2a
Changed files (2)
src
link
src/link/Elf/Object.zig
@@ -311,58 +311,6 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
};
}
-fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u32 {
- const name = blk: {
- const name = self.getString(shdr.sh_name);
- if (elf_file.base.isRelocatable()) break :blk name;
- if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name;
- const sh_name_prefixes: []const [:0]const u8 = &.{
- ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
- ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", ".ctors",
- ".dtors", ".gnu.warning",
- };
- inline for (sh_name_prefixes) |prefix| {
- if (std.mem.eql(u8, name, prefix) or std.mem.startsWith(u8, name, prefix ++ ".")) {
- break :blk prefix;
- }
- }
- break :blk name;
- };
- const @"type" = tt: {
- if (elf_file.getTarget().cpu.arch == .x86_64 and
- shdr.sh_type == elf.SHT_X86_64_UNWIND) break :tt elf.SHT_PROGBITS;
-
- const @"type" = switch (shdr.sh_type) {
- elf.SHT_NULL => unreachable,
- elf.SHT_PROGBITS => blk: {
- if (std.mem.eql(u8, name, ".init_array") or std.mem.startsWith(u8, name, ".init_array."))
- break :blk elf.SHT_INIT_ARRAY;
- if (std.mem.eql(u8, name, ".fini_array") or std.mem.startsWith(u8, name, ".fini_array."))
- break :blk elf.SHT_FINI_ARRAY;
- break :blk shdr.sh_type;
- },
- else => shdr.sh_type,
- };
- break :tt @"type";
- };
- const flags = blk: {
- var flags = shdr.sh_flags;
- if (!elf_file.base.isRelocatable()) {
- flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN);
- }
- break :blk switch (@"type") {
- elf.SHT_INIT_ARRAY, elf.SHT_FINI_ARRAY => flags | elf.SHF_WRITE,
- else => flags,
- };
- };
- const out_shndx = elf_file.sectionByName(name) orelse try elf_file.addSection(.{
- .type = @"type",
- .flags = flags,
- .name = try elf_file.insertShString(name),
- });
- return out_shndx;
-}
-
fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool {
const comp = elf_file.base.comp;
const shdr = self.shdrs.items[index];
@@ -985,7 +933,11 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void {
const atom_ptr = self.atom(atom_index) orelse continue;
if (!atom_ptr.alive) continue;
const shdr = atom_ptr.inputShdr(elf_file);
- _ = try self.initOutputSection(elf_file, shdr);
+ _ = try elf_file.initOutputSection(.{
+ .name = self.getString(shdr.sh_name),
+ .flags = shdr.sh_flags,
+ .type = shdr.sh_type,
+ });
}
}
@@ -994,7 +946,11 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
const atom_ptr = self.atom(atom_index) orelse continue;
if (!atom_ptr.alive) continue;
const shdr = atom_ptr.inputShdr(elf_file);
- atom_ptr.output_section_index = self.initOutputSection(elf_file, shdr) catch unreachable;
+ atom_ptr.output_section_index = elf_file.initOutputSection(.{
+ .name = self.getString(shdr.sh_name),
+ .flags = shdr.sh_flags,
+ .type = shdr.sh_type,
+ }) catch unreachable;
const comp = elf_file.base.comp;
const gpa = comp.gpa;
@@ -1009,7 +965,11 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {
if (!atom_ptr.alive) continue;
const shndx = atom_ptr.relocsShndx() orelse continue;
const shdr = self.shdrs.items[shndx];
- const out_shndx = try self.initOutputSection(elf_file, shdr);
+ const out_shndx = try elf_file.initOutputSection(.{
+ .name = self.getString(shdr.sh_name),
+ .flags = shdr.sh_flags,
+ .type = shdr.sh_type,
+ });
const out_shdr = &elf_file.sections.items(.shdr)[out_shndx];
out_shdr.sh_type = elf.SHT_RELA;
out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);
@@ -1025,7 +985,11 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
const shndx = blk: {
const shndx = atom_ptr.relocsShndx() orelse continue;
const shdr = self.shdrs.items[shndx];
- break :blk self.initOutputSection(elf_file, shdr) catch unreachable;
+ break :blk elf_file.initOutputSection(.{
+ .name = self.getString(shdr.sh_name),
+ .flags = shdr.sh_flags,
+ .type = shdr.sh_type,
+ }) catch unreachable;
};
const slice = elf_file.sections.slice();
const shdr = &slice.items(.shdr)[shndx];
src/link/Elf.zig
@@ -1827,6 +1827,59 @@ fn scanRelocs(self: *Elf) !void {
}
}
+pub fn initOutputSection(self: *Elf, args: struct {
+ name: [:0]const u8,
+ flags: u64,
+ type: u32,
+}) error{OutOfMemory}!u32 {
+ const name = blk: {
+ if (self.base.isRelocatable()) break :blk args.name;
+ if (args.flags & elf.SHF_MERGE != 0) break :blk args.name;
+ const name_prefixes: []const [:0]const u8 = &.{
+ ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
+ ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", ".ctors",
+ ".dtors", ".gnu.warning",
+ };
+ inline for (name_prefixes) |prefix| {
+ if (std.mem.eql(u8, args.name, prefix) or std.mem.startsWith(u8, args.name, prefix ++ ".")) {
+ break :blk prefix;
+ }
+ }
+ break :blk args.name;
+ };
+ const @"type" = tt: {
+ if (self.getTarget().cpu.arch == .x86_64 and
+ args.type == elf.SHT_X86_64_UNWIND) break :tt elf.SHT_PROGBITS;
+ switch (args.type) {
+ elf.SHT_NULL => unreachable,
+ elf.SHT_PROGBITS => {
+ if (std.mem.eql(u8, args.name, ".init_array") or std.mem.startsWith(u8, args.name, ".init_array."))
+ break :tt elf.SHT_INIT_ARRAY;
+ if (std.mem.eql(u8, args.name, ".fini_array") or std.mem.startsWith(u8, args.name, ".fini_array."))
+ break :tt elf.SHT_FINI_ARRAY;
+ break :tt args.type;
+ },
+ else => break :tt args.type,
+ }
+ };
+ const flags = blk: {
+ var flags = args.flags;
+ if (!self.base.isRelocatable()) {
+ flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN);
+ }
+ break :blk switch (@"type") {
+ elf.SHT_INIT_ARRAY, elf.SHT_FINI_ARRAY => flags | elf.SHF_WRITE,
+ else => flags,
+ };
+ };
+ const out_shndx = self.sectionByName(name) orelse try self.addSection(.{
+ .type = @"type",
+ .flags = flags,
+ .name = try self.insertShString(name),
+ });
+ return out_shndx;
+}
+
fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
dev.check(.lld_linker);