Coverage Report

Created: 2017-02-02 11:39

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/LTO/LTOModule.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- LTOModule.cpp - LLVM Link Time Optimizer --------------------------===//
2
//
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
// This file implements the Link Time Optimization library. This library is
11
// intended to be used by linker to optimize code at link time.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/LTO/legacy/LTOModule.h"
16
#include "llvm/ADT/Triple.h"
17
#include "llvm/Bitcode/BitcodeReader.h"
18
#include "llvm/CodeGen/Analysis.h"
19
#include "llvm/IR/Constants.h"
20
#include "llvm/IR/DiagnosticPrinter.h"
21
#include "llvm/IR/LLVMContext.h"
22
#include "llvm/IR/Metadata.h"
23
#include "llvm/IR/Module.h"
24
#include "llvm/MC/MCExpr.h"
25
#include "llvm/MC/MCInst.h"
26
#include "llvm/MC/MCInstrInfo.h"
27
#include "llvm/MC/MCParser/MCAsmParser.h"
28
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
29
#include "llvm/MC/MCSection.h"
30
#include "llvm/MC/MCSubtargetInfo.h"
31
#include "llvm/MC/MCSymbol.h"
32
#include "llvm/MC/SubtargetFeature.h"
33
#include "llvm/Object/IRObjectFile.h"
34
#include "llvm/Object/ObjectFile.h"
35
#include "llvm/Support/FileSystem.h"
36
#include "llvm/Support/Host.h"
37
#include "llvm/Support/MemoryBuffer.h"
38
#include "llvm/Support/Path.h"
39
#include "llvm/Support/SourceMgr.h"
40
#include "llvm/Support/TargetRegistry.h"
41
#include "llvm/Support/TargetSelect.h"
42
#include "llvm/Target/TargetLowering.h"
43
#include "llvm/Target/TargetLoweringObjectFile.h"
44
#include "llvm/Target/TargetRegisterInfo.h"
45
#include "llvm/Target/TargetSubtargetInfo.h"
46
#include "llvm/Transforms/Utils/GlobalStatus.h"
47
#include <system_error>
48
using namespace llvm;
49
using namespace llvm::object;
50
51
LTOModule::LTOModule(std::unique_ptr<Module> M, MemoryBufferRef MBRef,
52
                     llvm::TargetMachine *TM)
53
85
    : Mod(std::move(M)), MBRef(MBRef), _target(TM) {
54
85
  SymTab.addModule(Mod.get());
55
85
}
56
57
84
LTOModule::~LTOModule() {}
58
59
/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
60
/// bitcode.
61
0
bool LTOModule::isBitcodeFile(const void *Mem, size_t Length) {
62
0
  ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer(
63
0
      MemoryBufferRef(StringRef((const char *)Mem, Length), "<mem>"));
64
0
  return bool(BCData);
65
0
}
66
67
0
bool LTOModule::isBitcodeFile(StringRef Path) {
68
0
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
69
0
      MemoryBuffer::getFile(Path);
70
0
  if (!BufferOrErr)
71
0
    return false;
72
0
73
0
  ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer(
74
0
      BufferOrErr.get()->getMemBufferRef());
75
0
  return bool(BCData);
76
0
}
77
78
0
bool LTOModule::isThinLTO() {
79
0
  // Right now the detection is only based on the summary presence. We may want
80
0
  // to add a dedicated flag at some point.
81
0
  Expected<bool> Result = hasGlobalValueSummary(MBRef);
82
0
  if (
!Result0
)
{0
83
0
    logAllUnhandledErrors(Result.takeError(), errs(), "");
84
0
    return false;
85
0
  }
86
0
  return *Result;
87
0
}
88
89
bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer,
90
3
                                   StringRef TriplePrefix) {
91
3
  ErrorOr<MemoryBufferRef> BCOrErr =
92
3
      IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef());
93
3
  if (!BCOrErr)
94
0
    return false;
95
3
  LLVMContext Context;
96
3
  ErrorOr<std::string> TripleOrErr =
97
3
      expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(*BCOrErr));
98
3
  if (!TripleOrErr)
99
0
    return false;
