LTOModule.cpp revision 3cc52ea33c0b96d1682f14fc45c45b57df0f39b6
15ef31a039dbb9c36cfd78442b3554d1b6974ec4cChris Lattner//===-- LTOModule.cpp - LLVM Link Time Optimizer --------------------------===// 277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// The LLVM Compiler Infrastructure 477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// This file is distributed under the University of Illinois Open Source 677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// License. See LICENSE.TXT for details. 7b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// 877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===// 977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 10b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// This file implements the Link Time Optimization library. This library is 1177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// intended to be used by linker to optimize code at link time. 1277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 1377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===// 1477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 15ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "LTOModule.h" 16ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 173eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik#include "llvm/Constants.h" 188b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson#include "llvm/LLVMContext.h" 1977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Module.h" 20ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/ADT/OwningPtr.h" 21e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov#include "llvm/ADT/Triple.h" 2277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Bitcode/ReaderWriter.h" 2377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/SystemUtils.h" 2477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/MemoryBuffer.h" 25ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/Support/MathExtras.h" 263cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Host.h" 273cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Path.h" 283cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Process.h" 2945111d160cf0910030eeb6a949c69273502e5ad5Chris Lattner#include "llvm/Target/Mangler.h" 30604a818463b9a7797f8e2806d6c192949b490300Bill Wendling#include "llvm/Target/SubtargetFeature.h" 31af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h" 325ef31a039dbb9c36cfd78442b3554d1b6974ec4cChris Lattner#include "llvm/MC/MCContext.h" 33ff9834ab9daeee25dbb67ae5e2341930cde46c86Daniel Dunbar#include "llvm/Target/TargetMachine.h" 34ff9834ab9daeee25dbb67ae5e2341930cde46c86Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 35d42b58b61cd773e9f798d02c42652488d67d38dfNick Lewycky#include "llvm/Target/TargetSelect.h" 3677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 3777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikusing namespace llvm; 3877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 39b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFile(const void *mem, size_t length) { 40b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return llvm::sys::IdentifyFileType((char*)mem, length) 41b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar == llvm::sys::Bitcode_FileType; 4277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 4377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 44b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFile(const char *path) { 45b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return llvm::sys::Path(path).isBitcodeFile(); 4677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 4777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 48b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length, 49b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *triplePrefix) { 50b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar MemoryBuffer *buffer = makeBuffer(mem, length); 51b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!buffer) 52b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return false; 53b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return isTargetMatch(buffer, triplePrefix); 5477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 5577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 56ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 57b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFileForTarget(const char *path, 58b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *triplePrefix) { 59b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar MemoryBuffer *buffer = MemoryBuffer::getFile(path); 60b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (buffer == NULL) 61b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return false; 62b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return isTargetMatch(buffer, triplePrefix); 63ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 64ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 65b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// Takes ownership of buffer. 66b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) { 6734711747a1d2c8713e69333bacef1c880810e371Bill Wendling std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); 6834711747a1d2c8713e69333bacef1c880810e371Bill Wendling delete buffer; 6934711747a1d2c8713e69333bacef1c880810e371Bill Wendling return (strncmp(Triple.c_str(), triplePrefix, 7034711747a1d2c8713e69333bacef1c880810e371Bill Wendling strlen(triplePrefix)) == 0); 7177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 7277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 7377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 74b06913dd183fe4d294b88a166d4180d3de660135Daniel DunbarLTOModule::LTOModule(Module *m, TargetMachine *t) 75b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar : _module(m), _target(t), _symbolsParsed(false) 7677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 7777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 7877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 79b06913dd183fe4d294b88a166d4180d3de660135Daniel DunbarLTOModule *LTOModule::makeLTOModule(const char *path, 80b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string &errMsg) { 81b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg)); 82b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!buffer) 83b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 84b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return makeLTOModule(buffer.get(), errMsg); 8577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 8677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 87b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar/// makeBuffer - Create a MemoryBuffer from a memory range. MemoryBuffer 88b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar/// requires the byte past end of the buffer to be a zero. We might get lucky 89b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar/// and already be that way, otherwise make a copy. Also if next byte is on a 90b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar/// different page, don't assume it is readable. 91b06913dd183fe4d294b88a166d4180d3de660135Daniel DunbarMemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { 92b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *startPtr = (char*)mem; 93b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *endPtr = startPtr+length; 94b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (((uintptr_t)endPtr & (sys::Process::GetPageSize()-1)) == 0 || 95b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar *endPtr != 0) 96b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return MemoryBuffer::getMemBufferCopy(StringRef(startPtr, length)); 97b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 98b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return MemoryBuffer::getMemBuffer(StringRef(startPtr, length)); 9990dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik} 10090dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik 10190dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik 102b06913dd183fe4d294b88a166d4180d3de660135Daniel DunbarLTOModule *LTOModule::makeLTOModule(const void *mem, size_t length, 103b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string &errMsg) { 104b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length)); 105b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!buffer) 106b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 107b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return makeLTOModule(buffer.get(), errMsg); 108ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 10977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 110b06913dd183fe4d294b88a166d4180d3de660135Daniel DunbarLTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, 111b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string &errMsg) { 112b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar InitializeAllTargets(); 113b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 114b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // parse bitcode buffer 115b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar OwningPtr<Module> m(ParseBitcodeFile(buffer, getGlobalContext(), &errMsg)); 116b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!m) 117b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 118b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 119b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string Triple = m->getTargetTriple(); 120b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (Triple.empty()) 121b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar Triple = sys::getHostTriple(); 122b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 123b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // find machine architecture for this module 124b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); 125b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!march) 126b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 127b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 128b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // construct LTModule, hand over ownership of module and target 129b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar SubtargetFeatures Features; 130b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar Features.getDefaultSubtargetFeatures("" /* cpu */, llvm::Triple(Triple)); 131b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string FeatureStr = Features.getString(); 132b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar TargetMachine *target = march->createTargetMachine(Triple, FeatureStr); 133b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return new LTOModule(m.take(), target); 13477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 13577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 136ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 137b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarconst char *LTOModule::getTargetTriple() { 138b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return _module->getTargetTriple().c_str(); 139ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 140ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 141b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::setTargetTriple(const char *triple) { 142b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _module->setTargetTriple(triple); 143cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola} 144cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola 145b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addDefinedFunctionSymbol(Function *f, Mangler &mangler) { 146b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // add to list of defined symbols 147b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addDefinedSymbol(f, mangler, true); 148b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 149b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // add external symbols referenced by this function. 150b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar for (Function::iterator b = f->begin(); b != f->end(); ++b) { 151b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) { 152b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar for (unsigned count = 0, total = i->getNumOperands(); 153b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar count != total; ++count) { 154b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar findExternalRefs(i->getOperand(count), mangler); 155b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 15677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 157b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 15877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 15977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 160b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// Get string that data pointer points to. 161b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) { 162b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) { 163b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar Constant *op = ce->getOperand(0); 164b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) { 165b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar Constant *cn = gvn->getInitializer(); 166b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (ConstantArray *ca = dyn_cast<ConstantArray>(cn)) { 167b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (ca->isCString()) { 168b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar name = ".objc_class_name_" + ca->getAsString(); 169b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return true; 1703eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 171b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 1723eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 173b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 174b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return false; 1753eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 1763eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 177b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// Parse i386/ppc ObjC class data structure. 178b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addObjCClass(GlobalVariable *clgv) { 179b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { 180b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // second slot in __OBJC,__class is pointer to superclass name 181b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string superclassName; 182b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { 183b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 184b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (_undefines.find(superclassName.c_str()) == _undefines.end()) { 185b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *symbolName = ::strdup(superclassName.c_str()); 1868d0843dcffad90ba200663c5b3aca3ce1e362e96Daniel Dunbar info.name = symbolName; 187b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 188b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // string is owned by _undefines 189b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _undefines[info.name] = info; 190b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 1913eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 192b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // third slot in __OBJC,__class is pointer to class name 193b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string className; 194b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (objcClassNameFromExpression(c->getOperand(2), className)) { 195b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *symbolName = ::strdup(className.c_str()); 196b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 197b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.name = symbolName; 198b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = (lto_symbol_attributes) 199b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar (LTO_SYMBOL_PERMISSIONS_DATA | 200b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar LTO_SYMBOL_DEFINITION_REGULAR | 201b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar LTO_SYMBOL_SCOPE_DEFAULT); 202b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _symbols.push_back(info); 203b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _defines[info.name] = 1; 2043eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 205b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 2063eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 2073eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2083eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 209b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// Parse i386/ppc ObjC category data structure. 210b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addObjCCategory(GlobalVariable *clgv) { 211b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { 212b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // second slot in __OBJC,__category is pointer to target class name 2133eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik std::string targetclassName; 214b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (objcClassNameFromExpression(c->getOperand(1), targetclassName)) { 215b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 216b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (_undefines.find(targetclassName.c_str()) == _undefines.end()) { 217b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *symbolName = ::strdup(targetclassName.c_str()); 2188d0843dcffad90ba200663c5b3aca3ce1e362e96Daniel Dunbar info.name = symbolName; 219b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 220b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // string is owned by _undefines 221b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _undefines[info.name] = info; 222b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 2233eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 224b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 2253eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 2263eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2273eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 228b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// Parse i386/ppc ObjC class list data structure. 229b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addObjCClassRef(GlobalVariable *clgv) { 230b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string targetclassName; 231b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) { 232b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 233b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (_undefines.find(targetclassName.c_str()) == _undefines.end()) { 234b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *symbolName = ::strdup(targetclassName.c_str()); 2358d0843dcffad90ba200663c5b3aca3ce1e362e96Daniel Dunbar info.name = symbolName; 236b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 237b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // string is owned by _undefines 238b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _undefines[info.name] = info; 239ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik } 240b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 24177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 24277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 243ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 244b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addDefinedDataSymbol(GlobalValue *v, Mangler &mangler) { 245b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // Add to list of defined symbols. 246b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addDefinedSymbol(v, mangler, false); 247b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 248b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // Special case i386/ppc ObjC data structures in magic sections: 249b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // The issue is that the old ObjC object format did some strange 250b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // contortions to avoid real linker symbols. For instance, the 251b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ObjC class data structure is allocated statically in the executable 252b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // that defines that class. That data structures contains a pointer to 253b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // its superclass. But instead of just initializing that part of the 254b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // struct to the address of its superclass, and letting the static and 255b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // dynamic linkers do the rest, the runtime works by having that field 256b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // instead point to a C-string that is the name of the superclass. 257b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // At runtime the objc initialization updates that pointer and sets 258b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // it to point to the actual super class. As far as the linker 259b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // knows it is just a pointer to a string. But then someone wanted the 260b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // linker to issue errors at build time if the superclass was not found. 261b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // So they figured out a way in mach-o object format to use an absolute 262b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // symbols (.objc_class_name_Foo = 0) and a floating reference 263b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // (.reference .objc_class_name_Bar) to cause the linker into erroring when 264b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // a class was missing. 265b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // The following synthesizes the implicit .objc_* symbols for the linker 266b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // from the ObjC data structures generated by the front end. 267b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (v->hasSection() /* && isTargetDarwin */) { 268b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // special case if this data blob is an ObjC class definition 269b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { 270b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 271b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addObjCClass(gv); 272b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 27377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 274b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 275b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // special case if this data blob is an ObjC category definition 276b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { 277b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 278b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addObjCCategory(gv); 279b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 2806a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen } 281b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 282b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // special case if this data blob is the list of referenced classes 283b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { 284b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 285b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addObjCClassRef(gv); 286b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 28777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 288b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 28977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 290b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // add external symbols referenced by this data. 291b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar for (unsigned count = 0, total = v->getNumOperands(); 292b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar count != total; ++count) { 293b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar findExternalRefs(v->getOperand(count), mangler); 294b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 29577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 29677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 297b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 298b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler, 299b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar bool isFunction) { 300b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ignore all llvm.* symbols 301b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (def->getName().startswith("llvm.")) 302b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 303b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 304b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // string is owned by _defines 305b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *symbolName = ::strdup(mangler.getNameWithPrefix(def).c_str()); 306b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 307b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set alignment part log2() can have rounding errors 308b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar uint32_t align = def->getAlignment(); 309b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0; 310b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 311b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set permissions part 312b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (isFunction) 313b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_PERMISSIONS_CODE; 314b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else { 315b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar GlobalVariable *gv = dyn_cast<GlobalVariable>(def); 316b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (gv && gv->isConstant()) 317b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_PERMISSIONS_RODATA; 318b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 319b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_PERMISSIONS_DATA; 320b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 321b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 322b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set definition part 323563ef5ec911d219b54fdb508518abd02a8dd3cfdBill Wendling if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() || 324563ef5ec911d219b54fdb508518abd02a8dd3cfdBill Wendling def->hasLinkerPrivateWeakLinkage() || 3257afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling def->hasLinkerPrivateWeakDefAutoLinkage()) 326b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_DEFINITION_WEAK; 3277afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else if (def->hasCommonLinkage()) 328b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; 3297afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else 330b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_DEFINITION_REGULAR; 331b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 332b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set scope part 333b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (def->hasHiddenVisibility()) 334b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_SCOPE_HIDDEN; 335b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else if (def->hasProtectedVisibility()) 336b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_SCOPE_PROTECTED; 3377afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else if (def->hasExternalLinkage() || def->hasWeakLinkage() || 3387afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling def->hasLinkOnceLinkage() || def->hasCommonLinkage() || 3397afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling def->hasLinkerPrivateWeakLinkage()) 3403eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik attr |= LTO_SYMBOL_SCOPE_DEFAULT; 3417afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else if (def->hasLinkerPrivateWeakDefAutoLinkage()) 3427afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; 343b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 344b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_SCOPE_INTERNAL; 345b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 346b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // add to table of symbols 347b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 348b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.name = symbolName; 349b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = (lto_symbol_attributes)attr; 350b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _symbols.push_back(info); 351b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _defines[info.name] = 1; 352c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel} 35377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 354b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addAsmGlobalSymbol(const char *name) { 355b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // only add new define if not already defined 356f4452c37d03ab6cdcd2b23cb15b921c0bba591a7Daniel Dunbar if (_defines.count(name)) 357b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 358b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 359b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // string is owned by _defines 360b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *symbolName = ::strdup(name); 361b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR; 362b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_SCOPE_DEFAULT; 363b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 364b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.name = symbolName; 365b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = (lto_symbol_attributes)attr; 366b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _symbols.push_back(info); 367b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _defines[info.name] = 1; 368b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar} 3693eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 370b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, 371b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar Mangler &mangler) { 372b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ignore all llvm.* symbols 373b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (decl->getName().startswith("llvm.")) 374b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 375b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 376b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ignore all aliases 377b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (isa<GlobalAlias>(decl)) 378b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 379b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 380b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string name = mangler.getNameWithPrefix(decl); 381b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 382b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // we already have the symbol 383b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (_undefines.find(name) != _undefines.end()) 384b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 385b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 386b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 387b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // string is owned by _undefines 388b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.name = ::strdup(name.c_str()); 389b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (decl->hasExternalWeakLinkage()) 390b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; 391b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 392b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 393b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _undefines[name] = info; 394b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar} 395485ded0db71b2abe51da919bd58501cee345c443Nick Lewycky 3967431af050f287011fd52e64034ede6dd98193febRafael Espindola 3977431af050f287011fd52e64034ede6dd98193febRafael Espindola 398b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar// Find external symbols referenced by VALUE. This is a recursive function. 399b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::findExternalRefs(Value *value, Mangler &mangler) { 400b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) { 401b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!gv->hasExternalLinkage()) 402b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addPotentialUndefinedSymbol(gv, mangler); 403b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // If this is a variable definition, do not recursively process 404b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // initializer. It might contain a reference to this variable 405b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // and cause an infinite loop. The initializer will be 406b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // processed in addDefinedDataSymbol(). 407b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 408b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 409b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 410b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // GlobalValue, even with InternalLinkage type, may have operands with 411b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ExternalLinkage type. Do not ignore these operands. 412b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (Constant *c = dyn_cast<Constant>(value)) { 413b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // Handle ConstantExpr, ConstantStruct, ConstantArry etc. 414b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i) 415b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar findExternalRefs(c->getOperand(i), mangler); 416b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 41777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 41877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 419b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::lazyParseSymbols() { 420e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar if (_symbolsParsed) 421e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar return; 4224136e7b90ea5ce8b4d708cdd54d0b052d520a96eGabor Greif 423e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar _symbolsParsed = true; 42477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 425e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // Use mangler to add GlobalPrefix to names to match linker names. 426e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar MCContext Context(*_target->getMCAsmInfo()); 427e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar Mangler mangler(Context, *_target->getTargetData()); 428c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel 429e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // add functions 430e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { 431e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar if (f->isDeclaration()) 432e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar addPotentialUndefinedSymbol(f, mangler); 433e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar else 434e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar addDefinedFunctionSymbol(f, mangler); 435e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar } 436e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 437e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // add data 438e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar for (Module::global_iterator v = _module->global_begin(), 439e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar e = _module->global_end(); v != e; ++v) { 440e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar if (v->isDeclaration()) 441e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar addPotentialUndefinedSymbol(v, mangler); 442e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar else 443e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar addDefinedDataSymbol(v, mangler); 444e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar } 445e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 446e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // add asm globals 447e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar const std::string &inlineAsm = _module->getModuleInlineAsm(); 448e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar const std::string glbl = ".globl"; 449e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar std::string asmSymbolName; 450e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar std::string::size_type pos = inlineAsm.find(glbl, 0); 451e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar while (pos != std::string::npos) { 452e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // eat .globl 453e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar pos = pos + 6; 454e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 455e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // skip white space between .globl and symbol name 456e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar std::string::size_type pbegin = inlineAsm.find_first_not_of(' ', pos); 457e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar if (pbegin == std::string::npos) 458e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar break; 459e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 460e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // find end-of-line 461e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar std::string::size_type pend = inlineAsm.find_first_of('\n', pbegin); 462e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar if (pend == std::string::npos) 463e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar break; 464e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 465e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar asmSymbolName.assign(inlineAsm, pbegin, pend - pbegin); 466e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar addAsmGlobalSymbol(asmSymbolName.c_str()); 467e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 468e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // search next .globl 469e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar pos = inlineAsm.find(glbl, pend); 470e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar } 471e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 47202003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola // add aliases 47302003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola for (Module::alias_iterator i = _module->alias_begin(), 47402003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola e = _module->alias_end(); i != e; ++i) { 47502003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola if (i->isDeclaration()) 47602003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola addPotentialUndefinedSymbol(i, mangler); 47702003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola else 47802003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola addDefinedDataSymbol(i, mangler); 47902003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola } 48002003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola 481e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // make symbols for all undefines 482e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar for (StringMap<NameAndAttributes>::iterator it=_undefines.begin(); 483e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar it != _undefines.end(); ++it) { 484e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // if this symbol also has a definition, then don't make an undefine 485e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // because it is a tentative definition 486e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar if (_defines.count(it->getKey()) == 0) { 487e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar NameAndAttributes info = it->getValue(); 488e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar _symbols.push_back(info); 489b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 490b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 491ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 492ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 493ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 494b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbaruint32_t LTOModule::getSymbolCount() { 495b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar lazyParseSymbols(); 496b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return _symbols.size(); 49777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 49877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 49977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 500b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarlto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) { 501b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar lazyParseSymbols(); 502b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (index < _symbols.size()) 503b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return _symbols[index].attributes; 504b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 505b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return lto_symbol_attributes(0); 50677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 50777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 508b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarconst char *LTOModule::getSymbolName(uint32_t index) { 509b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar lazyParseSymbols(); 510b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (index < _symbols.size()) 511b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return _symbols[index].name; 512b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 513b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 51477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 515