File tree Expand file tree Collapse file tree 1 file changed +10
-4
lines changed Expand file tree Collapse file tree 1 file changed +10
-4
lines changed Original file line number Diff line number Diff line change @@ -101,11 +101,17 @@ impl CompiledBlob {
101101 let base = get_address ( name) ;
102102 let what = unsafe { base. offset ( isize:: try_from ( addend) . unwrap ( ) ) } ;
103103 let get_page = |x| x & ( !0xfff ) ;
104- let pcrel = i32:: try_from ( get_page ( what as isize ) - get_page ( at as isize ) )
105- . unwrap ( )
106- . cast_unsigned ( ) ;
104+ // NOTE: This should technically be i33 given that this relocation type allows
105+ // a range from -4GB to +4GB, not -2GB to +2GB. But this doesn't really matter
106+ // as the target is unlikely to be more than 2GB from the adrp instruction. We
107+ // need to be careful to not cast to an unsigned int until after doing >> 12 to
108+ // compute the upper 21bits of the pcrel address however as otherwise the top
109+ // bit of the 33bit pcrel address would be forced 0 through zero extension
110+ // instead of being sign extended as it should be.
111+ let pcrel =
112+ i32:: try_from ( get_page ( what as isize ) - get_page ( at as isize ) ) . unwrap ( ) ;
107113 let iptr = at as * mut u32 ;
108- let hi21 = pcrel >> 12 ;
114+ let hi21 = ( pcrel >> 12 ) . cast_unsigned ( ) ;
109115 let lo = ( hi21 & 0x3 ) << 29 ;
110116 let hi = ( hi21 & 0x1ffffc ) << 3 ;
111117 unsafe { modify_inst32 ( iptr, |inst| inst | lo | hi) } ;
You can’t perform that action at this time.
0 commit comments