100
3
  return StringRef(*TripleOrErr).startswith(TriplePrefix);
101
3
}
102
103
0
std::string LTOModule::getProducerString(MemoryBuffer *Buffer) {
104
0
  ErrorOr<MemoryBufferRef> BCOrErr =
105
0
      IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef());
106
0
  if (!BCOrErr)
107
0
    return "";
108
0
  LLVMContext Context;
109
0
  ErrorOr<std::string> ProducerOrErr = expectedToErrorOrAndEmitErrors(
110
0
      Context, getBitcodeProducerString(*BCOrErr));
111
0
  if (!ProducerOrErr)
112
0
    return "";
113
0
  return *ProducerOrErr;
114
0
}
115
116
ErrorOr<std::unique_ptr<LTOModule>>
117
LTOModule::createFromFile(LLVMContext &Context, StringRef path,
118
42
                          const TargetOptions &options) {
119
42
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
120
42
      MemoryBuffer::getFile(path);
121
42
  if (std::error_code 
EC42
= BufferOrErr.getError())
{1
122
1
    Context.emitError(EC.message());
123
1
    return EC;
124
1
  }
125
41
  std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
126
41
  return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
127
41
                       /* ShouldBeLazy*/ false);
128
42
}
129
130
ErrorOr<std::unique_ptr<LTOModule>>
131
LTOModule::createFromOpenFile(LLVMContext &Context, int fd, StringRef path,
132
0
                              size_t size, const TargetOptions &options) {
133
0
  return createFromOpenFileSlice(Context, fd, path, size, 0, options);
134
0
}
135
136
ErrorOr<std::unique_ptr<LTOModule>>
137
LTOModule::createFromOpenFileSlice(LLVMContext &Context, int fd, StringRef path,
138
                                   size_t map_size, off_t offset,
139
0
                                   const TargetOptions &options) {
140
0
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
141
0
      MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset);
142
0
  if (std::error_code 
EC0
= BufferOrErr.getError())
{0
143
0
    Context.emitError(EC.message());
144
0
    return EC;
145
0
  }
146
0
  std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
147
0
  return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
148
0
                       /* ShouldBeLazy */ false);
