@@ -84,7 +84,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
8484 let cs_start = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
8585 let cs_len = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
8686 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 ( ) ;
8888 // Callsite table is sorted by cs_start, so if we've passed the ip, we
8989 // may stop searching.
9090 if ip < func_start + cs_start {
@@ -95,7 +95,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
9595 return Ok ( EHAction :: None ) ;
9696 } else {
9797 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) ) ;
9999 }
100100 }
101101 }
@@ -113,26 +113,39 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
113113 let mut idx = ip;
114114 loop {
115115 let cs_lpad = reader. read_uleb128 ( ) ;
116- let cs_action = reader. read_uleb128 ( ) ;
116+ let cs_action_entry = reader. read_uleb128 ( ) ;
117117 idx -= 1 ;
118118 if idx == 0 {
119119 // Can never have null landing pad for sjlj -- that would have
120120 // been indicated by a -1 call site index.
121121 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) ) ;
123123 }
124124 }
125125 }
126126}
127127
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
131135 // for both Rust panics and foreign exceptions.
132136 EHAction :: Cleanup ( lpad)
133137 } 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+ }
136149 }
137150}
138151
0 commit comments