summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/llvm/Transforms/Utils/SymbolRewriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983e/include/llvm/Transforms/Utils/SymbolRewriter.h')
-rw-r--r--clang-r353983e/include/llvm/Transforms/Utils/SymbolRewriter.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/clang-r353983e/include/llvm/Transforms/Utils/SymbolRewriter.h b/clang-r353983e/include/llvm/Transforms/Utils/SymbolRewriter.h
new file mode 100644
index 00000000..ce9dcaf2
--- /dev/null
+++ b/clang-r353983e/include/llvm/Transforms/Utils/SymbolRewriter.h
@@ -0,0 +1,141 @@
+//===- SymbolRewriter.h - Symbol Rewriting Pass -----------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the prototypes and definitions related to the Symbol
+// Rewriter pass.
+//
+// The Symbol Rewriter pass takes a set of rewrite descriptors which define
+// transformations for symbol names. These can be either single name to name
+// trnsformation or more broad regular expression based transformations.
+//
+// All the functions are re-written at the IR level. The Symbol Rewriter itself
+// is exposed as a module level pass. All symbols at the module level are
+// iterated. For any matching symbol, the requested transformation is applied,
+// updating references to it as well (a la RAUW). The resulting binary will
+// only contain the rewritten symbols.
+//
+// By performing this operation in the compiler, we are able to catch symbols
+// that would otherwise not be possible to catch (e.g. inlined symbols).
+//
+// This makes it possible to cleanly transform symbols without resorting to
+// overly-complex macro tricks and the pre-processor. An example of where this
+// is useful is the sanitizers where we would like to intercept a well-defined
+// set of functions across the module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
+#define LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
+
+#include "llvm/IR/PassManager.h"
+#include <list>
+#include <memory>
+#include <string>
+
+namespace llvm {
+
+class MemoryBuffer;
+class Module;
+class ModulePass;
+
+namespace yaml {
+
+class KeyValueNode;
+class MappingNode;
+class ScalarNode;
+class Stream;
+
+} // end namespace yaml
+
+namespace SymbolRewriter {
+
+/// The basic entity representing a rewrite operation. It serves as the base
+/// class for any rewrite descriptor. It has a certain set of specializations
+/// which describe a particular rewrite.
+///
+/// The RewriteMapParser can be used to parse a mapping file that provides the
+/// mapping for rewriting the symbols. The descriptors individually describe
+/// whether to rewrite a function, global variable, or global alias. Each of
+/// these can be selected either by explicitly providing a name for the ones to
+/// be rewritten or providing a (posix compatible) regular expression that will
+/// select the symbols to rewrite. This descriptor list is passed to the
+/// SymbolRewriter pass.
+class RewriteDescriptor {
+public:
+ enum class Type {
+ Invalid, /// invalid
+ Function, /// function - descriptor rewrites a function
+ GlobalVariable, /// global variable - descriptor rewrites a global variable
+ NamedAlias, /// named alias - descriptor rewrites a global alias
+ };
+
+ RewriteDescriptor(const RewriteDescriptor &) = delete;
+ RewriteDescriptor &operator=(const RewriteDescriptor &) = delete;
+ virtual ~RewriteDescriptor() = default;
+
+ Type getType() const { return Kind; }
+
+ virtual bool performOnModule(Module &M) = 0;
+
+protected:
+ explicit RewriteDescriptor(Type T) : Kind(T) {}
+
+private:
+ const Type Kind;
+};
+
+using RewriteDescriptorList = std::list<std::unique_ptr<RewriteDescriptor>>;
+
+class RewriteMapParser {
+public:
+ bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors);
+
+private:
+ bool parse(std::unique_ptr<MemoryBuffer> &MapFile, RewriteDescriptorList *DL);
+ bool parseEntry(yaml::Stream &Stream, yaml::KeyValueNode &Entry,
+ RewriteDescriptorList *DL);
+ bool parseRewriteFunctionDescriptor(yaml::Stream &Stream,
+ yaml::ScalarNode *Key,
+ yaml::MappingNode *Value,
+ RewriteDescriptorList *DL);
+ bool parseRewriteGlobalVariableDescriptor(yaml::Stream &Stream,
+ yaml::ScalarNode *Key,
+ yaml::MappingNode *Value,
+ RewriteDescriptorList *DL);
+ bool parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
+ yaml::MappingNode *V,
+ RewriteDescriptorList *DL);
+};
+
+} // end namespace SymbolRewriter
+
+ModulePass *createRewriteSymbolsPass();
+ModulePass *createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &);
+
+class RewriteSymbolPass : public PassInfoMixin<RewriteSymbolPass> {
+public:
+ RewriteSymbolPass() { loadAndParseMapFiles(); }
+
+ RewriteSymbolPass(SymbolRewriter::RewriteDescriptorList &DL) {
+ Descriptors.splice(Descriptors.begin(), DL);
+ }
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+
+ // Glue for old PM
+ bool runImpl(Module &M);
+
+private:
+ void loadAndParseMapFiles();
+
+ SymbolRewriter::RewriteDescriptorList Descriptors;
+};
+
+} // end namespace llvm
+
+#endif //LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H