149
0
}
150
151
ErrorOr<std::unique_ptr<LTOModule>>
152
LTOModule::createFromBuffer(LLVMContext &Context, const void *mem,
153
                            size_t length, const TargetOptions &options,
154
39
                            StringRef path) {
155
39
  StringRef Data((const char *)mem, length);
156
39
  MemoryBufferRef Buffer(Data, path);
157
39
  return makeLTOModule(Buffer, options, Context, /* ShouldBeLazy */ false);
158
39
}
159
160
ErrorOr<std::unique_ptr<LTOModule>>
161
LTOModule::createInLocalContext(std::unique_ptr<LLVMContext> Context,
162
                                const void *mem, size_t length,
163
7
                                const TargetOptions &options, StringRef path) {
164
7
  StringRef Data((const char *)mem, length);
165
7
  MemoryBufferRef Buffer(Data, path);
166
7
  // If we own a context, we know this is being used only for symbol extraction,
167
7
  // not linking.  Be lazy in that case.
168
7
  ErrorOr<std::unique_ptr<LTOModule>> Ret =
169
7
      makeLTOModule(Buffer, options, *Context, /* ShouldBeLazy */ true);
170
7
  if (Ret)
171
6
    (*Ret)->OwnedContext = std::move(Context);
172
7
  return Ret;
173
7
}
174
175
static ErrorOr<std::unique_ptr<Module>>
176
parseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context,
177
87
                     bool ShouldBeLazy) {
178
87
179
87
  // Find the buffer.
180
87
  ErrorOr<MemoryBufferRef> MBOrErr =
181
87
      IRObjectFile::findBitcodeInMemBuffer(Buffer);
182
87
  if (std::error_code 
EC87
= MBOrErr.getError())
{1
183
1
    Context.emitError(EC.message());
184
1
    return EC;
185
1
  }
186
87
187
86
  
if (86
!ShouldBeLazy86
)
{80
188
80
    // Parse the full file.
189
80
    return expectedToErrorOrAndEmitErrors(Context,
190
80
                                          parseBitcodeFile(*MBOrErr, Context));
191
80
  }
192
86
193
86
  // Parse lazily.
194
6
  return expectedToErrorOrAndEmitErrors(
195
6
      Context,
196
6
      getLazyBitcodeModule(*MBOrErr, Context, true /*ShouldLazyLoadMetadata*/));
197
86
}
198
199
ErrorOr<std::unique_ptr<LTOModule>>
200
LTOModule::makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options,
201
87
                         LLVMContext &Context, bool ShouldBeLazy) {
202
87
  ErrorOr<std::unique_ptr<Module>> MOrErr =
203
87
      parseBitcodeFileImpl(Buffer, Context, ShouldBeLazy);
204
87
  if (std::error_code EC = MOrErr.getError())
205
0
    return EC;
206
87
  std::unique_ptr<Module> &M = *MOrErr;
207
87
208
87
  std::string TripleStr = M->getTargetTriple();
209
87
  if (TripleStr.empty())
210
9
    TripleStr = sys::getDefaultTargetTriple();
211
87
  llvm::Triple Triple(TripleStr);
212
87
213
87
  // find machine architecture for this module
214
87
  std::string errMsg;
215
87
  const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
216
87
  if (!march)
217
0
    return std::unique_ptr<LTOModule>(nullptr);
218
87
219
87
  // construct LTOModule, hand over ownership of module and target
220
87
  SubtargetFeatures Features;
221
87
  Features.getDefaultSubtargetFeatures(Triple);
222
87
  std::string FeatureStr = Features.getString();
223
87
  // Set a default CPU for Darwin triples.
224
87
  std::string CPU;
225
87
  if (
Triple.isOSDarwin()87
)
{28
226
28
    if (Triple.getArch() == llvm::Triple::x86_64)
227
27
      CPU = "core2";
228
1
    else 
if (1
Triple.getArch() == llvm::Triple::x861
)
229
0
      CPU = "yonah";
230
1
    else 
if (1
Triple.getArch() == llvm::Triple::aarch641
)
231
0
      CPU = "cyclone";
232
28
  }
233
87
234
87
  TargetMachine *target =
235
87
      march->createTargetMachine(TripleStr, CPU, FeatureStr, options, None);
236
87
237
87
  std::unique_ptr<LTOModule> Ret(new LTOModule(std::move(M), Buffer, target));
238
87
  Ret->parseSymbols();
239
87
  Ret->parseMetadata();
240
87
241
87
  return std::move(Ret);
242
87
}
243
244
/// Create a MemoryBuffer from a memory range with an optional name.
245
std::unique_ptr<MemoryBuffer>
246
3
LTOModule::makeBuffer(const void *mem, size_t length, StringRef name) {
247
3
  const char *startPtr = (const char*)mem;
248
3
  return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false);
