| ... | @@ -68,13 +68,18 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { | ... | @@ -68,13 +68,18 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 68 | for (info.records.items) |ref| { | 68 | for (info.records.items) |ref| { |
| 69 | const rec = ref.getUnwindRecord(macho_file); | 69 | const rec = ref.getUnwindRecord(macho_file); |
| 70 | if (rec.getFde(macho_file)) |fde| { | 70 | if (rec.getFde(macho_file)) |fde| { |
| 71 | // The unwinder will start looking for a matching CFI at the offset we specify here; it | 71 | // The unwinder will look for the DWARF entry starting at the hint, |
| 72 | // isn't actually an offset to the exact CFI for this record. A consequence of this is | 72 | // assuming the hint points to a valid CFI record start. If it |
| 73 | // that if the offset doesn't fit in 24 bits, we can just leave it as zero so the | 73 | // fails to find the record, it proceeds in a linear search through |
| 74 | // unwinder starts searching at the beginning of the section. | 74 | // the contiguous CFI records from the hint until the end of the |
| 75 | if (std.math.cast(u24, fde.out_offset)) |off| { | 75 | // section. Ideally, in the case where the offset is too large to |
| 76 | rec.enc.setDwarfSectionOffset(off); | 76 | // be encoded, we would instead encode the largest possible offset |
| 77 | } | 77 | // to a valid CFI record, but since we don't keep track of that, |
| | 78 | // just encode zero -- the start of the section is always the start |
| | 79 | // of a CFI record. |
| | 80 | const hint = std.math.cast(u24, fde.out_offset) orelse 0; |
| | 81 | rec.enc.setDwarfSectionOffset(hint); |
| | 82 | |
| 78 | if (fde.getLsdaAtom(macho_file)) |lsda| { | 83 | if (fde.getLsdaAtom(macho_file)) |lsda| { |
| 79 | rec.lsda = lsda.atom_index; | 84 | rec.lsda = lsda.atom_index; |
| 80 | rec.lsda_offset = fde.lsda_offset; | 85 | rec.lsda_offset = fde.lsda_offset; |