| ... | ... | @@ -65,6 +65,16 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 65 | 65 | const rec = macho_file.getUnwindRecord(index); |
| 66 | 66 | if (rec.getFde(macho_file)) |fde| { |
| 67 | 67 | rec.enc.setDwarfSectionOffset(@intCast(fde.out_offset)); |
| 68 | if (fde.getLsdaAtom(macho_file)) |lsda| { |
| 69 | rec.lsda = lsda.atom_index; |
| 70 | rec.lsda_offset = fde.lsda_offset; |
| 71 | rec.enc.setHasLsda(true); |
| 72 | } |
| 73 | const cie = fde.getCie(macho_file); |
| 74 | if (cie.getPersonality(macho_file)) |_| { |
| 75 | const personality_index = try info.getOrPutPersonalityFunction(cie.personality.?.index); // TODO handle error |
| 76 | rec.enc.setPersonalityIndex(personality_index + 1); |
| 77 | } |
| 68 | 78 | } else if (rec.getPersonality(macho_file)) |_| { |
| 69 | 79 | const personality_index = try info.getOrPutPersonalityFunction(rec.personality.?); // TODO handle error |
| 70 | 80 | rec.enc.setPersonalityIndex(personality_index + 1); |
| ... | ... | @@ -232,11 +242,13 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 232 | 242 | } |
| 233 | 243 | |
| 234 | 244 | // Save records having an LSDA pointer |
| 245 | log.debug("LSDA pointers:", .{}); |
| 235 | 246 | try info.lsdas_lookup.ensureTotalCapacityPrecise(gpa, info.records.items.len); |
| 236 | 247 | for (info.records.items, 0..) |index, i| { |
| 237 | 248 | const rec = macho_file.getUnwindRecord(index); |
| 238 | 249 | info.lsdas_lookup.appendAssumeCapacity(@intCast(info.lsdas.items.len)); |
| 239 | | if (rec.getLsdaAtom(macho_file)) |_| { |
| 250 | if (rec.getLsdaAtom(macho_file)) |lsda| { |
| 251 | log.debug(" @{x} => lsda({d})", .{ rec.getAtomAddress(macho_file), lsda.atom_index }); |
| 240 | 252 | try info.lsdas.append(gpa, @intCast(i)); |
| 241 | 253 | } |
| 242 | 254 | } |
| ... | ... | @@ -367,7 +379,8 @@ pub const Encoding = extern struct { |
| 367 | 379 | |
| 368 | 380 | pub fn getMode(enc: Encoding) u4 { |
| 369 | 381 | comptime assert(macho.UNWIND_ARM64_MODE_MASK == macho.UNWIND_X86_64_MODE_MASK); |
| 370 | | return @as(u4, @truncate((enc.enc & macho.UNWIND_ARM64_MODE_MASK) >> 24)); |
| 382 | const shift = comptime @ctz(macho.UNWIND_ARM64_MODE_MASK); |
| 383 | return @as(u4, @truncate((enc.enc & macho.UNWIND_ARM64_MODE_MASK) >> shift)); |
| 371 | 384 | } |
| 372 | 385 | |
| 373 | 386 | pub fn isDwarf(enc: Encoding, macho_file: *MachO) bool { |
| ... | ... | @@ -380,26 +393,32 @@ pub const Encoding = extern struct { |
| 380 | 393 | } |
| 381 | 394 | |
| 382 | 395 | pub fn setMode(enc: *Encoding, mode: anytype) void { |
| 383 | | enc.enc |= @as(u32, @intCast(@intFromEnum(mode))) << 24; |
| 396 | comptime assert(macho.UNWIND_ARM64_MODE_MASK == macho.UNWIND_X86_64_MODE_MASK); |
| 397 | const shift = comptime @ctz(macho.UNWIND_ARM64_MODE_MASK); |
| 398 | enc.enc |= @as(u32, @intCast(@intFromEnum(mode))) << shift; |
| 384 | 399 | } |
| 385 | 400 | |
| 386 | 401 | pub fn hasLsda(enc: Encoding) bool { |
| 387 | | const has_lsda = @as(u1, @truncate((enc.enc & macho.UNWIND_HAS_LSDA) >> 31)); |
| 402 | const shift = comptime @ctz(macho.UNWIND_HAS_LSDA); |
| 403 | const has_lsda = @as(u1, @truncate((enc.enc & macho.UNWIND_HAS_LSDA) >> shift)); |
| 388 | 404 | return has_lsda == 1; |
| 389 | 405 | } |
| 390 | 406 | |
| 391 | 407 | pub fn setHasLsda(enc: *Encoding, has_lsda: bool) void { |
| 392 | | const mask = @as(u32, @intCast(@intFromBool(has_lsda))) << 31; |
| 408 | const shift = comptime @ctz(macho.UNWIND_HAS_LSDA); |
| 409 | const mask = @as(u32, @intCast(@intFromBool(has_lsda))) << shift; |
| 393 | 410 | enc.enc |= mask; |
| 394 | 411 | } |
| 395 | 412 | |
| 396 | 413 | pub fn getPersonalityIndex(enc: Encoding) u2 { |
| 397 | | const index = @as(u2, @truncate((enc.enc & macho.UNWIND_PERSONALITY_MASK) >> 28)); |
| 414 | const shift = comptime @ctz(macho.UNWIND_PERSONALITY_MASK); |
| 415 | const index = @as(u2, @truncate((enc.enc & macho.UNWIND_PERSONALITY_MASK) >> shift)); |
| 398 | 416 | return index; |
| 399 | 417 | } |
| 400 | 418 | |
| 401 | 419 | pub fn setPersonalityIndex(enc: *Encoding, index: u2) void { |
| 402 | | const mask = @as(u32, @intCast(index)) << 28; |
| 420 | const shift = comptime @ctz(macho.UNWIND_PERSONALITY_MASK); |
| 421 | const mask = @as(u32, @intCast(index)) << shift; |
| 403 | 422 | enc.enc |= mask; |
| 404 | 423 | } |
| 405 | 424 | |