249
3
}
250
251
/// objcClassNameFromExpression - Get string that the data pointer points to.
252
bool
253
0
LTOModule::objcClassNameFromExpression(const Constant *c, std::string &name) {
254
0
  if (const ConstantExpr *
ce0
= dyn_cast<ConstantExpr>(c))
{0
255
0
    Constant *op = ce->getOperand(0);
256
0
    if (GlobalVariable *
gvn0
= dyn_cast<GlobalVariable>(op))
{0
257
0
      Constant *cn = gvn->getInitializer();
258
0
      if (ConstantDataArray *
ca0
= dyn_cast<ConstantDataArray>(cn))
{0
259
0
        if (
ca->isCString()0
)
{0
260
0
          name = (".objc_class_name_" + ca->getAsCString()).str();
261
0
          return true;
262
0
        }
263
0
      }
264
0
    }
265
0
  }
266
0
  return false;
267
0
}
268
269
/// addObjCClass - Parse i386/ppc ObjC class data structure.
270
0
void LTOModule::addObjCClass(const GlobalVariable *clgv) {
271
0
  const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
272
0
  if (
!c0
)
return0
;
273
0
274
0
  // second slot in __OBJC,__class is pointer to superclass name
275
0
  std::string superclassName;
276
0
  if (
objcClassNameFromExpression(c->getOperand(1), superclassName)0
)
{0
277
0
    auto IterBool =
278
0
        _undefines.insert(std::make_pair(superclassName, NameAndAttributes()));
279
0
    if (
IterBool.second0
)
{0
280
0
      NameAndAttributes &info = IterBool.first->second;
281
0
      info.name = IterBool.first->first();
282
0
      info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
283
0
      info.isFunction = false;
284
0
      info.symbol = clgv;
285
0
    }
286
0
  }
287
0
288
0
  // third slot in __OBJC,__class is pointer to class name
289
0
  std::string className;
290
0
  if (
objcClassNameFromExpression(c->getOperand(2), className)0
)
{0
291
0
    auto Iter = _defines.insert(className).first;
292
0
293
0
    NameAndAttributes info;
294
0
    info.name = Iter->first();
295
0
    info.attributes = LTO_SYMBOL_PERMISSIONS_DATA |
296
0
      LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT;
297
0
    info.isFunction = false;
298
0
    info.symbol = clgv;
299
0
    _symbols.push_back(info);
300
0
  }
301
0
}
302
303
/// addObjCCategory - Parse i386/ppc ObjC category data structure.
304
0
void LTOModule::addObjCCategory(const GlobalVariable *clgv) {
305
0
  const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
306
0
  if (
!c0
)
return0
;
307
0
308
0
  // second slot in __OBJC,__category is pointer to target class name
309
0
  std::string targetclassName;
310
0
  if (!objcClassNameFromExpression(c->getOperand(1), targetclassName))
311
0
    return;
312
0
313
0
  auto IterBool =
314
0
      _undefines.insert(std::make_pair(targetclassName, NameAndAttributes()));
315
0
316
0
  if (!IterBool.second)
317
0
    return;
318
0
319
0
  NameAndAttributes &info = IterBool.first->second;
320
0
  info.name = IterBool.first->first();
321
0
  info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
322
0
  info.isFunction = false;
323
0
  info.symbol = clgv;
324
0
}
325
326
/// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
327
0
void LTOModule::addObjCClassRef(const GlobalVariable *clgv) {
328
0
  std::string targetclassName;
329
0
  if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName))
330
0
    return;
331
0
332
0
  auto IterBool =
333
0
      _undefines.insert(std::make_pair(targetclassName, NameAndAttributes()));
334
0
335
0
  if (!IterBool.second)
336
0
    return;
337
0
338
0
  NameAndAttributes &info = IterBool.first->second;
339
0
  info.name = IterBool.first->first();
340
0
  info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
341
0
  info.isFunction = false;
342
0
  info.symbol = clgv;
