11use std:: cmp;
2+ use std:: ops:: Range ;
23
3- use rustc_abi:: { Align , BackendRepr , ExternAbi , HasDataLayout , Reg , Size , WrappingRange } ;
4+ use rustc_abi:: {
5+ Align , ArmCall , BackendRepr , CanonAbi , ExternAbi , HasDataLayout , Reg , Size , WrappingRange ,
6+ } ;
47use rustc_ast as ast;
58use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
69use rustc_data_structures:: packed:: Pu128 ;
@@ -597,6 +600,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
597600 }
598601 ZeroSized => bug ! ( "ZST return value shouldn't be in PassMode::Cast" ) ,
599602 } ;
603+
604+ if self . fn_abi . conv == CanonAbi :: Arm ( ArmCall :: CCmseNonSecureEntry ) {
605+ // The return value of an `extern "cmse-nonsecure-entry"` function crosses the
606+ // secure boundary. Zero padding bytes so information does not leak.
607+ //
608+ // This only zeroes "guaranteed" padding. There may be more bytes that are
609+ // padding for some but not all variants of this type; those are not zeroed.
610+ //
611+ // Returning a value with value-dependent padding will instead trigger a lint.
612+ let ret_layout = self . fn_abi . ret . layout ;
613+ let uninit_ranges = ret_layout. padding_ranges ( bx. cx ( ) ) ;
614+ self . zero_byte_ranges ( bx, llslot, ret_layout. size , & uninit_ranges) ;
615+ }
616+
600617 load_cast ( bx, cast_ty, llslot, self . fn_abi . ret . layout . align . abi )
601618 }
602619 } ;
@@ -1341,6 +1358,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13411358
13421359 self . codegen_argument (
13431360 bx,
1361+ fn_abi. conv ,
13441362 op,
13451363 by_move,
13461364 & mut llargs,
@@ -1351,6 +1369,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13511369 let num_untupled = untuple. map ( |tup| {
13521370 self . codegen_arguments_untupled (
13531371 bx,
1372+ fn_abi. conv ,
13541373 & tup. node ,
13551374 & mut llargs,
13561375 & fn_abi. args [ first_args. len ( ) ..] ,
@@ -1380,6 +1399,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13801399 let last_arg = fn_abi. args . last ( ) . unwrap ( ) ;
13811400 self . codegen_argument (
13821401 bx,
1402+ fn_abi. conv ,
13831403 location,
13841404 /* by_move */ false ,
13851405 & mut llargs,
@@ -1696,9 +1716,31 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16961716 }
16971717 }
16981718
1719+ fn zero_byte_ranges (
1720+ & mut self ,
1721+ bx : & mut Bx ,
1722+ ptr : Bx :: Value ,
1723+ limit : Size ,
1724+ ranges : & [ Range < Size > ] ,
1725+ ) {
1726+ let zero = bx. const_u8 ( 0 ) ;
1727+
1728+ for range in ranges {
1729+ let end = cmp:: min ( range. end , limit) ;
1730+ if range. start >= end {
1731+ continue ;
1732+ }
1733+ let offset = bx. const_usize ( range. start . bytes ( ) ) ;
1734+ let len = bx. const_usize ( ( end - range. start ) . bytes ( ) ) ;
1735+ let ptr = bx. inbounds_ptradd ( ptr, offset) ;
1736+ bx. memset ( ptr, zero, len, Align :: ONE , MemFlags :: empty ( ) ) ;
1737+ }
1738+ }
1739+
16991740 fn codegen_argument (
17001741 & mut self ,
17011742 bx : & mut Bx ,
1743+ conv : CanonAbi ,
17021744 op : OperandRef < ' tcx , Bx :: Value > ,
17031745 by_move : bool ,
17041746 llargs : & mut Vec < Bx :: Value > ,
@@ -1822,6 +1864,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18221864 MemFlags :: empty ( ) ,
18231865 None ,
18241866 ) ;
1867+
1868+ // The arguments of an `extern "cmse-nonsecure-call"` function cross the secure
1869+ // boundary. Zero padding bytes so information does not leak.
1870+ //
1871+ // This only zeroes "guaranteed" padding. There may be more bytes that are
1872+ // padding for some but not all variants of this type; those are not zeroed.
1873+ //
1874+ // Passing an argument with value-dependent padding will instead trigger a lint.
1875+ if conv == CanonAbi :: Arm ( ArmCall :: CCmseNonSecureCall ) {
1876+ self . zero_byte_ranges (
1877+ bx,
1878+ llscratch,
1879+ Size :: from_bytes ( copy_bytes) ,
1880+ & arg. layout . padding_ranges ( bx. cx ( ) ) ,
1881+ ) ;
1882+ }
1883+
18251884 // ...and then load it with the ABI type.
18261885 llval = load_cast ( bx, cast, llscratch, scratch_align) ;
18271886 bx. lifetime_end ( llscratch, scratch_size) ;
@@ -1848,6 +1907,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18481907 fn codegen_arguments_untupled (
18491908 & mut self ,
18501909 bx : & mut Bx ,
1910+ conv : CanonAbi ,
18511911 operand : & mir:: Operand < ' tcx > ,
18521912 llargs : & mut Vec < Bx :: Value > ,
18531913 args : & [ ArgAbi < ' tcx , Ty < ' tcx > > ] ,
@@ -1867,6 +1927,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18671927 let field = bx. load_operand ( field_ptr) ;
18681928 self . codegen_argument (
18691929 bx,
1930+ conv,
18701931 field,
18711932 by_move,
18721933 llargs,
@@ -1878,7 +1939,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18781939 // If the tuple is immediate, the elements are as well.
18791940 for i in 0 ..tuple. layout . fields . count ( ) {
18801941 let op = tuple. extract_field ( self , bx, i) ;
1881- self . codegen_argument ( bx, op, by_move, llargs, & args[ i] , lifetime_ends_after_call) ;
1942+ self . codegen_argument (
1943+ bx,
1944+ conv,
1945+ op,
1946+ by_move,
1947+ llargs,
1948+ & args[ i] ,
1949+ lifetime_ends_after_call,
1950+ ) ;
18821951 }
18831952 }
18841953 tuple. layout . fields . count ( )
0 commit comments