Skip to content

Commit

Permalink
Special case Rust unwind terminate for forced unwind
Browse files Browse the repository at this point in the history
This changes the personality to match the current libstd impl.
  • Loading branch information
nbdd0121 committed Aug 24, 2024
1 parent c7c2baf commit 2f19304
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 29 additions & 12 deletions src/personality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ enum EHAction {
None,
Cleanup(usize),
Catch(usize),
Filter(usize),
Terminate,
}

fn parse_pointer_encoding(input: &mut StaticSlice) -> gimli::Result<constants::DwEhPe> {
Expand Down Expand Up @@ -92,31 +94,31 @@ fn find_eh_action(

let call_site_encoding = parse_pointer_encoding(reader)?;
let call_site_table_length = reader.read_uleb128()?;
reader.truncate(call_site_table_length as _)?;
let (mut call_site_table, mut action_table) = reader.split_at(call_site_table_length as _);

while !reader.is_empty() {
while !call_site_table.is_empty() {
let cs_start = unsafe {
deref_pointer(parse_encoded_pointer(
call_site_encoding,
unwind_ctx,
reader,
&mut call_site_table,
)?)
};
let cs_len = unsafe {
deref_pointer(parse_encoded_pointer(
call_site_encoding,
unwind_ctx,
reader,
&mut call_site_table,
)?)
};
let cs_lpad = unsafe {
deref_pointer(parse_encoded_pointer(
call_site_encoding,
unwind_ctx,
reader,
&mut call_site_table,
)?)
};
let cs_action = reader.read_uleb128()?;
let cs_action = call_site_table.read_uleb128()?;
if ip < func_start + cs_start {
break;
}
Expand All @@ -125,14 +127,23 @@ fn find_eh_action(
return Ok(EHAction::None);
} else {
let lpad = lpad_base + cs_lpad;
return Ok(match cs_action {
0 => EHAction::Cleanup(lpad),
_ => EHAction::Catch(lpad),
if cs_action == 0 {
return Ok(EHAction::Cleanup(lpad));
}

action_table.skip((cs_action - 1) as _)?;
let ttype_index = action_table.read_sleb128()?;
return Ok(if ttype_index == 0 {
EHAction::Cleanup(lpad)
} else if ttype_index > 0 {
EHAction::Catch(lpad)
} else {
EHAction::Filter(lpad)
});
}
}
}
Ok(EHAction::None)
Ok(EHAction::Terminate)
}

#[lang = "eh_personality"]
Expand Down Expand Up @@ -161,12 +172,17 @@ unsafe fn rust_eh_personality(
if actions.contains(UnwindAction::SEARCH_PHASE) {
match eh_action {
EHAction::None | EHAction::Cleanup(_) => UnwindReasonCode::CONTINUE_UNWIND,
EHAction::Catch(_) => UnwindReasonCode::HANDLER_FOUND,
EHAction::Catch(_) | EHAction::Filter(_) => UnwindReasonCode::HANDLER_FOUND,
EHAction::Terminate => UnwindReasonCode::FATAL_PHASE1_ERROR,
}
} else {
match eh_action {
EHAction::None => UnwindReasonCode::CONTINUE_UNWIND,
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
// Forced unwinding hits a terminate action.
EHAction::Filter(_) if actions.contains(UnwindAction::FORCE_UNWIND) => {
UnwindReasonCode::CONTINUE_UNWIND
}
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
_Unwind_SetGR(
unwind_ctx,
Arch::UNWIND_DATA_REG.0 .0 as _,
Expand All @@ -176,6 +192,7 @@ unsafe fn rust_eh_personality(
_Unwind_SetIP(unwind_ctx, lpad);
UnwindReasonCode::INSTALL_CONTEXT
}
EHAction::Terminate => UnwindReasonCode::FATAL_PHASE2_ERROR,
}
}
}

0 comments on commit 2f19304

Please sign in to comment.