343
0
}
344
345
27
void LTOModule::addDefinedDataSymbol(ModuleSymbolTable::Symbol Sym) {
346
27
  SmallString<64> Buffer;
347
27
  {
348
27
    raw_svector_ostream OS(Buffer);
349
27
    SymTab.printSymbolName(OS, Sym);
350
27
    Buffer.c_str();
351
27
  }
352
27
353
27
  const GlobalValue *V = Sym.get<GlobalValue *>();
354
27
  addDefinedDataSymbol(Buffer, V);
355
27
}
356
357
27
void LTOModule::addDefinedDataSymbol(StringRef Name, const GlobalValue *v) {
358
27
  // Add to list of defined symbols.
359
27
  addDefinedSymbol(Name, v, false);
360
27
361
27
  if (!v->hasSection() /* || !isTargetDarwin */)
362
27
    return;
363
27
364
27
  // Special case i386/ppc ObjC data structures in magic sections:
365
27
  // The issue is that the old ObjC object format did some strange
366
27
  // contortions to avoid real linker symbols.  For instance, the
367
27
  // ObjC class data structure is allocated statically in the executable
368
27
  // that defines that class.  That data structures contains a pointer to
369
27
  // its superclass.  But instead of just initializing that part of the
370
27
  // struct to the address of its superclass, and letting the static and
371
27
  // dynamic linkers do the rest, the runtime works by having that field
372
27
  // instead point to a C-string that is the name of the superclass.
373
27
  // At runtime the objc initialization updates that pointer and sets
374
27
  // it to point to the actual super class.  As far as the linker
375
27
  // knows it is just a pointer to a string.  But then someone wanted the
376
27
  // linker to issue errors at build time if the superclass was not found.
377
27
  // So they figured out a way in mach-o object format to use an absolute
378
27
  // symbols (.objc_class_name_Foo = 0) and a floating reference
379
27
  // (.reference .objc_class_name_Bar) to cause the linker into erroring when
380
27
  // a class was missing.
381
27
  // The following synthesizes the implicit .objc_* symbols for the linker
382
27
  // from the ObjC data structures generated by the front end.
383
27
384
27
  // special case if this data blob is an ObjC class definition
385
0
  std::string Section = v->getSection();
386
0
  if (
Section.compare(0, 15, "__OBJC,__class,") == 00
)
{0
387
0
    if (const GlobalVariable *
gv0
= dyn_cast<GlobalVariable>(v))
{0
388
0
      addObjCClass(gv);
389
0
    }
390
0
  }
391
0
392
0
  // special case if this data blob is an ObjC category definition
393
0
  else 
if (0
Section.compare(0, 18, "__OBJC,__category,") == 00
)
{0
394
0
    if (const GlobalVariable *
gv0
= dyn_cast<GlobalVariable>(v))
{0
395
0
      addObjCCategory(gv);
396
0
    }
397
0
  }
398
0
399
0
  // special case if this data blob is the list of referenced classes
400
0
  else 
if (0
Section.compare(0, 18, "__OBJC,__cls_refs,") == 00
)
{0
401
0
    if (const GlobalVariable *
gv0
= dyn_cast<GlobalVariable>(v))
{0
402
0
      addObjCClassRef(gv);
403
0
    }
404
0
  }
405
0
}
406
407
148
void LTOModule::addDefinedFunctionSymbol(ModuleSymbolTable::Symbol Sym) {
408
148
  SmallString<64> Buffer;
409
148
  {
410
148
    raw_svector_ostream OS(Buffer);
411
148
    SymTab.printSymbolName(OS, Sym);
412
148
    Buffer.c_str();
413
148
  }
414
148
415
148
  const Function *F = cast<Function>(Sym.get<GlobalValue *>());
416
148
  addDefinedFunctionSymbol(Buffer, F);
417
148
}
418
419
151
void LTOModule::addDefinedFunctionSymbol(StringRef Name, const Function *F) {
420
151
  // add to list of defined symbols
421
151
  addDefinedSymbol(Name, F, true);
422
151
}
423
424
void LTOModule::addDefinedSymbol(StringRef Name, const GlobalValue *def,
425
178
                                 bool isFunction) {
426
178
  // set alignment part log2() can have rounding errors
427
178
  uint32_t align = def->getAlignment();
428
174
  uint32_t attr = align ? 
countTrailingZeros(align)4
:
0174
;
429
178
430
178
  // set permissions part
431
178
  if (
isFunction178
)
{151
432
151
    attr |= LTO_SYMBOL_PERMISSIONS_CODE;
433
27
  } else {
434
27
    const GlobalVariable *gv = dyn_cast<GlobalVariable>(def);
435
27
    if (
gv && 27
gv->isConstant()25
)
436
10
      attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
437
27
    else
438
17
      attr |= LTO_SYMBOL_PERMISSIONS_DATA;
439
27
  }
440
178
441
178
  // set definition part
442
178
  if (
def->hasWeakLinkage() || 178
def->hasLinkOnceLinkage()176
)
443
36
    attr |= LTO_SYMBOL_DEFINITION_WEAK;
444
142
  else 
if (142
def->hasCommonLinkage()142
)
445
0
    attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
446
142
  else
447
142
    attr |= LTO_SYMBOL_DEFINITION_REGULAR;
448
178
449
178
  // set scope part
450
178
  if (def->hasLocalLinkage())
451
178
    // Ignore visibility if linkage is local.
452
17
    attr |= LTO_SYMBOL_SCOPE_INTERNAL;
453
161
  else 
if (161
def->hasHiddenVisibility()161
)
454
2
    attr |= LTO_SYMBOL_SCOPE_HIDDEN;
455
159
  else 
if (159
def->hasProtectedVisibility()159
)
456
0
    attr |= LTO_SYMBOL_SCOPE_PROTECTED;
457
159
  else 
if (159
canBeOmittedFromSymbolTable(def)159
)
458
10
    attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
459
159
  else
460
149
    attr |= LTO_SYMBOL_SCOPE_DEFAULT;
461
178
462
178
  if (def->hasComdat())
463
20
    attr |= LTO_SYMBOL_COMDAT;
464
178
465
178
  if (isa<GlobalAlias>(def))
466
2
    attr |= LTO_SYMBOL_ALIAS;
467
178
468
178
  auto Iter = _defines.insert(Name).first;
469
178
470
178
  // fill information structure
471
178
  NameAndAttributes info;
472
178
  StringRef NameRef = Iter->first();
473
178
  info.name = NameRef;
474
178
  assert(NameRef.data()[NameRef.size()] == '\0');
475
178
  info.attributes = attr;
476
178
  info.isFunction = isFunction;
477
178
  info.symbol = def;
478
178
479
178
  // add to table of symbols
480
178
  _symbols.push_back(info);
481
178
}
482
483
/// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the
484
/// defined list.
485
void LTOModule::addAsmGlobalSymbol(StringRef name,
486
4
                                   lto_symbol_attributes scope) {
487
4
  auto IterBool = _defines.insert(name);
488
4
489
4
  // only add new define if not already defined
490
4
  if (!IterBool.second)
491
0
    return;
492
4
493
4
  NameAndAttributes &info = _undefines[IterBool.first->first()];
494
4
495
4
  if (
info.symbol == nullptr4
)
{1
496
1
    // FIXME: This is trying to take care of module ASM like this:
497
1
    //
498
1
    //   module asm ".zerofill __FOO, __foo, _bar_baz_qux, 0"
499
1
    //
500
1
    // but is gross and its mother dresses it funny. Have the ASM parser give us
501
1
    // more details for this type of situation so that we're not guessing so
502
1
    // much.
503
1
504
1
    // fill information structure
505
1
    info.name = IterBool.first->first();
506
1
    info.attributes =
507
1
      LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope;
508
1
    info.isFunction = false;
509
1
    info.symbol = nullptr;
510
1
511
1
    // add to table of symbols
512
1
    _symbols.push_back(info);
513
1
    return;
514
1
  }
515
4
516
3
  
if (3
info.isFunction3
)
517
3
    addDefinedFunctionSymbol(info.name, cast<Function>(info.symbol));
518
3
  else
519
0
    addDefinedDataSymbol(info.name, info.symbol);
520
3
521
3
  _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK;
522
3
  _symbols.back().attributes |= scope;
523
3
}
524
525
/// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the
526
/// undefined list.
527
1
void LTOModule::addAsmGlobalSymbolUndef(StringRef name) {
528
1
  auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes()));
