]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Transforms/Utils/SymbolRewriter.cpp
Move all sources from the llvm project into contrib/llvm-project.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Transforms / Utils / SymbolRewriter.cpp
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
59 #include "llvm/Transforms/Utils/SymbolRewriter.h"
60 #include "llvm/ADT/STLExtras.h"
61 #include "llvm/ADT/SmallString.h"
62 #include "llvm/ADT/StringRef.h"
63 #include "llvm/ADT/ilist.h"
64 #include "llvm/ADT/iterator_range.h"
65 #include "llvm/IR/Comdat.h"
66 #include "llvm/IR/Function.h"
67 #include "llvm/IR/GlobalAlias.h"
68 #include "llvm/IR/GlobalObject.h"
69 #include "llvm/IR/GlobalVariable.h"
70 #include "llvm/IR/Module.h"
71 #include "llvm/IR/Value.h"
72 #include "llvm/Pass.h"
73 #include "llvm/Support/Casting.h"
74 #include "llvm/Support/CommandLine.h"
75 #include "llvm/Support/ErrorHandling.h"
76 #include "llvm/Support/ErrorOr.h"
77 #include "llvm/Support/MemoryBuffer.h"
78 #include "llvm/Support/Regex.h"
79 #include "llvm/Support/SourceMgr.h"
80 #include "llvm/Support/YAMLParser.h"
81 #include <memory>
82 #include <string>
83 #include <vector>
84
85 using namespace llvm;
86 using namespace SymbolRewriter;
87
88 #define DEBUG_TYPE "symbol-rewriter"
89
90 static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
91                                              cl::desc("Symbol Rewrite Map"),
92                                              cl::value_desc("filename"),
93                                              cl::Hidden);
94
95 static void rewriteComdat(Module &M, GlobalObject *GO,
96                           const std::string &Source,
97                           const std::string &Target) {
98   if (Comdat *CD = GO->getComdat()) {
99     auto &Comdats = M.getComdatSymbolTable();
100
101     Comdat *C = M.getOrInsertComdat(Target);
102     C->setSelectionKind(CD->getSelectionKind());
103     GO->setComdat(C);
104
105     Comdats.erase(Comdats.find(Source));
106   }
107 }
108
109 namespace {
110
111 template <RewriteDescriptor::Type DT, typename ValueType,
112           ValueType *(Module::*Get)(StringRef) const>
113 class ExplicitRewriteDescriptor : public RewriteDescriptor {
114 public:
115   const std::string Source;
116   const std::string Target;
117
118   ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked)
119       : RewriteDescriptor(DT), Source(Naked ? StringRef("\01" + S.str()) : S),
120         Target(T) {}
121
122   bool performOnModule(Module &M) override;
123
124   static bool classof(const RewriteDescriptor *RD) {
125     return RD->getType() == DT;
126   }
127 };
128
129 } // end anonymous namespace
130
131 template <RewriteDescriptor::Type DT, typename ValueType,
132           ValueType *(Module::*Get)(StringRef) const>
133 bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
134   bool Changed = false;
135   if (ValueType *S = (M.*Get)(Source)) {
136     if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
137       rewriteComdat(M, GO, Source, Target);
138
139     if (Value *T = (M.*Get)(Target))
140       S->setValueName(T->getValueName());
141     else
142       S->setName(Target);
143
144     Changed = true;
145   }
146   return Changed;
147 }
148
149 namespace {
150
151 template <RewriteDescriptor::Type DT, typename ValueType,
152           ValueType *(Module::*Get)(StringRef) const,
153           iterator_range<typename iplist<ValueType>::iterator>
154           (Module::*Iterator)()>
155 class PatternRewriteDescriptor : public RewriteDescriptor {
156 public:
157   const std::string Pattern;
158   const std::string Transform;
159
160   PatternRewriteDescriptor(StringRef P, StringRef T)
161     : RewriteDescriptor(DT), Pattern(P), Transform(T) { }
162
163   bool performOnModule(Module &M) override;
164
165   static bool classof(const RewriteDescriptor *RD) {
166     return RD->getType() == DT;
167   }
168 };
169
170 } // end anonymous namespace
171
172 template <RewriteDescriptor::Type DT, typename ValueType,
173           ValueType *(Module::*Get)(StringRef) const,
174           iterator_range<typename iplist<ValueType>::iterator>
175           (Module::*Iterator)()>
176 bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
177 performOnModule(Module &M) {
178   bool Changed = false;
179   for (auto &C : (M.*Iterator)()) {
180     std::string Error;
181
182     std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
183     if (!Error.empty())
184       report_fatal_error("unable to transforn " + C.getName() + " in " +
185                          M.getModuleIdentifier() + ": " + Error);
186
187     if (C.getName() == Name)
188       continue;
189
190     if (GlobalObject *GO = dyn_cast<GlobalObject>(&C))
191       rewriteComdat(M, GO, C.getName(), Name);
192
193     if (Value *V = (M.*Get)(Name))
194       C.setValueName(V->getValueName());
195     else
196       C.setName(Name);
197
198     Changed = true;
199   }
200   return Changed;
201 }
202
203 namespace {
204
205 /// Represents a rewrite for an explicitly named (function) symbol.  Both the
206 /// source function name and target function name of the transformation are
207 /// explicitly spelt out.
208 using ExplicitRewriteFunctionDescriptor =
209     ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, Function,
210                               &Module::getFunction>;
211
212 /// Represents a rewrite for an explicitly named (global variable) symbol.  Both
213 /// the source variable name and target variable name are spelt out.  This
214 /// applies only to module level variables.
215 using ExplicitRewriteGlobalVariableDescriptor =
216     ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
217                               GlobalVariable, &Module::getGlobalVariable>;
218
219 /// Represents a rewrite for an explicitly named global alias.  Both the source
220 /// and target name are explicitly spelt out.
221 using ExplicitRewriteNamedAliasDescriptor =
222     ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,
223                               &Module::getNamedAlias>;
224
225 /// Represents a rewrite for a regular expression based pattern for functions.
226 /// A pattern for the function name is provided and a transformation for that
227 /// pattern to determine the target function name create the rewrite rule.
228 using PatternRewriteFunctionDescriptor =
229     PatternRewriteDescriptor<RewriteDescriptor::Type::Function, Function,
230                              &Module::getFunction, &Module::functions>;
231
232 /// Represents a rewrite for a global variable based upon a matching pattern.
233 /// Each global variable matching the provided pattern will be transformed as
234 /// described in the transformation pattern for the target.  Applies only to
235 /// module level variables.
236 using PatternRewriteGlobalVariableDescriptor =
237     PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
238                              GlobalVariable, &Module::getGlobalVariable,
239                              &Module::globals>;
240
241 /// PatternRewriteNamedAliasDescriptor - represents a rewrite for global
242 /// aliases which match a given pattern.  The provided transformation will be
243 /// applied to each of the matching names.
244 using PatternRewriteNamedAliasDescriptor =
245     PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,
246                              &Module::getNamedAlias, &Module::aliases>;
247
248 } // end anonymous namespace
249
250 bool RewriteMapParser::parse(const std::string &MapFile,
251                              RewriteDescriptorList *DL) {
252   ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping =
253       MemoryBuffer::getFile(MapFile);
254
255   if (!Mapping)
256     report_fatal_error("unable to read rewrite map '" + MapFile + "': " +
257                        Mapping.getError().message());
258
259   if (!parse(*Mapping, DL))
260     report_fatal_error("unable to parse rewrite map '" + MapFile + "'");
261
262   return true;
263 }
264
265 bool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile,
266                              RewriteDescriptorList *DL) {
267   SourceMgr SM;
268   yaml::Stream YS(MapFile->getBuffer(), SM);
269
270   for (auto &Document : YS) {
271     yaml::MappingNode *DescriptorList;
272
273     // ignore empty documents
274     if (isa<yaml::NullNode>(Document.getRoot()))
275       continue;
276
277     DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot());
278     if (!DescriptorList) {
279       YS.printError(Document.getRoot(), "DescriptorList node must be a map");
280       return false;
281     }
282
283     for (auto &Descriptor : *DescriptorList)
284       if (!parseEntry(YS, Descriptor, DL))
285         return false;
286   }
287
288   return true;
289 }
290
291 bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,
292                                   RewriteDescriptorList *DL) {
293   yaml::ScalarNode *Key;
294   yaml::MappingNode *Value;
295   SmallString<32> KeyStorage;
296   StringRef RewriteType;
297
298   Key = dyn_cast<yaml::ScalarNode>(Entry.getKey());
299   if (!Key) {
300     YS.printError(Entry.getKey(), "rewrite type must be a scalar");
301     return false;
302   }
303
304   Value = dyn_cast<yaml::MappingNode>(Entry.getValue());
305   if (!Value) {
306     YS.printError(Entry.getValue(), "rewrite descriptor must be a map");
307     return false;
308   }
309
310   RewriteType = Key->getValue(KeyStorage);
311   if (RewriteType.equals("function"))
312     return parseRewriteFunctionDescriptor(YS, Key, Value, DL);
313   else if (RewriteType.equals("global variable"))
314     return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);
315   else if (RewriteType.equals("global alias"))
316     return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);
317
318   YS.printError(Entry.getKey(), "unknown rewrite type");
319   return false;
320 }
321
322 bool RewriteMapParser::
323 parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
324                                yaml::MappingNode *Descriptor,
325                                RewriteDescriptorList *DL) {
326   bool Naked = false;
327   std::string Source;
328   std::string Target;
329   std::string Transform;
330
331   for (auto &Field : *Descriptor) {
332     yaml::ScalarNode *Key;
333     yaml::ScalarNode *Value;
334     SmallString<32> KeyStorage;
335     SmallString<32> ValueStorage;
336     StringRef KeyValue;
337
338     Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
339     if (!Key) {
340       YS.printError(Field.getKey(), "descriptor key must be a scalar");
341       return false;
342     }
343
344     Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
345     if (!Value) {
346       YS.printError(Field.getValue(), "descriptor value must be a scalar");
347       return false;
348     }
349
350     KeyValue = Key->getValue(KeyStorage);
351     if (KeyValue.equals("source")) {
352       std::string Error;
353
354       Source = Value->getValue(ValueStorage);
355       if (!Regex(Source).isValid(Error)) {
356         YS.printError(Field.getKey(), "invalid regex: " + Error);
357         return false;
358       }
359     } else if (KeyValue.equals("target")) {
360       Target = Value->getValue(ValueStorage);
361     } else if (KeyValue.equals("transform")) {
362       Transform = Value->getValue(ValueStorage);
363     } else if (KeyValue.equals("naked")) {
364       std::string Undecorated;
365
366       Undecorated = Value->getValue(ValueStorage);
367       Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1";
368     } else {
369       YS.printError(Field.getKey(), "unknown key for function");
370       return false;
371     }
372   }
373
374   if (Transform.empty() == Target.empty()) {
375     YS.printError(Descriptor,
376                   "exactly one of transform or target must be specified");
377     return false;
378   }
379
380   // TODO see if there is a more elegant solution to selecting the rewrite
381   // descriptor type
382   if (!Target.empty())
383     DL->push_back(llvm::make_unique<ExplicitRewriteFunctionDescriptor>(
384         Source, Target, Naked));
385   else
386     DL->push_back(
387         llvm::make_unique<PatternRewriteFunctionDescriptor>(Source, Transform));
388
389   return true;
390 }
391
392 bool RewriteMapParser::
393 parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
394                                      yaml::MappingNode *Descriptor,
395                                      RewriteDescriptorList *DL) {
396   std::string Source;
397   std::string Target;
398   std::string Transform;
399
400   for (auto &Field : *Descriptor) {
401     yaml::ScalarNode *Key;
402     yaml::ScalarNode *Value;
403     SmallString<32> KeyStorage;
404     SmallString<32> ValueStorage;
405     StringRef KeyValue;
406
407     Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
408     if (!Key) {
409       YS.printError(Field.getKey(), "descriptor Key must be a scalar");
410       return false;
411     }
412
413     Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
414     if (!Value) {
415       YS.printError(Field.getValue(), "descriptor value must be a scalar");
416       return false;
417     }
418
419     KeyValue = Key->getValue(KeyStorage);
420     if (KeyValue.equals("source")) {
421       std::string Error;
422
423       Source = Value->getValue(ValueStorage);
424       if (!Regex(Source).isValid(Error)) {
425         YS.printError(Field.getKey(), "invalid regex: " + Error);
426         return false;
427       }
428     } else if (KeyValue.equals("target")) {
429       Target = Value->getValue(ValueStorage);
430     } else if (KeyValue.equals("transform")) {
431       Transform = Value->getValue(ValueStorage);
432     } else {
433       YS.printError(Field.getKey(), "unknown Key for Global Variable");
434       return false;
435     }
436   }
437
438   if (Transform.empty() == Target.empty()) {
439     YS.printError(Descriptor,
440                   "exactly one of transform or target must be specified");
441     return false;
442   }
443
444   if (!Target.empty())
445     DL->push_back(llvm::make_unique<ExplicitRewriteGlobalVariableDescriptor>(
446         Source, Target,
447         /*Naked*/ false));
448   else
449     DL->push_back(llvm::make_unique<PatternRewriteGlobalVariableDescriptor>(
450         Source, Transform));
451
452   return true;
453 }
454
455 bool RewriteMapParser::
456 parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
457                                   yaml::MappingNode *Descriptor,
458                                   RewriteDescriptorList *DL) {
459   std::string Source;
460   std::string Target;
461   std::string Transform;
462
463   for (auto &Field : *Descriptor) {
464     yaml::ScalarNode *Key;
465     yaml::ScalarNode *Value;
466     SmallString<32> KeyStorage;
467     SmallString<32> ValueStorage;
468     StringRef KeyValue;
469
470     Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
471     if (!Key) {
472       YS.printError(Field.getKey(), "descriptor key must be a scalar");
473       return false;
474     }
475
476     Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
477     if (!Value) {
478       YS.printError(Field.getValue(), "descriptor value must be a scalar");
479       return false;
480     }
481
482     KeyValue = Key->getValue(KeyStorage);
483     if (KeyValue.equals("source")) {
484       std::string Error;
485
486       Source = Value->getValue(ValueStorage);
487       if (!Regex(Source).isValid(Error)) {
488         YS.printError(Field.getKey(), "invalid regex: " + Error);
489         return false;
490       }
491     } else if (KeyValue.equals("target")) {
492       Target = Value->getValue(ValueStorage);
493     } else if (KeyValue.equals("transform")) {
494       Transform = Value->getValue(ValueStorage);
495     } else {
496       YS.printError(Field.getKey(), "unknown key for Global Alias");
497       return false;
498     }
499   }
500
501   if (Transform.empty() == Target.empty()) {
502     YS.printError(Descriptor,
503                   "exactly one of transform or target must be specified");
504     return false;
505   }
506
507   if (!Target.empty())
508     DL->push_back(llvm::make_unique<ExplicitRewriteNamedAliasDescriptor>(
509         Source, Target,
510         /*Naked*/ false));
511   else
512     DL->push_back(llvm::make_unique<PatternRewriteNamedAliasDescriptor>(
513         Source, Transform));
514
515   return true;
516 }
517
518 namespace {
519
520 class RewriteSymbolsLegacyPass : public ModulePass {
521 public:
522   static char ID; // Pass identification, replacement for typeid
523
524   RewriteSymbolsLegacyPass();
525   RewriteSymbolsLegacyPass(SymbolRewriter::RewriteDescriptorList &DL);
526
527   bool runOnModule(Module &M) override;
528
529 private:
530   RewriteSymbolPass Impl;
531 };
532
533 } // end anonymous namespace
534
535 char RewriteSymbolsLegacyPass::ID = 0;
536
537 RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass() : ModulePass(ID) {
538   initializeRewriteSymbolsLegacyPassPass(*PassRegistry::getPassRegistry());
539 }
540
541 RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass(
542     SymbolRewriter::RewriteDescriptorList &DL)
543     : ModulePass(ID), Impl(DL) {}
544
545 bool RewriteSymbolsLegacyPass::runOnModule(Module &M) {
546   return Impl.runImpl(M);
547 }
548
549 PreservedAnalyses RewriteSymbolPass::run(Module &M, ModuleAnalysisManager &AM) {
550   if (!runImpl(M))
551     return PreservedAnalyses::all();
552
553   return PreservedAnalyses::none();
554 }
555
556 bool RewriteSymbolPass::runImpl(Module &M) {
557   bool Changed;
558
559   Changed = false;
560   for (auto &Descriptor : Descriptors)
561     Changed |= Descriptor->performOnModule(M);
562
563   return Changed;
564 }
565
566 void RewriteSymbolPass::loadAndParseMapFiles() {
567   const std::vector<std::string> MapFiles(RewriteMapFiles);
568   SymbolRewriter::RewriteMapParser Parser;
569
570   for (const auto &MapFile : MapFiles)
571     Parser.parse(MapFile, &Descriptors);
572 }
573
574 INITIALIZE_PASS(RewriteSymbolsLegacyPass, "rewrite-symbols", "Rewrite Symbols",
575                 false, false)
576
577 ModulePass *llvm::createRewriteSymbolsPass() {
578   return new RewriteSymbolsLegacyPass();
579 }
580
581 ModulePass *
582 llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) {
583   return new RewriteSymbolsLegacyPass(DL);
584 }