mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
elf: init output COMDAT group sections
This commit is contained in:
parent
031d9faf02
commit
acd7cbf0b5
@ -1664,6 +1664,8 @@ pub const EM = enum(u16) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const GRP_COMDAT = 1;
|
||||||
|
|
||||||
/// Section data should be writable during execution.
|
/// Section data should be writable during execution.
|
||||||
pub const SHF_WRITE = 0x1;
|
pub const SHF_WRITE = 0x1;
|
||||||
|
|
||||||
|
|||||||
@ -102,6 +102,9 @@ copy_rel: CopyRelSection = .{},
|
|||||||
rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
|
rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
|
||||||
/// .got.zig section
|
/// .got.zig section
|
||||||
zig_got: ZigGotSection = .{},
|
zig_got: ZigGotSection = .{},
|
||||||
|
/// SHT_GROUP sections
|
||||||
|
/// Applies only to a relocatable.
|
||||||
|
comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
|
||||||
|
|
||||||
/// Tracked section headers with incremental updates to Zig object.
|
/// Tracked section headers with incremental updates to Zig object.
|
||||||
/// .rela.* sections are only used when emitting a relocatable object file.
|
/// .rela.* sections are only used when emitting a relocatable object file.
|
||||||
@ -394,6 +397,7 @@ pub fn deinit(self: *Elf) void {
|
|||||||
self.rela_dyn.deinit(gpa);
|
self.rela_dyn.deinit(gpa);
|
||||||
self.rela_plt.deinit(gpa);
|
self.rela_plt.deinit(gpa);
|
||||||
self.zig_got.deinit(gpa);
|
self.zig_got.deinit(gpa);
|
||||||
|
self.comdat_group_sections.deinit(gpa);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 {
|
pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 {
|
||||||
@ -3585,10 +3589,35 @@ fn initSectionsObject(self: *Elf) !void {
|
|||||||
self.eh_frame_rela_section_index = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?);
|
self.eh_frame_rela_section_index = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try self.initComdatGroups();
|
||||||
try self.initSymtab();
|
try self.initSymtab();
|
||||||
try self.initShStrtab();
|
try self.initShStrtab();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initComdatGroups(self: *Elf) !void {
|
||||||
|
const gpa = self.base.allocator;
|
||||||
|
|
||||||
|
for (self.objects.items) |index| {
|
||||||
|
const object = self.file(index).?.object;
|
||||||
|
|
||||||
|
for (object.comdat_groups.items) |cg_index| {
|
||||||
|
const cg = self.comdatGroup(cg_index);
|
||||||
|
const cg_owner = self.comdatGroupOwner(cg.owner);
|
||||||
|
if (cg_owner.file != index) continue;
|
||||||
|
|
||||||
|
const cg_sec = try self.comdat_group_sections.addOne(gpa);
|
||||||
|
cg_sec.* = .{
|
||||||
|
.shndx = try self.addSection(.{
|
||||||
|
.name = ".group",
|
||||||
|
.type = elf.SHT_GROUP,
|
||||||
|
.entsize = @sizeOf(u32),
|
||||||
|
}),
|
||||||
|
.cg_index = cg_index,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn initSymtab(self: *Elf) !void {
|
fn initSymtab(self: *Elf) !void {
|
||||||
const small_ptr = switch (self.ptr_width) {
|
const small_ptr = switch (self.ptr_width) {
|
||||||
.p32 => true,
|
.p32 => true,
|
||||||
@ -3892,7 +3921,7 @@ fn shdrRank(self: *Elf, shndx: u16) u8 {
|
|||||||
|
|
||||||
elf.SHT_DYNAMIC => return 0xf3,
|
elf.SHT_DYNAMIC => return 0xf3,
|
||||||
|
|
||||||
elf.SHT_RELA => return 0xf,
|
elf.SHT_RELA, elf.SHT_GROUP => return 0xf,
|
||||||
|
|
||||||
elf.SHT_PROGBITS => if (flags & elf.SHF_ALLOC != 0) {
|
elf.SHT_PROGBITS => if (flags & elf.SHF_ALLOC != 0) {
|
||||||
if (flags & elf.SHF_EXECINSTR != 0) {
|
if (flags & elf.SHF_EXECINSTR != 0) {
|
||||||
@ -4131,6 +4160,10 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void {
|
|||||||
shdr.sh_link = self.symtab_section_index.?;
|
shdr.sh_link = self.symtab_section_index.?;
|
||||||
shdr.sh_info = shndx;
|
shdr.sh_info = shndx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (self.comdat_group_sections.items) |*cg| {
|
||||||
|
cg.shndx = backlinks[cg.shndx];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updateSectionSizes(self: *Elf) !void {
|
fn updateSectionSizes(self: *Elf) !void {
|
||||||
@ -4260,10 +4293,15 @@ fn updateSectionSizesObject(self: *Elf) !void {
|
|||||||
shdr.sh_size = eh_frame.calcEhFrameRelocs(self) * shdr.sh_entsize;
|
shdr.sh_size = eh_frame.calcEhFrameRelocs(self) * shdr.sh_entsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.updateComdatGroupsSizes();
|
||||||
try self.updateSymtabSize();
|
try self.updateSymtabSize();
|
||||||
self.updateShStrtabSize();
|
self.updateShStrtabSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn updateComdatGroupsSizes(self: *Elf) void {
|
||||||
|
_ = self;
|
||||||
|
}
|
||||||
|
|
||||||
fn updateShStrtabSize(self: *Elf) void {
|
fn updateShStrtabSize(self: *Elf) void {
|
||||||
if (self.shstrtab_section_index) |index| {
|
if (self.shstrtab_section_index) |index| {
|
||||||
self.shdrs.items[index].sh_size = self.shstrtab.items.len;
|
self.shdrs.items[index].sh_size = self.shstrtab.items.len;
|
||||||
@ -6168,7 +6206,12 @@ fn fmtDumpState(
|
|||||||
try writer.print("{}\n", .{self.got.fmt(self)});
|
try writer.print("{}\n", .{self.got.fmt(self)});
|
||||||
try writer.print("{}\n", .{self.zig_got.fmt(self)});
|
try writer.print("{}\n", .{self.zig_got.fmt(self)});
|
||||||
|
|
||||||
try writer.writeAll("Output shdrs\n");
|
try writer.writeAll("Output COMDAT groups\n");
|
||||||
|
for (self.comdat_group_sections.items) |cg| {
|
||||||
|
try writer.print("shdr({d}) : COMDAT({d})\n", .{ cg.shndx, cg.cg_index });
|
||||||
|
}
|
||||||
|
|
||||||
|
try writer.writeAll("\nOutput shdrs\n");
|
||||||
for (self.shdrs.items, 0..) |shdr, shndx| {
|
for (self.shdrs.items, 0..) |shdr, shndx| {
|
||||||
try writer.print("shdr({d}) : phdr({?d}) : {}\n", .{
|
try writer.print("shdr({d}) : phdr({?d}) : {}\n", .{
|
||||||
shndx,
|
shndx,
|
||||||
@ -6332,6 +6375,7 @@ const Archive = @import("Elf/Archive.zig");
|
|||||||
pub const Atom = @import("Elf/Atom.zig");
|
pub const Atom = @import("Elf/Atom.zig");
|
||||||
const Cache = std.Build.Cache;
|
const Cache = std.Build.Cache;
|
||||||
const Compilation = @import("../Compilation.zig");
|
const Compilation = @import("../Compilation.zig");
|
||||||
|
const ComdatGroupSection = synthetic_sections.ComdatGroupSection;
|
||||||
const CopyRelSection = synthetic_sections.CopyRelSection;
|
const CopyRelSection = synthetic_sections.CopyRelSection;
|
||||||
const DynamicSection = synthetic_sections.DynamicSection;
|
const DynamicSection = synthetic_sections.DynamicSection;
|
||||||
const DynsymSection = synthetic_sections.DynsymSection;
|
const DynsymSection = synthetic_sections.DynsymSection;
|
||||||
|
|||||||
@ -142,7 +142,7 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void {
|
|||||||
const group_nmembers = @divExact(group_raw_data.len, @sizeOf(u32));
|
const group_nmembers = @divExact(group_raw_data.len, @sizeOf(u32));
|
||||||
const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers];
|
const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers];
|
||||||
|
|
||||||
if (group_members[0] != 0x1) { // GRP_COMDAT
|
if (group_members[0] != elf.GRP_COMDAT) {
|
||||||
// TODO convert into an error
|
// TODO convert into an error
|
||||||
log.debug("{}: unknown SHT_GROUP format", .{self.fmtPath()});
|
log.debug("{}: unknown SHT_GROUP format", .{self.fmtPath()});
|
||||||
continue;
|
continue;
|
||||||
@ -939,11 +939,12 @@ fn formatComdatGroups(
|
|||||||
_ = options;
|
_ = options;
|
||||||
const object = ctx.object;
|
const object = ctx.object;
|
||||||
const elf_file = ctx.elf_file;
|
const elf_file = ctx.elf_file;
|
||||||
try writer.writeAll(" comdat groups\n");
|
try writer.writeAll(" COMDAT groups\n");
|
||||||
for (object.comdat_groups.items) |cg_index| {
|
for (object.comdat_groups.items) |cg_index| {
|
||||||
const cg = elf_file.comdatGroup(cg_index);
|
const cg = elf_file.comdatGroup(cg_index);
|
||||||
const cg_owner = elf_file.comdatGroupOwner(cg.owner);
|
const cg_owner = elf_file.comdatGroupOwner(cg.owner);
|
||||||
if (cg_owner.file != object.index) continue;
|
if (cg_owner.file != object.index) continue;
|
||||||
|
try writer.print(" COMDAT({d})\n", .{cg_index});
|
||||||
const cg_members = object.comdatGroupMembers(cg.shndx);
|
const cg_members = object.comdatGroupMembers(cg.shndx);
|
||||||
for (cg_members) |shndx| {
|
for (cg_members) |shndx| {
|
||||||
const atom_index = object.atoms.items[shndx];
|
const atom_index = object.atoms.items[shndx];
|
||||||
|
|||||||
@ -1499,6 +1499,30 @@ pub const VerneedSection = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const ComdatGroupSection = struct {
|
||||||
|
shndx: u32,
|
||||||
|
cg_index: u32,
|
||||||
|
|
||||||
|
// pub fn size(cg: ComdatGroupSection) usize {
|
||||||
|
// return cg.members.items.len + 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn write(cg: ComdatGroupSection, elf_file: *Elf, writer: anytype) !void {
|
||||||
|
// try writeInt(@as(u32, elf.GRP_COMDAT), elf_file, writer);
|
||||||
|
// for (cg.members.items) |atom_index| {
|
||||||
|
// const atom = elf_file.atom(atom_index);
|
||||||
|
// const input_shdr = atom.inputShdr(elf_file);
|
||||||
|
// switch (input_shdr.sh_type) {
|
||||||
|
// elf.SHT_RELA => {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// else => {},
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// try writer.writeAll(mem.sliceAsBytes(cg.members.items));
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {
|
fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {
|
||||||
const entry_size = elf_file.archPtrWidthBytes();
|
const entry_size = elf_file.archPtrWidthBytes();
|
||||||
const endian = elf_file.base.options.target.cpu.arch.endian();
|
const endian = elf_file.base.options.target.cpu.arch.endian();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user