@@ -12,6 +12,7 @@ use object::{
12
12
13
13
use snap:: write:: FrameEncoder ;
14
14
15
+ use object:: elf:: NT_GNU_PROPERTY_TYPE_0 ;
15
16
use rustc_data_structures:: memmap:: Mmap ;
16
17
use rustc_data_structures:: owned_slice:: try_slice_owned;
17
18
use rustc_data_structures:: sync:: MetadataRef ;
@@ -93,6 +94,46 @@ pub(super) fn search_for_section<'a>(
93
94
. map_err ( |e| format ! ( "failed to read {} section in '{}': {}" , section, path. display( ) , e) )
94
95
}
95
96
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
+
96
137
pub ( crate ) fn create_object_file ( sess : & Session ) -> Option < write:: Object < ' static > > {
97
138
let endianness = match sess. target . options . endian {
98
139
Endian :: Little => Endianness :: Little ,
@@ -205,6 +246,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
205
246
_ => elf:: ELFOSABI_NONE ,
206
247
} ;
207
248
let abi_version = 0 ;
249
+ add_gnu_property_note ( & mut file, architecture, binary_format) ;
208
250
file. flags = FileFlags :: Elf { os_abi, abi_version, e_flags } ;
209
251
Some ( file)
210
252
}
0 commit comments