mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
Merge pull request #24094 from jacobly0/x86_64-ld-scripts
link: support static archives that are linker scripts
This commit is contained in:
commit
98646e5cf8
22
src/link.zig
22
src/link.zig
@ -2294,9 +2294,10 @@ fn resolvePathInputLib(
|
||||
const test_path: Path = pq.path;
|
||||
// In the case of shared libraries, they might actually be "linker scripts"
|
||||
// that contain references to other libraries.
|
||||
if (pq.query.allow_so_scripts and target.ofmt == .elf and
|
||||
Compilation.classifyFileExt(test_path.sub_path) == .shared_library)
|
||||
{
|
||||
if (pq.query.allow_so_scripts and target.ofmt == .elf and switch (Compilation.classifyFileExt(test_path.sub_path)) {
|
||||
.static_library, .shared_library => true,
|
||||
else => false,
|
||||
}) {
|
||||
var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
|
||||
error.FileNotFound => return .no_match,
|
||||
else => |e| fatal("unable to search for {s} library '{'}': {s}", .{
|
||||
@ -2304,14 +2305,13 @@ fn resolvePathInputLib(
|
||||
}),
|
||||
};
|
||||
errdefer file.close();
|
||||
try ld_script_bytes.resize(gpa, @sizeOf(std.elf.Elf64_Ehdr));
|
||||
try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len));
|
||||
const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{'}': {s}", .{
|
||||
test_path, @errorName(err),
|
||||
});
|
||||
elf_file: {
|
||||
if (n != ld_script_bytes.items.len) break :elf_file;
|
||||
if (!mem.eql(u8, ld_script_bytes.items[0..4], "\x7fELF")) break :elf_file;
|
||||
// Appears to be an ELF file.
|
||||
const buf = ld_script_bytes.items[0..n];
|
||||
if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) {
|
||||
// Appears to be an ELF or archive file.
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
|
||||
}
|
||||
const stat = file.stat() catch |err|
|
||||
@ -2319,10 +2319,10 @@ fn resolvePathInputLib(
|
||||
const size = std.math.cast(u32, stat.size) orelse
|
||||
fatal("{}: linker script too big", .{test_path});
|
||||
try ld_script_bytes.resize(gpa, size);
|
||||
const buf = ld_script_bytes.items[n..];
|
||||
const n2 = file.preadAll(buf, n) catch |err|
|
||||
const buf2 = ld_script_bytes.items[n..];
|
||||
const n2 = file.preadAll(buf2, n) catch |err|
|
||||
fatal("failed to read {}: {s}", .{ test_path, @errorName(err) });
|
||||
if (n2 != buf.len) fatal("failed to read {}: unexpected end of file", .{test_path});
|
||||
if (n2 != buf2.len) fatal("failed to read {}: unexpected end of file", .{test_path});
|
||||
var diags = Diags.init(gpa);
|
||||
defer diags.deinit();
|
||||
const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items);
|
||||
|
||||
@ -99,7 +99,7 @@ copy_rel: CopyRelSection = .{},
|
||||
rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .empty,
|
||||
/// SHT_GROUP sections
|
||||
/// Applies only to a relocatable.
|
||||
comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .empty,
|
||||
group_sections: std.ArrayListUnmanaged(GroupSection) = .empty,
|
||||
|
||||
resolver: SymbolResolver = .{},
|
||||
|
||||
@ -510,7 +510,7 @@ pub fn deinit(self: *Elf) void {
|
||||
self.copy_rel.deinit(gpa);
|
||||
self.rela_dyn.deinit(gpa);
|
||||
self.rela_plt.deinit(gpa);
|
||||
self.comdat_group_sections.deinit(gpa);
|
||||
self.group_sections.deinit(gpa);
|
||||
self.dump_argv_list.deinit(gpa);
|
||||
}
|
||||
|
||||
@ -919,7 +919,7 @@ fn flushModuleInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
|
||||
&self.sections,
|
||||
self.shstrtab.items,
|
||||
self.merge_sections.items,
|
||||
self.comdat_group_sections.items,
|
||||
self.group_sections.items,
|
||||
self.zigObjectPtr(),
|
||||
self.files,
|
||||
);
|
||||
@ -1315,16 +1315,16 @@ pub fn resolveSymbols(self: *Elf) !void {
|
||||
}
|
||||
|
||||
{
|
||||
// Dedup comdat groups.
|
||||
// Dedup groups.
|
||||
var table = std.StringHashMap(Ref).init(self.base.comp.gpa);
|
||||
defer table.deinit();
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
try self.file(index).?.object.resolveComdatGroups(self, &table);
|
||||
try self.file(index).?.object.resolveGroups(self, &table);
|
||||
}
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
self.file(index).?.object.markComdatGroupsDead(self);
|
||||
self.file(index).?.object.markGroupsDead(self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3125,7 +3125,7 @@ pub fn sortShdrs(
|
||||
sections: *std.MultiArrayList(Section),
|
||||
shstrtab: []const u8,
|
||||
merge_sections: []Merge.Section,
|
||||
comdat_group_sections: []ComdatGroupSection,
|
||||
comdat_group_sections: []GroupSection,
|
||||
zig_object_ptr: ?*ZigObject,
|
||||
files: std.MultiArrayList(File.Entry),
|
||||
) !void {
|
||||
@ -4446,8 +4446,8 @@ pub fn atom(self: *Elf, ref: Ref) ?*Atom {
|
||||
return file_ptr.atom(ref.index);
|
||||
}
|
||||
|
||||
pub fn comdatGroup(self: *Elf, ref: Ref) *ComdatGroup {
|
||||
return self.file(ref.file).?.comdatGroup(ref.index);
|
||||
pub fn group(self: *Elf, ref: Ref) *Group {
|
||||
return self.file(ref.file).?.group(ref.index);
|
||||
}
|
||||
|
||||
pub fn symbol(self: *Elf, ref: Ref) ?*Symbol {
|
||||
@ -4814,7 +4814,7 @@ fn fmtDumpState(
|
||||
object.fmtCies(self),
|
||||
object.fmtFdes(self),
|
||||
object.fmtSymtab(self),
|
||||
object.fmtComdatGroups(self),
|
||||
object.fmtGroups(self),
|
||||
});
|
||||
}
|
||||
|
||||
@ -4852,9 +4852,9 @@ fn fmtDumpState(
|
||||
try writer.print("{}\n", .{self.got.fmt(self)});
|
||||
try writer.print("{}\n", .{self.plt.fmt(self)});
|
||||
|
||||
try writer.writeAll("Output COMDAT groups\n");
|
||||
for (self.comdat_group_sections.items) |cg| {
|
||||
try writer.print(" shdr({d}) : COMDAT({})\n", .{ cg.shndx, cg.cg_ref });
|
||||
try writer.writeAll("Output groups\n");
|
||||
for (self.group_sections.items) |cg| {
|
||||
try writer.print(" shdr({d}) : GROUP({})\n", .{ cg.shndx, cg.cg_ref });
|
||||
}
|
||||
|
||||
try writer.writeAll("\nOutput merge sections\n");
|
||||
@ -4934,25 +4934,26 @@ const default_entry_addr = 0x8000000;
|
||||
|
||||
pub const base_tag: link.File.Tag = .elf;
|
||||
|
||||
pub const ComdatGroup = struct {
|
||||
pub const Group = struct {
|
||||
signature_off: u32,
|
||||
file_index: File.Index,
|
||||
shndx: u32,
|
||||
members_start: u32,
|
||||
members_len: u32,
|
||||
is_comdat: bool,
|
||||
alive: bool = true,
|
||||
|
||||
pub fn file(cg: ComdatGroup, elf_file: *Elf) File {
|
||||
pub fn file(cg: Group, elf_file: *Elf) File {
|
||||
return elf_file.file(cg.file_index).?;
|
||||
}
|
||||
|
||||
pub fn signature(cg: ComdatGroup, elf_file: *Elf) [:0]const u8 {
|
||||
pub fn signature(cg: Group, elf_file: *Elf) [:0]const u8 {
|
||||
return cg.file(elf_file).object.getString(cg.signature_off);
|
||||
}
|
||||
|
||||
pub fn comdatGroupMembers(cg: ComdatGroup, elf_file: *Elf) []const u32 {
|
||||
pub fn members(cg: Group, elf_file: *Elf) []const u32 {
|
||||
const object = cg.file(elf_file).object;
|
||||
return object.comdat_group_data.items[cg.members_start..][0..cg.members_len];
|
||||
return object.group_data.items[cg.members_start..][0..cg.members_len];
|
||||
}
|
||||
|
||||
pub const Index = u32;
|
||||
@ -5310,7 +5311,7 @@ const Air = @import("../Air.zig");
|
||||
const Archive = @import("Elf/Archive.zig");
|
||||
const AtomList = @import("Elf/AtomList.zig");
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const ComdatGroupSection = synthetic_sections.ComdatGroupSection;
|
||||
const GroupSection = synthetic_sections.GroupSection;
|
||||
const CopyRelSection = synthetic_sections.CopyRelSection;
|
||||
const Diags = @import("../link.zig").Diags;
|
||||
const DynamicSection = synthetic_sections.DynamicSection;
|
||||
|
||||
@ -20,8 +20,8 @@ atoms: std.ArrayListUnmanaged(Atom) = .empty,
|
||||
atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .empty,
|
||||
atoms_extra: std.ArrayListUnmanaged(u32) = .empty,
|
||||
|
||||
comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup) = .empty,
|
||||
comdat_group_data: std.ArrayListUnmanaged(u32) = .empty,
|
||||
groups: std.ArrayListUnmanaged(Elf.Group) = .empty,
|
||||
group_data: std.ArrayListUnmanaged(u32) = .empty,
|
||||
|
||||
input_merge_sections: std.ArrayListUnmanaged(Merge.InputSection) = .empty,
|
||||
input_merge_sections_indexes: std.ArrayListUnmanaged(Merge.InputSection.Index) = .empty,
|
||||
@ -49,8 +49,8 @@ pub fn deinit(self: *Object, gpa: Allocator) void {
|
||||
self.atoms.deinit(gpa);
|
||||
self.atoms_indexes.deinit(gpa);
|
||||
self.atoms_extra.deinit(gpa);
|
||||
self.comdat_groups.deinit(gpa);
|
||||
self.comdat_group_data.deinit(gpa);
|
||||
self.groups.deinit(gpa);
|
||||
self.group_data.deinit(gpa);
|
||||
self.relocs.deinit(gpa);
|
||||
self.fdes.deinit(gpa);
|
||||
self.cies.deinit(gpa);
|
||||
@ -304,22 +304,22 @@ fn initAtoms(
|
||||
}
|
||||
const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers];
|
||||
|
||||
if (group_members[0] != elf.GRP_COMDAT) {
|
||||
return diags.failParse(path, "corrupt section group: unknown SHT_GROUP format", .{});
|
||||
switch (group_members[0]) {
|
||||
0, elf.GRP_COMDAT => {
|
||||
const group_start: u32 = @intCast(self.group_data.items.len);
|
||||
try self.group_data.appendUnalignedSlice(gpa, group_members[1..]);
|
||||
|
||||
self.group(try self.addGroup(gpa)).* = .{
|
||||
.signature_off = group_signature,
|
||||
.file_index = self.index,
|
||||
.shndx = shndx,
|
||||
.members_start = group_start,
|
||||
.members_len = @intCast(group_nmembers - 1),
|
||||
.is_comdat = group_members[0] == elf.GRP_COMDAT,
|
||||
};
|
||||
},
|
||||
else => return diags.failParse(path, "corrupt section group: unknown SHT_GROUP format", .{}),
|
||||
}
|
||||
|
||||
const group_start: u32 = @intCast(self.comdat_group_data.items.len);
|
||||
try self.comdat_group_data.appendUnalignedSlice(gpa, group_members[1..]);
|
||||
|
||||
const comdat_group_index = try self.addComdatGroup(gpa);
|
||||
const comdat_group = self.comdatGroup(comdat_group_index);
|
||||
comdat_group.* = .{
|
||||
.signature_off = group_signature,
|
||||
.file_index = self.index,
|
||||
.shndx = shndx,
|
||||
.members_start = group_start,
|
||||
.members_len = @intCast(group_nmembers - 1),
|
||||
};
|
||||
},
|
||||
|
||||
elf.SHT_SYMTAB_SHNDX => @panic("TODO SHT_SYMTAB_SHNDX"),
|
||||
@ -986,28 +986,28 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolveComdatGroups(self: *Object, elf_file: *Elf, table: anytype) !void {
|
||||
for (self.comdat_groups.items, 0..) |*cg, cgi| {
|
||||
const signature = cg.signature(elf_file);
|
||||
pub fn resolveGroups(self: *Object, elf_file: *Elf, table: anytype) !void {
|
||||
for (self.groups.items, 0..) |*g, gi| {
|
||||
const signature = g.signature(elf_file);
|
||||
const gop = try table.getOrPut(signature);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{ .index = @intCast(cgi), .file = self.index };
|
||||
gop.value_ptr.* = .{ .index = @intCast(gi), .file = self.index };
|
||||
continue;
|
||||
}
|
||||
const current = elf_file.comdatGroup(gop.value_ptr.*);
|
||||
cg.alive = false;
|
||||
const current = elf_file.group(gop.value_ptr.*);
|
||||
g.alive = false;
|
||||
if (self.index < current.file_index) {
|
||||
current.alive = false;
|
||||
cg.alive = true;
|
||||
gop.value_ptr.* = .{ .index = @intCast(cgi), .file = self.index };
|
||||
g.alive = true;
|
||||
gop.value_ptr.* = .{ .index = @intCast(gi), .file = self.index };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn markComdatGroupsDead(self: *Object, elf_file: *Elf) void {
|
||||
for (self.comdat_groups.items) |cg| {
|
||||
if (cg.alive) continue;
|
||||
for (cg.comdatGroupMembers(elf_file)) |shndx| {
|
||||
pub fn markGroupsDead(self: *Object, elf_file: *Elf) void {
|
||||
for (self.groups.items) |g| {
|
||||
if (g.alive) continue;
|
||||
for (g.members(elf_file)) |shndx| {
|
||||
const atom_index = self.atoms_indexes.items[shndx];
|
||||
if (self.atom(atom_index)) |atom_ptr| {
|
||||
atom_ptr.alive = false;
|
||||
@ -1421,15 +1421,15 @@ fn inputMergeSection(self: *Object, index: Merge.InputSection.Index) ?*Merge.Inp
|
||||
return &self.input_merge_sections.items[index];
|
||||
}
|
||||
|
||||
fn addComdatGroup(self: *Object, gpa: Allocator) !Elf.ComdatGroup.Index {
|
||||
const index = @as(Elf.ComdatGroup.Index, @intCast(self.comdat_groups.items.len));
|
||||
_ = try self.comdat_groups.addOne(gpa);
|
||||
fn addGroup(self: *Object, gpa: Allocator) !Elf.Group.Index {
|
||||
const index: Elf.Group.Index = @intCast(self.groups.items.len);
|
||||
_ = try self.groups.addOne(gpa);
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn comdatGroup(self: *Object, index: Elf.ComdatGroup.Index) *Elf.ComdatGroup {
|
||||
assert(index < self.comdat_groups.items.len);
|
||||
return &self.comdat_groups.items[index];
|
||||
pub fn group(self: *Object, index: Elf.Group.Index) *Elf.Group {
|
||||
assert(index < self.groups.items.len);
|
||||
return &self.groups.items[index];
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
@ -1550,14 +1550,14 @@ fn formatFdes(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fmtComdatGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatComdatGroups) {
|
||||
pub fn fmtGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatGroups) {
|
||||
return .{ .data = .{
|
||||
.object = self,
|
||||
.elf_file = elf_file,
|
||||
} };
|
||||
}
|
||||
|
||||
fn formatComdatGroups(
|
||||
fn formatGroups(
|
||||
ctx: FormatContext,
|
||||
comptime unused_fmt_string: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
@ -1567,13 +1567,13 @@ fn formatComdatGroups(
|
||||
_ = options;
|
||||
const object = ctx.object;
|
||||
const elf_file = ctx.elf_file;
|
||||
try writer.writeAll(" COMDAT groups\n");
|
||||
for (object.comdat_groups.items, 0..) |cg, cg_index| {
|
||||
try writer.print(" COMDAT({d})", .{cg_index});
|
||||
if (!cg.alive) try writer.writeAll(" : [*]");
|
||||
try writer.writeAll(" groups\n");
|
||||
for (object.groups.items, 0..) |g, g_index| {
|
||||
try writer.print(" {s}({d})", .{ if (g.is_comdat) "COMDAT" else "GROUP", g_index });
|
||||
if (!g.alive) try writer.writeAll(" : [*]");
|
||||
try writer.writeByte('\n');
|
||||
const cg_members = cg.comdatGroupMembers(elf_file);
|
||||
for (cg_members) |shndx| {
|
||||
const g_members = g.members(elf_file);
|
||||
for (g_members) |shndx| {
|
||||
const atom_index = object.atoms_indexes.items[shndx];
|
||||
const atom_ptr = object.atom(atom_index) orelse continue;
|
||||
try writer.print(" atom({d}) : {s}\n", .{ atom_index, atom_ptr.name(elf_file) });
|
||||
|
||||
@ -198,10 +198,10 @@ pub const File = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn comdatGroup(file: File, ind: Elf.ComdatGroup.Index) *Elf.ComdatGroup {
|
||||
pub fn group(file: File, ind: Elf.Group.Index) *Elf.Group {
|
||||
return switch (file) {
|
||||
.linker_defined, .shared_object, .zig_object => unreachable,
|
||||
.object => |x| x.comdatGroup(ind),
|
||||
.object => |x| x.group(ind),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
|
||||
&elf_file.sections,
|
||||
elf_file.shstrtab.items,
|
||||
elf_file.merge_sections.items,
|
||||
elf_file.comdat_group_sections.items,
|
||||
elf_file.group_sections.items,
|
||||
elf_file.zigObjectPtr(),
|
||||
elf_file.files,
|
||||
);
|
||||
@ -152,7 +152,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void {
|
||||
&elf_file.sections,
|
||||
elf_file.shstrtab.items,
|
||||
elf_file.merge_sections.items,
|
||||
elf_file.comdat_group_sections.items,
|
||||
elf_file.group_sections.items,
|
||||
elf_file.zigObjectPtr(),
|
||||
elf_file.files,
|
||||
);
|
||||
@ -233,19 +233,19 @@ fn initSections(elf_file: *Elf) !void {
|
||||
);
|
||||
}
|
||||
|
||||
try initComdatGroups(elf_file);
|
||||
try initGroups(elf_file);
|
||||
try elf_file.initSymtab();
|
||||
try elf_file.initShStrtab();
|
||||
}
|
||||
|
||||
fn initComdatGroups(elf_file: *Elf) !void {
|
||||
fn initGroups(elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
|
||||
for (elf_file.objects.items) |index| {
|
||||
const object = elf_file.file(index).?.object;
|
||||
for (object.comdat_groups.items, 0..) |cg, cg_index| {
|
||||
for (object.groups.items, 0..) |cg, cg_index| {
|
||||
if (!cg.alive) continue;
|
||||
const cg_sec = try elf_file.comdat_group_sections.addOne(gpa);
|
||||
const cg_sec = try elf_file.group_sections.addOne(gpa);
|
||||
cg_sec.* = .{
|
||||
.shndx = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".group"),
|
||||
@ -292,12 +292,12 @@ fn updateSectionSizes(elf_file: *Elf) !void {
|
||||
}
|
||||
|
||||
try elf_file.updateSymtabSize();
|
||||
updateComdatGroupsSizes(elf_file);
|
||||
updateGroupsSizes(elf_file);
|
||||
elf_file.updateShStrtabSize();
|
||||
}
|
||||
|
||||
fn updateComdatGroupsSizes(elf_file: *Elf) void {
|
||||
for (elf_file.comdat_group_sections.items) |cg| {
|
||||
fn updateGroupsSizes(elf_file: *Elf) void {
|
||||
for (elf_file.group_sections.items) |cg| {
|
||||
const shdr = &elf_file.sections.items(.shdr)[cg.shndx];
|
||||
shdr.sh_size = cg.size(elf_file);
|
||||
shdr.sh_link = elf_file.section_indexes.symtab.?;
|
||||
@ -436,21 +436,21 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
|
||||
try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset);
|
||||
}
|
||||
|
||||
try writeComdatGroups(elf_file);
|
||||
try writeGroups(elf_file);
|
||||
try elf_file.writeSymtab();
|
||||
try elf_file.writeShStrtab();
|
||||
}
|
||||
|
||||
fn writeComdatGroups(elf_file: *Elf) !void {
|
||||
fn writeGroups(elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
for (elf_file.comdat_group_sections.items) |cgs| {
|
||||
for (elf_file.group_sections.items) |cgs| {
|
||||
const shdr = elf_file.sections.items(.shdr)[cgs.shndx];
|
||||
const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
try cgs.write(elf_file, buffer.writer());
|
||||
assert(buffer.items.len == sh_size);
|
||||
log.debug("writing COMDAT group from 0x{x} to 0x{x}", .{
|
||||
log.debug("writing group from 0x{x} to 0x{x}", .{
|
||||
shdr.sh_offset,
|
||||
shdr.sh_offset + shdr.sh_size,
|
||||
});
|
||||
|
||||
@ -1484,33 +1484,33 @@ pub const VerneedSection = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const ComdatGroupSection = struct {
|
||||
pub const GroupSection = struct {
|
||||
shndx: u32,
|
||||
cg_ref: Elf.Ref,
|
||||
|
||||
fn comdatGroup(cgs: ComdatGroupSection, elf_file: *Elf) *Elf.ComdatGroup {
|
||||
fn group(cgs: GroupSection, elf_file: *Elf) *Elf.Group {
|
||||
const cg_file = elf_file.file(cgs.cg_ref.file).?;
|
||||
return cg_file.object.comdatGroup(cgs.cg_ref.index);
|
||||
return cg_file.object.group(cgs.cg_ref.index);
|
||||
}
|
||||
|
||||
pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) *Symbol {
|
||||
const cg = cgs.comdatGroup(elf_file);
|
||||
pub fn symbol(cgs: GroupSection, elf_file: *Elf) *Symbol {
|
||||
const cg = cgs.group(elf_file);
|
||||
const object = cg.file(elf_file).object;
|
||||
const shdr = object.shdrs.items[cg.shndx];
|
||||
return &object.symbols.items[shdr.sh_info];
|
||||
}
|
||||
|
||||
pub fn size(cgs: ComdatGroupSection, elf_file: *Elf) usize {
|
||||
const cg = cgs.comdatGroup(elf_file);
|
||||
const members = cg.comdatGroupMembers(elf_file);
|
||||
pub fn size(cgs: GroupSection, elf_file: *Elf) usize {
|
||||
const cg = cgs.group(elf_file);
|
||||
const members = cg.members(elf_file);
|
||||
return (members.len + 1) * @sizeOf(u32);
|
||||
}
|
||||
|
||||
pub fn write(cgs: ComdatGroupSection, elf_file: *Elf, writer: anytype) !void {
|
||||
const cg = cgs.comdatGroup(elf_file);
|
||||
pub fn write(cgs: GroupSection, elf_file: *Elf, writer: anytype) !void {
|
||||
const cg = cgs.group(elf_file);
|
||||
const object = cg.file(elf_file).object;
|
||||
const members = cg.comdatGroupMembers(elf_file);
|
||||
try writer.writeInt(u32, elf.GRP_COMDAT, .little);
|
||||
const members = cg.members(elf_file);
|
||||
try writer.writeInt(u32, if (cg.is_comdat) elf.GRP_COMDAT else 0, .little);
|
||||
for (members) |shndx| {
|
||||
const shdr = object.shdrs.items[shndx];
|
||||
switch (shdr.sh_type) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user