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