LTOModule.cpp revision 327952
1259698Sdim//===-- LTOModule.cpp - LLVM Link Time Optimizer --------------------------===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// This file implements the Link Time Optimization library. This library is 11259698Sdim// intended to be used by linker to optimize code at link time. 12259698Sdim// 13259698Sdim//===----------------------------------------------------------------------===// 14259698Sdim 15309124Sdim#include "llvm/LTO/legacy/LTOModule.h" 16259698Sdim#include "llvm/ADT/Triple.h" 17321369Sdim#include "llvm/Analysis/ObjectUtils.h" 18314564Sdim#include "llvm/Bitcode/BitcodeReader.h" 19327952Sdim#include "llvm/CodeGen/TargetLoweringObjectFile.h" 20327952Sdim#include "llvm/CodeGen/TargetSubtargetInfo.h" 21259698Sdim#include "llvm/IR/Constants.h" 22259698Sdim#include "llvm/IR/LLVMContext.h" 23321369Sdim#include "llvm/IR/Mangler.h" 24276479Sdim#include "llvm/IR/Metadata.h" 25259698Sdim#include "llvm/IR/Module.h" 26259698Sdim#include "llvm/MC/MCExpr.h" 27259698Sdim#include "llvm/MC/MCInst.h" 28259698Sdim#include "llvm/MC/MCParser/MCAsmParser.h" 29276479Sdim#include "llvm/MC/MCSection.h" 30259698Sdim#include "llvm/MC/MCSubtargetInfo.h" 31259698Sdim#include "llvm/MC/MCSymbol.h" 32259698Sdim#include "llvm/MC/SubtargetFeature.h" 33280031Sdim#include "llvm/Object/IRObjectFile.h" 34280031Sdim#include "llvm/Object/ObjectFile.h" 35276479Sdim#include "llvm/Support/FileSystem.h" 36259698Sdim#include "llvm/Support/Host.h" 37259698Sdim#include "llvm/Support/MemoryBuffer.h" 38259698Sdim#include "llvm/Support/Path.h" 39259698Sdim#include "llvm/Support/SourceMgr.h" 40259698Sdim#include "llvm/Support/TargetRegistry.h" 41259698Sdim#include "llvm/Support/TargetSelect.h" 42259698Sdim#include "llvm/Transforms/Utils/GlobalStatus.h" 43276479Sdim#include <system_error> 44259698Sdimusing namespace llvm; 45280031Sdimusing namespace llvm::object; 46259698Sdim 47314564SdimLTOModule::LTOModule(std::unique_ptr<Module> M, MemoryBufferRef MBRef, 48276479Sdim llvm::TargetMachine *TM) 49314564Sdim : Mod(std::move(M)), MBRef(MBRef), _target(TM) { 50314564Sdim SymTab.addModule(Mod.get()); 51314564Sdim} 52259698Sdim 53280031SdimLTOModule::~LTOModule() {} 54280031Sdim 55259698Sdim/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM 56259698Sdim/// bitcode. 57280031Sdimbool LTOModule::isBitcodeFile(const void *Mem, size_t Length) { 58327952Sdim Expected<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer( 59280031Sdim MemoryBufferRef(StringRef((const char *)Mem, Length), "<mem>")); 60327952Sdim if (!BCData) { 61327952Sdim consumeError(BCData.takeError()); 62327952Sdim return false; 63327952Sdim } 64327952Sdim return true; 65259698Sdim} 66259698Sdim 67314564Sdimbool LTOModule::isBitcodeFile(StringRef Path) { 68280031Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 69280031Sdim MemoryBuffer::getFile(Path); 70280031Sdim if (!BufferOrErr) 71259698Sdim return false; 72280031Sdim 73327952Sdim Expected<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer( 74280031Sdim BufferOrErr.get()->getMemBufferRef()); 75327952Sdim if (!BCData) { 76327952Sdim consumeError(BCData.takeError()); 77327952Sdim return false; 78327952Sdim } 79327952Sdim return true; 80259698Sdim} 81259698Sdim 82309124Sdimbool LTOModule::isThinLTO() { 83321369Sdim Expected<BitcodeLTOInfo> Result = getBitcodeLTOInfo(MBRef); 84314564Sdim if (!Result) { 85314564Sdim logAllUnhandledErrors(Result.takeError(), errs(), ""); 86314564Sdim return false; 87314564Sdim } 88321369Sdim return Result->IsThinLTO; 89309124Sdim} 90309124Sdim 91280031Sdimbool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, 92280031Sdim StringRef TriplePrefix) { 93327952Sdim Expected<MemoryBufferRef> BCOrErr = 94280031Sdim IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); 95327952Sdim if (!BCOrErr) { 96327952Sdim consumeError(BCOrErr.takeError()); 97280031Sdim return false; 98327952Sdim } 99280031Sdim LLVMContext Context; 100314564Sdim ErrorOr<std::string> TripleOrErr = 101314564Sdim expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(*BCOrErr)); 102314564Sdim if (!TripleOrErr) 103314564Sdim return false; 104314564Sdim return StringRef(*TripleOrErr).startswith(TriplePrefix); 105259698Sdim} 106259698Sdim 107296417Sdimstd::string LTOModule::getProducerString(MemoryBuffer *Buffer) { 108327952Sdim Expected<MemoryBufferRef> BCOrErr = 109296417Sdim IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); 110327952Sdim if (!BCOrErr) { 111327952Sdim consumeError(BCOrErr.takeError()); 112296417Sdim return ""; 113327952Sdim } 114296417Sdim LLVMContext Context; 115314564Sdim ErrorOr<std::string> ProducerOrErr = expectedToErrorOrAndEmitErrors( 116314564Sdim Context, getBitcodeProducerString(*BCOrErr)); 117314564Sdim if (!ProducerOrErr) 118314564Sdim return ""; 119314564Sdim return *ProducerOrErr; 120296417Sdim} 121296417Sdim 122296417SdimErrorOr<std::unique_ptr<LTOModule>> 123314564SdimLTOModule::createFromFile(LLVMContext &Context, StringRef path, 124309124Sdim const TargetOptions &options) { 125276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 126276479Sdim MemoryBuffer::getFile(path); 127309124Sdim if (std::error_code EC = BufferOrErr.getError()) { 128309124Sdim Context.emitError(EC.message()); 129296417Sdim return EC; 130309124Sdim } 131280031Sdim std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); 132309124Sdim return makeLTOModule(Buffer->getMemBufferRef(), options, Context, 133309124Sdim /* ShouldBeLazy*/ false); 134259698Sdim} 135259698Sdim 136296417SdimErrorOr<std::unique_ptr<LTOModule>> 137314564SdimLTOModule::createFromOpenFile(LLVMContext &Context, int fd, StringRef path, 138309124Sdim size_t size, const TargetOptions &options) { 139296417Sdim return createFromOpenFileSlice(Context, fd, path, size, 0, options); 140259698Sdim} 141259698Sdim 142296417SdimErrorOr<std::unique_ptr<LTOModule>> 143314564SdimLTOModule::createFromOpenFileSlice(LLVMContext &Context, int fd, StringRef path, 144314564Sdim size_t map_size, off_t offset, 145314564Sdim const TargetOptions &options) { 146276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 147276479Sdim MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset); 148309124Sdim if (std::error_code EC = BufferOrErr.getError()) { 149309124Sdim Context.emitError(EC.message()); 150296417Sdim return EC; 151309124Sdim } 152280031Sdim std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); 153309124Sdim return makeLTOModule(Buffer->getMemBufferRef(), options, Context, 154309124Sdim /* ShouldBeLazy */ false); 155259698Sdim} 156259698Sdim 157296417SdimErrorOr<std::unique_ptr<LTOModule>> 158296417SdimLTOModule::createFromBuffer(LLVMContext &Context, const void *mem, 159309124Sdim size_t length, const TargetOptions &options, 160296417Sdim StringRef path) { 161309124Sdim StringRef Data((const char *)mem, length); 162309124Sdim MemoryBufferRef Buffer(Data, path); 163309124Sdim return makeLTOModule(Buffer, options, Context, /* ShouldBeLazy */ false); 164259698Sdim} 165259698Sdim 166296417SdimErrorOr<std::unique_ptr<LTOModule>> 167309124SdimLTOModule::createInLocalContext(std::unique_ptr<LLVMContext> Context, 168309124Sdim const void *mem, size_t length, 169309124Sdim const TargetOptions &options, StringRef path) { 170280031Sdim StringRef Data((const char *)mem, length); 171280031Sdim MemoryBufferRef Buffer(Data, path); 172309124Sdim // If we own a context, we know this is being used only for symbol extraction, 173309124Sdim // not linking. Be lazy in that case. 174309124Sdim ErrorOr<std::unique_ptr<LTOModule>> Ret = 175309124Sdim makeLTOModule(Buffer, options, *Context, /* ShouldBeLazy */ true); 176309124Sdim if (Ret) 177309124Sdim (*Ret)->OwnedContext = std::move(Context); 178309124Sdim return Ret; 179280031Sdim} 180280031Sdim 181296417Sdimstatic ErrorOr<std::unique_ptr<Module>> 182296417SdimparseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context, 183296417Sdim bool ShouldBeLazy) { 184280031Sdim // Find the buffer. 185327952Sdim Expected<MemoryBufferRef> MBOrErr = 186280031Sdim IRObjectFile::findBitcodeInMemBuffer(Buffer); 187327952Sdim if (Error E = MBOrErr.takeError()) { 188327952Sdim std::error_code EC = errorToErrorCode(std::move(E)); 189309124Sdim Context.emitError(EC.message()); 190296417Sdim return EC; 191309124Sdim } 192259698Sdim 193280031Sdim if (!ShouldBeLazy) { 194280031Sdim // Parse the full file. 195314564Sdim return expectedToErrorOrAndEmitErrors(Context, 196314564Sdim parseBitcodeFile(*MBOrErr, Context)); 197280031Sdim } 198280031Sdim 199280031Sdim // Parse lazily. 200314564Sdim return expectedToErrorOrAndEmitErrors( 201314564Sdim Context, 202314564Sdim getLazyBitcodeModule(*MBOrErr, Context, true /*ShouldLazyLoadMetadata*/)); 203280031Sdim} 204280031Sdim 205296417SdimErrorOr<std::unique_ptr<LTOModule>> 206309124SdimLTOModule::makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options, 207309124Sdim LLVMContext &Context, bool ShouldBeLazy) { 208296417Sdim ErrorOr<std::unique_ptr<Module>> MOrErr = 209309124Sdim parseBitcodeFileImpl(Buffer, Context, ShouldBeLazy); 210296417Sdim if (std::error_code EC = MOrErr.getError()) 211296417Sdim return EC; 212296417Sdim std::unique_ptr<Module> &M = *MOrErr; 213280031Sdim 214276479Sdim std::string TripleStr = M->getTargetTriple(); 215259698Sdim if (TripleStr.empty()) 216259698Sdim TripleStr = sys::getDefaultTargetTriple(); 217259698Sdim llvm::Triple Triple(TripleStr); 218259698Sdim 219259698Sdim // find machine architecture for this module 220296417Sdim std::string errMsg; 221259698Sdim const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); 222259698Sdim if (!march) 223296417Sdim return std::unique_ptr<LTOModule>(nullptr); 224259698Sdim 225259698Sdim // construct LTOModule, hand over ownership of module and target 226259698Sdim SubtargetFeatures Features; 227259698Sdim Features.getDefaultSubtargetFeatures(Triple); 228259698Sdim std::string FeatureStr = Features.getString(); 229259698Sdim // Set a default CPU for Darwin triples. 230259698Sdim std::string CPU; 231259698Sdim if (Triple.isOSDarwin()) { 232259698Sdim if (Triple.getArch() == llvm::Triple::x86_64) 233259698Sdim CPU = "core2"; 234259698Sdim else if (Triple.getArch() == llvm::Triple::x86) 235259698Sdim CPU = "yonah"; 236280031Sdim else if (Triple.getArch() == llvm::Triple::aarch64) 237276479Sdim CPU = "cyclone"; 238259698Sdim } 239259698Sdim 240309124Sdim TargetMachine *target = 241309124Sdim march->createTargetMachine(TripleStr, CPU, FeatureStr, options, None); 242259698Sdim 243314564Sdim std::unique_ptr<LTOModule> Ret(new LTOModule(std::move(M), Buffer, target)); 244296417Sdim Ret->parseSymbols(); 245276479Sdim Ret->parseMetadata(); 246276479Sdim 247296417Sdim return std::move(Ret); 248259698Sdim} 249259698Sdim 250276479Sdim/// Create a MemoryBuffer from a memory range with an optional name. 251280031Sdimstd::unique_ptr<MemoryBuffer> 252280031SdimLTOModule::makeBuffer(const void *mem, size_t length, StringRef name) { 253259698Sdim const char *startPtr = (const char*)mem; 254276479Sdim return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false); 255259698Sdim} 256259698Sdim 257259698Sdim/// objcClassNameFromExpression - Get string that the data pointer points to. 258259698Sdimbool 259259698SdimLTOModule::objcClassNameFromExpression(const Constant *c, std::string &name) { 260259698Sdim if (const ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) { 261259698Sdim Constant *op = ce->getOperand(0); 262259698Sdim if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) { 263259698Sdim Constant *cn = gvn->getInitializer(); 264259698Sdim if (ConstantDataArray *ca = dyn_cast<ConstantDataArray>(cn)) { 265259698Sdim if (ca->isCString()) { 266288943Sdim name = (".objc_class_name_" + ca->getAsCString()).str(); 267259698Sdim return true; 268259698Sdim } 269259698Sdim } 270259698Sdim } 271259698Sdim } 272259698Sdim return false; 273259698Sdim} 274259698Sdim 275259698Sdim/// addObjCClass - Parse i386/ppc ObjC class data structure. 276259698Sdimvoid LTOModule::addObjCClass(const GlobalVariable *clgv) { 277259698Sdim const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); 278259698Sdim if (!c) return; 279259698Sdim 280259698Sdim // second slot in __OBJC,__class is pointer to superclass name 281259698Sdim std::string superclassName; 282259698Sdim if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { 283280031Sdim auto IterBool = 284280031Sdim _undefines.insert(std::make_pair(superclassName, NameAndAttributes())); 285280031Sdim if (IterBool.second) { 286280031Sdim NameAndAttributes &info = IterBool.first->second; 287314564Sdim info.name = IterBool.first->first(); 288259698Sdim info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 289259698Sdim info.isFunction = false; 290259698Sdim info.symbol = clgv; 291259698Sdim } 292259698Sdim } 293259698Sdim 294259698Sdim // third slot in __OBJC,__class is pointer to class name 295259698Sdim std::string className; 296259698Sdim if (objcClassNameFromExpression(c->getOperand(2), className)) { 297280031Sdim auto Iter = _defines.insert(className).first; 298259698Sdim 299259698Sdim NameAndAttributes info; 300314564Sdim info.name = Iter->first(); 301259698Sdim info.attributes = LTO_SYMBOL_PERMISSIONS_DATA | 302259698Sdim LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT; 303259698Sdim info.isFunction = false; 304259698Sdim info.symbol = clgv; 305259698Sdim _symbols.push_back(info); 306259698Sdim } 307259698Sdim} 308259698Sdim 309259698Sdim/// addObjCCategory - Parse i386/ppc ObjC category data structure. 310259698Sdimvoid LTOModule::addObjCCategory(const GlobalVariable *clgv) { 311259698Sdim const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); 312259698Sdim if (!c) return; 313259698Sdim 314259698Sdim // second slot in __OBJC,__category is pointer to target class name 315259698Sdim std::string targetclassName; 316259698Sdim if (!objcClassNameFromExpression(c->getOperand(1), targetclassName)) 317259698Sdim return; 318259698Sdim 319280031Sdim auto IterBool = 320280031Sdim _undefines.insert(std::make_pair(targetclassName, NameAndAttributes())); 321259698Sdim 322280031Sdim if (!IterBool.second) 323259698Sdim return; 324259698Sdim 325280031Sdim NameAndAttributes &info = IterBool.first->second; 326314564Sdim info.name = IterBool.first->first(); 327259698Sdim info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 328259698Sdim info.isFunction = false; 329259698Sdim info.symbol = clgv; 330259698Sdim} 331259698Sdim 332259698Sdim/// addObjCClassRef - Parse i386/ppc ObjC class list data structure. 333259698Sdimvoid LTOModule::addObjCClassRef(const GlobalVariable *clgv) { 334259698Sdim std::string targetclassName; 335259698Sdim if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) 336259698Sdim return; 337259698Sdim 338280031Sdim auto IterBool = 339280031Sdim _undefines.insert(std::make_pair(targetclassName, NameAndAttributes())); 340280031Sdim 341280031Sdim if (!IterBool.second) 342259698Sdim return; 343259698Sdim 344280031Sdim NameAndAttributes &info = IterBool.first->second; 345314564Sdim info.name = IterBool.first->first(); 346259698Sdim info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 347259698Sdim info.isFunction = false; 348259698Sdim info.symbol = clgv; 349259698Sdim} 350259698Sdim 351314564Sdimvoid LTOModule::addDefinedDataSymbol(ModuleSymbolTable::Symbol Sym) { 352276479Sdim SmallString<64> Buffer; 353276479Sdim { 354276479Sdim raw_svector_ostream OS(Buffer); 355314564Sdim SymTab.printSymbolName(OS, Sym); 356314564Sdim Buffer.c_str(); 357276479Sdim } 358276479Sdim 359314564Sdim const GlobalValue *V = Sym.get<GlobalValue *>(); 360314564Sdim addDefinedDataSymbol(Buffer, V); 361276479Sdim} 362276479Sdim 363314564Sdimvoid LTOModule::addDefinedDataSymbol(StringRef Name, const GlobalValue *v) { 364259698Sdim // Add to list of defined symbols. 365276479Sdim addDefinedSymbol(Name, v, false); 366259698Sdim 367259698Sdim if (!v->hasSection() /* || !isTargetDarwin */) 368259698Sdim return; 369259698Sdim 370259698Sdim // Special case i386/ppc ObjC data structures in magic sections: 371259698Sdim // The issue is that the old ObjC object format did some strange 372259698Sdim // contortions to avoid real linker symbols. For instance, the 373259698Sdim // ObjC class data structure is allocated statically in the executable 374259698Sdim // that defines that class. That data structures contains a pointer to 375259698Sdim // its superclass. But instead of just initializing that part of the 376259698Sdim // struct to the address of its superclass, and letting the static and 377259698Sdim // dynamic linkers do the rest, the runtime works by having that field 378259698Sdim // instead point to a C-string that is the name of the superclass. 379259698Sdim // At runtime the objc initialization updates that pointer and sets 380259698Sdim // it to point to the actual super class. As far as the linker 381259698Sdim // knows it is just a pointer to a string. But then someone wanted the 382259698Sdim // linker to issue errors at build time if the superclass was not found. 383259698Sdim // So they figured out a way in mach-o object format to use an absolute 384259698Sdim // symbols (.objc_class_name_Foo = 0) and a floating reference 385259698Sdim // (.reference .objc_class_name_Bar) to cause the linker into erroring when 386259698Sdim // a class was missing. 387259698Sdim // The following synthesizes the implicit .objc_* symbols for the linker 388259698Sdim // from the ObjC data structures generated by the front end. 389259698Sdim 390259698Sdim // special case if this data blob is an ObjC class definition 391327952Sdim if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(v)) { 392327952Sdim StringRef Section = GV->getSection(); 393327952Sdim if (Section.startswith("__OBJC,__class,")) { 394327952Sdim addObjCClass(GV); 395259698Sdim } 396259698Sdim 397327952Sdim // special case if this data blob is an ObjC category definition 398327952Sdim else if (Section.startswith("__OBJC,__category,")) { 399327952Sdim addObjCCategory(GV); 400259698Sdim } 401259698Sdim 402327952Sdim // special case if this data blob is the list of referenced classes 403327952Sdim else if (Section.startswith("__OBJC,__cls_refs,")) { 404327952Sdim addObjCClassRef(GV); 405259698Sdim } 406259698Sdim } 407259698Sdim} 408259698Sdim 409314564Sdimvoid LTOModule::addDefinedFunctionSymbol(ModuleSymbolTable::Symbol Sym) { 410276479Sdim SmallString<64> Buffer; 411276479Sdim { 412276479Sdim raw_svector_ostream OS(Buffer); 413314564Sdim SymTab.printSymbolName(OS, Sym); 414314564Sdim Buffer.c_str(); 415276479Sdim } 416276479Sdim 417314564Sdim const Function *F = cast<Function>(Sym.get<GlobalValue *>()); 418314564Sdim addDefinedFunctionSymbol(Buffer, F); 419276479Sdim} 420276479Sdim 421314564Sdimvoid LTOModule::addDefinedFunctionSymbol(StringRef Name, const Function *F) { 422259698Sdim // add to list of defined symbols 423276479Sdim addDefinedSymbol(Name, F, true); 424259698Sdim} 425259698Sdim 426314564Sdimvoid LTOModule::addDefinedSymbol(StringRef Name, const GlobalValue *def, 427276479Sdim bool isFunction) { 428259698Sdim // set alignment part log2() can have rounding errors 429259698Sdim uint32_t align = def->getAlignment(); 430276479Sdim uint32_t attr = align ? countTrailingZeros(align) : 0; 431259698Sdim 432259698Sdim // set permissions part 433259698Sdim if (isFunction) { 434259698Sdim attr |= LTO_SYMBOL_PERMISSIONS_CODE; 435259698Sdim } else { 436259698Sdim const GlobalVariable *gv = dyn_cast<GlobalVariable>(def); 437259698Sdim if (gv && gv->isConstant()) 438259698Sdim attr |= LTO_SYMBOL_PERMISSIONS_RODATA; 439259698Sdim else 440259698Sdim attr |= LTO_SYMBOL_PERMISSIONS_DATA; 441259698Sdim } 442259698Sdim 443259698Sdim // set definition part 444276479Sdim if (def->hasWeakLinkage() || def->hasLinkOnceLinkage()) 445259698Sdim attr |= LTO_SYMBOL_DEFINITION_WEAK; 446259698Sdim else if (def->hasCommonLinkage()) 447259698Sdim attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; 448259698Sdim else 449259698Sdim attr |= LTO_SYMBOL_DEFINITION_REGULAR; 450259698Sdim 451259698Sdim // set scope part 452276479Sdim if (def->hasLocalLinkage()) 453276479Sdim // Ignore visibility if linkage is local. 454276479Sdim attr |= LTO_SYMBOL_SCOPE_INTERNAL; 455276479Sdim else if (def->hasHiddenVisibility()) 456259698Sdim attr |= LTO_SYMBOL_SCOPE_HIDDEN; 457259698Sdim else if (def->hasProtectedVisibility()) 458259698Sdim attr |= LTO_SYMBOL_SCOPE_PROTECTED; 459280031Sdim else if (canBeOmittedFromSymbolTable(def)) 460259698Sdim attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; 461276479Sdim else 462259698Sdim attr |= LTO_SYMBOL_SCOPE_DEFAULT; 463259698Sdim 464288943Sdim if (def->hasComdat()) 465288943Sdim attr |= LTO_SYMBOL_COMDAT; 466288943Sdim 467288943Sdim if (isa<GlobalAlias>(def)) 468288943Sdim attr |= LTO_SYMBOL_ALIAS; 469288943Sdim 470280031Sdim auto Iter = _defines.insert(Name).first; 471259698Sdim 472259698Sdim // fill information structure 473259698Sdim NameAndAttributes info; 474280031Sdim StringRef NameRef = Iter->first(); 475314564Sdim info.name = NameRef; 476314564Sdim assert(NameRef.data()[NameRef.size()] == '\0'); 477259698Sdim info.attributes = attr; 478259698Sdim info.isFunction = isFunction; 479259698Sdim info.symbol = def; 480259698Sdim 481259698Sdim // add to table of symbols 482259698Sdim _symbols.push_back(info); 483259698Sdim} 484259698Sdim 485259698Sdim/// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the 486259698Sdim/// defined list. 487314564Sdimvoid LTOModule::addAsmGlobalSymbol(StringRef name, 488259698Sdim lto_symbol_attributes scope) { 489280031Sdim auto IterBool = _defines.insert(name); 490259698Sdim 491259698Sdim // only add new define if not already defined 492280031Sdim if (!IterBool.second) 493259698Sdim return; 494259698Sdim 495314564Sdim NameAndAttributes &info = _undefines[IterBool.first->first()]; 496259698Sdim 497276479Sdim if (info.symbol == nullptr) { 498259698Sdim // FIXME: This is trying to take care of module ASM like this: 499259698Sdim // 500259698Sdim // module asm ".zerofill __FOO, __foo, _bar_baz_qux, 0" 501259698Sdim // 502259698Sdim // but is gross and its mother dresses it funny. Have the ASM parser give us 503259698Sdim // more details for this type of situation so that we're not guessing so 504259698Sdim // much. 505259698Sdim 506259698Sdim // fill information structure 507314564Sdim info.name = IterBool.first->first(); 508259698Sdim info.attributes = 509259698Sdim LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope; 510259698Sdim info.isFunction = false; 511276479Sdim info.symbol = nullptr; 512259698Sdim 513259698Sdim // add to table of symbols 514259698Sdim _symbols.push_back(info); 515259698Sdim return; 516259698Sdim } 517259698Sdim 518259698Sdim if (info.isFunction) 519276479Sdim addDefinedFunctionSymbol(info.name, cast<Function>(info.symbol)); 520259698Sdim else 521276479Sdim addDefinedDataSymbol(info.name, info.symbol); 522259698Sdim 523259698Sdim _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK; 524259698Sdim _symbols.back().attributes |= scope; 525259698Sdim} 526259698Sdim 527259698Sdim/// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the 528259698Sdim/// undefined list. 529314564Sdimvoid LTOModule::addAsmGlobalSymbolUndef(StringRef name) { 530280031Sdim auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes())); 531259698Sdim 532314564Sdim _asm_undefines.push_back(IterBool.first->first()); 533259698Sdim 534259698Sdim // we already have the symbol 535280031Sdim if (!IterBool.second) 536259698Sdim return; 537259698Sdim 538276479Sdim uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED; 539259698Sdim attr |= LTO_SYMBOL_SCOPE_DEFAULT; 540280031Sdim NameAndAttributes &info = IterBool.first->second; 541314564Sdim info.name = IterBool.first->first(); 542259698Sdim info.attributes = attr; 543259698Sdim info.isFunction = false; 544276479Sdim info.symbol = nullptr; 545259698Sdim} 546259698Sdim 547276479Sdim/// Add a symbol which isn't defined just yet to a list to be resolved later. 548314564Sdimvoid LTOModule::addPotentialUndefinedSymbol(ModuleSymbolTable::Symbol Sym, 549276479Sdim bool isFunc) { 550259698Sdim SmallString<64> name; 551276479Sdim { 552276479Sdim raw_svector_ostream OS(name); 553314564Sdim SymTab.printSymbolName(OS, Sym); 554314564Sdim name.c_str(); 555276479Sdim } 556259698Sdim 557280031Sdim auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes())); 558259698Sdim 559259698Sdim // we already have the symbol 560280031Sdim if (!IterBool.second) 561259698Sdim return; 562259698Sdim 563280031Sdim NameAndAttributes &info = IterBool.first->second; 564259698Sdim 565314564Sdim info.name = IterBool.first->first(); 566259698Sdim 567314564Sdim const GlobalValue *decl = Sym.dyn_cast<GlobalValue *>(); 568276479Sdim 569259698Sdim if (decl->hasExternalWeakLinkage()) 570259698Sdim info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; 571259698Sdim else 572259698Sdim info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 573259698Sdim 574259698Sdim info.isFunction = isFunc; 575259698Sdim info.symbol = decl; 576259698Sdim} 577259698Sdim 578296417Sdimvoid LTOModule::parseSymbols() { 579314564Sdim for (auto Sym : SymTab.symbols()) { 580314564Sdim auto *GV = Sym.dyn_cast<GlobalValue *>(); 581314564Sdim uint32_t Flags = SymTab.getSymbolFlags(Sym); 582276479Sdim if (Flags & object::BasicSymbolRef::SF_FormatSpecific) 583276479Sdim continue; 584259698Sdim 585276479Sdim bool IsUndefined = Flags & object::BasicSymbolRef::SF_Undefined; 586259698Sdim 587276479Sdim if (!GV) { 588276479Sdim SmallString<64> Buffer; 589276479Sdim { 590276479Sdim raw_svector_ostream OS(Buffer); 591314564Sdim SymTab.printSymbolName(OS, Sym); 592314564Sdim Buffer.c_str(); 593259698Sdim } 594314564Sdim StringRef Name(Buffer); 595259698Sdim 596276479Sdim if (IsUndefined) 597276479Sdim addAsmGlobalSymbolUndef(Name); 598276479Sdim else if (Flags & object::BasicSymbolRef::SF_Global) 599276479Sdim addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_DEFAULT); 600276479Sdim else 601276479Sdim addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_INTERNAL); 602276479Sdim continue; 603259698Sdim } 604259698Sdim 605276479Sdim auto *F = dyn_cast<Function>(GV); 606276479Sdim if (IsUndefined) { 607276479Sdim addPotentialUndefinedSymbol(Sym, F != nullptr); 608276479Sdim continue; 609259698Sdim } 610259698Sdim 611276479Sdim if (F) { 612276479Sdim addDefinedFunctionSymbol(Sym); 613276479Sdim continue; 614259698Sdim } 615259698Sdim 616276479Sdim if (isa<GlobalVariable>(GV)) { 617276479Sdim addDefinedDataSymbol(Sym); 618276479Sdim continue; 619259698Sdim } 620259698Sdim 621276479Sdim assert(isa<GlobalAlias>(GV)); 622276479Sdim addDefinedDataSymbol(Sym); 623259698Sdim } 624259698Sdim 625259698Sdim // make symbols for all undefines 626259698Sdim for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(), 627259698Sdim e = _undefines.end(); u != e; ++u) { 628259698Sdim // If this symbol also has a definition, then don't make an undefine because 629259698Sdim // it is a tentative definition. 630259698Sdim if (_defines.count(u->getKey())) continue; 631259698Sdim NameAndAttributes info = u->getValue(); 632259698Sdim _symbols.push_back(info); 633259698Sdim } 634259698Sdim} 635276479Sdim 636276479Sdim/// parseMetadata - Parse metadata from the module 637276479Sdimvoid LTOModule::parseMetadata() { 638288943Sdim raw_string_ostream OS(LinkerOpts); 639288943Sdim 640276479Sdim // Linker Options 641321369Sdim if (NamedMDNode *LinkerOptions = 642321369Sdim getModule().getNamedMetadata("llvm.linker.options")) { 643276479Sdim for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { 644321369Sdim MDNode *MDOptions = LinkerOptions->getOperand(i); 645276479Sdim for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { 646276479Sdim MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii)); 647288943Sdim OS << " " << MDOption->getString(); 648276479Sdim } 649276479Sdim } 650276479Sdim } 651276479Sdim 652321369Sdim // Globals - we only need to do this for COFF. 653321369Sdim const Triple TT(_target->getTargetTriple()); 654321369Sdim if (!TT.isOSBinFormatCOFF()) 655321369Sdim return; 656321369Sdim Mangler M; 657288943Sdim for (const NameAndAttributes &Sym : _symbols) { 658288943Sdim if (!Sym.symbol) 659288943Sdim continue; 660321369Sdim emitLinkerFlagsForGlobalCOFF(OS, Sym.symbol, TT, M); 661288943Sdim } 662288943Sdim 663276479Sdim // Add other interesting metadata here. 664276479Sdim} 665