macho: fix __unwind_info sentinel entry not always being the upper bound (#16395)

macho: record highest address of unwind records before folding

---------

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
This commit is contained in:
Casey Banner 2023-07-14 07:47:00 -04:00 committed by GitHub
parent b177e17d15
commit 094cd92615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -44,6 +44,9 @@ lsdas_lookup: std.AutoHashMapUnmanaged(RecordIndex, u32) = .{},
/// List of second level pages.
pages: std.ArrayListUnmanaged(Page) = .{},
/// Upper bound (exclusive) of all the record ranges
end_boundary: u64 = 0,
const RecordIndex = u32;
const max_personalities = 3;
@ -327,6 +330,13 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void {
}
}
// Record the ending boundary before folding.
assert(records.items.len > 0);
info.end_boundary = blk: {
const last_record = records.items[records.items.len - 1];
break :blk last_record.rangeStart + last_record.rangeLength;
};
// Fold records
try info.records.ensureTotalCapacity(info.gpa, records.items.len);
try info.records_lookup.ensureTotalCapacity(info.gpa, @as(u32, @intCast(atom_indexes.items.len)));
@ -629,10 +639,10 @@ pub fn write(info: *UnwindInfo, zld: *Zld) !void {
});
}
const last_entry = info.records.items[info.records.items.len - 1];
const sentinel_address = @as(u32, @intCast(last_entry.rangeStart + last_entry.rangeLength));
// Relocate end boundary address
const end_boundary = @as(u32, @intCast(info.end_boundary + text_sect.addr - seg.vmaddr));
try writer.writeStruct(macho.unwind_info_section_header_index_entry{
.functionOffset = sentinel_address,
.functionOffset = end_boundary,
.secondLevelPagesSectionOffset = 0,
.lsdaIndexArraySectionOffset = lsda_base_offset +
@as(u32, @intCast(info.lsdas.items.len)) * @sizeOf(macho.unwind_info_section_header_lsda_index_entry),