SymbolRewriter.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. //===- SymbolRewriter.cpp - Symbol Rewriter -------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // SymbolRewriter is a LLVM pass which can rewrite symbols transparently within
  10. // existing code. It is implemented as a compiler pass and is configured via a
  11. // YAML configuration file.
  12. //
  13. // The YAML configuration file format is as follows:
  14. //
  15. // RewriteMapFile := RewriteDescriptors
  16. // RewriteDescriptors := RewriteDescriptor | RewriteDescriptors
  17. // RewriteDescriptor := RewriteDescriptorType ':' '{' RewriteDescriptorFields '}'
  18. // RewriteDescriptorFields := RewriteDescriptorField | RewriteDescriptorFields
  19. // RewriteDescriptorField := FieldIdentifier ':' FieldValue ','
  20. // RewriteDescriptorType := Identifier
  21. // FieldIdentifier := Identifier
  22. // FieldValue := Identifier
  23. // Identifier := [0-9a-zA-Z]+
  24. //
  25. // Currently, the following descriptor types are supported:
  26. //
  27. // - function: (function rewriting)
  28. // + Source (original name of the function)
  29. // + Target (explicit transformation)
  30. // + Transform (pattern transformation)
  31. // + Naked (boolean, whether the function is undecorated)
  32. // - global variable: (external linkage global variable rewriting)
  33. // + Source (original name of externally visible variable)
  34. // + Target (explicit transformation)
  35. // + Transform (pattern transformation)
  36. // - global alias: (global alias rewriting)
  37. // + Source (original name of the aliased name)
  38. // + Target (explicit transformation)
  39. // + Transform (pattern transformation)
  40. //
  41. // Note that source and exactly one of [Target, Transform] must be provided
  42. //
  43. // New rewrite descriptors can be created. Addding a new rewrite descriptor
  44. // involves:
  45. //
  46. // a) extended the rewrite descriptor kind enumeration
  47. // (<anonymous>::RewriteDescriptor::RewriteDescriptorType)
  48. // b) implementing the new descriptor
  49. // (c.f. <anonymous>::ExplicitRewriteFunctionDescriptor)
  50. // c) extending the rewrite map parser
  51. // (<anonymous>::RewriteMapParser::parseEntry)
  52. //
  53. // Specify to rewrite the symbols using the `-rewrite-symbols` option, and
  54. // specify the map file to use for the rewriting via the `-rewrite-map-file`
  55. // option.
  56. //
  57. //===----------------------------------------------------------------------===//
  58. #include "llvm/Transforms/Utils/SymbolRewriter.h"
  59. #include "llvm/ADT/SmallString.h"
  60. #include "llvm/ADT/StringRef.h"
  61. #include "llvm/ADT/ilist.h"
  62. #include "llvm/ADT/iterator_range.h"
  63. #include "llvm/IR/Comdat.h"
  64. #include "llvm/IR/Function.h"
  65. #include "llvm/IR/GlobalAlias.h"
  66. #include "llvm/IR/GlobalObject.h"
  67. #include "llvm/IR/GlobalVariable.h"
  68. #include "llvm/IR/Module.h"
  69. #include "llvm/IR/Value.h"
  70. #include "llvm/InitializePasses.h"
  71. #include "llvm/Pass.h"
  72. #include "llvm/Support/Casting.h"
  73. #include "llvm/Support/CommandLine.h"
  74. #include "llvm/Support/ErrorHandling.h"
  75. #include "llvm/Support/ErrorOr.h"
  76. #include "llvm/Support/MemoryBuffer.h"
  77. #include "llvm/Support/Regex.h"
  78. #include "llvm/Support/SourceMgr.h"
  79. #include "llvm/Support/YAMLParser.h"
  80. #include <memory>
  81. #include <string>
  82. #include <vector>
  83. using namespace llvm;
  84. using namespace SymbolRewriter;
  85. #define DEBUG_TYPE "symbol-rewriter"
  86. static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
  87. cl::desc("Symbol Rewrite Map"),
  88. cl::value_desc("filename"),
  89. cl::Hidden);
  90. static void rewriteComdat(Module &M, GlobalObject *GO,
  91. const std::string &Source,
  92. const std::string &Target) {
  93. if (Comdat *CD = GO->getComdat()) {
  94. auto &Comdats = M.getComdatSymbolTable();
  95. Comdat *C = M.getOrInsertComdat(Target);
  96. C->setSelectionKind(CD->getSelectionKind());
  97. GO->setComdat(C);
  98. Comdats.erase(Comdats.find(Source));
  99. }
  100. }
  101. namespace {
  102. template <RewriteDescriptor::Type DT, typename ValueType,
  103. ValueType *(Module::*Get)(StringRef) const>
  104. class ExplicitRewriteDescriptor : public RewriteDescriptor {
  105. public:
  106. const std::string Source;
  107. const std::string Target;
  108. ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked)
  109. : RewriteDescriptor(DT),
  110. Source(std::string(Naked ? StringRef("\01" + S.str()) : S)),
  111. Target(std::string(T)) {}
  112. bool performOnModule(Module &M) override;
  113. static bool classof(const RewriteDescriptor *RD) {
  114. return RD->getType() == DT;
  115. }
  116. };
  117. } // end anonymous namespace
  118. template <RewriteDescriptor::Type DT, typename ValueType,
  119. ValueType *(Module::*Get)(StringRef) const>
  120. bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
  121. bool Changed = false;
  122. if (ValueType *S = (M.*Get)(Source)) {
  123. if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
  124. rewriteComdat(M, GO, Source, Target);
  125. if (Value *T = (M.*Get)(Target))
  126. S->setValueName(T->getValueName());
  127. else
  128. S->setName(Target);
  129. Changed = true;
  130. }
  131. return Changed;
  132. }
  133. namespace {
  134. template <RewriteDescriptor::Type DT, typename ValueType,
  135. ValueType *(Module::*Get)(StringRef) const,
  136. iterator_range<typename iplist<ValueType>::iterator>
  137. (Module::*Iterator)()>
  138. class PatternRewriteDescriptor : public RewriteDescriptor {
  139. public:
  140. const std::string Pattern;
  141. const std::string Transform;
  142. PatternRewriteDescriptor(StringRef P, StringRef T)
  143. : RewriteDescriptor(DT), Pattern(std::string(P)),
  144. Transform(std::string(T)) {}
  145. bool performOnModule(Module &M) override;
  146. static bool classof(const RewriteDescriptor *RD) {
  147. return RD->getType() == DT;
  148. }
  149. };
  150. } // end anonymous namespace
  151. template <RewriteDescriptor::Type DT, typename ValueType,
  152. ValueType *(Module::*Get)(StringRef) const,
  153. iterator_range<typename iplist<ValueType>::iterator>
  154. (Module::*Iterator)()>
  155. bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
  156. performOnModule(Module &M) {
  157. bool Changed = false;
  158. for (auto &C : (M.*Iterator)()) {
  159. std::string Error;
  160. std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
  161. if (!Error.empty())
  162. report_fatal_error(Twine("unable to transforn ") + C.getName() + " in " +
  163. M.getModuleIdentifier() + ": " + Error);
  164. if (C.getName() == Name)
  165. continue;
  166. if (GlobalObject *GO = dyn_cast<GlobalObject>(&C))
  167. rewriteComdat(M, GO, std::string(C.getName()), Name);
  168. if (Value *V = (M.*Get)(Name))
  169. C.setValueName(V->getValueName());
  170. else
  171. C.setName(Name);
  172. Changed = true;
  173. }
  174. return Changed;
  175. }
  176. namespace {
  177. /// Represents a rewrite for an explicitly named (function) symbol. Both the
  178. /// source function name and target function name of the transformation are
  179. /// explicitly spelt out.
  180. using ExplicitRewriteFunctionDescriptor =
  181. ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, Function,
  182. &Module::getFunction>;
  183. /// Represents a rewrite for an explicitly named (global variable) symbol. Both
  184. /// the source variable name and target variable name are spelt out. This
  185. /// applies only to module level variables.
  186. using ExplicitRewriteGlobalVariableDescriptor =
  187. ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
  188. GlobalVariable, &Module::getGlobalVariable>;
  189. /// Represents a rewrite for an explicitly named global alias. Both the source
  190. /// and target name are explicitly spelt out.
  191. using ExplicitRewriteNamedAliasDescriptor =
  192. ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,
  193. &Module::getNamedAlias>;
  194. /// Represents a rewrite for a regular expression based pattern for functions.
  195. /// A pattern for the function name is provided and a transformation for that
  196. /// pattern to determine the target function name create the rewrite rule.
  197. using PatternRewriteFunctionDescriptor =
  198. PatternRewriteDescriptor<RewriteDescriptor::Type::Function, Function,
  199. &Module::getFunction, &Module::functions>;
  200. /// Represents a rewrite for a global variable based upon a matching pattern.
  201. /// Each global variable matching the provided pattern will be transformed as
  202. /// described in the transformation pattern for the target. Applies only to
  203. /// module level variables.
  204. using PatternRewriteGlobalVariableDescriptor =
  205. PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
  206. GlobalVariable, &Module::getGlobalVariable,
  207. &Module::globals>;
  208. /// PatternRewriteNamedAliasDescriptor - represents a rewrite for global
  209. /// aliases which match a given pattern. The provided transformation will be
  210. /// applied to each of the matching names.
  211. using PatternRewriteNamedAliasDescriptor =
  212. PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,
  213. &Module::getNamedAlias, &Module::aliases>;
  214. } // end anonymous namespace
  215. bool RewriteMapParser::parse(const std::string &MapFile,
  216. RewriteDescriptorList *DL) {
  217. ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping =
  218. MemoryBuffer::getFile(MapFile);
  219. if (!Mapping)
  220. report_fatal_error(Twine("unable to read rewrite map '") + MapFile +
  221. "': " + Mapping.getError().message());
  222. if (!parse(*Mapping, DL))
  223. report_fatal_error(Twine("unable to parse rewrite map '") + MapFile + "'");
  224. return true;
  225. }
  226. bool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile,
  227. RewriteDescriptorList *DL) {
  228. SourceMgr SM;
  229. yaml::Stream YS(MapFile->getBuffer(), SM);
  230. for (auto &Document : YS) {
  231. yaml::MappingNode *DescriptorList;
  232. // ignore empty documents
  233. if (isa<yaml::NullNode>(Document.getRoot()))
  234. continue;
  235. DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot());
  236. if (!DescriptorList) {
  237. YS.printError(Document.getRoot(), "DescriptorList node must be a map");
  238. return false;
  239. }
  240. for (auto &Descriptor : *DescriptorList)
  241. if (!parseEntry(YS, Descriptor, DL))
  242. return false;
  243. }
  244. return true;
  245. }
  246. bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,
  247. RewriteDescriptorList *DL) {
  248. yaml::ScalarNode *Key;
  249. yaml::MappingNode *Value;
  250. SmallString<32> KeyStorage;
  251. StringRef RewriteType;
  252. Key = dyn_cast<yaml::ScalarNode>(Entry.getKey());
  253. if (!Key) {
  254. YS.printError(Entry.getKey(), "rewrite type must be a scalar");
  255. return false;
  256. }
  257. Value = dyn_cast<yaml::MappingNode>(Entry.getValue());
  258. if (!Value) {
  259. YS.printError(Entry.getValue(), "rewrite descriptor must be a map");
  260. return false;
  261. }
  262. RewriteType = Key->getValue(KeyStorage);
  263. if (RewriteType.equals("function"))
  264. return parseRewriteFunctionDescriptor(YS, Key, Value, DL);
  265. else if (RewriteType.equals("global variable"))
  266. return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);
  267. else if (RewriteType.equals("global alias"))
  268. return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);
  269. YS.printError(Entry.getKey(), "unknown rewrite type");
  270. return false;
  271. }
  272. bool RewriteMapParser::
  273. parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
  274. yaml::MappingNode *Descriptor,
  275. RewriteDescriptorList *DL) {
  276. bool Naked = false;
  277. std::string Source;
  278. std::string Target;
  279. std::string Transform;
  280. for (auto &Field : *Descriptor) {
  281. yaml::ScalarNode *Key;
  282. yaml::ScalarNode *Value;
  283. SmallString<32> KeyStorage;
  284. SmallString<32> ValueStorage;
  285. StringRef KeyValue;
  286. Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
  287. if (!Key) {
  288. YS.printError(Field.getKey(), "descriptor key must be a scalar");
  289. return false;
  290. }
  291. Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
  292. if (!Value) {
  293. YS.printError(Field.getValue(), "descriptor value must be a scalar");
  294. return false;
  295. }
  296. KeyValue = Key->getValue(KeyStorage);
  297. if (KeyValue.equals("source")) {
  298. std::string Error;
  299. Source = std::string(Value->getValue(ValueStorage));
  300. if (!Regex(Source).isValid(Error)) {
  301. YS.printError(Field.getKey(), "invalid regex: " + Error);
  302. return false;
  303. }
  304. } else if (KeyValue.equals("target")) {
  305. Target = std::string(Value->getValue(ValueStorage));
  306. } else if (KeyValue.equals("transform")) {
  307. Transform = std::string(Value->getValue(ValueStorage));
  308. } else if (KeyValue.equals("naked")) {
  309. std::string Undecorated;
  310. Undecorated = std::string(Value->getValue(ValueStorage));
  311. Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1";
  312. } else {
  313. YS.printError(Field.getKey(), "unknown key for function");
  314. return false;
  315. }
  316. }
  317. if (Transform.empty() == Target.empty()) {
  318. YS.printError(Descriptor,
  319. "exactly one of transform or target must be specified");
  320. return false;
  321. }
  322. // TODO see if there is a more elegant solution to selecting the rewrite
  323. // descriptor type
  324. if (!Target.empty())
  325. DL->push_back(std::make_unique<ExplicitRewriteFunctionDescriptor>(
  326. Source, Target, Naked));
  327. else
  328. DL->push_back(
  329. std::make_unique<PatternRewriteFunctionDescriptor>(Source, Transform));
  330. return true;
  331. }
  332. bool RewriteMapParser::
  333. parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
  334. yaml::MappingNode *Descriptor,
  335. RewriteDescriptorList *DL) {
  336. std::string Source;
  337. std::string Target;
  338. std::string Transform;
  339. for (auto &Field : *Descriptor) {
  340. yaml::ScalarNode *Key;
  341. yaml::ScalarNode *Value;
  342. SmallString<32> KeyStorage;
  343. SmallString<32> ValueStorage;
  344. StringRef KeyValue;
  345. Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
  346. if (!Key) {
  347. YS.printError(Field.getKey(), "descriptor Key must be a scalar");
  348. return false;
  349. }
  350. Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
  351. if (!Value) {
  352. YS.printError(Field.getValue(), "descriptor value must be a scalar");
  353. return false;
  354. }
  355. KeyValue = Key->getValue(KeyStorage);
  356. if (KeyValue.equals("source")) {
  357. std::string Error;
  358. Source = std::string(Value->getValue(ValueStorage));
  359. if (!Regex(Source).isValid(Error)) {
  360. YS.printError(Field.getKey(), "invalid regex: " + Error);
  361. return false;
  362. }
  363. } else if (KeyValue.equals("target")) {
  364. Target = std::string(Value->getValue(ValueStorage));
  365. } else if (KeyValue.equals("transform")) {
  366. Transform = std::string(Value->getValue(ValueStorage));
  367. } else {
  368. YS.printError(Field.getKey(), "unknown Key for Global Variable");
  369. return false;
  370. }
  371. }
  372. if (Transform.empty() == Target.empty()) {
  373. YS.printError(Descriptor,
  374. "exactly one of transform or target must be specified");
  375. return false;
  376. }
  377. if (!Target.empty())
  378. DL->push_back(std::make_unique<ExplicitRewriteGlobalVariableDescriptor>(
  379. Source, Target,
  380. /*Naked*/ false));
  381. else
  382. DL->push_back(std::make_unique<PatternRewriteGlobalVariableDescriptor>(
  383. Source, Transform));
  384. return true;
  385. }
  386. bool RewriteMapParser::
  387. parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
  388. yaml::MappingNode *Descriptor,
  389. RewriteDescriptorList *DL) {
  390. std::string Source;
  391. std::string Target;
  392. std::string Transform;
  393. for (auto &Field : *Descriptor) {
  394. yaml::ScalarNode *Key;
  395. yaml::ScalarNode *Value;
  396. SmallString<32> KeyStorage;
  397. SmallString<32> ValueStorage;
  398. StringRef KeyValue;
  399. Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
  400. if (!Key) {
  401. YS.printError(Field.getKey(), "descriptor key must be a scalar");
  402. return false;
  403. }
  404. Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
  405. if (!Value) {
  406. YS.printError(Field.getValue(), "descriptor value must be a scalar");
  407. return false;
  408. }
  409. KeyValue = Key->getValue(KeyStorage);
  410. if (KeyValue.equals("source")) {
  411. std::string Error;
  412. Source = std::string(Value->getValue(ValueStorage));
  413. if (!Regex(Source).isValid(Error)) {
  414. YS.printError(Field.getKey(), "invalid regex: " + Error);
  415. return false;
  416. }
  417. } else if (KeyValue.equals("target")) {
  418. Target = std::string(Value->getValue(ValueStorage));
  419. } else if (KeyValue.equals("transform")) {
  420. Transform = std::string(Value->getValue(ValueStorage));
  421. } else {
  422. YS.printError(Field.getKey(), "unknown key for Global Alias");
  423. return false;
  424. }
  425. }
  426. if (Transform.empty() == Target.empty()) {
  427. YS.printError(Descriptor,
  428. "exactly one of transform or target must be specified");
  429. return false;
  430. }
  431. if (!Target.empty())
  432. DL->push_back(std::make_unique<ExplicitRewriteNamedAliasDescriptor>(
  433. Source, Target,
  434. /*Naked*/ false));
  435. else
  436. DL->push_back(std::make_unique<PatternRewriteNamedAliasDescriptor>(
  437. Source, Transform));
  438. return true;
  439. }
  440. namespace {
  441. class RewriteSymbolsLegacyPass : public ModulePass {
  442. public:
  443. static char ID; // Pass identification, replacement for typeid
  444. RewriteSymbolsLegacyPass();
  445. RewriteSymbolsLegacyPass(SymbolRewriter::RewriteDescriptorList &DL);
  446. bool runOnModule(Module &M) override;
  447. private:
  448. RewriteSymbolPass Impl;
  449. };
  450. } // end anonymous namespace
  451. char RewriteSymbolsLegacyPass::ID = 0;
  452. RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass() : ModulePass(ID) {
  453. initializeRewriteSymbolsLegacyPassPass(*PassRegistry::getPassRegistry());
  454. }
  455. RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass(
  456. SymbolRewriter::RewriteDescriptorList &DL)
  457. : ModulePass(ID), Impl(DL) {}
  458. bool RewriteSymbolsLegacyPass::runOnModule(Module &M) {
  459. return Impl.runImpl(M);
  460. }
  461. PreservedAnalyses RewriteSymbolPass::run(Module &M, ModuleAnalysisManager &AM) {
  462. if (!runImpl(M))
  463. return PreservedAnalyses::all();
  464. return PreservedAnalyses::none();
  465. }
  466. bool RewriteSymbolPass::runImpl(Module &M) {
  467. bool Changed;
  468. Changed = false;
  469. for (auto &Descriptor : Descriptors)
  470. Changed |= Descriptor->performOnModule(M);
  471. return Changed;
  472. }
  473. void RewriteSymbolPass::loadAndParseMapFiles() {
  474. const std::vector<std::string> MapFiles(RewriteMapFiles);
  475. SymbolRewriter::RewriteMapParser Parser;
  476. for (const auto &MapFile : MapFiles)
  477. Parser.parse(MapFile, &Descriptors);
  478. }
  479. INITIALIZE_PASS(RewriteSymbolsLegacyPass, "rewrite-symbols", "Rewrite Symbols",
  480. false, false)
  481. ModulePass *llvm::createRewriteSymbolsPass() {
  482. return new RewriteSymbolsLegacyPass();
  483. }
  484. ModulePass *
  485. llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) {
  486. return new RewriteSymbolsLegacyPass(DL);
  487. }