@@ -84,7 +84,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
84
84
let cs_start = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
85
85
let cs_len = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
86
86
let cs_lpad = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
87
- let cs_action = reader. read_uleb128 ( ) ;
87
+ let cs_action_entry = reader. read_uleb128 ( ) ;
88
88
// Callsite table is sorted by cs_start, so if we've passed the ip, we
89
89
// may stop searching.
90
90
if ip < func_start + cs_start {
@@ -95,7 +95,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
95
95
return Ok ( EHAction :: None ) ;
96
96
} else {
97
97
let lpad = lpad_base + cs_lpad;
98
- return Ok ( interpret_cs_action ( cs_action , lpad) ) ;
98
+ return Ok ( interpret_cs_action ( action_table as * mut u8 , cs_action_entry , lpad) ) ;
99
99
}
100
100
}
101
101
}
@@ -113,26 +113,39 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
113
113
let mut idx = ip;
114
114
loop {
115
115
let cs_lpad = reader. read_uleb128 ( ) ;
116
- let cs_action = reader. read_uleb128 ( ) ;
116
+ let cs_action_entry = reader. read_uleb128 ( ) ;
117
117
idx -= 1 ;
118
118
if idx == 0 {
119
119
// Can never have null landing pad for sjlj -- that would have
120
120
// been indicated by a -1 call site index.
121
121
let lpad = ( cs_lpad + 1 ) as usize ;
122
- return Ok ( interpret_cs_action ( cs_action , lpad) ) ;
122
+ return Ok ( interpret_cs_action ( action_table as * mut u8 , cs_action_entry , lpad) ) ;
123
123
}
124
124
}
125
125
}
126
126
}
127
127
128
- fn interpret_cs_action ( cs_action : u64 , lpad : usize ) -> EHAction {
129
- if cs_action == 0 {
130
- // If cs_action is 0 then this is a cleanup (Drop::drop). We run these
128
+ unsafe fn interpret_cs_action (
129
+ action_table : * mut u8 ,
130
+ cs_action_entry : u64 ,
131
+ lpad : usize ,
132
+ ) -> EHAction {
133
+ if cs_action_entry == 0 {
134
+ // If cs_action_entry is 0 then this is a cleanup (Drop::drop). We run these
131
135
// for both Rust panics and foreign exceptions.
132
136
EHAction :: Cleanup ( lpad)
133
137
} else {
134
- // Stop unwinding Rust panics at catch_unwind.
135
- EHAction :: Catch ( lpad)
138
+ // If lpad != 0 and cs_action_entry != 0, we have to check ttype_index.
139
+ // If ttype_index == 0 under the condition, we take cleanup action.
140
+ let action_record = ( action_table as * mut u8 ) . offset ( cs_action_entry as isize - 1 ) ;
141
+ let mut action_reader = DwarfReader :: new ( action_record) ;
142
+ let ttype_index = action_reader. read_sleb128 ( ) ;
143
+ if ttype_index == 0 {
144
+ EHAction :: Cleanup ( lpad)
145
+ } else {
146
+ // Stop unwinding Rust panics at catch_unwind.
147
+ EHAction :: Catch ( lpad)
148
+ }
136
149
}
137
150
}
138
151
0 commit comments