mirror of
https://github.com/ziglang/zig.git
synced 2024-12-02 01:00:19 +00:00
elf: move merge subsections ownership into merge sections
This commit is contained in:
parent
24126f5382
commit
0701646beb
@ -208,9 +208,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{},
|
||||
|
||||
/// List of output merge sections with deduped contents.
|
||||
merge_sections: std.ArrayListUnmanaged(MergeSection) = .{},
|
||||
/// List of output merge subsections.
|
||||
/// Each subsection is akin to Atom but belongs to a MergeSection.
|
||||
merge_subsections: std.ArrayListUnmanaged(MergeSubsection) = .{},
|
||||
|
||||
/// Table of last atom index in a section and matching atom free list if any.
|
||||
last_atom_and_free_list_table: LastAtomAndFreeListTable = .{},
|
||||
@ -497,7 +494,6 @@ pub fn deinit(self: *Elf) void {
|
||||
sect.deinit(gpa);
|
||||
}
|
||||
self.merge_sections.deinit(gpa);
|
||||
self.merge_subsections.deinit(gpa);
|
||||
for (self.last_atom_and_free_list_table.values()) |*value| {
|
||||
value.free_list.deinit(gpa);
|
||||
}
|
||||
@ -3288,12 +3284,13 @@ fn checkDuplicates(self: *Elf) !void {
|
||||
}
|
||||
|
||||
pub fn addCommentString(self: *Elf) !void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const msec_index = try self.getOrCreateMergeSection(".comment", elf.SHF_MERGE | elf.SHF_STRINGS, elf.SHT_PROGBITS);
|
||||
const msec = self.mergeSection(msec_index);
|
||||
const res = try msec.insertZ(self.base.comp.gpa, "zig " ++ builtin.zig_version_string);
|
||||
const res = try msec.insertZ(gpa, "zig " ++ builtin.zig_version_string);
|
||||
if (res.found_existing) return;
|
||||
const msub_index = try self.addMergeSubsection();
|
||||
const msub = self.mergeSubsection(msub_index);
|
||||
const msub_index = try msec.addMergeSubsection(gpa);
|
||||
const msub = msec.mergeSubsection(msub_index);
|
||||
msub.merge_section_index = msec_index;
|
||||
msub.string_index = res.key.pos;
|
||||
msub.alignment = .@"1";
|
||||
@ -3340,8 +3337,8 @@ pub fn finalizeMergeSections(self: *Elf) !void {
|
||||
pub fn updateMergeSectionSizes(self: *Elf) !void {
|
||||
for (self.merge_sections.items) |*msec| {
|
||||
const shdr = &self.shdrs.items[msec.output_section_index];
|
||||
for (msec.subsections.items) |msub_index| {
|
||||
const msub = self.mergeSubsection(msub_index);
|
||||
for (msec.finalized_subsections.items) |msub_index| {
|
||||
const msub = msec.mergeSubsection(msub_index);
|
||||
assert(msub.alive);
|
||||
const offset = msub.alignment.forward(shdr.sh_size);
|
||||
const padding = offset - shdr.sh_size;
|
||||
@ -3357,14 +3354,14 @@ pub fn writeMergeSections(self: *Elf) !void {
|
||||
var buffer = std.ArrayList(u8).init(gpa);
|
||||
defer buffer.deinit();
|
||||
|
||||
for (self.merge_sections.items) |msec| {
|
||||
for (self.merge_sections.items) |*msec| {
|
||||
const shdr = self.shdrs.items[msec.output_section_index];
|
||||
const size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
||||
try buffer.ensureTotalCapacity(size);
|
||||
buffer.appendNTimesAssumeCapacity(0, size);
|
||||
|
||||
for (msec.subsections.items) |msub_index| {
|
||||
const msub = self.mergeSubsection(msub_index);
|
||||
for (msec.finalized_subsections.items) |msub_index| {
|
||||
const msub = msec.mergeSubsection(msub_index);
|
||||
assert(msub.alive);
|
||||
const string = msub.getString(self);
|
||||
const off = math.cast(usize, msub.value) orelse return error.Overflow;
|
||||
@ -3384,7 +3381,7 @@ fn initOutputSections(self: *Elf) !void {
|
||||
|
||||
pub fn initMergeSections(self: *Elf) !void {
|
||||
for (self.merge_sections.items) |*msec| {
|
||||
if (msec.subsections.items.len == 0) continue;
|
||||
if (msec.finalized_subsections.items.len == 0) continue;
|
||||
const name = msec.name(self);
|
||||
const shndx = self.sectionByName(name) orelse try self.addSection(.{
|
||||
.name = name,
|
||||
@ -3393,9 +3390,9 @@ pub fn initMergeSections(self: *Elf) !void {
|
||||
});
|
||||
msec.output_section_index = shndx;
|
||||
|
||||
var entsize = self.mergeSubsection(msec.subsections.items[0]).entsize;
|
||||
for (msec.subsections.items) |index| {
|
||||
const msub = self.mergeSubsection(index);
|
||||
var entsize = msec.mergeSubsection(msec.finalized_subsections.items[0]).entsize;
|
||||
for (msec.finalized_subsections.items) |msub_index| {
|
||||
const msub = msec.mergeSubsection(msub_index);
|
||||
entsize = @min(entsize, msub.entsize);
|
||||
}
|
||||
const shdr = &self.shdrs.items[shndx];
|
||||
@ -5706,18 +5703,6 @@ pub fn zigObjectPtr(self: *Elf) ?*ZigObject {
|
||||
return self.file(index).?.zig_object;
|
||||
}
|
||||
|
||||
pub fn addMergeSubsection(self: *Elf) !MergeSubsection.Index {
|
||||
const index: MergeSubsection.Index = @intCast(self.merge_subsections.items.len);
|
||||
const msec = try self.merge_subsections.addOne(self.base.comp.gpa);
|
||||
msec.* = .{};
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn mergeSubsection(self: *Elf, index: MergeSubsection.Index) *MergeSubsection {
|
||||
assert(index < self.merge_subsections.items.len);
|
||||
return &self.merge_subsections.items[index];
|
||||
}
|
||||
|
||||
pub fn getOrCreateMergeSection(self: *Elf, name: []const u8, flags: u64, @"type": u32) !MergeSection.Index {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const out_name = name: {
|
||||
|
@ -47,7 +47,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) void {
|
||||
const global = elf_file.symbol(index);
|
||||
if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) {
|
||||
global.value = 0;
|
||||
global.atom_ref = .{ .index = 0, .file = 0 };
|
||||
global.ref = .{ .index = 0, .file = 0 };
|
||||
global.file_index = self.index;
|
||||
global.esym_index = sym_idx;
|
||||
global.version_index = elf_file.default_sym_version;
|
||||
|
@ -388,7 +388,7 @@ fn initSymtab(self: *Object, allocator: Allocator, elf_file: *Elf) !void {
|
||||
sym_ptr.esym_index = @as(u32, @intCast(i));
|
||||
sym_ptr.file_index = self.index;
|
||||
if (sym.st_shndx != elf.SHN_ABS) {
|
||||
sym_ptr.atom_ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index };
|
||||
sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index };
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,7 +575,7 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void {
|
||||
if (self.asFile().symbolRank(esym, !self.alive) < global.symbolRank(elf_file)) {
|
||||
switch (esym.st_shndx) {
|
||||
elf.SHN_ABS, elf.SHN_COMMON => {},
|
||||
else => global.atom_ref = .{
|
||||
else => global.ref = .{
|
||||
.index = self.atoms_indexes.items[esym.st_shndx],
|
||||
.file = self.index,
|
||||
},
|
||||
@ -609,7 +609,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {
|
||||
};
|
||||
|
||||
global.value = 0;
|
||||
global.atom_ref = .{ .index = 0, .file = 0 };
|
||||
global.ref = .{ .index = 0, .file = 0 };
|
||||
global.esym_index = esym_index;
|
||||
global.file_index = self.index;
|
||||
global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version;
|
||||
@ -630,7 +630,7 @@ pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void {
|
||||
}
|
||||
|
||||
global.value = 0;
|
||||
global.atom_ref = .{ .index = 0, .file = 0 };
|
||||
global.ref = .{ .index = 0, .file = 0 };
|
||||
global.esym_index = esym_index;
|
||||
global.file_index = self.index;
|
||||
}
|
||||
@ -785,8 +785,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void {
|
||||
const string = imsec.bytes.items[str.pos..][0..str.len];
|
||||
const res = try msec.insert(gpa, string);
|
||||
if (!res.found_existing) {
|
||||
const msub_index = try elf_file.addMergeSubsection();
|
||||
const msub = elf_file.mergeSubsection(msub_index);
|
||||
const msub_index = try msec.addMergeSubsection(gpa);
|
||||
const msub = msec.mergeSubsection(msub_index);
|
||||
msub.merge_section_index = imsec.merge_section_index;
|
||||
msub.string_index = res.key.pos;
|
||||
msub.alignment = atom_ptr.alignment;
|
||||
@ -810,7 +810,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void {
|
||||
const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx];
|
||||
const imsec = self.inputMergeSection(imsec_index) orelse continue;
|
||||
if (imsec.offsets.items.len == 0) continue;
|
||||
const msub_index, const offset = imsec.findSubsection(@intCast(esym.st_value)) orelse {
|
||||
const res = imsec.findSubsection(@intCast(esym.st_value)) orelse {
|
||||
var err = try elf_file.base.addErrorWithNotes(2);
|
||||
try err.addMsg("invalid symbol value: {x}", .{esym.st_value});
|
||||
try err.addNote("for symbol {s}", .{sym.name(elf_file)});
|
||||
@ -818,9 +818,9 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void {
|
||||
return error.MalformedObject;
|
||||
};
|
||||
|
||||
try sym.addExtra(.{ .subsection = msub_index }, elf_file);
|
||||
sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index };
|
||||
sym.flags.merge_subsection = true;
|
||||
sym.value = offset;
|
||||
sym.value = res.offset;
|
||||
}
|
||||
|
||||
for (self.atoms_indexes.items) |atom_index| {
|
||||
@ -835,28 +835,27 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void {
|
||||
const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx];
|
||||
const imsec = self.inputMergeSection(imsec_index) orelse continue;
|
||||
if (imsec.offsets.items.len == 0) continue;
|
||||
const msub_index, const offset = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse {
|
||||
const msec = elf_file.mergeSection(imsec.merge_section_index);
|
||||
const res = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse {
|
||||
var err = try elf_file.base.addErrorWithNotes(1);
|
||||
try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset});
|
||||
try err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
|
||||
return error.MalformedObject;
|
||||
};
|
||||
const msub = elf_file.mergeSubsection(msub_index);
|
||||
const msec = msub.mergeSection(elf_file);
|
||||
|
||||
const out_sym_idx: u64 = @intCast(self.symbols.items.len);
|
||||
try self.symbols.ensureUnusedCapacity(gpa, 1);
|
||||
const name = try std.fmt.allocPrint(gpa, "{s}$subsection{d}", .{ msec.name(elf_file), msub_index });
|
||||
const name = try std.fmt.allocPrint(gpa, "{s}$subsection{d}", .{ msec.name(elf_file), res.msub_index });
|
||||
defer gpa.free(name);
|
||||
const sym_index = try elf_file.addSymbol();
|
||||
const sym = elf_file.symbol(sym_index);
|
||||
sym.* = .{
|
||||
.value = @bitCast(@as(i64, @intCast(offset)) - rel.r_addend),
|
||||
.value = @bitCast(@as(i64, @intCast(res.offset)) - rel.r_addend),
|
||||
.name_offset = try self.addString(gpa, name),
|
||||
.esym_index = rel.r_sym(),
|
||||
.file_index = self.index,
|
||||
};
|
||||
try sym.addExtra(.{ .subsection = msub_index }, elf_file);
|
||||
sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index };
|
||||
sym.flags.merge_subsection = true;
|
||||
self.symbols.addOneAssumeCapacity().* = sym_index;
|
||||
rel.r_info = (out_sym_idx << 32) | rel.r_type();
|
||||
@ -920,7 +919,7 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
|
||||
try self.atoms_indexes.append(gpa, atom_index);
|
||||
|
||||
global.value = 0;
|
||||
global.atom_ref = .{ .index = atom_index, .file = self.index };
|
||||
global.ref = .{ .index = atom_index, .file = self.index };
|
||||
global.flags.weak = false;
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ pub fn resolveSymbols(self: *SharedObject, elf_file: *Elf) void {
|
||||
const global = elf_file.symbol(index);
|
||||
if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) {
|
||||
global.value = @intCast(this_sym.st_value);
|
||||
global.atom_ref = .{ .index = 0, .file = 0 };
|
||||
global.ref = .{ .index = 0, .file = 0 };
|
||||
global.esym_index = esym_index;
|
||||
global.version_index = self.versyms.items[esym_index];
|
||||
global.file_index = self.index;
|
||||
|
@ -9,9 +9,9 @@ name_offset: u32 = 0,
|
||||
/// Index of file where this symbol is defined.
|
||||
file_index: File.Index = 0,
|
||||
|
||||
/// Reference to Atom containing this symbol if any.
|
||||
/// Use `atom` to get the pointer to the atom.
|
||||
atom_ref: Elf.Ref = .{ .index = 0, .file = 0 },
|
||||
/// Reference to Atom or merge subsection containing this symbol if any.
|
||||
/// Use `atom` or `mergeSubsection` to get the pointer to the atom.
|
||||
ref: Elf.Ref = .{ .index = 0, .file = 0 },
|
||||
|
||||
/// Assigned output section index for this symbol.
|
||||
output_section_index: u32 = 0,
|
||||
@ -71,14 +71,15 @@ pub fn name(symbol: Symbol, elf_file: *Elf) [:0]const u8 {
|
||||
}
|
||||
|
||||
pub fn atom(symbol: Symbol, elf_file: *Elf) ?*Atom {
|
||||
const file_ptr = elf_file.file(symbol.atom_ref.file) orelse return null;
|
||||
return file_ptr.atom(symbol.atom_ref.index);
|
||||
if (symbol.flags.merge_subsection) return null;
|
||||
const file_ptr = elf_file.file(symbol.ref.file) orelse return null;
|
||||
return file_ptr.atom(symbol.ref.index);
|
||||
}
|
||||
|
||||
pub fn mergeSubsection(symbol: Symbol, elf_file: *Elf) ?*MergeSubsection {
|
||||
if (!symbol.flags.merge_subsection) return null;
|
||||
const extras = symbol.extra(elf_file).?;
|
||||
return elf_file.mergeSubsection(extras.subsection);
|
||||
const msec = elf_file.mergeSection(symbol.ref.file);
|
||||
return msec.mergeSubsection(symbol.ref.index);
|
||||
}
|
||||
|
||||
pub fn file(symbol: Symbol, elf_file: *Elf) ?File {
|
||||
@ -262,7 +263,6 @@ const AddExtraOpts = struct {
|
||||
gottp: ?u32 = null,
|
||||
tlsdesc: ?u32 = null,
|
||||
zig_got: ?u32 = null,
|
||||
subsection: ?u32 = null,
|
||||
};
|
||||
|
||||
pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void {
|
||||
@ -488,7 +488,7 @@ pub const Extra = struct {
|
||||
gottp: u32 = 0,
|
||||
tlsdesc: u32 = 0,
|
||||
zig_got: u32 = 0,
|
||||
subsection: u32 = 0,
|
||||
merge_section: u32 = 0,
|
||||
};
|
||||
|
||||
pub const Index = u32;
|
||||
|
@ -291,7 +291,7 @@ pub fn newAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index {
|
||||
|
||||
const symbol_ptr = elf_file.symbol(symbol_index);
|
||||
symbol_ptr.file_index = self.index;
|
||||
symbol_ptr.atom_ref = .{ .index = atom_index, .file = self.index };
|
||||
symbol_ptr.ref = .{ .index = atom_index, .file = self.index };
|
||||
|
||||
self.local_esyms.items(.shndx)[esym_index] = atom_index;
|
||||
self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM;
|
||||
@ -342,7 +342,7 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void {
|
||||
else => unreachable,
|
||||
};
|
||||
global.value = @intCast(esym.st_value);
|
||||
global.atom_ref = .{ .index = atom_index, .file = self.index };
|
||||
global.ref = .{ .index = atom_index, .file = self.index };
|
||||
global.esym_index = esym_index;
|
||||
global.file_index = self.index;
|
||||
global.version_index = elf_file.default_sym_version;
|
||||
@ -371,7 +371,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void {
|
||||
};
|
||||
|
||||
global.value = 0;
|
||||
global.atom_ref = .{ .index = 0, .file = 0 };
|
||||
global.ref = .{ .index = 0, .file = 0 };
|
||||
global.esym_index = esym_index;
|
||||
global.file_index = self.index;
|
||||
global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version;
|
||||
@ -392,7 +392,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void {
|
||||
}
|
||||
|
||||
global.value = 0;
|
||||
global.atom_ref = .{ .index = 0, .file = 0 };
|
||||
global.ref = .{ .index = 0, .file = 0 };
|
||||
global.esym_index = esym_index;
|
||||
global.file_index = self.index;
|
||||
}
|
||||
|
@ -10,12 +10,14 @@ pub const MergeSection = struct {
|
||||
IndexContext,
|
||||
std.hash_map.default_max_load_percentage,
|
||||
) = .{},
|
||||
subsections: std.ArrayListUnmanaged(MergeSubsection.Index) = .{},
|
||||
subsections: std.ArrayListUnmanaged(MergeSubsection) = .{},
|
||||
finalized_subsections: std.ArrayListUnmanaged(MergeSubsection.Index) = .{},
|
||||
|
||||
pub fn deinit(msec: *MergeSection, allocator: Allocator) void {
|
||||
msec.bytes.deinit(allocator);
|
||||
msec.table.deinit(allocator);
|
||||
msec.subsections.deinit(allocator);
|
||||
msec.finalized_subsections.deinit(allocator);
|
||||
}
|
||||
|
||||
pub fn name(msec: MergeSection, elf_file: *Elf) [:0]const u8 {
|
||||
@ -60,23 +62,25 @@ pub const MergeSection = struct {
|
||||
/// Sorts all owned subsections.
|
||||
pub fn finalize(msec: *MergeSection, elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
try msec.subsections.ensureTotalCapacityPrecise(gpa, msec.table.count());
|
||||
try msec.finalized_subsections.ensureTotalCapacityPrecise(gpa, msec.subsections.items.len);
|
||||
|
||||
var it = msec.table.iterator();
|
||||
while (it.next()) |entry| {
|
||||
const msub = elf_file.mergeSubsection(entry.value_ptr.*);
|
||||
const msub = msec.mergeSubsection(entry.value_ptr.*);
|
||||
if (!msub.alive) continue;
|
||||
msec.subsections.appendAssumeCapacity(entry.value_ptr.*);
|
||||
msec.finalized_subsections.appendAssumeCapacity(entry.value_ptr.*);
|
||||
}
|
||||
msec.table.clearAndFree(gpa);
|
||||
|
||||
const sortFn = struct {
|
||||
pub fn sortFn(ctx: *Elf, lhs: MergeSubsection.Index, rhs: MergeSubsection.Index) bool {
|
||||
pub fn sortFn(ctx: *MergeSection, lhs: MergeSubsection.Index, rhs: MergeSubsection.Index) bool {
|
||||
const lhs_msub = ctx.mergeSubsection(lhs);
|
||||
const rhs_msub = ctx.mergeSubsection(rhs);
|
||||
if (lhs_msub.alignment.compareStrict(.eq, rhs_msub.alignment)) {
|
||||
if (lhs_msub.size == rhs_msub.size) {
|
||||
return mem.order(u8, lhs_msub.getString(ctx), rhs_msub.getString(ctx)) == .lt;
|
||||
const lhs_string = ctx.bytes.items[lhs_msub.string_index..][0..lhs_msub.size];
|
||||
const rhs_string = ctx.bytes.items[rhs_msub.string_index..][0..rhs_msub.size];
|
||||
return mem.order(u8, lhs_string, rhs_string) == .lt;
|
||||
}
|
||||
return lhs_msub.size < rhs_msub.size;
|
||||
}
|
||||
@ -84,7 +88,19 @@ pub const MergeSection = struct {
|
||||
}
|
||||
}.sortFn;
|
||||
|
||||
std.mem.sort(MergeSubsection.Index, msec.subsections.items, elf_file, sortFn);
|
||||
std.mem.sort(MergeSubsection.Index, msec.finalized_subsections.items, msec, sortFn);
|
||||
}
|
||||
|
||||
pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index {
|
||||
const index: MergeSubsection.Index = @intCast(msec.subsections.items.len);
|
||||
const msub = try msec.subsections.addOne(allocator);
|
||||
msub.* = .{};
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn mergeSubsection(msec: *MergeSection, index: MergeSubsection.Index) *MergeSubsection {
|
||||
assert(index < msec.subsections.items.len);
|
||||
return &msec.subsections.items[index];
|
||||
}
|
||||
|
||||
pub const IndexContext = struct {
|
||||
@ -154,8 +170,8 @@ pub const MergeSection = struct {
|
||||
msec.type,
|
||||
msec.flags,
|
||||
});
|
||||
for (msec.subsections.items) |index| {
|
||||
try writer.print(" {}\n", .{elf_file.mergeSubsection(index).fmt(elf_file)});
|
||||
for (msec.subsections.items) |msub| {
|
||||
try writer.print(" {}\n", .{msub.fmt(elf_file)});
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,18 +266,26 @@ pub const InputMergeSection = struct {
|
||||
// TODO: imsec.strings.clearAndFree(allocator);
|
||||
}
|
||||
|
||||
pub fn findSubsection(imsec: InputMergeSection, offset: u32) ?struct { MergeSubsection.Index, u32 } {
|
||||
const FindSubsectionResult = struct {
|
||||
msub_index: MergeSubsection.Index,
|
||||
offset: u32,
|
||||
};
|
||||
|
||||
pub fn findSubsection(imsec: InputMergeSection, offset: u32) ?FindSubsectionResult {
|
||||
// TODO: binary search
|
||||
for (imsec.offsets.items, 0..) |off, index| {
|
||||
if (offset < off) return .{
|
||||
imsec.subsections.items[index - 1],
|
||||
offset - imsec.offsets.items[index - 1],
|
||||
.msub_index = imsec.subsections.items[index - 1],
|
||||
.offset = offset - imsec.offsets.items[index - 1],
|
||||
};
|
||||
}
|
||||
const last = imsec.offsets.items.len - 1;
|
||||
const last_off = imsec.offsets.items[last];
|
||||
const last_len = imsec.strings.items[last].len;
|
||||
if (offset < last_off + last_len) return .{ imsec.subsections.items[last], offset - last_off };
|
||||
if (offset < last_off + last_len) return .{
|
||||
.msub_index = imsec.subsections.items[last],
|
||||
.offset = offset - last_off,
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user