@@ -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,54 @@ 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
+ 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
+
96
145
pub ( crate ) fn create_object_file ( sess : & Session ) -> Option < write:: Object < ' static > > {
97
146
let endianness = match sess. target . options . endian {
98
147
Endian :: Little => Endianness :: Little ,
@@ -205,6 +254,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
205
254
_ => elf:: ELFOSABI_NONE ,
206
255
} ;
207
256
let abi_version = 0 ;
257
+ add_gnu_property_note ( & mut file, architecture, binary_format, endianness) ;
208
258
file. flags = FileFlags :: Elf { os_abi, abi_version, e_flags } ;
209
259
Some ( file)
210
260
}
0 commit comments