Skip to content

Commit 02a85bd

Browse files
authored
Rollup merge of #110304 - cchiw:master, r=davidtwco
Add GNU Property Note Fix #103001 Generates the missing property note: ``` Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: x86 feature: IBT ```
2 parents 33a01e2 + 37f3e2f commit 02a85bd

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

compiler/rustc_codegen_ssa/src/back/metadata.rs

+50
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use object::{
1212

1313
use snap::write::FrameEncoder;
1414

15+
use object::elf::NT_GNU_PROPERTY_TYPE_0;
1516
use rustc_data_structures::memmap::Mmap;
1617
use rustc_data_structures::owned_slice::try_slice_owned;
1718
use 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+
96145
pub(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
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Check for GNU Property Note
2+
3+
include ../tools.mk
4+
5+
# How to run this
6+
# python3 x.py test --target x86_64-unknown-linux-gnu tests/run-make/branch-protection-check-IBT/
7+
8+
# only-x86_64
9+
10+
all:
11+
ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86_64)
12+
$(RUSTC) --target x86_64-unknown-linux-gnu -Z cf-protection=branch -L$(TMPDIR) -C link-args='-nostartfiles' -C save-temps ./main.rs -o $(TMPDIR)/rsmain
13+
readelf -nW $(TMPDIR)/rsmain | $(CGREP) -e ".note.gnu.property"
14+
endif
15+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("hello world");
3+
}

0 commit comments

Comments
 (0)