Index: llvm/include/llvm/CodeGen/IndirectThunks.h =================================================================== --- llvm/include/llvm/CodeGen/IndirectThunks.h +++ llvm/include/llvm/CodeGen/IndirectThunks.h @@ -27,7 +27,8 @@ protected: bool InsertedThunks; void doInitialization(Module &M) {} - void createThunkFunction(MachineModuleInfo &MMI, StringRef Name); + void createThunkFunction(MachineModuleInfo &MMI, StringRef Name, + bool Comdat = true); public: void init(Module &M) { @@ -40,17 +41,21 @@ template void ThunkInserter::createThunkFunction(MachineModuleInfo &MMI, - StringRef Name) { + StringRef Name, bool Comdat) { assert(Name.startswith(getDerived().getThunkPrefix()) && "Created a thunk with an unexpected prefix!"); Module &M = const_cast(*MMI.getModule()); LLVMContext &Ctx = M.getContext(); auto Type = FunctionType::get(Type::getVoidTy(Ctx), false); - Function *F = - Function::Create(Type, GlobalValue::LinkOnceODRLinkage, Name, &M); - F->setVisibility(GlobalValue::HiddenVisibility); - F->setComdat(M.getOrInsertComdat(Name)); + Function *F = Function::Create(Type, + Comdat ? GlobalValue::LinkOnceODRLinkage + : GlobalValue::InternalLinkage, + Name, &M); + if (Comdat) { + F->setVisibility(GlobalValue::HiddenVisibility); + F->setComdat(M.getOrInsertComdat(Name)); + } // Add Attributes so that we don't create a frame, unwind information, or // inline. Index: llvm/lib/Target/AArch64/AArch64SLSHardening.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64SLSHardening.cpp +++ llvm/lib/Target/AArch64/AArch64SLSHardening.cpp @@ -38,6 +38,10 @@ #define AARCH64_SLS_HARDENING_NAME "AArch64 sls hardening pass" +static cl::opt + ComdatThunks("aarch64-sls-hardening-comdat", + cl::desc("Output SLS hardening thunks in comdats"), + cl::init(true), cl::Hidden); namespace { class AArch64SLSHardening : public MachineFunctionPass { @@ -200,7 +204,7 @@ // based on which registers are actually used in BLR instructions in this // function. But would that be a worthwhile optimization? for (auto T : SLSBLRThunks) - createThunkFunction(MMI, T.Name); + createThunkFunction(MMI, T.Name, ComdatThunks); } void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) { Index: llvm/lib/Target/ARM/ARMSLSHardening.cpp =================================================================== --- llvm/lib/Target/ARM/ARMSLSHardening.cpp +++ llvm/lib/Target/ARM/ARMSLSHardening.cpp @@ -30,6 +30,11 @@ #define ARM_SLS_HARDENING_NAME "ARM sls hardening pass" +static cl::opt + ComdatThunks("arm-sls-hardening-comdat", + cl::desc("Output SLS hardening thunks in comdats"), + cl::init(true), cl::Hidden); + namespace { class ARMSLSHardening : public MachineFunctionPass { @@ -179,7 +184,7 @@ // based on which registers are actually used in indirect calls in this // function. But would that be a worthwhile optimization? for (auto T : SLSBLRThunks) - createThunkFunction(MMI, T.Name); + createThunkFunction(MMI, T.Name, ComdatThunks); } void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) {