blob: 3640541e63cc0b53c58c4f15ae59cde9fce95cb6 [file] [log] [blame]
Eugene Zelenko286d5892017-10-11 21:41:43 +00001//===- SymbolRewriter.cpp - Symbol Rewriter -------------------------------===//
Saleem Abdulrasool5898e092014-11-07 21:32:08 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// SymbolRewriter is a LLVM pass which can rewrite symbols transparently within
11// existing code. It is implemented as a compiler pass and is configured via a
12// YAML configuration file.
13//
14// The YAML configuration file format is as follows:
15//
16// RewriteMapFile := RewriteDescriptors
17// RewriteDescriptors := RewriteDescriptor | RewriteDescriptors
18// RewriteDescriptor := RewriteDescriptorType ':' '{' RewriteDescriptorFields '}'
19// RewriteDescriptorFields := RewriteDescriptorField | RewriteDescriptorFields
20// RewriteDescriptorField := FieldIdentifier ':' FieldValue ','
21// RewriteDescriptorType := Identifier
22// FieldIdentifier := Identifier
23// FieldValue := Identifier
24// Identifier := [0-9a-zA-Z]+
25//
26// Currently, the following descriptor types are supported:
27//
28// - function: (function rewriting)
29// + Source (original name of the function)
30// + Target (explicit transformation)
31// + Transform (pattern transformation)
32// + Naked (boolean, whether the function is undecorated)
33// - global variable: (external linkage global variable rewriting)
34// + Source (original name of externally visible variable)
35// + Target (explicit transformation)
36// + Transform (pattern transformation)
37// - global alias: (global alias rewriting)
38// + Source (original name of the aliased name)
39// + Target (explicit transformation)
40// + Transform (pattern transformation)
41//
42// Note that source and exactly one of [Target, Transform] must be provided
43//
44// New rewrite descriptors can be created. Addding a new rewrite descriptor
45// involves:
46//
47// a) extended the rewrite descriptor kind enumeration
48// (<anonymous>::RewriteDescriptor::RewriteDescriptorType)
49// b) implementing the new descriptor
50// (c.f. <anonymous>::ExplicitRewriteFunctionDescriptor)
51// c) extending the rewrite map parser
52// (<anonymous>::RewriteMapParser::parseEntry)
53//
54// Specify to rewrite the symbols using the `-rewrite-symbols` option, and
55// specify the map file to use for the rewriting via the `-rewrite-map-file`
56// option.
57//
58//===----------------------------------------------------------------------===//
59
Michael Kuperstein39feb622016-07-25 20:52:00 +000060#include "llvm/Transforms/Utils/SymbolRewriter.h"
Eugene Zelenko286d5892017-10-11 21:41:43 +000061#include "llvm/ADT/STLExtras.h"
Benjamin Kramer16132e62015-03-23 18:07:13 +000062#include "llvm/ADT/SmallString.h"
Eugene Zelenko286d5892017-10-11 21:41:43 +000063#include "llvm/ADT/StringRef.h"
64#include "llvm/ADT/ilist.h"
65#include "llvm/ADT/iterator_range.h"
66#include "llvm/IR/Comdat.h"
67#include "llvm/IR/Function.h"
68#include "llvm/IR/GlobalAlias.h"
69#include "llvm/IR/GlobalObject.h"
70#include "llvm/IR/GlobalVariable.h"
71#include "llvm/IR/Module.h"
72#include "llvm/IR/Value.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000073#include "llvm/Pass.h"
Eugene Zelenko286d5892017-10-11 21:41:43 +000074#include "llvm/Support/Casting.h"
Saleem Abdulrasool5898e092014-11-07 21:32:08 +000075#include "llvm/Support/CommandLine.h"
Eugene Zelenko286d5892017-10-11 21:41:43 +000076#include "llvm/Support/ErrorHandling.h"
77#include "llvm/Support/ErrorOr.h"
Saleem Abdulrasool5898e092014-11-07 21:32:08 +000078#include "llvm/Support/MemoryBuffer.h"
79#include "llvm/Support/Regex.h"
80#include "llvm/Support/SourceMgr.h"
81#include "llvm/Support/YAMLParser.h"
Eugene Zelenko286d5892017-10-11 21:41:43 +000082#include <memory>
83#include <string>
84#include <vector>
Saleem Abdulrasool5898e092014-11-07 21:32:08 +000085
86using namespace llvm;
Benjamin Kramerfd3bc742015-03-09 15:50:47 +000087using namespace SymbolRewriter;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +000088
Eugene Zelenko286d5892017-10-11 21:41:43 +000089#define DEBUG_TYPE "symbol-rewriter"
90
Saleem Abdulrasool5898e092014-11-07 21:32:08 +000091static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
92 cl::desc("Symbol Rewrite Map"),
Zachary Turner8065f0b2017-12-01 00:53:10 +000093 cl::value_desc("filename"),
94 cl::Hidden);
Saleem Abdulrasool5898e092014-11-07 21:32:08 +000095
Benjamin Kramerfd3bc742015-03-09 15:50:47 +000096static void rewriteComdat(Module &M, GlobalObject *GO,
97 const std::string &Source,
98 const std::string &Target) {
Saleem Abdulrasoolc44d71b2015-01-27 22:57:39 +000099 if (Comdat *CD = GO->getComdat()) {
100 auto &Comdats = M.getComdatSymbolTable();
101
102 Comdat *C = M.getOrInsertComdat(Target);
103 C->setSelectionKind(CD->getSelectionKind());
104 GO->setComdat(C);
105
106 Comdats.erase(Comdats.find(Source));
107 }
108}
109
Benjamin Kramerfd3bc742015-03-09 15:50:47 +0000110namespace {
Eugene Zelenko286d5892017-10-11 21:41:43 +0000111
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000112template <RewriteDescriptor::Type DT, typename ValueType,
Eugene Zelenko286d5892017-10-11 21:41:43 +0000113 ValueType *(Module::*Get)(StringRef) const>
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000114class ExplicitRewriteDescriptor : public RewriteDescriptor {
115public:
116 const std::string Source;
117 const std::string Target;
118
119 ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked)
120 : RewriteDescriptor(DT), Source(Naked ? StringRef("\01" + S.str()) : S),
121 Target(T) {}
122
123 bool performOnModule(Module &M) override;
124
125 static bool classof(const RewriteDescriptor *RD) {
126 return RD->getType() == DT;
127 }
128};
129
Eugene Zelenko286d5892017-10-11 21:41:43 +0000130} // end anonymous namespace
131
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000132template <RewriteDescriptor::Type DT, typename ValueType,
Eugene Zelenko286d5892017-10-11 21:41:43 +0000133 ValueType *(Module::*Get)(StringRef) const>
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000134bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
135 bool Changed = false;
136 if (ValueType *S = (M.*Get)(Source)) {
Saleem Abdulrasoolc44d71b2015-01-27 22:57:39 +0000137 if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
138 rewriteComdat(M, GO, Source, Target);
139
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000140 if (Value *T = (M.*Get)(Target))
141 S->setValueName(T->getValueName());
142 else
143 S->setName(Target);
Saleem Abdulrasoolc44d71b2015-01-27 22:57:39 +0000144
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000145 Changed = true;
146 }
147 return Changed;
148}
149
Eugene Zelenko286d5892017-10-11 21:41:43 +0000150namespace {
151
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000152template <RewriteDescriptor::Type DT, typename ValueType,
Eugene Zelenko286d5892017-10-11 21:41:43 +0000153 ValueType *(Module::*Get)(StringRef) const,
Saleem Abdulrasoold37ce302015-01-05 17:56:29 +0000154 iterator_range<typename iplist<ValueType>::iterator>
Eugene Zelenko286d5892017-10-11 21:41:43 +0000155 (Module::*Iterator)()>
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000156class PatternRewriteDescriptor : public RewriteDescriptor {
157public:
158 const std::string Pattern;
159 const std::string Transform;
160
161 PatternRewriteDescriptor(StringRef P, StringRef T)
162 : RewriteDescriptor(DT), Pattern(P), Transform(T) { }
163
164 bool performOnModule(Module &M) override;
165
166 static bool classof(const RewriteDescriptor *RD) {
167 return RD->getType() == DT;
168 }
169};
170
Eugene Zelenko286d5892017-10-11 21:41:43 +0000171} // end anonymous namespace
172
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000173template <RewriteDescriptor::Type DT, typename ValueType,
Eugene Zelenko286d5892017-10-11 21:41:43 +0000174 ValueType *(Module::*Get)(StringRef) const,
Saleem Abdulrasoold37ce302015-01-05 17:56:29 +0000175 iterator_range<typename iplist<ValueType>::iterator>
Eugene Zelenko286d5892017-10-11 21:41:43 +0000176 (Module::*Iterator)()>
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000177bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
178performOnModule(Module &M) {
179 bool Changed = false;
180 for (auto &C : (M.*Iterator)()) {
181 std::string Error;
182
183 std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error);
184 if (!Error.empty())
185 report_fatal_error("unable to transforn " + C.getName() + " in " +
186 M.getModuleIdentifier() + ": " + Error);
187
Saleem Abdulrasool9769b182015-01-27 22:57:35 +0000188 if (C.getName() == Name)
189 continue;
190
Saleem Abdulrasoolc44d71b2015-01-27 22:57:39 +0000191 if (GlobalObject *GO = dyn_cast<GlobalObject>(&C))
192 rewriteComdat(M, GO, C.getName(), Name);
193
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000194 if (Value *V = (M.*Get)(Name))
195 C.setValueName(V->getValueName());
196 else
197 C.setName(Name);
198
199 Changed = true;
200 }
201 return Changed;
202}
203
Eugene Zelenko286d5892017-10-11 21:41:43 +0000204namespace {
205
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000206/// Represents a rewrite for an explicitly named (function) symbol. Both the
207/// source function name and target function name of the transformation are
208/// explicitly spelt out.
Eugene Zelenko286d5892017-10-11 21:41:43 +0000209using ExplicitRewriteFunctionDescriptor =
210 ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, Function,
211 &Module::getFunction>;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000212
213/// Represents a rewrite for an explicitly named (global variable) symbol. Both
214/// the source variable name and target variable name are spelt out. This
215/// applies only to module level variables.
Eugene Zelenko286d5892017-10-11 21:41:43 +0000216using ExplicitRewriteGlobalVariableDescriptor =
217 ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
218 GlobalVariable, &Module::getGlobalVariable>;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000219
220/// Represents a rewrite for an explicitly named global alias. Both the source
221/// and target name are explicitly spelt out.
Eugene Zelenko286d5892017-10-11 21:41:43 +0000222using ExplicitRewriteNamedAliasDescriptor =
223 ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,
224 &Module::getNamedAlias>;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000225
226/// Represents a rewrite for a regular expression based pattern for functions.
227/// A pattern for the function name is provided and a transformation for that
228/// pattern to determine the target function name create the rewrite rule.
Eugene Zelenko286d5892017-10-11 21:41:43 +0000229using PatternRewriteFunctionDescriptor =
230 PatternRewriteDescriptor<RewriteDescriptor::Type::Function, Function,
231 &Module::getFunction, &Module::functions>;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000232
233/// Represents a rewrite for a global variable based upon a matching pattern.
234/// Each global variable matching the provided pattern will be transformed as
235/// described in the transformation pattern for the target. Applies only to
236/// module level variables.
Eugene Zelenko286d5892017-10-11 21:41:43 +0000237using PatternRewriteGlobalVariableDescriptor =
238 PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
239 GlobalVariable, &Module::getGlobalVariable,
240 &Module::globals>;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000241
242/// PatternRewriteNamedAliasDescriptor - represents a rewrite for global
243/// aliases which match a given pattern. The provided transformation will be
244/// applied to each of the matching names.
Eugene Zelenko286d5892017-10-11 21:41:43 +0000245using PatternRewriteNamedAliasDescriptor =
246 PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,
247 &Module::getNamedAlias, &Module::aliases>;
248
249} // end anonymous namespace
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000250
251bool RewriteMapParser::parse(const std::string &MapFile,
252 RewriteDescriptorList *DL) {
253 ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping =
254 MemoryBuffer::getFile(MapFile);
255
256 if (!Mapping)
257 report_fatal_error("unable to read rewrite map '" + MapFile + "': " +
258 Mapping.getError().message());
259
260 if (!parse(*Mapping, DL))
261 report_fatal_error("unable to parse rewrite map '" + MapFile + "'");
262
263 return true;
264}
265
266bool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile,
267 RewriteDescriptorList *DL) {
268 SourceMgr SM;
269 yaml::Stream YS(MapFile->getBuffer(), SM);
270
271 for (auto &Document : YS) {
272 yaml::MappingNode *DescriptorList;
273
274 // ignore empty documents
275 if (isa<yaml::NullNode>(Document.getRoot()))
276 continue;
277
278 DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot());
279 if (!DescriptorList) {
280 YS.printError(Document.getRoot(), "DescriptorList node must be a map");
281 return false;
282 }
283
284 for (auto &Descriptor : *DescriptorList)
285 if (!parseEntry(YS, Descriptor, DL))
286 return false;
287 }
288
289 return true;
290}
291
292bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,
293 RewriteDescriptorList *DL) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000294 yaml::ScalarNode *Key;
295 yaml::MappingNode *Value;
296 SmallString<32> KeyStorage;
297 StringRef RewriteType;
298
299 Key = dyn_cast<yaml::ScalarNode>(Entry.getKey());
300 if (!Key) {
301 YS.printError(Entry.getKey(), "rewrite type must be a scalar");
302 return false;
303 }
304
305 Value = dyn_cast<yaml::MappingNode>(Entry.getValue());
306 if (!Value) {
307 YS.printError(Entry.getValue(), "rewrite descriptor must be a map");
308 return false;
309 }
310
311 RewriteType = Key->getValue(KeyStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000312 if (RewriteType.equals("function"))
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000313 return parseRewriteFunctionDescriptor(YS, Key, Value, DL);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000314 else if (RewriteType.equals("global variable"))
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000315 return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000316 else if (RewriteType.equals("global alias"))
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000317 return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);
318
319 YS.printError(Entry.getKey(), "unknown rewrite type");
320 return false;
321}
322
323bool RewriteMapParser::
324parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
325 yaml::MappingNode *Descriptor,
326 RewriteDescriptorList *DL) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000327 bool Naked = false;
328 std::string Source;
329 std::string Target;
330 std::string Transform;
331
332 for (auto &Field : *Descriptor) {
333 yaml::ScalarNode *Key;
334 yaml::ScalarNode *Value;
335 SmallString<32> KeyStorage;
336 SmallString<32> ValueStorage;
337 StringRef KeyValue;
338
339 Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
340 if (!Key) {
341 YS.printError(Field.getKey(), "descriptor key must be a scalar");
342 return false;
343 }
344
345 Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
346 if (!Value) {
347 YS.printError(Field.getValue(), "descriptor value must be a scalar");
348 return false;
349 }
350
351 KeyValue = Key->getValue(KeyStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000352 if (KeyValue.equals("source")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000353 std::string Error;
354
355 Source = Value->getValue(ValueStorage);
356 if (!Regex(Source).isValid(Error)) {
357 YS.printError(Field.getKey(), "invalid regex: " + Error);
358 return false;
359 }
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000360 } else if (KeyValue.equals("target")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000361 Target = Value->getValue(ValueStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000362 } else if (KeyValue.equals("transform")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000363 Transform = Value->getValue(ValueStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000364 } else if (KeyValue.equals("naked")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000365 std::string Undecorated;
366
367 Undecorated = Value->getValue(ValueStorage);
368 Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1";
369 } else {
370 YS.printError(Field.getKey(), "unknown key for function");
371 return false;
372 }
373 }
374
375 if (Transform.empty() == Target.empty()) {
376 YS.printError(Descriptor,
377 "exactly one of transform or target must be specified");
378 return false;
379 }
380
381 // TODO see if there is a more elegant solution to selecting the rewrite
382 // descriptor type
383 if (!Target.empty())
Michael Kuperstein9a89b152016-07-25 18:39:08 +0000384 DL->push_back(llvm::make_unique<ExplicitRewriteFunctionDescriptor>(
385 Source, Target, Naked));
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000386 else
Michael Kuperstein8f8e1d12016-07-25 18:10:54 +0000387 DL->push_back(
Michael Kuperstein9a89b152016-07-25 18:39:08 +0000388 llvm::make_unique<PatternRewriteFunctionDescriptor>(Source, Transform));
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000389
390 return true;
391}
392
393bool RewriteMapParser::
394parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
395 yaml::MappingNode *Descriptor,
396 RewriteDescriptorList *DL) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000397 std::string Source;
398 std::string Target;
399 std::string Transform;
400
401 for (auto &Field : *Descriptor) {
402 yaml::ScalarNode *Key;
403 yaml::ScalarNode *Value;
404 SmallString<32> KeyStorage;
405 SmallString<32> ValueStorage;
406 StringRef KeyValue;
407
408 Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
409 if (!Key) {
410 YS.printError(Field.getKey(), "descriptor Key must be a scalar");
411 return false;
412 }
413
414 Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
415 if (!Value) {
416 YS.printError(Field.getValue(), "descriptor value must be a scalar");
417 return false;
418 }
419
420 KeyValue = Key->getValue(KeyStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000421 if (KeyValue.equals("source")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000422 std::string Error;
423
424 Source = Value->getValue(ValueStorage);
425 if (!Regex(Source).isValid(Error)) {
426 YS.printError(Field.getKey(), "invalid regex: " + Error);
427 return false;
428 }
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000429 } else if (KeyValue.equals("target")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000430 Target = Value->getValue(ValueStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000431 } else if (KeyValue.equals("transform")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000432 Transform = Value->getValue(ValueStorage);
433 } else {
434 YS.printError(Field.getKey(), "unknown Key for Global Variable");
435 return false;
436 }
437 }
438
439 if (Transform.empty() == Target.empty()) {
440 YS.printError(Descriptor,
441 "exactly one of transform or target must be specified");
442 return false;
443 }
444
445 if (!Target.empty())
Michael Kuperstein9a89b152016-07-25 18:39:08 +0000446 DL->push_back(llvm::make_unique<ExplicitRewriteGlobalVariableDescriptor>(
447 Source, Target,
448 /*Naked*/ false));
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000449 else
Michael Kuperstein9a89b152016-07-25 18:39:08 +0000450 DL->push_back(llvm::make_unique<PatternRewriteGlobalVariableDescriptor>(
451 Source, Transform));
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000452
453 return true;
454}
455
456bool RewriteMapParser::
457parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
458 yaml::MappingNode *Descriptor,
459 RewriteDescriptorList *DL) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000460 std::string Source;
461 std::string Target;
462 std::string Transform;
463
464 for (auto &Field : *Descriptor) {
465 yaml::ScalarNode *Key;
466 yaml::ScalarNode *Value;
467 SmallString<32> KeyStorage;
468 SmallString<32> ValueStorage;
469 StringRef KeyValue;
470
471 Key = dyn_cast<yaml::ScalarNode>(Field.getKey());
472 if (!Key) {
473 YS.printError(Field.getKey(), "descriptor key must be a scalar");
474 return false;
475 }
476
477 Value = dyn_cast<yaml::ScalarNode>(Field.getValue());
478 if (!Value) {
479 YS.printError(Field.getValue(), "descriptor value must be a scalar");
480 return false;
481 }
482
483 KeyValue = Key->getValue(KeyStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000484 if (KeyValue.equals("source")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000485 std::string Error;
486
487 Source = Value->getValue(ValueStorage);
488 if (!Regex(Source).isValid(Error)) {
489 YS.printError(Field.getKey(), "invalid regex: " + Error);
490 return false;
491 }
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000492 } else if (KeyValue.equals("target")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000493 Target = Value->getValue(ValueStorage);
Saleem Abdulrasoold2c5d7f2014-11-08 00:00:50 +0000494 } else if (KeyValue.equals("transform")) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000495 Transform = Value->getValue(ValueStorage);
496 } else {
497 YS.printError(Field.getKey(), "unknown key for Global Alias");
498 return false;
499 }
500 }
501
502 if (Transform.empty() == Target.empty()) {
503 YS.printError(Descriptor,
504 "exactly one of transform or target must be specified");
505 return false;
506 }
507
508 if (!Target.empty())
Michael Kuperstein9a89b152016-07-25 18:39:08 +0000509 DL->push_back(llvm::make_unique<ExplicitRewriteNamedAliasDescriptor>(
510 Source, Target,
511 /*Naked*/ false));
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000512 else
Michael Kuperstein9a89b152016-07-25 18:39:08 +0000513 DL->push_back(llvm::make_unique<PatternRewriteNamedAliasDescriptor>(
514 Source, Transform));
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000515
516 return true;
517}
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000518
519namespace {
Eugene Zelenko286d5892017-10-11 21:41:43 +0000520
Michael Kuperstein39feb622016-07-25 20:52:00 +0000521class RewriteSymbolsLegacyPass : public ModulePass {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000522public:
523 static char ID; // Pass identification, replacement for typeid
524
Michael Kuperstein39feb622016-07-25 20:52:00 +0000525 RewriteSymbolsLegacyPass();
526 RewriteSymbolsLegacyPass(SymbolRewriter::RewriteDescriptorList &DL);
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000527
David Blaikie711cd9c2014-11-14 19:06:36 +0000528 bool runOnModule(Module &M) override;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000529
530private:
Michael Kuperstein39feb622016-07-25 20:52:00 +0000531 RewriteSymbolPass Impl;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000532};
533
Eugene Zelenko286d5892017-10-11 21:41:43 +0000534} // end anonymous namespace
535
Michael Kuperstein39feb622016-07-25 20:52:00 +0000536char RewriteSymbolsLegacyPass::ID = 0;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000537
Eugene Zelenko286d5892017-10-11 21:41:43 +0000538RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass() : ModulePass(ID) {
Michael Kuperstein39feb622016-07-25 20:52:00 +0000539 initializeRewriteSymbolsLegacyPassPass(*PassRegistry::getPassRegistry());
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000540}
541
Michael Kuperstein39feb622016-07-25 20:52:00 +0000542RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass(
543 SymbolRewriter::RewriteDescriptorList &DL)
544 : ModulePass(ID), Impl(DL) {}
545
546bool RewriteSymbolsLegacyPass::runOnModule(Module &M) {
547 return Impl.runImpl(M);
548}
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000549
Michael Kuperstein39feb622016-07-25 20:52:00 +0000550PreservedAnalyses RewriteSymbolPass::run(Module &M, ModuleAnalysisManager &AM) {
551 if (!runImpl(M))
552 return PreservedAnalyses::all();
553
554 return PreservedAnalyses::none();
555}
556
557bool RewriteSymbolPass::runImpl(Module &M) {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000558 bool Changed;
559
560 Changed = false;
561 for (auto &Descriptor : Descriptors)
Michael Kuperstein8f8e1d12016-07-25 18:10:54 +0000562 Changed |= Descriptor->performOnModule(M);
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000563
564 return Changed;
565}
566
Michael Kuperstein39feb622016-07-25 20:52:00 +0000567void RewriteSymbolPass::loadAndParseMapFiles() {
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000568 const std::vector<std::string> MapFiles(RewriteMapFiles);
Michael Kuperstein39feb622016-07-25 20:52:00 +0000569 SymbolRewriter::RewriteMapParser Parser;
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000570
571 for (const auto &MapFile : MapFiles)
Michael Kuperstein39feb622016-07-25 20:52:00 +0000572 Parser.parse(MapFile, &Descriptors);
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000573}
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000574
Michael Kuperstein39feb622016-07-25 20:52:00 +0000575INITIALIZE_PASS(RewriteSymbolsLegacyPass, "rewrite-symbols", "Rewrite Symbols",
576 false, false)
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000577
Michael Kuperstein39feb622016-07-25 20:52:00 +0000578ModulePass *llvm::createRewriteSymbolsPass() {
579 return new RewriteSymbolsLegacyPass();
580}
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000581
582ModulePass *
583llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) {
Michael Kuperstein39feb622016-07-25 20:52:00 +0000584 return new RewriteSymbolsLegacyPass(DL);
Saleem Abdulrasool5898e092014-11-07 21:32:08 +0000585}