forked from OSchip/llvm-project
[AArch64] Emit PAC/BTI .note.gnu.property flags
This patch make LLVM emit the processor specific program property types defined in AArch64 ELF spec https://developer.arm.com/docs/ihi0056/f/elf-for-the-arm-64-bit-architecture-aarch64-abi-2019q2-documentation A file containing no functions gets both property flags. Otherwise, a property is set iff all the functions in the file have the corresponding attribute. Patch by Daniel Kiss and Momchil Velikov. Differential Revision: https://reviews.llvm.org/D71019
This commit is contained in:
parent
f99eedeb72
commit
d53e61863d
|
@ -84,6 +84,7 @@ public:
|
||||||
return MCInstLowering.lowerOperand(MO, MCOp);
|
return MCInstLowering.lowerOperand(MO, MCOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmitStartOfAsmFile(Module &M) override;
|
||||||
void EmitJumpTableInfo() override;
|
void EmitJumpTableInfo() override;
|
||||||
void emitJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
void emitJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
||||||
const MachineBasicBlock *MBB, unsigned JTI);
|
const MachineBasicBlock *MBB, unsigned JTI);
|
||||||
|
@ -181,6 +182,65 @@ private:
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
void AArch64AsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||||
|
if (!TM.getTargetTriple().isOSBinFormatELF())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Assemble feature flags that may require creation of a note section.
|
||||||
|
unsigned Flags = ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
|
||||||
|
ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
|
||||||
|
|
||||||
|
if (any_of(M, [](const Function &F) {
|
||||||
|
return !F.isDeclaration() &&
|
||||||
|
!F.hasFnAttribute("branch-target-enforcement");
|
||||||
|
})) {
|
||||||
|
Flags &= ~ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Flags & ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI) == 0 &&
|
||||||
|
any_of(M, [](const Function &F) {
|
||||||
|
return F.hasFnAttribute("branch-target-enforcement");
|
||||||
|
})) {
|
||||||
|
errs() << "warning: some functions compiled with BTI and some compiled "
|
||||||
|
"without BTI\n"
|
||||||
|
<< "warning: not setting BTI in feature flags\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (any_of(M, [](const Function &F) {
|
||||||
|
if (F.isDeclaration())
|
||||||
|
return false;
|
||||||
|
Attribute A = F.getFnAttribute("sign-return-address");
|
||||||
|
return !A.isStringAttribute() || A.getValueAsString() == "none";
|
||||||
|
})) {
|
||||||
|
Flags &= ~ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Flags == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Emit a .note.gnu.property section with the flags.
|
||||||
|
MCSection *Cur = OutStreamer->getCurrentSectionOnly();
|
||||||
|
MCSection *Nt = MMI->getContext().getELFSection(
|
||||||
|
".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
|
||||||
|
OutStreamer->SwitchSection(Nt);
|
||||||
|
|
||||||
|
// Emit the note header.
|
||||||
|
EmitAlignment(Align(8));
|
||||||
|
OutStreamer->EmitIntValue(4, 4); // data size for "GNU\0"
|
||||||
|
OutStreamer->EmitIntValue(4 * 4, 4); // Elf_Prop size
|
||||||
|
OutStreamer->EmitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4);
|
||||||
|
OutStreamer->EmitBytes(StringRef("GNU", 4)); // note name
|
||||||
|
|
||||||
|
// Emit the PAC/BTI properties.
|
||||||
|
OutStreamer->EmitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND, 4);
|
||||||
|
OutStreamer->EmitIntValue(4, 4); // data size
|
||||||
|
OutStreamer->EmitIntValue(Flags, 4); // data
|
||||||
|
OutStreamer->EmitIntValue(0, 4); // pad
|
||||||
|
|
||||||
|
OutStreamer->endSection(Nt);
|
||||||
|
OutStreamer->SwitchSection(Cur);
|
||||||
|
}
|
||||||
|
|
||||||
void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
|
void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
|
||||||
{
|
{
|
||||||
EmitSled(MI, SledKind::FUNCTION_ENTER);
|
EmitSled(MI, SledKind::FUNCTION_ENTER);
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ
|
||||||
|
@x = common dso_local global i32 0, align 4
|
||||||
|
|
||||||
|
attributes #0 = { "branch-target-enforcement" }
|
||||||
|
|
||||||
|
; Both attributes present in a file with no functions.
|
||||||
|
; ASM: .word 3221225472
|
||||||
|
; ASM-NEXT: .word 4
|
||||||
|
; ASM-NEXT .word 3
|
||||||
|
|
||||||
|
; OBJ: Properties: aarch64 feature: BTI, PAC
|
|
@ -0,0 +1,18 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "branch-target-enforcement" }
|
||||||
|
|
||||||
|
; BTI attribute present
|
||||||
|
; ASM: .word 3221225472
|
||||||
|
; ASM-NEXT: .word 4
|
||||||
|
; ASM-NEXT .word 1
|
||||||
|
|
||||||
|
; OBJ: Properties: aarch64 feature: BTI
|
|
@ -0,0 +1,18 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "sign-return-address"="all" }
|
||||||
|
|
||||||
|
; PAC attribute present
|
||||||
|
; ASM: .word 3221225472
|
||||||
|
; ASM-NEXT: .word 4
|
||||||
|
; ASM-NEXT .word 2
|
||||||
|
|
||||||
|
; OBJ: Properties: aarch64 feature: PAC
|
|
@ -0,0 +1,18 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" }
|
||||||
|
|
||||||
|
; Both attribute present
|
||||||
|
; ASM: .word 3221225472
|
||||||
|
; ASM-NEXT: .word 4
|
||||||
|
; ASM-NEXT .word 3
|
||||||
|
|
||||||
|
; OBJ: Properties: aarch64 feature: BTI, PAC
|
|
@ -0,0 +1,25 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
define dso_local i32 @g() #1 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" }
|
||||||
|
|
||||||
|
attributes #1 = { "branch-target-enforcement" }
|
||||||
|
|
||||||
|
; Only the common atttribute (BTI)
|
||||||
|
; ASM: .word 3221225472
|
||||||
|
; ASM-NEXT: .word 4
|
||||||
|
; ASM-NEXT .word 1
|
||||||
|
|
||||||
|
; OBJ: Properties: aarch64 feature: BTI
|
|
@ -0,0 +1,26 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - 2>&1 | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
define dso_local i32 @g() #1 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" }
|
||||||
|
|
||||||
|
attributes #1 = { "sign-return-address"="all" }
|
||||||
|
|
||||||
|
; Only the common atttribute (PAC)
|
||||||
|
; ASM: warning: not setting BTI in feature flags
|
||||||
|
; ASM: .word 3221225472
|
||||||
|
; ASM-NEXT: .word 4
|
||||||
|
; ASM-NEXT .word 2
|
||||||
|
|
||||||
|
; OBJ: Properties: aarch64 feature: PAC
|
|
@ -0,0 +1,22 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf -S | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
define dso_local i32 @g() #1 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "sign-return-address"="non-leaf" }
|
||||||
|
|
||||||
|
attributes #1 = { "sign-return-address"="none" }
|
||||||
|
|
||||||
|
; No common attribute, no note section
|
||||||
|
; ASM-NOT: .note.gnu.property
|
||||||
|
; OBJ-NOT: .note.gnu.property
|
|
@ -0,0 +1,23 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - 2>&1 | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf -S | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
define dso_local i32 @g() #1 {
|
||||||
|
entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "sign-return-address"="non-leaf" }
|
||||||
|
|
||||||
|
attributes #1 = { "branch-target-enforcement" }
|
||||||
|
|
||||||
|
; No common attribute, no note section
|
||||||
|
; ASM: warning: not setting BTI in feature flags
|
||||||
|
; ASM-NOT: .note.gnu.property
|
||||||
|
; OBJ-NOT: .note.gnu.property
|
|
@ -0,0 +1,21 @@
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
|
||||||
|
; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
define dso_local i32 @f() #0 {
|
||||||
|
entry:
|
||||||
|
%r = tail call i32 @g()
|
||||||
|
ret i32 %r
|
||||||
|
}
|
||||||
|
|
||||||
|
declare dso_local i32 @g()
|
||||||
|
|
||||||
|
attributes #0 = { "branch-target-enforcement" }
|
||||||
|
|
||||||
|
; Declarations don't prevent setting BTI
|
||||||
|
; ASM: .word 3221225472
|
||||||
|
; ASM-NEXT: .word 4
|
||||||
|
; ASM-NEXT .word 1
|
||||||
|
|
||||||
|
; OBJ: Properties: aarch64 feature: BTI
|
Loading…
Reference in New Issue