//===---- IndirectThunks.h - Indirect thunk insertion helpers ---*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// Contains a base ThunkInserter class that simplifies injection of MI thunks /// as well as a default implementation of MachineFunctionPass wrapping /// several `ThunkInserter`s for targets to extend. /// //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_INDIRECTTHUNKS_H #define LLVM_CODEGEN_INDIRECTTHUNKS_H #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" namespace llvm { /// This class assists in inserting MI thunk functions into the module and /// rewriting the existing machine functions to call these thunks. /// /// One of the common cases is implementing security mitigations that involve /// replacing some machine code patterns with calls to special thunk functions. /// /// Inserting a module pass late in the codegen pipeline may increase memory /// usage, as it serializes the transformations and forces preceding passes to /// produce machine code for all functions before running the module pass. /// For that reason, ThunkInserter can be driven by a MachineFunctionPass by /// passing one MachineFunction at a time to its `run(MMI, MF)` method. /// Then, the derived class should /// * call createThunkFunction from its insertThunks method exactly once for /// each of the thunk functions to be inserted /// * populate the thunk in its populateThunk method /// /// Note that if some other pass is responsible for rewriting the functions, /// the insertThunks method may simply create all possible thunks at once, /// probably postponed until the first occurrence of possibly affected MF. /// /// Alternatively, insertThunks method can rewrite MF by itself and only insert /// the thunks being called. In that case InsertedThunks variable can be used /// to track which thunks were already inserted. /// /// In any case, the thunk function has to be inserted on behalf of some other /// function and then populated on its own "iteration" later - this is because /// MachineFunctionPass will see the newly created functions, but they first /// have to go through the preceding passes from the same pass manager, /// possibly even through the instruction selector. // // FIXME Maybe implement a documented and less surprising way of modifying // the module from a MachineFunctionPass that is restricted to inserting // completely new functions to the module. template <typename Derived, typename InsertedThunksTy = bool> class ThunkInserter { … }; template <typename Derived, typename InsertedThunksTy> void ThunkInserter<Derived, InsertedThunksTy>::createThunkFunction( MachineModuleInfo &MMI, StringRef Name, bool Comdat, StringRef TargetAttrs) { … } template <typename Derived, typename InsertedThunksTy> bool ThunkInserter<Derived, InsertedThunksTy>::run(MachineModuleInfo &MMI, MachineFunction &MF) { … } /// Basic implementation of MachineFunctionPass wrapping one or more /// `ThunkInserter`s passed as type parameters. template <typename... Inserters> class ThunkInserterPass : public MachineFunctionPass { … }; } // namespace llvm #endif