about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCharisee <chiw@google.com>2023-04-22 01:00:36 +0000
committerCharisee <chiw@google.com>2023-04-22 01:00:36 +0000
commitcb4f8153d8285ac2bf2145c569c09014f3ba317d (patch)
tree04e8455e8c4f975ed5e4a012b57a812c12f86614
parenta41fc00eaf352541008965fec0dee811e44373b3 (diff)
downloadrust-cb4f8153d8285ac2bf2145c569c09014f3ba317d.tar.gz
rust-cb4f8153d8285ac2bf2145c569c09014f3ba317d.zip
Add GNU Property Note
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs42
1 files changed, 42 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index d5d843702c0..baf674cf9eb 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -12,6 +12,7 @@ use object::{
 
 use snap::write::FrameEncoder;
 
+use object::elf::NT_GNU_PROPERTY_TYPE_0;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::owned_slice::try_slice_owned;
 use rustc_data_structures::sync::MetadataRef;
@@ -93,6 +94,46 @@ pub(super) fn search_for_section<'a>(
         .map_err(|e| format!("failed to read {} section in '{}': {}", section, path.display(), e))
 }
 
+fn add_gnu_property_note(
+    file: &mut write::Object<'static>,
+    architecture: Architecture,
+    binary_format: BinaryFormat,
+) {
+    // check bti protection
+    if binary_format != BinaryFormat::Elf
+        || !matches!(architecture, Architecture::X86_64 | Architecture::Aarch64)
+    {
+        return;
+    }
+
+    let section = file.add_section(
+        file.segment_name(StandardSegment::Data).to_vec(),
+        b".note.gnu.property".to_vec(),
+        SectionKind::Note,
+    );
+    let mut data: Vec<u8> = Vec::new();
+    let n_namsz: u32 = 4; // Size of the n_name field
+    let n_descsz: u32 = 16; // Size of the n_desc field
+    let n_type: u32 = NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor
+    let values = [n_namsz, n_descsz, n_type];
+    values.map(|v| data.extend_from_slice(&(v.to_le_bytes())));
+    data.push(b'G'); // Owner of the program property note
+    data.push(b'N');
+    data.push(b'U');
+    data.push(0);
+    let pr_type: u32 = match architecture {
+        Architecture::X86_64 => 0xc0000002,
+        Architecture::Aarch64 => 0xc0000000,
+        _ => unreachable!(),
+    };
+    let pr_datasz: u32 = 4; //size of the pr_data field
+    let pr_data: u32 = 3; //program property descriptor
+    let pr_padding: u32 = 3;
+    let values = [pr_type, pr_datasz, pr_data, pr_padding];
+    values.map(|v| data.extend_from_slice(&(v.to_le_bytes())));
+    file.append_section_data(section, &data, 4);
+}
+
 pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static>> {
     let endianness = match sess.target.options.endian {
         Endian::Little => Endianness::Little,
@@ -205,6 +246,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
         _ => elf::ELFOSABI_NONE,
     };
     let abi_version = 0;
+    add_gnu_property_note(&mut file, architecture, binary_format);
     file.flags = FileFlags::Elf { os_abi, abi_version, e_flags };
     Some(file)
 }