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