@@ -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,54 @@ 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+ endianness : Endianness ,
102+ ) {
103+ // check bti protection
104+ if binary_format != BinaryFormat :: Elf
105+ || !matches ! ( architecture, Architecture :: X86_64 | Architecture :: Aarch64 )
106+ {
107+ return ;
108+ }
109+
110+ let section = file. add_section (
111+ file. segment_name ( StandardSegment :: Data ) . to_vec ( ) ,
112+ b".note.gnu.property" . to_vec ( ) ,
113+ SectionKind :: Note ,
114+ ) ;
115+ let mut data: Vec < u8 > = Vec :: new ( ) ;
116+ let n_namsz: u32 = 4 ; // Size of the n_name field
117+ let n_descsz: u32 = 16 ; // Size of the n_desc field
118+ let n_type: u32 = NT_GNU_PROPERTY_TYPE_0 ; // Type of note descriptor
119+ let header_values = [ n_namsz, n_descsz, n_type] ;
120+ header_values. iter ( ) . for_each ( |v| {
121+ data. extend_from_slice ( & match endianness {
122+ Endianness :: Little => v. to_le_bytes ( ) ,
123+ Endianness :: Big => v. to_be_bytes ( ) ,
124+ } )
125+ } ) ;
126+ data. extend_from_slice ( b"GNU\0 " ) ; // Owner of the program property note
127+ let pr_type: u32 = match architecture {
128+ Architecture :: X86_64 => 0xc0000002 ,
129+ Architecture :: Aarch64 => 0xc0000000 ,
130+ _ => unreachable ! ( ) ,
131+ } ;
132+ let pr_datasz: u32 = 4 ; //size of the pr_data field
133+ let pr_data: u32 = 3 ; //program property descriptor
134+ let pr_padding: u32 = 0 ;
135+ let property_values = [ pr_type, pr_datasz, pr_data, pr_padding] ;
136+ property_values. iter ( ) . for_each ( |v| {
137+ data. extend_from_slice ( & match endianness {
138+ Endianness :: Little => v. to_le_bytes ( ) ,
139+ Endianness :: Big => v. to_be_bytes ( ) ,
140+ } )
141+ } ) ;
142+ file. append_section_data ( section, & data, 8 ) ;
143+ }
144+
96145pub ( crate ) fn create_object_file ( sess : & Session ) -> Option < write:: Object < ' static > > {
97146 let endianness = match sess. target . options . endian {
98147 Endian :: Little => Endianness :: Little ,
@@ -205,6 +254,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
205254 _ => elf:: ELFOSABI_NONE ,
206255 } ;
207256 let abi_version = 0 ;
257+ add_gnu_property_note ( & mut file, architecture, binary_format, endianness) ;
208258 file. flags = FileFlags :: Elf { os_abi, abi_version, e_flags } ;
209259 Some ( file)
210260}
0 commit comments