| ... | @@ -65,6 +65,16 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { | ... | @@ -65,6 +65,16 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 65 | const rec = macho_file.getUnwindRecord(index); | 65 | const rec = macho_file.getUnwindRecord(index); |
| 66 | if (rec.getFde(macho_file)) |fde| { | 66 | if (rec.getFde(macho_file)) |fde| { |
| 67 | rec.enc.setDwarfSectionOffset(@intCast(fde.out_offset)); | 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 | } else if (rec.getPersonality(macho_file)) |_| { | 78 | } else if (rec.getPersonality(macho_file)) |_| { |
| 69 | const personality_index = try info.getOrPutPersonalityFunction(rec.personality.?); // TODO handle error | 79 | const personality_index = try info.getOrPutPersonalityFunction(rec.personality.?); // TODO handle error |
| 70 | rec.enc.setPersonalityIndex(personality_index + 1); | 80 | rec.enc.setPersonalityIndex(personality_index + 1); |
| ... | @@ -232,11 +242,13 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { | ... | @@ -232,11 +242,13 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 232 | } | 242 | } |
| 233 | | 243 | |
| 234 | // Save records having an LSDA pointer | 244 | // Save records having an LSDA pointer |
| | 245 | log.debug("LSDA pointers:", .{}); |
| 235 | try info.lsdas_lookup.ensureTotalCapacityPrecise(gpa, info.records.items.len); | 246 | try info.lsdas_lookup.ensureTotalCapacityPrecise(gpa, info.records.items.len); |
| 236 | for (info.records.items, 0..) |index, i| { | 247 | for (info.records.items, 0..) |index, i| { |
| 237 | const rec = macho_file.getUnwindRecord(index); | 248 | const rec = macho_file.getUnwindRecord(index); |
| 238 | info.lsdas_lookup.appendAssumeCapacity(@intCast(info.lsdas.items.len)); | 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 | try info.lsdas.append(gpa, @intCast(i)); | 252 | try info.lsdas.append(gpa, @intCast(i)); |
| 241 | } | 253 | } |
| 242 | } | 254 | } |
| ... | @@ -367,7 +379,8 @@ pub const Encoding = extern struct { | ... | @@ -367,7 +379,8 @@ pub const Encoding = extern struct { |
| 367 | | 379 | |
| 368 | pub fn getMode(enc: Encoding) u4 { | 380 | pub fn getMode(enc: Encoding) u4 { |
| 369 | comptime assert(macho.UNWIND_ARM64_MODE_MASK == macho.UNWIND_X86_64_MODE_MASK); | 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 | pub fn isDwarf(enc: Encoding, macho_file: *MachO) bool { | 386 | pub fn isDwarf(enc: Encoding, macho_file: *MachO) bool { |
| ... | @@ -380,26 +393,32 @@ pub const Encoding = extern struct { | ... | @@ -380,26 +393,32 @@ pub const Encoding = extern struct { |
| 380 | } | 393 | } |
| 381 | | 394 | |
| 382 | pub fn setMode(enc: *Encoding, mode: anytype) void { | 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 | pub fn hasLsda(enc: Encoding) bool { | 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 | return has_lsda == 1; | 404 | return has_lsda == 1; |
| 389 | } | 405 | } |
| 390 | | 406 | |
| 391 | pub fn setHasLsda(enc: *Encoding, has_lsda: bool) void { | 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 | enc.enc |= mask; | 410 | enc.enc |= mask; |
| 394 | } | 411 | } |
| 395 | | 412 | |
| 396 | pub fn getPersonalityIndex(enc: Encoding) u2 { | 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 | return index; | 416 | return index; |
| 399 | } | 417 | } |
| 400 | | 418 | |
| 401 | pub fn setPersonalityIndex(enc: *Encoding, index: u2) void { | 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 | enc.enc |= mask; | 422 | enc.enc |= mask; |
| 404 | } | 423 | } |
| 405 | | 424 | |