@@ -12,6 +12,7 @@ use object::{
1212
1313use snap:: write:: FrameEncoder ;
1414
15+ use object:: elf:: NT_GNU_PROPERTY_TYPE_0 ;
1516use rustc_data_structures:: memmap:: Mmap ;
1617use rustc_data_structures:: owned_slice:: try_slice_owned;
1718use rustc_data_structures:: sync:: MetadataRef ;
@@ -93,6 +94,46 @@ pub(super) fn search_for_section<'a>(
9394 . map_err ( |e| format ! ( "failed to read {} section in '{}': {}" , section, path. display( ) , e) )
9495}
9596
97+ fn add_gnu_property_note (
98+ file : & mut write:: Object < ' static > ,
99+ architecture : Architecture ,
100+ binary_format : BinaryFormat ,
101+ ) {
102+ // check bti protection
103+ if binary_format != BinaryFormat :: Elf
104+ || !matches ! ( architecture, Architecture :: X86_64 | Architecture :: Aarch64 )
105+ {
106+ return ;
107+ }
108+
109+ let section = file. add_section (
110+ file. segment_name ( StandardSegment :: Data ) . to_vec ( ) ,
111+ b".note.gnu.property" . to_vec ( ) ,
112+ SectionKind :: Note ,
113+ ) ;
114+ let mut data: Vec < u8 > = Vec :: new ( ) ;
115+ let n_namsz: u32 = 4 ; // Size of the n_name field
116+ let n_descsz: u32 = 16 ; // Size of the n_desc field
117+ let n_type: u32 = NT_GNU_PROPERTY_TYPE_0 ; // Type of note descriptor
118+ let values = [ n_namsz, n_descsz, n_type] ;
119+ values. map ( |v| data. extend_from_slice ( & ( v. to_le_bytes ( ) ) ) ) ;
120+ data. push ( b'G' ) ; // Owner of the program property note
121+ data. push ( b'N' ) ;
122+ data. push ( b'U' ) ;
123+ data. push ( 0 ) ;
124+ let pr_type: u32 = match architecture {
125+ Architecture :: X86_64 => 0xc0000002 ,
126+ Architecture :: Aarch64 => 0xc0000000 ,
127+ _ => unreachable ! ( ) ,
128+ } ;
129+ let pr_datasz: u32 = 4 ; //size of the pr_data field
130+ let pr_data: u32 = 3 ; //program property descriptor
131+ let pr_padding: u32 = 3 ;
132+ let values = [ pr_type, pr_datasz, pr_data, pr_padding] ;
133+ values. map ( |v| data. extend_from_slice ( & ( v. to_le_bytes ( ) ) ) ) ;
134+ file. append_section_data ( section, & data, 4 ) ;
135+ }
136+
96137pub ( crate ) fn create_object_file ( sess : & Session ) -> Option < write:: Object < ' static > > {
97138 let endianness = match sess. target . options . endian {
98139 Endian :: Little => Endianness :: Little ,
@@ -205,6 +246,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
205246 _ => elf:: ELFOSABI_NONE ,
206247 } ;
207248 let abi_version = 0 ;
249+ add_gnu_property_note ( & mut file, architecture, binary_format) ;
208250 file. flags = FileFlags :: Elf { os_abi, abi_version, e_flags } ;
209251 Some ( file)
210252}
0 commit comments