Skip to content

Commit 51e1031

Browse files
DanielKristofKissaokblast
authored andcommitted
[ARM][AArch64] BTI,GCS,PAC Module flag update. (llvm#86212)
Module flag is used to indicate the feature to be propagated to the function. As now the frontend emits all attributes accordingly let's help the auto upgrade to only do work when old and new bitcodes are merged. Depends on llvm#82819 and llvm#86031
1 parent 1df0467 commit 51e1031

File tree

22 files changed

+575
-55
lines changed

22 files changed

+575
-55
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,22 +1325,29 @@ void CodeGenModule::Release() {
13251325
"tag-stack-memory-buildattr", 1);
13261326

13271327
if (T.isARM() || T.isThumb() || T.isAArch64()) {
1328+
// Previously 1 is used and meant for the backed to derive the function
1329+
// attribute form it. 2 now means function attributes already set for all
1330+
// functions in this module, so no need to propagate those from the module
1331+
// flag. Value is only used in case of LTO module merge because the backend
1332+
// will see all required function attribute set already. Value is used
1333+
// before modules got merged. Any posive value means the feature is active
1334+
// and required binary markings need to be emit accordingly.
13281335
if (LangOpts.BranchTargetEnforcement)
13291336
getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement",
1330-
1);
1337+
2);
13311338
if (LangOpts.BranchProtectionPAuthLR)
13321339
getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr",
1333-
1);
1340+
2);
13341341
if (LangOpts.GuardedControlStack)
1335-
getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1);
1342+
getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 2);
13361343
if (LangOpts.hasSignReturnAddress())
1337-
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1);
1344+
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 2);
13381345
if (LangOpts.isSignReturnAddressScopeAll())
13391346
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-all",
1340-
1);
1347+
2);
13411348
if (!LangOpts.isSignReturnAddressWithAKey())
13421349
getModule().addModuleFlag(llvm::Module::Min,
1343-
"sign-return-address-with-bkey", 1);
1350+
"sign-return-address-with-bkey", 2);
13441351

13451352
if (LangOpts.PointerAuthELFGOT)
13461353
getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1);

clang/test/CodeGen/AArch64/sign-return-address.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@
2828
// NONE-NOT: !"branch-target-enforcement"
2929
// ALL-NOT: !"branch-target-enforcement"
3030
// PART-NOT: !"branch-target-enforcement"
31-
// BTE: !{i32 8, !"branch-target-enforcement", i32 1}
31+
// BTE: !{i32 8, !"branch-target-enforcement", i32 2}
3232
// B-KEY-NOT: !"branch-target-enforcement"
3333

3434
// NONE-NOT: !"sign-return-address"
35-
// ALL: !{i32 8, !"sign-return-address", i32 1}
36-
// PART: !{i32 8, !"sign-return-address", i32 1}
35+
// ALL: !{i32 8, !"sign-return-address", i32 2}
36+
// PART: !{i32 8, !"sign-return-address", i32 2}
3737
// BTE-NOT: !"sign-return-address"
38-
// B-KEY: !{i32 8, !"sign-return-address", i32 1}
38+
// B-KEY: !{i32 8, !"sign-return-address", i32 2}
3939

4040
// NONE-NOT: !"sign-return-address-all"
41-
// ALL: !{i32 8, !"sign-return-address-all", i32 1}
41+
// ALL: !{i32 8, !"sign-return-address-all", i32 2}
4242
// PART-NOT: !"sign-return-address-all"
4343
// BTE-NOT: !"sign-return-address-all"
4444
// B-KEY-NOT: !"sign-return-address-all"
@@ -47,6 +47,6 @@
4747
// ALL-NOT: !"sign-return-address-with-bkey"
4848
// PART-NOT: !"sign-return-address-with-bkey"
4949
// BTE-NOT: !"sign-return-address-with-bkey"
50-
// B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 1}
50+
// B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 2}
5151

5252
void foo() {}

clang/test/CodeGen/arm-branch-protection-attr-2.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@
2323
// NONE-NOT: !"branch-target-enforcement"
2424
// PART-NOT: !"branch-target-enforcement"
2525
// ALL-NOT: !"branch-target-enforcement"
26-
// BTE: !{i32 8, !"branch-target-enforcement", i32 1}
26+
// BTE: !{i32 8, !"branch-target-enforcement", i32 2}
2727

2828
// NONE-NOT: !"sign-return-address"
29-
// PART: !{i32 8, !"sign-return-address", i32 1}
30-
// ALL: !{i32 8, !"sign-return-address", i32 1}
29+
// PART: !{i32 8, !"sign-return-address", i32 2}
30+
// ALL: !{i32 8, !"sign-return-address", i32 2}
3131
// BTE-NOT: !"sign-return-address"
3232

