LTOModule.cpp revision 3eb445feb22647e867a339f4c59b0a716b03a21a
177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===-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. 777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===// 977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 1077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 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" 1877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Module.h" 1977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/ModuleProvider.h" 20ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/ADT/OwningPtr.h" 2177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Bitcode/ReaderWriter.h" 2277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/SystemUtils.h" 2377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/Mangler.h" 2477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/MemoryBuffer.h" 25ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/Support/MathExtras.h" 2677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/System/Path.h" 2790dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik#include "llvm/System/Process.h" 28604a818463b9a7797f8e2806d6c192949b490300Bill Wendling#include "llvm/Target/SubtargetFeature.h" 2977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Target/TargetMachine.h" 3077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Target/TargetMachineRegistry.h" 3177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Target/TargetAsmInfo.h" 3277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 3377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include <fstream> 3477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 3577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikusing namespace llvm; 3677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 3777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikbool LTOModule::isBitcodeFile(const void* mem, size_t length) 3877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 3977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return ( llvm::sys::IdentifyFileType((char*)mem, length) 4077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik == llvm::sys::Bitcode_FileType ); 4177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 4277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 4377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikbool LTOModule::isBitcodeFile(const char* path) 4477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 4577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return llvm::sys::Path(path).isBitcodeFile(); 4677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 4777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 48038112a4e0a9afd656f415ab397a230ae5921627Chris Lattnerbool LTOModule::isBitcodeFileForTarget(const void* mem, size_t length, 49038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner const char* triplePrefix) 5077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 5190dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik MemoryBuffer* buffer = makeBuffer(mem, length); 52ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( buffer == NULL ) 53ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return false; 54ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return isTargetMatch(buffer, triplePrefix); 5577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 5677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 57ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 5877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikbool LTOModule::isBitcodeFileForTarget(const char* path, 59038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner const char* triplePrefix) 6077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 61038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner MemoryBuffer *buffer = MemoryBuffer::getFile(path); 62038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner if (buffer == NULL) 63ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return false; 64ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return isTargetMatch(buffer, triplePrefix); 65ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 66ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 67ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik// takes ownership of buffer 68ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikbool LTOModule::isTargetMatch(MemoryBuffer* buffer, const char* triplePrefix) 69ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 70ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik OwningPtr<ModuleProvider> mp(getBitcodeModuleProvider(buffer)); 71ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // on success, mp owns buffer and both are deleted at end of this method 72ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !mp ) { 73ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik delete buffer; 74ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return false; 7577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 76ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik std::string actualTarget = mp->getModule()->getTargetTriple(); 77ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return ( strncmp(actualTarget.c_str(), triplePrefix, 78ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik strlen(triplePrefix)) == 0); 7977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 8077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 8177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 8277595fc35642f990bfc5ad05b8e68d4056695ecaNick KledzikLTOModule::LTOModule(Module* m, TargetMachine* t) 8377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik : _module(m), _target(t), _symbolsParsed(false) 8477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 8577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 8677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 87ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick KledzikLTOModule* LTOModule::makeLTOModule(const char* path, std::string& errMsg) 8877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 89038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg)); 90ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !buffer ) 91ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 92ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return makeLTOModule(buffer.get(), errMsg); 9377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 9477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 956b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// makeBuffer - create a MemoryBuffer from a memory range. 966b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// MemoryBuffer requires the byte past end of the buffer to be a zero. 976b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// We might get lucky and already be that way, otherwise make a copy. 986b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// Also if next byte is on a different page, don't assume it is readable. 9990dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick KledzikMemoryBuffer* LTOModule::makeBuffer(const void* mem, size_t length) 10090dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik{ 101ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik const char* startPtr = (char*)mem; 102ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik const char* endPtr = startPtr+length; 103ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik if ( (((uintptr_t)endPtr & (sys::Process::GetPageSize()-1)) == 0) 104ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik || (*endPtr != 0) ) 105ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik return MemoryBuffer::getMemBufferCopy(startPtr, endPtr); 106ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik else 107ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik return MemoryBuffer::getMemBuffer(startPtr, endPtr); 10890dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik} 10990dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik 11090dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik 111ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick KledzikLTOModule* LTOModule::makeLTOModule(const void* mem, size_t length, 112b454eabe7ff0824356ccdb75459a0312f43254c1Nick Lewycky std::string& errMsg) 113ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 11490dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length)); 115ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !buffer ) 116ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 117ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return makeLTOModule(buffer.get(), errMsg); 118ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 11977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 120e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// getFeatureString - Return a string listing the features associated with the 121e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// target triple. 122e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// 123e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// FIXME: This is an inelegant way of specifying the features of a 124e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// subtarget. It would be better if we could encode this information into the 125e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// IR. See <rdar://5972456>. 126e4242548976c04183a532695666803fb6a40ba06Bill Wendlingstd::string getFeatureString(const char *TargetTriple) { 127e4242548976c04183a532695666803fb6a40ba06Bill Wendling SubtargetFeatures Features; 128e4242548976c04183a532695666803fb6a40ba06Bill Wendling 129e4242548976c04183a532695666803fb6a40ba06Bill Wendling if (strncmp(TargetTriple, "powerpc-apple-", 14) == 0) { 130e4242548976c04183a532695666803fb6a40ba06Bill Wendling Features.AddFeature("altivec", true); 131e4242548976c04183a532695666803fb6a40ba06Bill Wendling } else if (strncmp(TargetTriple, "powerpc64-apple-", 16) == 0) { 132e4242548976c04183a532695666803fb6a40ba06Bill Wendling Features.AddFeature("64bit", true); 133e4242548976c04183a532695666803fb6a40ba06Bill Wendling Features.AddFeature("altivec", true); 134e4242548976c04183a532695666803fb6a40ba06Bill Wendling } 135e4242548976c04183a532695666803fb6a40ba06Bill Wendling 136e4242548976c04183a532695666803fb6a40ba06Bill Wendling return Features.getString(); 137e4242548976c04183a532695666803fb6a40ba06Bill Wendling} 138e4242548976c04183a532695666803fb6a40ba06Bill Wendling 139ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick KledzikLTOModule* LTOModule::makeLTOModule(MemoryBuffer* buffer, std::string& errMsg) 14077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 141ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // parse bitcode buffer 142ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik OwningPtr<Module> m(ParseBitcodeFile(buffer, &errMsg)); 143ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !m ) 144ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 145ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // find machine architecture for this module 146ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik const TargetMachineRegistry::entry* march = 147ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg); 148604a818463b9a7797f8e2806d6c192949b490300Bill Wendling 149ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( march == NULL ) 150ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 151604a818463b9a7797f8e2806d6c192949b490300Bill Wendling 152ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // construct LTModule, hand over ownership of module and target 153e4242548976c04183a532695666803fb6a40ba06Bill Wendling std::string FeatureStr = getFeatureString(m->getTargetTriple().c_str()); 154e4242548976c04183a532695666803fb6a40ba06Bill Wendling TargetMachine* target = march->CtorFn(*m, FeatureStr); 155ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return new LTOModule(m.take(), target); 15677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 15777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 158ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 159ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikconst char* LTOModule::getTargetTriple() 16077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 161ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return _module->getTargetTriple().c_str(); 162ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 163ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 164ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikvoid LTOModule::addDefinedFunctionSymbol(Function* f, Mangler &mangler) 165ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 166ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add to list of defined symbols 167ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedSymbol(f, mangler, true); 168ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 169ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add external symbols referenced by this function. 170ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik for (Function::iterator b = f->begin(); b != f->end(); ++b) { 171ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) { 172ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik for (unsigned count = 0, total = i->getNumOperands(); 173ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik count != total; ++count) { 174ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik findExternalRefs(i->getOperand(count), mangler); 17577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 17677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 17777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 17877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 17977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 1803eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik// get string that data pointer points to 1813eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzikbool LTOModule::objcClassNameFromExpression(Constant* c, std::string& name) 1823eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik{ 1833eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (ConstantExpr* ce = dyn_cast<ConstantExpr>(c)) { 1843eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik Constant* op = ce->getOperand(0); 1853eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (GlobalVariable* gvn = dyn_cast<GlobalVariable>(op)) { 1863eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik Constant* cn = gvn->getInitializer(); 1873eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (ConstantArray* ca = dyn_cast<ConstantArray>(cn)) { 1883eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( ca->isCString() ) { 1893eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik name = ".objc_class_name_" + ca->getAsString(); 1903eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik return true; 1913eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 1923eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 1933eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 1943eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 1953eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik return false; 1963eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 1973eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 1983eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik// parse i386/ppc ObjC class data structure 1993eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzikvoid LTOModule::addObjCClass(GlobalVariable* clgv) 2003eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik{ 2013eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (ConstantStruct* c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { 2023eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // second slot in __OBJC,__class is pointer to superclass name 2033eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik std::string superclassName; 2043eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( objcClassNameFromExpression(c->getOperand(1), superclassName) ) { 2053eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik NameAndAttributes info; 2063eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( _undefines.find(superclassName.c_str()) == _undefines.end() ) { 2073eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik const char* symbolName = ::strdup(superclassName.c_str()); 2083eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.name = ::strdup(symbolName); 2093eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 2103eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // string is owned by _undefines 2113eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik _undefines[info.name] = info; 2123eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2133eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2143eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // third slot in __OBJC,__class is pointer to class name 2153eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik std::string className; 2163eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( objcClassNameFromExpression(c->getOperand(2), className) ) { 2173eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik const char* symbolName = ::strdup(className.c_str()); 2183eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik NameAndAttributes info; 2193eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.name = symbolName; 2203eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.attributes = (lto_symbol_attributes) 2213eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik (LTO_SYMBOL_PERMISSIONS_DATA | 2223eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik LTO_SYMBOL_DEFINITION_REGULAR | 2233eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik LTO_SYMBOL_SCOPE_DEFAULT); 2243eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik _symbols.push_back(info); 2253eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik _defines[info.name] = 1; 2263eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2273eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2283eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 2293eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2303eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2313eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik// parse i386/ppc ObjC category data structure 2323eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzikvoid LTOModule::addObjCCategory(GlobalVariable* clgv) 2333eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik{ 2343eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (ConstantStruct* c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { 2353eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // second slot in __OBJC,__category is pointer to target class name 2363eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik std::string targetclassName; 2373eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( objcClassNameFromExpression(c->getOperand(1), targetclassName) ) { 2383eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik NameAndAttributes info; 2393eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( _undefines.find(targetclassName.c_str()) == _undefines.end() ){ 2403eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik const char* symbolName = ::strdup(targetclassName.c_str()); 2413eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.name = ::strdup(symbolName); 2423eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 2433eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // string is owned by _undefines 2443eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik _undefines[info.name] = info; 2453eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2463eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2473eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2483eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 2493eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2503eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2513eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik// parse i386/ppc ObjC class list data structure 2523eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzikvoid LTOModule::addObjCClassRef(GlobalVariable* clgv) 2533eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik{ 2543eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik std::string targetclassName; 2553eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( objcClassNameFromExpression(clgv->getInitializer(), targetclassName) ){ 2563eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik NameAndAttributes info; 2573eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( _undefines.find(targetclassName.c_str()) == _undefines.end() ) { 2583eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik const char* symbolName = ::strdup(targetclassName.c_str()); 2593eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.name = ::strdup(symbolName); 2603eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 2613eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // string is owned by _undefines 2623eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik _undefines[info.name] = info; 2633eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2643eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2653eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 2663eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2673eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2683eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzikvoid LTOModule::addDefinedDataSymbol(GlobalValue* v, Mangler& mangler) 269ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 270ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add to list of defined symbols 271ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedSymbol(v, mangler, false); 27277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 2733eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // special case i386/ppc ObjC data structures in magic sections 2743eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( v->hasSection() ) { 2753eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // special case if this data blob is an ObjC class definition 2763eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( v->getSection().compare(0, 15, "__OBJC,__class,") == 0 ) { 2773eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (GlobalVariable* gv = dyn_cast<GlobalVariable>(v)) { 2783eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik addObjCClass(gv); 2793eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2803eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2813eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2823eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // special case if this data blob is an ObjC category definition 2833eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik else if ( v->getSection().compare(0, 18, "__OBJC,__category,") == 0 ) { 2843eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (GlobalVariable* gv = dyn_cast<GlobalVariable>(v)) { 2853eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik addObjCCategory(gv); 2863eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2873eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2883eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 2893eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // special case if this data blob is the list of referenced classes 2903eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik else if ( v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0 ) { 2913eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if (GlobalVariable* gv = dyn_cast<GlobalVariable>(v)) { 2923eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik addObjCClassRef(gv); 2933eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2943eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2953eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 2963eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 297ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add external symbols referenced by this data. 2989178a65263bb1f00bb52a53e4e371f62db27d3bbNick Kledzik for (unsigned count = 0, total = v->getNumOperands(); 299ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik count != total; ++count) { 300ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik findExternalRefs(v->getOperand(count), mangler); 301ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik } 30277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 30377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 304ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 30577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikvoid LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler, 30677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik bool isFunction) 30777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 3083eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // ignore all llvm.* symbols 3093eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( strncmp(def->getNameStart(), "llvm.", 5) == 0 ) 3103eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik return; 3113eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 312ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // string is owned by _defines 31377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik const char* symbolName = ::strdup(mangler.getValueName(def).c_str()); 3143eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 31577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set alignment part log2() can have rounding errors 31677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik uint32_t align = def->getAlignment(); 317ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0; 31877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 31977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set permissions part 32077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( isFunction ) 32177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_PERMISSIONS_CODE; 32277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else { 32377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik GlobalVariable* gv = dyn_cast<GlobalVariable>(def); 32477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( (gv != NULL) && gv->isConstant() ) 32577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_PERMISSIONS_RODATA; 32677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 32777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_PERMISSIONS_DATA; 32877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 32977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 33077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set definition part 33177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( def->hasWeakLinkage() || def->hasLinkOnceLinkage() ) { 332ed1ec3aa6b646a47943fdbdf6148c342f0b5a31fDale Johannesen attr |= LTO_SYMBOL_DEFINITION_WEAK; 33377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 3346a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen else if ( def->hasCommonLinkage()) { 3356a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; 3366a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen } 33777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else { 33877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_DEFINITION_REGULAR; 33977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 34077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 34177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set scope part 34277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( def->hasHiddenVisibility() ) 34377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_SCOPE_HIDDEN; 3444fd40e884c76ffbf1157ab4ca48a099c55eebb4fNick Lewycky else if ( def->hasProtectedVisibility() ) 3454fd40e884c76ffbf1157ab4ca48a099c55eebb4fNick Lewycky attr |= LTO_SYMBOL_SCOPE_PROTECTED; 346f0d286b77fe40017192b527e5cc5d87974093d54Devang Patel else if ( def->hasExternalLinkage() || def->hasWeakLinkage() 347db6535dd2008897f6446dcfa1ae754d1a6eb0270Nick Kledzik || def->hasLinkOnceLinkage() || def->hasCommonLinkage() ) 34877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_SCOPE_DEFAULT; 34977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 35077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_SCOPE_INTERNAL; 35177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 35277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // add to table of symbols 35377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik NameAndAttributes info; 35477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik info.name = symbolName; 35577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik info.attributes = (lto_symbol_attributes)attr; 35677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _symbols.push_back(info); 35777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _defines[info.name] = 1; 35877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 35977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 360c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patelvoid LTOModule::addAsmGlobalSymbol(const char *name) { 3613eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // only add new define if not already defined 3623eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( _defines.count(name, &name[strlen(name)+1]) == 0 ) 3633eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik return; 3643eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 3653eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // string is owned by _defines 3663eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik const char *symbolName = ::strdup(name); 3673eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR; 3683eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik attr |= LTO_SYMBOL_SCOPE_DEFAULT; 3693eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik NameAndAttributes info; 3703eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.name = symbolName; 3713eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik info.attributes = (lto_symbol_attributes)attr; 3723eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik _symbols.push_back(info); 3733eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik _defines[info.name] = 1; 374c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel} 37577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 376ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikvoid LTOModule::addPotentialUndefinedSymbol(GlobalValue* decl, Mangler &mangler) 377ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 37877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // ignore all llvm.* symbols 3793eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik if ( strncmp(decl->getNameStart(), "llvm.", 5) == 0 ) 3803eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik return; 3813eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 3823eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik const char* name = mangler.getValueName(decl).c_str(); 3837431af050f287011fd52e64034ede6dd98193febRafael Espindola 3847431af050f287011fd52e64034ede6dd98193febRafael Espindola // we already have the symbol 3857431af050f287011fd52e64034ede6dd98193febRafael Espindola if (_undefines.find(name) != _undefines.end()) 3867431af050f287011fd52e64034ede6dd98193febRafael Espindola return; 3877431af050f287011fd52e64034ede6dd98193febRafael Espindola 3887431af050f287011fd52e64034ede6dd98193febRafael Espindola NameAndAttributes info; 3897431af050f287011fd52e64034ede6dd98193febRafael Espindola // string is owned by _undefines 3907431af050f287011fd52e64034ede6dd98193febRafael Espindola info.name = ::strdup(name); 3917431af050f287011fd52e64034ede6dd98193febRafael Espindola if (decl->hasExternalWeakLinkage()) 3927431af050f287011fd52e64034ede6dd98193febRafael Espindola info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; 3937431af050f287011fd52e64034ede6dd98193febRafael Espindola else 3947431af050f287011fd52e64034ede6dd98193febRafael Espindola info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 3957431af050f287011fd52e64034ede6dd98193febRafael Espindola _undefines[name] = info; 39677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 39777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 39877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 39977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 40077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// Find exeternal symbols referenced by VALUE. This is a recursive function. 40177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikvoid LTOModule::findExternalRefs(Value* value, Mangler &mangler) { 40277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 40377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if (GlobalValue* gv = dyn_cast<GlobalValue>(value)) { 40477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( !gv->hasExternalLinkage() ) 405ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addPotentialUndefinedSymbol(gv, mangler); 406ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // If this is a variable definition, do not recursively process 407ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // initializer. It might contain a reference to this variable 408ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // and cause an infinite loop. The initializer will be 409ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // processed in addDefinedDataSymbol(). 410ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik return; 41177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 412ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik 41377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // GlobalValue, even with InternalLinkage type, may have operands with 41477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // ExternalLinkage type. Do not ignore these operands. 41577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if (Constant* c = dyn_cast<Constant>(value)) { 41677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // Handle ConstantExpr, ConstantStruct, ConstantArry etc.. 41777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i) 41877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik findExternalRefs(c->getOperand(i), mangler); 41977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 42077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 42177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 422ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikvoid LTOModule::lazyParseSymbols() 42377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 42477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( !_symbolsParsed ) { 42577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _symbolsParsed = true; 42677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 42777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // Use mangler to add GlobalPrefix to names to match linker names. 42877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix()); 4293eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik // add chars used in ObjC method names so method names aren't mangled 4303eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik mangler.markCharAcceptable('['); 4313eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik mangler.markCharAcceptable(']'); 4323eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik mangler.markCharAcceptable('('); 4333eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik mangler.markCharAcceptable(')'); 4343eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik mangler.markCharAcceptable('-'); 4353eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik mangler.markCharAcceptable('+'); 4363eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik mangler.markCharAcceptable(' '); 43777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 43877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // add functions 43977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { 440ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( f->isDeclaration() ) 441ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addPotentialUndefinedSymbol(f, mangler); 442ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik else 443ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedFunctionSymbol(f, mangler); 44477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 44577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 44677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // add data 44777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik for (Module::global_iterator v = _module->global_begin(), 44877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik e = _module->global_end(); v != e; ++v) { 449ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( v->isDeclaration() ) 450ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addPotentialUndefinedSymbol(v, mangler); 451ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik else 452ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedDataSymbol(v, mangler); 45377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 45477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 455c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel // add asm globals 456c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel const std::string &inlineAsm = _module->getModuleInlineAsm(); 457c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel const std::string glbl = ".globl"; 458c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel std::string asmSymbolName; 459c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel std::string::size_type pos = inlineAsm.find(glbl, 0); 460c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel while (pos != std::string::npos) { 461c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel // eat .globl 462c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel pos = pos + 6; 463c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel 464c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel // skip white space between .globl and symbol name 465c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel std::string::size_type pbegin = inlineAsm.find_first_not_of(' ', pos); 466c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel if (pbegin == std::string::npos) 467c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel break; 468c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel 469c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel // find end-of-line 470c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel std::string::size_type pend = inlineAsm.find_first_of('\n', pbegin); 471c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel if (pend == std::string::npos) 472c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel break; 473c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel 474413907000e6949849e4b9c2fabda7105f8bedabdDevang Patel asmSymbolName.assign(inlineAsm, pbegin, pend - pbegin); 475c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel addAsmGlobalSymbol(asmSymbolName.c_str()); 476c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel 477c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel // search next .globl 478c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel pos = inlineAsm.find(glbl, pend); 479c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel } 480c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel 48177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // make symbols for all undefines 4827431af050f287011fd52e64034ede6dd98193febRafael Espindola for (StringMap<NameAndAttributes>::iterator it=_undefines.begin(); 48377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik it != _undefines.end(); ++it) { 48477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // if this symbol also has a definition, then don't make an undefine 48577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // because it is a tentative definition 486ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( _defines.count(it->getKeyData(), it->getKeyData()+ 487ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik it->getKeyLength()) == 0 ) { 4887431af050f287011fd52e64034ede6dd98193febRafael Espindola NameAndAttributes info = it->getValue(); 4897431af050f287011fd52e64034ede6dd98193febRafael Espindola _symbols.push_back(info); 49077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 49177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 492ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik } 493ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 494ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 495ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 496ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikuint32_t LTOModule::getSymbolCount() 497ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 498ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik lazyParseSymbols(); 49977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return _symbols.size(); 50077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 50177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 50277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 50377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledziklto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) 50477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 505ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik lazyParseSymbols(); 50677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( index < _symbols.size() ) 50777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return _symbols[index].attributes; 50877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 50977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return lto_symbol_attributes(0); 51077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 51177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 51277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikconst char* LTOModule::getSymbolName(uint32_t index) 51377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 514ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik lazyParseSymbols(); 51577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( index < _symbols.size() ) 51677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return _symbols[index].name; 51777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 51877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return NULL; 51977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 52077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 521