529
1
530
1
  _asm_undefines.push_back(IterBool.first->first());
531
1
532
1
  // we already have the symbol
533
1
  if (!IterBool.second)
534
0
    return;
535
1
536
1
  uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED;
537
1
  attr |= LTO_SYMBOL_SCOPE_DEFAULT;
538
1
  NameAndAttributes &info = IterBool.first->second;
539
1
  info.name = IterBool.first->first();
540
1
  info.attributes = attr;
541
1
  info.isFunction = false;
542
1
  info.symbol = nullptr;
543
1
}
544
545
/// Add a symbol which isn't defined just yet to a list to be resolved later.
546
void LTOModule::addPotentialUndefinedSymbol(ModuleSymbolTable::Symbol Sym,
547
29
                                            bool isFunc) {
548
29
  SmallString<64> name;
549
29
  {
550
29
    raw_svector_ostream OS(name);
551
29
    SymTab.printSymbolName(OS, Sym);
552
29
    name.c_str();
553
29
  }
554
29
555
29
  auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes()));
556
29
557
29
  // we already have the symbol
558
29
  if (!IterBool.second)
559
0
    return;
560
29
561
29
  NameAndAttributes &info = IterBool.first->second;
562
29
563
29
  info.name = IterBool.first->first();
564
29
565
29
  const GlobalValue *decl = Sym.dyn_cast<GlobalValue *>();