3333
// NONE-NOT: !"sign-return-address-all", i32 0}
3434
// PART-NOT: !"sign-return-address-all", i32 0}
35-
// ALL: !{i32 8, !"sign-return-address-all", i32 1}
35+
// ALL: !{i32 8, !"sign-return-address-all", i32 2}
3636
// BTE-NOT: !"sign-return-address-all", i32 0}
3737

3838
void foo() {}

clang/test/Frontend/arm-ignore-branch-protection-option.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ __attribute__((target("arch=cortex-m0"))) void f() {}
1515
// CHECK-NOT: attributes { {{.*}} "branch-target-enforcement"
1616

1717
/// Check that there are branch protection module attributes despite the warning.
18-
// CHECK: !{i32 8, !"branch-target-enforcement", i32 1}
18+
// CHECK: !{i32 8, !"branch-target-enforcement", i32 2}

llvm/include/llvm/IR/AutoUpgrade.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ namespace llvm {
9696
/// info. Return true if module is modified.
9797
LLVM_ABI bool UpgradeDebugInfo(Module &M);
9898

99+
/// Copies module attributes to the functions in the module.
100+
/// Currently only effects ARM, Thumb and AArch64 targets.
101+
/// Supported attributes:
102+
/// - branch-target-enforcement
103+
/// - branch-protection-pauth-lr
104+
/// - guarded-control-stack
105+
/// - sign-return-address
106+
/// - sign-return-address-with-bkey
107+
void copyModuleAttrToFunctions(Module &M);
108+
99109
/// Check whether a string looks like an old loop attachment tag.
100110
inline bool mayBeOldLoopAttachmentTag(StringRef Name) {
101111
return Name.starts_with("llvm.vectorizer.");

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
451451
UpgradeModuleFlags(*M);
452452
UpgradeNVVMAnnotations(*M);
453453
UpgradeSectionAttributes(*M);
454+
copyModuleAttrToFunctions(*M);
454455

455456
if (!Slots)
456457
return false;

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7143,6 +7143,8 @@ Error BitcodeReader::materializeModule() {
71437143

71447144
UpgradeARCRuntime(*TheModule);
71457145

7146+
copyModuleAttrToFunctions(*TheModule);
7147+
71467148
return Error::success();
71477149
}
71487150

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6045,6 +6045,120 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
60456045
}
60466046
}
60476047

