166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===-- LTOModule.cpp - LLVM Link Time Optimizer --------------------------===// 266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// The LLVM Compiler Infrastructure 466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This file is distributed under the University of Illinois Open Source 666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// License. See LICENSE.TXT for details. 766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===// 966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 1066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This file implements the Link Time Optimization library. This library is 1166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// intended to be used by linker to optimize code at link time. 1266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 1366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===// 1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "LTOModule.h" 1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Constants.h" 1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/LLVMContext.h" 1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Module.h" 2066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/OwningPtr.h" 2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/Triple.h" 2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Bitcode/ReaderWriter.h" 2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/SystemUtils.h" 2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/MemoryBuffer.h" 2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/MathExtras.h" 2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Host.h" 2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Path.h" 2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Process.h" 2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/SourceMgr.h" 3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/TargetRegistry.h" 3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/TargetSelect.h" 3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/system_error.h" 3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Target/Mangler.h" 3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCAsmInfo.h" 3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCContext.h" 3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCExpr.h" 3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCInst.h" 3866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCParser/MCAsmParser.h" 3966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCStreamer.h" 4066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCSubtargetInfo.h" 4166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCSymbol.h" 4266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/SubtargetFeature.h" 4366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCTargetAsmParser.h" 4466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Target/TargetMachine.h" 4566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Target/TargetRegisterInfo.h" 4666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 4766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanusing namespace llvm; 4866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 4966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::isBitcodeFile(const void *mem, size_t length) { 5066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return llvm::sys::IdentifyFileType((char*)mem, length) 5166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman == llvm::sys::Bitcode_FileType; 5266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 5366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 5466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::isBitcodeFile(const char *path) { 5566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return llvm::sys::Path(path).isBitcodeFile(); 5666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 5766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 5866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length, 5966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char *triplePrefix) { 6066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman MemoryBuffer *buffer = makeBuffer(mem, length); 6166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!buffer) 6266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return false; 6366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return isTargetMatch(buffer, triplePrefix); 6466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 6566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 6666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 6766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::isBitcodeFileForTarget(const char *path, 6866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char *triplePrefix) { 6966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<MemoryBuffer> buffer; 7066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (MemoryBuffer::getFile(path, buffer)) 7166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return false; 7266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return isTargetMatch(buffer.take(), triplePrefix); 7366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 7466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 7566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Takes ownership of buffer. 7666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) { 7766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); 7866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman delete buffer; 7966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return (strncmp(Triple.c_str(), triplePrefix, 8066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman strlen(triplePrefix)) == 0); 8166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 8266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8466b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanLTOModule::LTOModule(Module *m, TargetMachine *t) 8566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman : _module(m), _target(t) 8666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman{ 8766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 8866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8966b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanLTOModule *LTOModule::makeLTOModule(const char *path, 9066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string &errMsg) { 9166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<MemoryBuffer> buffer; 9266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (error_code ec = MemoryBuffer::getFile(path, buffer)) { 9366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errMsg = ec.message(); 9466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 9566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 9666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return makeLTOModule(buffer.take(), errMsg); 9766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 9866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 9966b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanLTOModule *LTOModule::makeLTOModule(int fd, const char *path, 10066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman size_t size, 10166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string &errMsg) { 10266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return makeLTOModule(fd, path, size, size, 0, errMsg); 10366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 10466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 10566b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanLTOModule *LTOModule::makeLTOModule(int fd, const char *path, 10666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman size_t file_size, 10766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman size_t map_size, 10866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman off_t offset, 10966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string &errMsg) { 11066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<MemoryBuffer> buffer; 11166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (error_code ec = MemoryBuffer::getOpenFile(fd, path, buffer, file_size, 11266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman map_size, offset, false)) { 11366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errMsg = ec.message(); 11466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 11566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 11666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return makeLTOModule(buffer.take(), errMsg); 11766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 11866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 11966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// makeBuffer - Create a MemoryBuffer from a memory range. 12066b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanMemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { 12166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char *startPtr = (char*)mem; 12266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false); 12366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 12466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 12566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 12666b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanLTOModule *LTOModule::makeLTOModule(const void *mem, size_t length, 12766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string &errMsg) { 12866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length)); 12966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!buffer) 13066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 13166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return makeLTOModule(buffer.take(), errMsg); 13266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 13366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 13466b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanLTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, 13566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string &errMsg) { 13666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static bool Initialized = false; 13766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!Initialized) { 13866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman InitializeAllTargets(); 13966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman InitializeAllTargetMCs(); 14066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman InitializeAllAsmParsers(); 14166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Initialized = true; 14266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 14366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 14466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // parse bitcode buffer 14566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext(), 14666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman &errMsg)); 14766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!m) { 14866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman delete buffer; 14966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 15066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 15166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 15266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string Triple = m->getTargetTriple(); 15366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Triple.empty()) 15466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Triple = sys::getHostTriple(); 15566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 15666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // find machine architecture for this module 15766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); 15866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!march) 15966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 16066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 16166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // construct LTOModule, hand over ownership of module and target 16266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman SubtargetFeatures Features; 16366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Features.getDefaultSubtargetFeatures(llvm::Triple(Triple)); 16466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string FeatureStr = Features.getString(); 16566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string CPU; 16666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr); 16766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman LTOModule *Ret = new LTOModule(m.take(), target); 16866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman bool Err = Ret->ParseSymbols(errMsg); 16966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Err) { 17066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman delete Ret; 17166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 17266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 17366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return Ret; 17466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 17566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 17666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 17766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanconst char *LTOModule::getTargetTriple() { 17866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return _module->getTargetTriple().c_str(); 17966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 18066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 18166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::setTargetTriple(const char *triple) { 18266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _module->setTargetTriple(triple); 18366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 18466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 18566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addDefinedFunctionSymbol(Function *f, Mangler &mangler) { 18666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // add to list of defined symbols 18766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addDefinedSymbol(f, mangler, true); 18866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 18966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 19066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Get string that data pointer points to. 19166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) { 19266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) { 19366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Constant *op = ce->getOperand(0); 19466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) { 19566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Constant *cn = gvn->getInitializer(); 19666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (ConstantArray *ca = dyn_cast<ConstantArray>(cn)) { 19766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (ca->isCString()) { 19866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman name = ".objc_class_name_" + ca->getAsCString(); 19966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return true; 20066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 20166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 20266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 20366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 20466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return false; 20566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 20666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 20766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Parse i386/ppc ObjC class data structure. 20866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addObjCClass(GlobalVariable *clgv) { 20966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { 21066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // second slot in __OBJC,__class is pointer to superclass name 21166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string superclassName; 21266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { 21366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 21466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringMap<NameAndAttributes>::value_type &entry = 21566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _undefines.GetOrCreateValue(superclassName); 21666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!entry.getValue().name) { 21766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char *symbolName = entry.getKey().data(); 21866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = symbolName; 21966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 22066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(info); 22166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 22266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 22366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // third slot in __OBJC,__class is pointer to class name 22466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string className; 22566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (objcClassNameFromExpression(c->getOperand(2), className)) { 22666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringSet::value_type &entry = 22766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _defines.GetOrCreateValue(className); 22866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(1); 22966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 23066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = entry.getKey().data(); 23166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = (lto_symbol_attributes) 23266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman (LTO_SYMBOL_PERMISSIONS_DATA | 23366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman LTO_SYMBOL_DEFINITION_REGULAR | 23466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman LTO_SYMBOL_SCOPE_DEFAULT); 23566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _symbols.push_back(info); 23666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 23766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 23866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 23966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 24066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 24166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Parse i386/ppc ObjC category data structure. 24266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addObjCCategory(GlobalVariable *clgv) { 24366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { 24466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // second slot in __OBJC,__category is pointer to target class name 24566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string targetclassName; 24666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (objcClassNameFromExpression(c->getOperand(1), targetclassName)) { 24766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 24866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 24966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringMap<NameAndAttributes>::value_type &entry = 25066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _undefines.GetOrCreateValue(targetclassName); 25166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 25266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (entry.getValue().name) 25366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 25466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 25566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char *symbolName = entry.getKey().data(); 25666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = symbolName; 25766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 25866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(info); 25966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 26066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 26166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 26266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 26366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 26466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Parse i386/ppc ObjC class list data structure. 26566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addObjCClassRef(GlobalVariable *clgv) { 26666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string targetclassName; 26766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) { 26866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 26966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 27066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringMap<NameAndAttributes>::value_type &entry = 27166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _undefines.GetOrCreateValue(targetclassName); 27266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (entry.getValue().name) 27366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 27466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 27566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char *symbolName = entry.getKey().data(); 27666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = symbolName; 27766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 27866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(info); 27966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 28066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 28166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 28266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 28366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addDefinedDataSymbol(GlobalValue *v, Mangler &mangler) { 28466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add to list of defined symbols. 28566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addDefinedSymbol(v, mangler, false); 28666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 28766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Special case i386/ppc ObjC data structures in magic sections: 28866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // The issue is that the old ObjC object format did some strange 28966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // contortions to avoid real linker symbols. For instance, the 29066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // ObjC class data structure is allocated statically in the executable 29166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // that defines that class. That data structures contains a pointer to 29266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // its superclass. But instead of just initializing that part of the 29366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // struct to the address of its superclass, and letting the static and 29466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // dynamic linkers do the rest, the runtime works by having that field 29566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // instead point to a C-string that is the name of the superclass. 29666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // At runtime the objc initialization updates that pointer and sets 29766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // it to point to the actual super class. As far as the linker 29866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // knows it is just a pointer to a string. But then someone wanted the 29966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // linker to issue errors at build time if the superclass was not found. 30066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // So they figured out a way in mach-o object format to use an absolute 30166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // symbols (.objc_class_name_Foo = 0) and a floating reference 30266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // (.reference .objc_class_name_Bar) to cause the linker into erroring when 30366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // a class was missing. 30466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // The following synthesizes the implicit .objc_* symbols for the linker 30566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // from the ObjC data structures generated by the front end. 30666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (v->hasSection() /* && isTargetDarwin */) { 30766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // special case if this data blob is an ObjC class definition 30866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { 30966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 31066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addObjCClass(gv); 31166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 31266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 31366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 31466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // special case if this data blob is an ObjC category definition 31566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { 31666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 31766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addObjCCategory(gv); 31866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 31966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 32066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 32166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // special case if this data blob is the list of referenced classes 32266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { 32366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 32466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addObjCClassRef(gv); 32566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 32666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 32766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 32866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 32966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 33066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 33166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler, 33266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman bool isFunction) { 33366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // ignore all llvm.* symbols 33466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (def->getName().startswith("llvm.")) 33566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 33666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 33766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // string is owned by _defines 33866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman SmallString<64> Buffer; 33966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mangler.getNameWithPrefix(Buffer, def, false); 34066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 34166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // set alignment part log2() can have rounding errors 34266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman uint32_t align = def->getAlignment(); 34366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0; 34466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 34566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // set permissions part 34666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (isFunction) 34766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_PERMISSIONS_CODE; 34866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else { 34966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman GlobalVariable *gv = dyn_cast<GlobalVariable>(def); 35066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (gv && gv->isConstant()) 35166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_PERMISSIONS_RODATA; 35266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 35366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_PERMISSIONS_DATA; 35466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 35566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 35666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // set definition part 35766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() || 35866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman def->hasLinkerPrivateWeakLinkage() || 35966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman def->hasLinkerPrivateWeakDefAutoLinkage()) 36066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_DEFINITION_WEAK; 36166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (def->hasCommonLinkage()) 36266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; 36366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 36466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_DEFINITION_REGULAR; 36566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 36666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // set scope part 36766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (def->hasHiddenVisibility()) 36866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_SCOPE_HIDDEN; 36966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (def->hasProtectedVisibility()) 37066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_SCOPE_PROTECTED; 37166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (def->hasExternalLinkage() || def->hasWeakLinkage() || 37266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman def->hasLinkOnceLinkage() || def->hasCommonLinkage() || 37366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman def->hasLinkerPrivateWeakLinkage()) 37466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_SCOPE_DEFAULT; 37566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (def->hasLinkerPrivateWeakDefAutoLinkage()) 37666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; 37766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 37866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_SCOPE_INTERNAL; 37966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 38066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // add to table of symbols 38166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 38266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer); 38366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(1); 38466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 38566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringRef Name = entry.getKey(); 38666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = Name.data(); 38766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman assert(info.name[Name.size()] == '\0'); 38866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = (lto_symbol_attributes)attr; 38966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _symbols.push_back(info); 39066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 39166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 39266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addAsmGlobalSymbol(const char *name, 39366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman lto_symbol_attributes scope) { 39466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringSet::value_type &entry = _defines.GetOrCreateValue(name); 39566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 39666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // only add new define if not already defined 39766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (entry.getValue()) 39866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 39966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 40066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(1); 40166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char *symbolName = entry.getKey().data(); 40266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR; 40366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= scope; 40466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 40566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = symbolName; 40666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = (lto_symbol_attributes)attr; 40766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _symbols.push_back(info); 40866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 40966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 41066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addAsmGlobalSymbolUndef(const char *name) { 41166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringMap<NameAndAttributes>::value_type &entry = 41266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _undefines.GetOrCreateValue(name); 41366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 41466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _asm_undefines.push_back(entry.getKey().data()); 41566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 41666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // we already have the symbol 41766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (entry.getValue().name) 41866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 41966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 42066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED;; 42166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman attr |= LTO_SYMBOL_SCOPE_DEFAULT; 42266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 42366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = entry.getKey().data(); 42466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = (lto_symbol_attributes)attr; 42566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 42666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(info); 42766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 42866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 42966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, 43066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Mangler &mangler) { 43166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // ignore all llvm.* symbols 43266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (decl->getName().startswith("llvm.")) 43366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 43466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 43566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // ignore all aliases 43666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (isa<GlobalAlias>(decl)) 43766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 43866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 43966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman SmallString<64> name; 44066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mangler.getNameWithPrefix(name, decl, false); 44166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 44266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringMap<NameAndAttributes>::value_type &entry = 44366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _undefines.GetOrCreateValue(name); 44466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 44566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // we already have the symbol 44666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (entry.getValue().name) 44766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 44866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 44966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info; 45066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 45166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.name = entry.getKey().data(); 45266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (decl->hasExternalWeakLinkage()) 45366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; 45466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 45566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 45666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 45766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entry.setValue(info); 45866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 45966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 46066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 46166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace { 46266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman class RecordStreamer : public MCStreamer { 46366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman public: 46466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman enum State { NeverSeen, Global, Defined, DefinedGlobal, Used}; 46566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 46666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman private: 46766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringMap<State> Symbols; 46866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 46966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman void markDefined(const MCSymbol &Symbol) { 47066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman State &S = Symbols[Symbol.getName()]; 47166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman switch (S) { 47266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case DefinedGlobal: 47366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Global: 47466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman S = DefinedGlobal; 47566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 47666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case NeverSeen: 47766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Defined: 47866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Used: 47966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman S = Defined; 48066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 48166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 48266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 48366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman void markGlobal(const MCSymbol &Symbol) { 48466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman State &S = Symbols[Symbol.getName()]; 48566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman switch (S) { 48666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case DefinedGlobal: 48766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Defined: 48866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman S = DefinedGlobal; 48966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 49066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 49166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case NeverSeen: 49266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Global: 49366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Used: 49466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman S = Global; 49566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 49666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 49766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 49866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman void markUsed(const MCSymbol &Symbol) { 49966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman State &S = Symbols[Symbol.getName()]; 50066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman switch (S) { 50166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case DefinedGlobal: 50266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Defined: 50366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Global: 50466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 50566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 50666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case NeverSeen: 50766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Used: 50866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman S = Used; 50966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 51066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 51166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 51266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 51366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // FIXME: mostly copied for the obj streamer. 51466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman void AddValueSymbols(const MCExpr *Value) { 51566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman switch (Value->getKind()) { 51666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case MCExpr::Target: 51766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // FIXME: What should we do in here? 51866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 51966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 52066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case MCExpr::Constant: 52166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 52266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 52366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case MCExpr::Binary: { 52466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 52566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman AddValueSymbols(BE->getLHS()); 52666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman AddValueSymbols(BE->getRHS()); 52766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 52866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 52966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 53066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case MCExpr::SymbolRef: 53166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman markUsed(cast<MCSymbolRefExpr>(Value)->getSymbol()); 53266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 53366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 53466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case MCExpr::Unary: 53566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 53666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman break; 53766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 53866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 53966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 54066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman public: 54166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typedef StringMap<State>::const_iterator const_iterator; 54266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 54366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const_iterator begin() { 54466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return Symbols.begin(); 54566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 54666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 54766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const_iterator end() { 54866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return Symbols.end(); 54966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 55066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 55166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman RecordStreamer(MCContext &Context) : MCStreamer(Context) {} 55266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 55366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void ChangeSection(const MCSection *Section) {} 55466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void InitSections() {} 55566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitLabel(MCSymbol *Symbol) { 55666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Symbol->setSection(*getCurrentSection()); 55766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman markDefined(*Symbol); 55866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 55966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {} 56066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitThumbFunc(MCSymbol *Func) {} 56166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 56266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // FIXME: should we handle aliases? 56366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman markDefined(*Symbol); 56466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 56566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { 56666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Attribute == MCSA_Global) 56766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman markGlobal(*Symbol); 56866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 56966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} 57066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} 57166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {} 57266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitCOFFSymbolStorageClass(int StorageClass) {} 57366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 57466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned Size , unsigned ByteAlignment) { 57566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman markDefined(*Symbol); 57666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 57766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitCOFFSymbolType(int Type) {} 57866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EndCOFFSymbolDef() {} 57966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 58066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned ByteAlignment) { 58166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman markDefined(*Symbol); 58266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 58366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} 58466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 58566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned ByteAlignment) {} 58666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 58766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman uint64_t Size, unsigned ByteAlignment) {} 58866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {} 58966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, 59066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned AddrSpace) {} 59166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitULEB128Value(const MCExpr *Value) {} 59266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitSLEB128Value(const MCExpr *Value) {} 59366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 59466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned ValueSize, 59566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned MaxBytesToEmit) {} 59666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitCodeAlignment(unsigned ByteAlignment, 59766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned MaxBytesToEmit) {} 59866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitValueToOffset(const MCExpr *Offset, 59966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned char Value ) {} 60066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitFileDirective(StringRef Filename) {} 60166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, 60266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const MCSymbol *LastLabel, 60366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const MCSymbol *Label, 60466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned PointerSize) {} 60566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 60666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void EmitInstruction(const MCInst &Inst) { 60766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Scan for values. 60866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned i = Inst.getNumOperands(); i--; ) 60966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Inst.getOperand(i).isExpr()) 61066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman AddValueSymbols(Inst.getOperand(i).getExpr()); 61166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 61266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman virtual void Finish() {} 61366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman }; 61466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 61566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 61666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::addAsmGlobalSymbols(MCContext &Context, std::string &errMsg) { 61766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const std::string &inlineAsm = _module->getModuleInlineAsm(); 61866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (inlineAsm.empty()) 61966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return false; 62066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 62166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<RecordStreamer> Streamer(new RecordStreamer(Context)); 62266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm); 62366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman SourceMgr SrcMgr; 62466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); 62566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, 62666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Context, *Streamer, 62766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman *_target->getMCAsmInfo())); 62866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<MCSubtargetInfo> STI(_target->getTarget(). 62966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman createMCSubtargetInfo(_target->getTargetTriple(), 63066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _target->getTargetCPU(), 63166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _target->getTargetFeatureString())); 63266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<MCTargetAsmParser> 63366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman TAP(_target->getTarget().createMCAsmParser(*STI, *Parser.get())); 63466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!TAP) { 63566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errMsg = "target " + std::string(_target->getTarget().getName()) + 63666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman " does not define AsmParser."; 63766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return true; 63866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 63966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 64066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Parser->setTargetParser(*TAP); 64166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman int Res = Parser->Run(false); 64266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Res) 64366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return true; 64466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 64566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (RecordStreamer::const_iterator i = Streamer->begin(), 64666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman e = Streamer->end(); i != e; ++i) { 64766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman StringRef Key = i->first(); 64866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman RecordStreamer::State Value = i->second; 64966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Value == RecordStreamer::DefinedGlobal) 65066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_DEFAULT); 65166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (Value == RecordStreamer::Defined) 65266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_INTERNAL); 65366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else if (Value == RecordStreamer::Global || 65466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Value == RecordStreamer::Used) 65566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addAsmGlobalSymbolUndef(Key.data()); 65666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 65766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return false; 65866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 65966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 66066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic bool isDeclaration(const GlobalValue &V) { 66166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (V.hasAvailableExternallyLinkage()) 66266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return true; 66366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (V.isMaterializable()) 66466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return false; 66566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return V.isDeclaration(); 66666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 66766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 66866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic bool isAliasToDeclaration(const GlobalAlias &V) { 66966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return isDeclaration(*V.getAliasedGlobal()); 67066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 67166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 67266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanbool LTOModule::ParseSymbols(std::string &errMsg) { 67366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Use mangler to add GlobalPrefix to names to match linker names. 67466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL); 67566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Mangler mangler(Context, *_target->getTargetData()); 67666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 67766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // add functions 67866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { 67966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (isDeclaration(*f)) 68066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addPotentialUndefinedSymbol(f, mangler); 68166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 68266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addDefinedFunctionSymbol(f, mangler); 68366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 68466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 68566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // add data 68666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (Module::global_iterator v = _module->global_begin(), 68766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman e = _module->global_end(); v != e; ++v) { 68866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (isDeclaration(*v)) 68966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addPotentialUndefinedSymbol(v, mangler); 69066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 69166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addDefinedDataSymbol(v, mangler); 69266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 69366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 69466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // add asm globals 69566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (addAsmGlobalSymbols(Context, errMsg)) 69666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return true; 69766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 69866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // add aliases 69966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (Module::alias_iterator i = _module->alias_begin(), 70066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman e = _module->alias_end(); i != e; ++i) { 70166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (isAliasToDeclaration(*i)) 70266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addPotentialUndefinedSymbol(i, mangler); 70366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 70466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman addDefinedDataSymbol(i, mangler); 70566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 70666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 70766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // make symbols for all undefines 70866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (StringMap<NameAndAttributes>::iterator it=_undefines.begin(); 70966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman it != _undefines.end(); ++it) { 71066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // if this symbol also has a definition, then don't make an undefine 71166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // because it is a tentative definition 71266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (_defines.count(it->getKey()) == 0) { 71366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NameAndAttributes info = it->getValue(); 71466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman _symbols.push_back(info); 71566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 71666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 71766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return false; 71866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 71966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 72066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 72166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanuint32_t LTOModule::getSymbolCount() { 72266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return _symbols.size(); 72366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 72466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 72566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 72666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanlto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) { 72766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (index < _symbols.size()) 72866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return _symbols[index].attributes; 72966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 73066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return lto_symbol_attributes(0); 73166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 73266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 73366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanconst char *LTOModule::getSymbolName(uint32_t index) { 73466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (index < _symbols.size()) 73566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return _symbols[index].name; 73666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 73766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 73866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 739