11//! Parsing of GCC-style Language-Specific Data Area (LSDA)
22//! For details see:
33//! * <https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html>
4+ //! * <https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html>
45//! * <https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf>
56//! * <https://www.airs.com/blog/archives/460>
67//! * <https://www.airs.com/blog/archives/464>
@@ -37,17 +38,19 @@ pub const DW_EH_PE_indirect: u8 = 0x80;
3738
3839#[ derive( Copy , Clone ) ]
3940pub struct EHContext < ' a > {
40- pub ip : usize , // Current instruction pointer
41- pub func_start : usize , // Address of the current function
42- pub get_text_start : & ' a dyn Fn ( ) -> usize , // Get address of the code section
43- pub get_data_start : & ' a dyn Fn ( ) -> usize , // Get address of the data section
41+ pub ip : * const u8 , // Current instruction pointer
42+ pub func_start : * const u8 , // Pointer to the current function
43+ pub get_text_start : & ' a dyn Fn ( ) -> * const u8 , // Get pointer to the code section
44+ pub get_data_start : & ' a dyn Fn ( ) -> * const u8 , // Get pointer to the data section
4445}
4546
47+ /// Landing pad.
48+ type LPad = * const u8 ;
4649pub enum EHAction {
4750 None ,
48- Cleanup ( usize ) ,
49- Catch ( usize ) ,
50- Filter ( usize ) ,
51+ Cleanup ( LPad ) ,
52+ Catch ( LPad ) ,
53+ Filter ( LPad ) ,
5154 Terminate ,
5255}
5356
@@ -82,21 +85,21 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
8285
8386 if !USING_SJLJ_EXCEPTIONS {
8487 while reader. ptr < action_table {
85- let cs_start = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
86- let cs_len = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
87- let cs_lpad = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?;
88+ let cs_start = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?. addr ( ) ;
89+ let cs_len = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?. addr ( ) ;
90+ let cs_lpad = read_encoded_pointer ( & mut reader, context, call_site_encoding) ?. addr ( ) ;
8891 let cs_action_entry = reader. read_uleb128 ( ) ;
8992 // Callsite table is sorted by cs_start, so if we've passed the ip, we
9093 // may stop searching.
91- if ip < func_start + cs_start {
94+ if ip < func_start. wrapping_add ( cs_start) {
9295 break ;
9396 }
94- if ip < func_start + cs_start + cs_len {
97+ if ip < func_start. wrapping_add ( cs_start + cs_len) {
9598 if cs_lpad == 0 {
9699 return Ok ( EHAction :: None ) ;
97100 } else {
98- let lpad = lpad_base + cs_lpad;
99- return Ok ( interpret_cs_action ( action_table as * mut u8 , cs_action_entry, lpad) ) ;
101+ let lpad = lpad_base. wrapping_add ( cs_lpad) ;
102+ return Ok ( interpret_cs_action ( action_table, cs_action_entry, lpad) ) ;
100103 }
101104 }
102105 }
@@ -106,30 +109,31 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
106109 // SjLj version:
107110 // The "IP" is an index into the call-site table, with two exceptions:
108111 // -1 means 'no-action', and 0 means 'terminate'.
109- match ip as isize {
112+ match ip. addr ( ) as isize {
110113 -1 => return Ok ( EHAction :: None ) ,
111114 0 => return Ok ( EHAction :: Terminate ) ,
112115 _ => ( ) ,
113116 }
114- let mut idx = ip;
117+ let mut idx = ip. addr ( ) ;
115118 loop {
116119 let cs_lpad = reader. read_uleb128 ( ) ;
117120 let cs_action_entry = reader. read_uleb128 ( ) ;
118121 idx -= 1 ;
119122 if idx == 0 {
120123 // Can never have null landing pad for sjlj -- that would have
121124 // been indicated by a -1 call site index.
122- let lpad = ( cs_lpad + 1 ) as usize ;
123- return Ok ( interpret_cs_action ( action_table as * mut u8 , cs_action_entry, lpad) ) ;
125+ // FIXME(strict provenance)
126+ let lpad = ptr:: from_exposed_addr ( ( cs_lpad + 1 ) as usize ) ;
127+ return Ok ( interpret_cs_action ( action_table, cs_action_entry, lpad) ) ;
124128 }
125129 }
126130 }
127131}
128132
129133unsafe fn interpret_cs_action (
130- action_table : * mut u8 ,
134+ action_table : * const u8 ,
131135 cs_action_entry : u64 ,
132- lpad : usize ,
136+ lpad : LPad ,
133137) -> EHAction {
134138 if cs_action_entry == 0 {
135139 // If cs_action_entry is 0 then this is a cleanup (Drop::drop). We run these
@@ -138,7 +142,7 @@ unsafe fn interpret_cs_action(
138142 } else {
139143 // If lpad != 0 and cs_action_entry != 0, we have to check ttype_index.
140144 // If ttype_index == 0 under the condition, we take cleanup action.
141- let action_record = ( action_table as * mut u8 ) . offset ( cs_action_entry as isize - 1 ) ;
145+ let action_record = action_table. offset ( cs_action_entry as isize - 1 ) ;
142146 let mut action_reader = DwarfReader :: new ( action_record) ;
143147 let ttype_index = action_reader. read_sleb128 ( ) ;
144148 if ttype_index == 0 {
@@ -161,15 +165,16 @@ unsafe fn read_encoded_pointer(
161165 reader : & mut DwarfReader ,
162166 context : & EHContext < ' _ > ,
163167 encoding : u8 ,
164- ) -> Result < usize , ( ) > {
168+ ) -> Result < * const u8 , ( ) > {
165169 if encoding == DW_EH_PE_omit {
166170 return Err ( ( ) ) ;
167171 }
168172
169173 // DW_EH_PE_aligned implies it's an absolute pointer value
170174 if encoding == DW_EH_PE_aligned {
171- reader. ptr = reader. ptr . with_addr ( round_up ( reader. ptr . addr ( ) , mem:: size_of :: < usize > ( ) ) ?) ;
172- return Ok ( reader. read :: < usize > ( ) ) ;
175+ reader. ptr =
176+ reader. ptr . with_addr ( round_up ( reader. ptr . addr ( ) , mem:: size_of :: < * const u8 > ( ) ) ?) ;
177+ return Ok ( reader. read :: < * const u8 > ( ) ) ;
173178 }
174179
175180 let mut result = match encoding & 0x0F {
@@ -190,18 +195,21 @@ unsafe fn read_encoded_pointer(
190195 // relative to address of the encoded value, despite the name
191196 DW_EH_PE_pcrel => reader. ptr . expose_addr ( ) ,
192197 DW_EH_PE_funcrel => {
193- if context. func_start == 0 {
198+ if context. func_start . is_null ( ) {
194199 return Err ( ( ) ) ;
195200 }
196- context. func_start
201+ context. func_start . expose_addr ( )
197202 }
198- DW_EH_PE_textrel => ( * context. get_text_start ) ( ) ,
199- DW_EH_PE_datarel => ( * context. get_data_start ) ( ) ,
203+ DW_EH_PE_textrel => ( * context. get_text_start ) ( ) . expose_addr ( ) ,
204+ DW_EH_PE_datarel => ( * context. get_data_start ) ( ) . expose_addr ( ) ,
200205 _ => return Err ( ( ) ) ,
201206 } ;
202207
208+ // FIXME(strict provenance)
209+ let mut result: * const u8 = ptr:: from_exposed_addr :: < u8 > ( result) ;
210+
203211 if encoding & DW_EH_PE_indirect != 0 {
204- result = * ptr :: from_exposed_addr :: < usize > ( result ) ;
212+ result = * ( result . cast :: < * const u8 > ( ) ) ;
205213 }
206214
207215 Ok ( result)
0 commit comments