Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:44

0001 //===- SymbolRewriter.h - Symbol Rewriting Pass -----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file provides the prototypes and definitions related to the Symbol
0010 // Rewriter pass.
0011 //
0012 // The Symbol Rewriter pass takes a set of rewrite descriptors which define
0013 // transformations for symbol names.  These can be either single name to name
0014 // trnsformation or more broad regular expression based transformations.
0015 //
0016 // All the functions are re-written at the IR level.  The Symbol Rewriter itself
0017 // is exposed as a module level pass.  All symbols at the module level are
0018 // iterated.  For any matching symbol, the requested transformation is applied,
0019 // updating references to it as well (a la RAUW).  The resulting binary will
0020 // only contain the rewritten symbols.
0021 //
0022 // By performing this operation in the compiler, we are able to catch symbols
0023 // that would otherwise not be possible to catch (e.g. inlined symbols).
0024 //
0025 // This makes it possible to cleanly transform symbols without resorting to
0026 // overly-complex macro tricks and the pre-processor.  An example of where this
0027 // is useful is the sanitizers where we would like to intercept a well-defined
0028 // set of functions across the module.
0029 //
0030 //===----------------------------------------------------------------------===//
0031 
0032 #ifndef LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
0033 #define LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
0034 
0035 #include "llvm/IR/PassManager.h"
0036 #include <list>
0037 #include <memory>
0038 #include <string>
0039 
0040 namespace llvm {
0041 
0042 class MemoryBuffer;
0043 class Module;
0044 
0045 namespace yaml {
0046 
0047 class KeyValueNode;
0048 class MappingNode;
0049 class ScalarNode;
0050 class Stream;
0051 
0052 } // end namespace yaml
0053 
0054 namespace SymbolRewriter {
0055 
0056 /// The basic entity representing a rewrite operation.  It serves as the base
0057 /// class for any rewrite descriptor.  It has a certain set of specializations
0058 /// which describe a particular rewrite.
0059 ///
0060 /// The RewriteMapParser can be used to parse a mapping file that provides the
0061 /// mapping for rewriting the symbols.  The descriptors individually describe
0062 /// whether to rewrite a function, global variable, or global alias.  Each of
0063 /// these can be selected either by explicitly providing a name for the ones to
0064 /// be rewritten or providing a (posix compatible) regular expression that will
0065 /// select the symbols to rewrite.  This descriptor list is passed to the
0066 /// SymbolRewriter pass.
0067 class RewriteDescriptor {
0068 public:
0069   enum class Type {
0070     Invalid,        /// invalid
0071     Function,       /// function - descriptor rewrites a function
0072     GlobalVariable, /// global variable - descriptor rewrites a global variable
0073     NamedAlias,     /// named alias - descriptor rewrites a global alias
0074   };
0075 
0076   RewriteDescriptor(const RewriteDescriptor &) = delete;
0077   RewriteDescriptor &operator=(const RewriteDescriptor &) = delete;
0078   virtual ~RewriteDescriptor() = default;
0079 
0080   Type getType() const { return Kind; }
0081 
0082   virtual bool performOnModule(Module &M) = 0;
0083 
0084 protected:
0085   explicit RewriteDescriptor(Type T) : Kind(T) {}
0086 
0087 private:
0088   const Type Kind;
0089 };
0090 
0091 using RewriteDescriptorList = std::list<std::unique_ptr<RewriteDescriptor>>;
0092 
0093 class RewriteMapParser {
0094 public:
0095   bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors);
0096 
0097 private:
0098   bool parse(std::unique_ptr<MemoryBuffer> &MapFile, RewriteDescriptorList *DL);
0099   bool parseEntry(yaml::Stream &Stream, yaml::KeyValueNode &Entry,
0100                   RewriteDescriptorList *DL);
0101   bool parseRewriteFunctionDescriptor(yaml::Stream &Stream,
0102                                       yaml::ScalarNode *Key,
0103                                       yaml::MappingNode *Value,
0104                                       RewriteDescriptorList *DL);
0105   bool parseRewriteGlobalVariableDescriptor(yaml::Stream &Stream,
0106                                             yaml::ScalarNode *Key,
0107                                             yaml::MappingNode *Value,
0108                                             RewriteDescriptorList *DL);
0109   bool parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
0110                                          yaml::MappingNode *V,
0111                                          RewriteDescriptorList *DL);
0112 };
0113 
0114 } // end namespace SymbolRewriter
0115 
0116 class RewriteSymbolPass : public PassInfoMixin<RewriteSymbolPass> {
0117 public:
0118   RewriteSymbolPass() { loadAndParseMapFiles(); }
0119 
0120   RewriteSymbolPass(SymbolRewriter::RewriteDescriptorList &DL) {
0121     Descriptors.splice(Descriptors.begin(), DL);
0122   }
0123 
0124   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
0125 
0126   // Glue for old PM
0127   bool runImpl(Module &M);
0128 
0129 private:
0130   void loadAndParseMapFiles();
0131 
0132   SymbolRewriter::RewriteDescriptorList Descriptors;
0133 };
0134 
0135 } // end namespace llvm
0136 
0137 #endif // LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H