566
29
567
29
  if (decl->hasExternalWeakLinkage())
568
0
    info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF;
569
29
  else
570
29
    info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
571
29
572
29
  info.isFunction = isFunc;
573
29
  info.symbol = decl;
574
29
}
575
576
85
void LTOModule::parseSymbols() {
577
217
  for (auto Sym : SymTab.symbols()) {
578
217
    auto *GV = Sym.dyn_cast<GlobalValue *>();
579
217
    uint32_t Flags = SymTab.getSymbolFlags(Sym);
580
217
    if (Flags & object::BasicSymbolRef::SF_FormatSpecific)
581
8
      continue;
582
217
583
209
    bool IsUndefined = Flags & object::BasicSymbolRef::SF_Undefined;
584
209
585
209
    if (
!GV209
)
{5
586
5
      SmallString<64> Buffer;
587
5
      {
588
5
        raw_svector_ostream OS(Buffer);
589
5
        SymTab.printSymbolName(OS, Sym);
590
5
        Buffer.c_str();
591
5
      }
592
5
      StringRef Name(Buffer);
593
5
594
5
      if (IsUndefined)
595
1
        addAsmGlobalSymbolUndef(Name);
596
4
      else 
if (4
Flags & object::BasicSymbolRef::SF_Global4
)
597
0
        addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_DEFAULT);
598
4
      else
599
4
        addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_INTERNAL);
600
5
      continue;
601
5
    }
602
209
603
204
    auto *F = dyn_cast<Function>(GV);
604
204
    if (
IsUndefined204
)
{29
605
29
      addPotentialUndefinedSymbol(Sym, F != nullptr);
606
29
      continue;
607
29
    }
608
204
609
175
    
if (175
F175
)
{148
610
148
      addDefinedFunctionSymbol(Sym);
611
148
      continue;
612
148
    }
613
175
614
27
    
if (27
isa<GlobalVariable>(GV)27
)
{25
615
25
      addDefinedDataSymbol(Sym);
616
25
      continue;
617
25
    }
618
27
619
2
    assert(isa<GlobalAlias>(GV));
620
2
    addDefinedDataSymbol(Sym);
621
2
  }
622
85
623
85
  // make symbols for all undefines
624
85
  for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(),
625
116
         e = _undefines.end(); 
u != e116
;
++u31
)
{31
626
31
    // If this symbol also has a definition, then don't make an undefine because
627
31
    // it is a tentative definition.
628
31
    if (
_defines.count(u->getKey())31
)
continue5
;
629
26
    NameAndAttributes info = u->getValue();
630
26
    _symbols.push_back(info);
631
26
  }
632
85
}
633
634
/// parseMetadata - Parse metadata from the module
635
85
void LTOModule::parseMetadata() {
636
85
  raw_string_ostream OS(LinkerOpts);
637
85
638
85
  // Linker Options
639
85
  if (Metadata *
Val85
= getModule().getModuleFlag("Linker Options"))
{2
640
2
    MDNode *LinkerOptions = cast<MDNode>(Val);
641
4
    for (unsigned i = 0, e = LinkerOptions->getNumOperands(); 
i != e4
;
++i2
)
{2
642
2
      MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
643
4
      for (unsigned ii = 0, ie = MDOptions->getNumOperands(); 
ii != ie4
;
++ii2
)
{2
644
2
        MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
645
2
        OS << " " << MDOption->getString();
646
2
      }
647
2
    }
648
2
  }
649
85
650
85
  // Globals
651
205
  for (const NameAndAttributes &Sym : _symbols) {
652
205
    if (!Sym.symbol)
653
1
      continue;
654
204
    _target->getObjFileLowering()->emitLinkerFlagsForGlobal(OS, Sym.symbol);
655
204
  }
656
85
657
85
  // Add other interesting metadata here.
658
85
}