SymbolRewriter.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- SymbolRewriter.h - Symbol Rewriting Pass -----------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file provides the prototypes and definitions related to the Symbol
  15. // Rewriter pass.
  16. //
  17. // The Symbol Rewriter pass takes a set of rewrite descriptors which define
  18. // transformations for symbol names. These can be either single name to name
  19. // trnsformation or more broad regular expression based transformations.
  20. //
  21. // All the functions are re-written at the IR level. The Symbol Rewriter itself
  22. // is exposed as a module level pass. All symbols at the module level are
  23. // iterated. For any matching symbol, the requested transformation is applied,
  24. // updating references to it as well (a la RAUW). The resulting binary will
  25. // only contain the rewritten symbols.
  26. //
  27. // By performing this operation in the compiler, we are able to catch symbols
  28. // that would otherwise not be possible to catch (e.g. inlined symbols).
  29. //
  30. // This makes it possible to cleanly transform symbols without resorting to
  31. // overly-complex macro tricks and the pre-processor. An example of where this
  32. // is useful is the sanitizers where we would like to intercept a well-defined
  33. // set of functions across the module.
  34. //
  35. //===----------------------------------------------------------------------===//
  36. #ifndef LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
  37. #define LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
  38. #include "llvm/IR/PassManager.h"
  39. #include <list>
  40. #include <memory>
  41. #include <string>
  42. namespace llvm {
  43. class MemoryBuffer;
  44. class Module;
  45. class ModulePass;
  46. namespace yaml {
  47. class KeyValueNode;
  48. class MappingNode;
  49. class ScalarNode;
  50. class Stream;
  51. } // end namespace yaml
  52. namespace SymbolRewriter {
  53. /// The basic entity representing a rewrite operation. It serves as the base
  54. /// class for any rewrite descriptor. It has a certain set of specializations
  55. /// which describe a particular rewrite.
  56. ///
  57. /// The RewriteMapParser can be used to parse a mapping file that provides the
  58. /// mapping for rewriting the symbols. The descriptors individually describe
  59. /// whether to rewrite a function, global variable, or global alias. Each of
  60. /// these can be selected either by explicitly providing a name for the ones to
  61. /// be rewritten or providing a (posix compatible) regular expression that will
  62. /// select the symbols to rewrite. This descriptor list is passed to the
  63. /// SymbolRewriter pass.
  64. class RewriteDescriptor {
  65. public:
  66. enum class Type {
  67. Invalid, /// invalid
  68. Function, /// function - descriptor rewrites a function
  69. GlobalVariable, /// global variable - descriptor rewrites a global variable
  70. NamedAlias, /// named alias - descriptor rewrites a global alias
  71. };
  72. RewriteDescriptor(const RewriteDescriptor &) = delete;
  73. RewriteDescriptor &operator=(const RewriteDescriptor &) = delete;
  74. virtual ~RewriteDescriptor() = default;
  75. Type getType() const { return Kind; }
  76. virtual bool performOnModule(Module &M) = 0;
  77. protected:
  78. explicit RewriteDescriptor(Type T) : Kind(T) {}
  79. private:
  80. const Type Kind;
  81. };
  82. using RewriteDescriptorList = std::list<std::unique_ptr<RewriteDescriptor>>;
  83. class RewriteMapParser {
  84. public:
  85. bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors);
  86. private:
  87. bool parse(std::unique_ptr<MemoryBuffer> &MapFile, RewriteDescriptorList *DL);
  88. bool parseEntry(yaml::Stream &Stream, yaml::KeyValueNode &Entry,
  89. RewriteDescriptorList *DL);
  90. bool parseRewriteFunctionDescriptor(yaml::Stream &Stream,
  91. yaml::ScalarNode *Key,
  92. yaml::MappingNode *Value,
  93. RewriteDescriptorList *DL);
  94. bool parseRewriteGlobalVariableDescriptor(yaml::Stream &Stream,
  95. yaml::ScalarNode *Key,
  96. yaml::MappingNode *Value,
  97. RewriteDescriptorList *DL);
  98. bool parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
  99. yaml::MappingNode *V,
  100. RewriteDescriptorList *DL);
  101. };
  102. } // end namespace SymbolRewriter
  103. ModulePass *createRewriteSymbolsPass();
  104. ModulePass *createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &);
  105. class RewriteSymbolPass : public PassInfoMixin<RewriteSymbolPass> {
  106. public:
  107. RewriteSymbolPass() { loadAndParseMapFiles(); }
  108. RewriteSymbolPass(SymbolRewriter::RewriteDescriptorList &DL) {
  109. Descriptors.splice(Descriptors.begin(), DL);
  110. }
  111. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  112. // Glue for old PM
  113. bool runImpl(Module &M);
  114. private:
  115. void loadAndParseMapFiles();
  116. SymbolRewriter::RewriteDescriptorList Descriptors;
  117. };
  118. } // end namespace llvm
  119. #endif // LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
  120. #ifdef __GNUC__
  121. #pragma GCC diagnostic pop
  122. #endif