mirror of
https://github.com/rui314/mold.git
synced 2026-11-07 09:16:04 -10:00
Merge GNU_PROPERTY_AARCH64_FEATURE_1_AND
We used to merge only x86 properties in .note.gnu.property, so an ARM64 output lost GNU_PROPERTY_AARCH64_FEATURE_1_AND even if all its inputs were compiled with -mbranch-protection. We now AND-merge it as GNU ld and lld do, and merge x86 properties only on x86.
This commit is contained in:
1 parent
442f2d57a2
commit
38b10b4391
5 files changed
+62
-14
No files matched your search
+21
-11
@@ -2,7 +2,7 @@
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use crate::arch::Target;
|
||||
use crate::arch::{Family, Target};
|
||||
use crate::chunks::ChunkHeader;
|
||||
use crate::context::Context;
|
||||
use crate::elf::*;
|
||||
@@ -46,15 +46,21 @@ pub fn update_shdr<E: Target>(ctx: &mut Context<E>) {
|
||||
// Merge values for each key
|
||||
let mut map: BTreeMap<u32, u32> = BTreeMap::new();
|
||||
for key in keys {
|
||||
if (GNU_PROPERTY_X86_UINT32_AND_LO..=GNU_PROPERTY_X86_UINT32_AND_HI).contains(&key) {
|
||||
if (E::IS_X86
|
||||
&& (GNU_PROPERTY_X86_UINT32_AND_LO..=GNU_PROPERTY_X86_UINT32_AND_HI).contains(&key))
|
||||
|| (E::FAMILY == Family::Arm64 && key == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
|
||||
{
|
||||
// An AND feature is set if all input objects have the property and
|
||||
// the feature.
|
||||
map.insert(key, files.iter().fold(u32::MAX, |acc, f| acc & value(f, key)));
|
||||
} else if (GNU_PROPERTY_X86_UINT32_OR_LO..=GNU_PROPERTY_X86_UINT32_OR_HI).contains(&key) {
|
||||
} else if E::IS_X86
|
||||
&& (GNU_PROPERTY_X86_UINT32_OR_LO..=GNU_PROPERTY_X86_UINT32_OR_HI).contains(&key)
|
||||
{
|
||||
// An OR feature is set if some input object has the feature.
|
||||
map.insert(key, files.iter().fold(0, |acc, f| acc | value(f, key)));
|
||||
} else if (GNU_PROPERTY_X86_UINT32_OR_AND_LO..=GNU_PROPERTY_X86_UINT32_OR_AND_HI)
|
||||
.contains(&key)
|
||||
} else if E::IS_X86
|
||||
&& (GNU_PROPERTY_X86_UINT32_OR_AND_LO..=GNU_PROPERTY_X86_UINT32_OR_AND_HI)
|
||||
.contains(&key)
|
||||
{
|
||||
// An OR-AND feature is set if all input object files have the property
|
||||
// and some of them have the feature.
|
||||
@@ -64,13 +70,17 @@ pub fn update_shdr<E: Target>(ctx: &mut Context<E>) {
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.args.z_ibt {
|
||||
*map.entry(GNU_PROPERTY_X86_FEATURE_1_AND).or_insert(0) |= GNU_PROPERTY_X86_FEATURE_1_IBT;
|
||||
if E::IS_X86 {
|
||||
if ctx.args.z_ibt {
|
||||
*map.entry(GNU_PROPERTY_X86_FEATURE_1_AND).or_insert(0) |=
|
||||
GNU_PROPERTY_X86_FEATURE_1_IBT;
|
||||
}
|
||||
if ctx.args.z_shstk {
|
||||
*map.entry(GNU_PROPERTY_X86_FEATURE_1_AND).or_insert(0) |=
|
||||
GNU_PROPERTY_X86_FEATURE_1_SHSTK;
|
||||
}
|
||||
*map.entry(GNU_PROPERTY_X86_ISA_1_NEEDED).or_insert(0) |= ctx.args.z_x86_64_isa_level;
|
||||
}
|
||||
if ctx.args.z_shstk {
|
||||
*map.entry(GNU_PROPERTY_X86_FEATURE_1_AND).or_insert(0) |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
|
||||
}
|
||||
*map.entry(GNU_PROPERTY_X86_ISA_1_NEEDED).or_insert(0) |= ctx.args.z_x86_64_isa_level;
|
||||
|
||||
// Serialize the map
|
||||
let contents: Vec<(u32, u32)> = map.into_iter().filter(|&(_, v)| v != 0).collect();
|
||||
|
||||
@@ -264,6 +264,11 @@ pub const GNU_PROPERTY_X86_ISA_1_V2: u32 = 2;
|
||||
pub const GNU_PROPERTY_X86_ISA_1_V3: u32 = 4;
|
||||
pub const GNU_PROPERTY_X86_ISA_1_V4: u32 = 8;
|
||||
|
||||
pub const GNU_PROPERTY_AARCH64_FEATURE_1_AND: u32 = 0xc0000000;
|
||||
pub const GNU_PROPERTY_AARCH64_FEATURE_1_BTI: u32 = 1;
|
||||
pub const GNU_PROPERTY_AARCH64_FEATURE_1_PAC: u32 = 2;
|
||||
pub const GNU_PROPERTY_AARCH64_FEATURE_1_GCS: u32 = 4;
|
||||
|
||||
pub const ELFCOMPRESS_NONE: u32 = 0;
|
||||
pub const ELFCOMPRESS_ZLIB: u32 = 1;
|
||||
pub const ELFCOMPRESS_ZSTD: u32 = 2;
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ pub fn create_synthetic_sections<E: Target>(ctx: &mut Context<E>) {
|
||||
chunks.push(ChunkId::Verneed);
|
||||
chunks.push(ChunkId::NotePackage);
|
||||
|
||||
if E::IS_X86 {
|
||||
if E::IS_X86 || E::FAMILY == Family::Arm64 {
|
||||
ctx.note_property = Some(NotePropertySection::<E>::new());
|
||||
chunks.push(ChunkId::NoteProperty);
|
||||
}
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ use std::collections::HashMap;
|
||||
|
||||
use mold_common::util::align_to;
|
||||
|
||||
use crate::arch::Target;
|
||||
use crate::arch::{Family, Target};
|
||||
use crate::chunks::comdat_group::ComdatGroupSection;
|
||||
use crate::chunks::note_property::NotePropertySection;
|
||||
use crate::chunks::output_section::{self, OutputSection};
|
||||
@@ -109,7 +109,7 @@ fn create_synthetic_sections<E: Target>(ctx: &mut Context<E>) {
|
||||
ChunkId::Symtab,
|
||||
ChunkId::Shstrtab,
|
||||
]);
|
||||
if E::IS_X86 {
|
||||
if E::IS_X86 || E::FAMILY == Family::Arm64 {
|
||||
ctx.note_property = Some(NotePropertySection::<E>::new());
|
||||
ctx.chunks.push(ChunkId::NoteProperty);
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
. $(dirname $0)/common.inc
|
||||
|
||||
test_cflags -mbranch-protection=standard || skip
|
||||
|
||||
cat <<EOF | $CC -mbranch-protection=standard -c -o $t/a.o -xc -
|
||||
void _start() {}
|
||||
EOF
|
||||
|
||||
cat <<EOF | $CC -mbranch-protection=standard -c -o $t/b.o -xc -
|
||||
void foo() {}
|
||||
EOF
|
||||
|
||||
cat <<EOF | $CC -mbranch-protection=bti -c -o $t/c.o -xc -
|
||||
void bar() {}
|
||||
EOF
|
||||
|
||||
cat <<EOF | $CC -mbranch-protection=none -c -o $t/d.o -xc -
|
||||
void baz() {}
|
||||
EOF
|
||||
|
||||
./mold -o $t/exe1 $t/a.o $t/b.o
|
||||
readelf -n $t/exe1 | grep 'AArch64 feature: BTI, PAC'
|
||||
readelf -W --segments $t/exe1 | grep -w GNU_PROPERTY
|
||||
|
||||
./mold -o $t/exe2 $t/a.o $t/b.o $t/c.o
|
||||
readelf -n $t/exe2 | grep 'AArch64 feature: BTI$'
|
||||
|
||||
./mold -o $t/exe3 $t/a.o $t/b.o $t/c.o $t/d.o
|
||||
readelf -n $t/exe3 | not grep 'AArch64 feature'
|
||||
|
||||
./mold -r -o $t/e.o $t/a.o $t/b.o
|
||||
readelf -n $t/e.o | grep 'AArch64 feature: BTI, PAC'
|
||||
Reference in new issue
Block a user