6048+
// Check if the function attribute is not present and set it.
6049+
static void setFunctionAttrIfNotSet(Function &F, StringRef FnAttrName,
6050+
StringRef Value) {
6051+
if (!F.hasFnAttribute(FnAttrName))
6052+
F.addFnAttr(FnAttrName, Value);
6053+
}
6054+
6055+
// Check if the function attribute is not present and set it if needed.
6056+
// If the attribute is "false" then removes it.
6057+
// If the attribute is "true" resets it to a valueless attribute.
6058+
static void ConvertFunctionAttr(Function &F, bool Set, StringRef FnAttrName) {
6059+
if (!F.hasFnAttribute(FnAttrName)) {
6060+
if (Set)
6061+
F.addFnAttr(FnAttrName);
6062+
} else {
6063+
auto A = F.getFnAttribute(FnAttrName);
6064+
if ("false" == A.getValueAsString())
6065+
F.removeFnAttr(FnAttrName);
6066+
else if ("true" == A.getValueAsString()) {
6067+
F.removeFnAttr(FnAttrName);
6068+
F.addFnAttr(FnAttrName);
6069+
}
6070+
}
6071+
}
6072+
6073+
void llvm::copyModuleAttrToFunctions(Module &M) {
6074+
Triple T(M.getTargetTriple());
6075+
if (!T.isThumb() && !T.isARM() && !T.isAArch64())
6076+
return;
6077+
6078+
uint64_t BTEValue = 0;
6079+
uint64_t BPPLRValue = 0;
6080+
uint64_t GCSValue = 0;
6081+
uint64_t SRAValue = 0;
6082+
uint64_t SRAALLValue = 0;
6083+
uint64_t SRABKeyValue = 0;
6084+
6085+
NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
6086+
if (ModFlags) {
6087+
for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
6088+
MDNode *Op = ModFlags->getOperand(I);
6089+
if (Op->getNumOperands() != 3)
6090+
continue;
6091+
6092+
MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
6093+
auto *CI = mdconst::dyn_extract<ConstantInt>(Op->getOperand(2));
6094+
if (!ID || !CI)
6095+
continue;
6096+
6097+
StringRef IDStr = ID->getString();
6098+
uint64_t *ValPtr = IDStr == "branch-target-enforcement" ? &BTEValue
6099+
: IDStr == "branch-protection-pauth-lr" ? &BPPLRValue
6100+
: IDStr == "guarded-control-stack" ? &GCSValue
6101+
: IDStr == "sign-return-address" ? &SRAValue
6102+
: IDStr == "sign-return-address-all" ? &SRAALLValue
6103+
: IDStr == "sign-return-address-with-bkey"
6104+
? &SRABKeyValue
6105+
: nullptr;
6106+
if (!ValPtr)
6107+
continue;
6108+
6109+
*ValPtr = CI->getZExtValue();
6110+
if (*ValPtr == 2)
6111+
return;
6112+
}
6113+
}
6114+
6115+
bool BTE = BTEValue == 1;
6116+
bool BPPLR = BPPLRValue == 1;
6117+
bool GCS = GCSValue == 1;
6118+
bool SRA = SRAValue == 1;
6119+
6120+
StringRef SignTypeValue = "non-leaf";
6121+
if (SRA && SRAALLValue == 1)
6122+
SignTypeValue = "all";
6123+
6124+
StringRef SignKeyValue = "a_key";
6125+
if (SRA && SRABKeyValue == 1)
6126+
SignKeyValue = "b_key";
6127+
6128+
for (Function &F : M.getFunctionList()) {
6129+
if (F.isDeclaration())
6130+
continue;
6131+
6132+
if (SRA) {
6133+
setFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
6134+
setFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
6135+
} else {
6136+
if (auto A = F.getFnAttribute("sign-return-address");
6137+
A.isValid() && "none" == A.getValueAsString()) {
6138+
F.removeFnAttr("sign-return-address");
6139+
F.removeFnAttr("sign-return-address-key");
6140+
}
6141+
}
6142+
ConvertFunctionAttr(F, BTE, "branch-target-enforcement");
6143+
ConvertFunctionAttr(F, BPPLR, "branch-protection-pauth-lr");
6144+
ConvertFunctionAttr(F, GCS, "guarded-control-stack");
6145+
}
6146+
6147+
if (BTE)
6148+
M.setModuleFlag(llvm::Module::Min, "branch-target-enforcement", 2);
6149+
if (BPPLR)
6150+
M.setModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", 2);
6151+
if (GCS)
6152+
M.setModuleFlag(llvm::Module::Min, "guarded-control-stack", 2);
6153+
if (SRA) {
6154+
M.setModuleFlag(llvm::Module::Min, "sign-return-address", 2);
6155+
if (SRAALLValue == 1)
6156+
M.setModuleFlag(llvm::Module::Min, "sign-return-address-all", 2);
6157+
if (SRABKeyValue == 1)
6158+
M.setModuleFlag(llvm::Module::Min, "sign-return-address-with-bkey", 2);
6159+
}
6160+
}
6161+
60486162
static bool isOldLoopArgument(Metadata *MD) {
60496163
auto *T = dyn_cast_or_null<MDTuple>(MD);
60506164
if (!T)

llvm/lib/Linker/IRMover.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,11 @@ Error IRLinker::run() {
15121512
// Loop over all of the linked values to compute type mappings.
15131513
computeTypeMapping();
15141514

1515+
// Convert module level attributes to function level attributes because
1516+
// after merging modules the attributes might change and would have different
1517+
// effect on the functions as the original module would have.
1518+
copyModuleAttrToFunctions(*SrcM);
1519+
15151520
std::reverse(Worklist.begin(), Worklist.end());
15161521
while (!Worklist.empty()) {
15171522
GlobalValue *GV = Worklist.back();
@@ -1677,6 +1682,11 @@ IRMover::IRMover(Module &M) : Composite(M) {
16771682
for (const auto *MD : StructTypes.getVisitedMetadata()) {
16781683
SharedMDs[MD].reset(const_cast<MDNode *>(MD));
16791684
}
1685+
1686+
// Convert module level attributes to function level attributes because
1687+
// after merging modules the attributes might change and would have different
1688+
// effect on the functions as the original module would have.
1689+
copyModuleAttrToFunctions(M);
16801690
}
16811691

16821692
Error IRMover::move(std::unique_ptr<Module> Src,

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ void ARMAsmPrinter::emitAttributes() {
820820

821821
auto *BTIValue = mdconst::extract_or_null<ConstantInt>(
822822
SourceModule->getModuleFlag("branch-target-enforcement"));
823-
if (BTIValue && BTIValue->isOne()) {
823+
if (BTIValue && !BTIValue->isZero()) {
824824
// If "+pacbti" is used as an architecture extension,
825825
// Tag_BTI_extension is emitted in
826826
// ARMTargetStreamer::emitTargetAttributes().

0 commit comments

Comments
 (0)