@@ -5296,6 +5296,106 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
52965296 }
52975297}
52985298
5299+ // Check if the module attribute is present and set to one.
5300+ static bool isModuleAttributeOne (Module &M, const StringRef &ModAttr) {
5301+ const auto *Attr =
5302+ mdconst::extract_or_null<ConstantInt>(M.getModuleFlag (ModAttr));
5303+ return Attr && Attr->isOne ();
5304+ }
5305+
5306+ // Check if the module attribute is present and set to two.
5307+ static bool isModuleAttributeTwo (Module &M, const StringRef &ModAttr) {
5308+ const auto *Attr =
5309+ mdconst::extract_or_null<ConstantInt>(M.getModuleFlag (ModAttr));
5310+ return Attr && Attr->getZExtValue () == 2 ;
5311+ }
5312+
5313+ // Check if the function attribute is not present and set it.
5314+ static void SetFunctionAttrIfNotSet (Function &F, StringRef FnAttrName,
5315+ StringRef Value) {
5316+ if (!F.hasFnAttribute (FnAttrName))
5317+ F.addFnAttr (FnAttrName, Value);
5318+ }
5319+
5320+ // Check if the function attribute is not present and set it if needed.
5321+ // If the attribute is "false" then removes it.
5322+ // If the attribute is "true" resets it to a valueless attribute.
5323+ static void ConvertFunctionAttr (Function &F, bool Set, StringRef FnAttrName) {
5324+ if (!F.hasFnAttribute (FnAttrName)) {
5325+ if (Set)
5326+ F.addFnAttr (FnAttrName);
5327+ } else {
5328+ auto A = F.getFnAttribute (FnAttrName);
5329+ if (" false" == A.getValueAsString ())
5330+ F.removeFnAttr (FnAttrName);
5331+ else if (" true" == A.getValueAsString ()) {
5332+ F.removeFnAttr (FnAttrName);
5333+ F.addFnAttr (FnAttrName);
5334+ }
5335+ }
5336+ }
5337+
5338+ void llvm::CopyModuleAttrToFunctions (Module &M) {
5339+ Triple T (M.getTargetTriple ());
5340+ if (!T.isThumb () && !T.isARM () && !T.isAArch64 ())
5341+ return ;
5342+
5343+ if (isModuleAttributeTwo (M, " branch-target-enforcement" ))
5344+ return ;
5345+ if (isModuleAttributeTwo (M, " branch-protection-pauth-lr" ))
5346+ return ;
5347+ if (isModuleAttributeTwo (M, " guarded-control-stack" ))
5348+ return ;
5349+ if (isModuleAttributeTwo (M, " sign-return-address" ))
5350+ return ;
5351+
5352+ bool BTE = isModuleAttributeOne (M, " branch-target-enforcement" );
5353+ bool BPPLR = isModuleAttributeOne (M, " branch-protection-pauth-lr" );
5354+ bool GCS = isModuleAttributeOne (M, " guarded-control-stack" );
5355+ bool SRA = isModuleAttributeOne (M, " sign-return-address" );
5356+
5357+ StringRef SignTypeValue = " non-leaf" ;
5358+ if (SRA && isModuleAttributeOne (M, " sign-return-address-all" ))
5359+ SignTypeValue = " all" ;
5360+
5361+ StringRef SignKeyValue = " a_key" ;
5362+ if (SRA && isModuleAttributeOne (M, " sign-return-address-with-bkey" ))
5363+ SignKeyValue = " b_key" ;
5364+
5365+ for (Function &F : M.getFunctionList ()) {
5366+ if (F.isDeclaration ())
5367+ continue ;
5368+
5369+ if (SRA) {
5370+ SetFunctionAttrIfNotSet (F, " sign-return-address" , SignTypeValue);
5371+ SetFunctionAttrIfNotSet (F, " sign-return-address-key" , SignKeyValue);
5372+ } else {
5373+ if (auto A = F.getFnAttribute (" sign-return-address" );
5374+ A.isValid () && " none" == A.getValueAsString ()) {
5375+ F.removeFnAttr (" sign-return-address" );
5376+ F.removeFnAttr (" sign-return-address-key" );
5377+ }
5378+ }
5379+ ConvertFunctionAttr (F, BTE, " branch-target-enforcement" );
5380+ ConvertFunctionAttr (F, BPPLR, " branch-protection-pauth-lr" );
5381+ ConvertFunctionAttr (F, GCS, " guarded-control-stack" );
5382+ }
5383+
5384+ if (BTE)
5385+ M.setModuleFlag (llvm::Module::Min, " branch-target-enforcement" , 2 );
5386+ if (BPPLR)
5387+ M.setModuleFlag (llvm::Module::Min, " branch-protection-pauth-lr" , 2 );
5388+ if (GCS)
5389+ M.setModuleFlag (llvm::Module::Min, " guarded-control-stack" , 2 );
5390+ if (SRA) {
5391+ M.setModuleFlag (llvm::Module::Min, " sign-return-address" , 2 );
5392+ if (isModuleAttributeOne (M, " sign-return-address-all" ))
5393+ M.setModuleFlag (llvm::Module::Min, " sign-return-address-all" , 2 );
5394+ if (isModuleAttributeOne (M, " sign-return-address-with-bkey" ))
5395+ M.setModuleFlag (llvm::Module::Min, " sign-return-address-with-bkey" , 2 );
5396+ }
5397+ }
5398+
52995399static bool isOldLoopArgument (Metadata *MD) {
53005400 auto *T = dyn_cast_or_null<MDTuple>(MD);
53015401 if (!T)
0 commit comments