LTOModule.cpp revision 61476d6f90b772c0e6c725308199afe10743ce0e
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" 163eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik#include "llvm/Constants.h" 178b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson#include "llvm/LLVMContext.h" 1877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Module.h" 19ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/ADT/OwningPtr.h" 20e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov#include "llvm/ADT/Triple.h" 2177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Bitcode/ReaderWriter.h" 2277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/SystemUtils.h" 2377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/MemoryBuffer.h" 24ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/Support/MathExtras.h" 253cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Host.h" 263cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Path.h" 273cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Process.h" 2838c4e535493363b96eac47af9e7c056530137beaRafael Espindola#include "llvm/Support/SourceMgr.h" 293e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 303e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h" 31f2f516fc2680168caac9981a4dd17cc37c639c71Michael J. Spencer#include "llvm/Support/system_error.h" 32af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h" 3338c4e535493363b96eac47af9e7c056530137beaRafael Espindola#include "llvm/MC/MCExpr.h" 3438c4e535493363b96eac47af9e7c056530137beaRafael Espindola#include "llvm/MC/MCInst.h" 3538c4e535493363b96eac47af9e7c056530137beaRafael Espindola#include "llvm/MC/MCParser/MCAsmParser.h" 3638c4e535493363b96eac47af9e7c056530137beaRafael Espindola#include "llvm/MC/MCStreamer.h" 37ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng#include "llvm/MC/MCSubtargetInfo.h" 3838c4e535493363b96eac47af9e7c056530137beaRafael Espindola#include "llvm/MC/MCSymbol.h" 39ab8be96fd30ca9396e6b84fdddf1ac6208984cadEvan Cheng#include "llvm/MC/SubtargetFeature.h" 4094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 41ff9834ab9daeee25dbb67ae5e2341930cde46c86Daniel Dunbar#include "llvm/Target/TargetMachine.h" 420e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#include "llvm/Target/TargetRegisterInfo.h" 4377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikusing namespace llvm; 4477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 4562cf01e4c5de703e7712c72d12f577153b373cbaBill WendlingLTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t) 4662cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling : _module(m), _target(t), 4762cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL), 4862cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling _mangler(_context, *_target->getTargetData()) {} 4962cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling 5062cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM 5162cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// bitcode. 52b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFile(const void *mem, size_t length) { 53b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return llvm::sys::IdentifyFileType((char*)mem, length) 54b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar == llvm::sys::Bitcode_FileType; 5577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 5677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 57b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFile(const char *path) { 58b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return llvm::sys::Path(path).isBitcodeFile(); 5977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 6077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 6162cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// isBitcodeFileForTarget - Returns 'true' if the file (or memory contents) is 6262cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// LLVM bitcode for the specified triple. 63b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length, 64b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *triplePrefix) { 65b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar MemoryBuffer *buffer = makeBuffer(mem, length); 66b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!buffer) 67b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return false; 68b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return isTargetMatch(buffer, triplePrefix); 6977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 7077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 71b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isBitcodeFileForTarget(const char *path, 72b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const char *triplePrefix) { 733ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> buffer; 743ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer if (MemoryBuffer::getFile(path, buffer)) 75b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return false; 763ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer return isTargetMatch(buffer.take(), triplePrefix); 77ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 78ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 7962cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// isTargetMatch - Returns 'true' if the memory buffer is for the specified 8062cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// target triple. 81b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) { 8234711747a1d2c8713e69333bacef1c880810e371Bill Wendling std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); 8334711747a1d2c8713e69333bacef1c880810e371Bill Wendling delete buffer; 84931d4c204390752b30d4459264f8786de95b36d8Bill Wendling return strncmp(Triple.c_str(), triplePrefix, strlen(triplePrefix)) == 0; 8577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 8677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 8762cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// makeLTOModule - Create an LTOModule. N.B. These methods take ownership of 8862cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// the buffer. 8962cf01e4c5de703e7712c72d12f577153b373cbaBill WendlingLTOModule *LTOModule::makeLTOModule(const char *path, std::string &errMsg) { 903ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> buffer; 913ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer if (error_code ec = MemoryBuffer::getFile(path, buffer)) { 92f2f516fc2680168caac9981a4dd17cc37c639c71Michael J. Spencer errMsg = ec.message(); 93b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 94f2f516fc2680168caac9981a4dd17cc37c639c71Michael J. Spencer } 95f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola return makeLTOModule(buffer.take(), errMsg); 9677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 9777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 98b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael EspindolaLTOModule *LTOModule::makeLTOModule(int fd, const char *path, 99931d4c204390752b30d4459264f8786de95b36d8Bill Wendling size_t size, std::string &errMsg) { 100f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola return makeLTOModule(fd, path, size, size, 0, errMsg); 101f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola} 102f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola 103f21b1058a194f411000bdd8000a8b675a7874056Rafael EspindolaLTOModule *LTOModule::makeLTOModule(int fd, const char *path, 104f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola size_t file_size, 105f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola size_t map_size, 106f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola off_t offset, 107b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola std::string &errMsg) { 108b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola OwningPtr<MemoryBuffer> buffer; 109f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola if (error_code ec = MemoryBuffer::getOpenFile(fd, path, buffer, file_size, 110f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola map_size, offset, false)) { 111b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola errMsg = ec.message(); 112b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola return NULL; 113b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola } 114f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola return makeLTOModule(buffer.take(), errMsg); 115b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola} 116b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola 117b06913dd183fe4d294b88a166d4180d3de660135Daniel DunbarLTOModule *LTOModule::makeLTOModule(const void *mem, size_t length, 118b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string &errMsg) { 119b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length)); 120b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!buffer) 121b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 122f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola return makeLTOModule(buffer.take(), errMsg); 123ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 12477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 125b06913dd183fe4d294b88a166d4180d3de660135Daniel DunbarLTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, 126b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string &errMsg) { 12738c4e535493363b96eac47af9e7c056530137beaRafael Espindola static bool Initialized = false; 12838c4e535493363b96eac47af9e7c056530137beaRafael Espindola if (!Initialized) { 12938c4e535493363b96eac47af9e7c056530137beaRafael Espindola InitializeAllTargets(); 130e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng InitializeAllTargetMCs(); 13138c4e535493363b96eac47af9e7c056530137beaRafael Espindola InitializeAllAsmParsers(); 13238c4e535493363b96eac47af9e7c056530137beaRafael Espindola Initialized = true; 13338c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 134b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 135b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // parse bitcode buffer 136f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext(), 137f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola &errMsg)); 138f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola if (!m) { 139f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola delete buffer; 140b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 141f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola } 142b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 143b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string Triple = m->getTargetTriple(); 144b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (Triple.empty()) 1450173864d8a87d9243d304fbf91b556e20b5a32fcSebastian Pop Triple = sys::getDefaultTargetTriple(); 146b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 147b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // find machine architecture for this module 148b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); 149b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (!march) 150b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return NULL; 151b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 152333ed454d0c20d0f4999f7c9a404688b254a0cb0Nick Lewycky // construct LTOModule, hand over ownership of module and target 153b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar SubtargetFeatures Features; 154276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng Features.getDefaultSubtargetFeatures(llvm::Triple(Triple)); 155b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string FeatureStr = Features.getString(); 156276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng std::string CPU; 1578a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky TargetOptions Options; 1588a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr, 1598a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky Options); 16038c4e535493363b96eac47af9e7c056530137beaRafael Espindola LTOModule *Ret = new LTOModule(m.take(), target); 161931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (Ret->ParseSymbols(errMsg)) { 16238c4e535493363b96eac47af9e7c056530137beaRafael Espindola delete Ret; 16338c4e535493363b96eac47af9e7c056530137beaRafael Espindola return NULL; 16438c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 165931d4c204390752b30d4459264f8786de95b36d8Bill Wendling 16638c4e535493363b96eac47af9e7c056530137beaRafael Espindola return Ret; 16777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 16877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 16962cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// makeBuffer - Create a MemoryBuffer from a memory range. 17062cf01e4c5de703e7712c72d12f577153b373cbaBill WendlingMemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { 17162cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling const char *startPtr = (char*)mem; 17262cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false); 17377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 17477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 17562cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// objcClassNameFromExpression - Get string that the data pointer points to. 176b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarbool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) { 177b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) { 178b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar Constant *op = ce->getOperand(0); 179b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) { 180b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar Constant *cn = gvn->getInitializer(); 18118c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner if (ConstantDataArray *ca = dyn_cast<ConstantDataArray>(cn)) { 182b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (ca->isCString()) { 18318c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner name = ".objc_class_name_" + ca->getAsCString().str(); 184b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return true; 1853eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 186b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 1873eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 188b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 189b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return false; 1903eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 1913eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 19262cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addObjCClass - Parse i386/ppc ObjC class data structure. 193b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addObjCClass(GlobalVariable *clgv) { 194931d4c204390752b30d4459264f8786de95b36d8Bill Wendling ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); 195931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (!c) return; 196931d4c204390752b30d4459264f8786de95b36d8Bill Wendling 197931d4c204390752b30d4459264f8786de95b36d8Bill Wendling // second slot in __OBJC,__class is pointer to superclass name 198931d4c204390752b30d4459264f8786de95b36d8Bill Wendling std::string superclassName; 199931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { 200931d4c204390752b30d4459264f8786de95b36d8Bill Wendling NameAndAttributes info; 201931d4c204390752b30d4459264f8786de95b36d8Bill Wendling StringMap<NameAndAttributes>::value_type &entry = 202931d4c204390752b30d4459264f8786de95b36d8Bill Wendling _undefines.GetOrCreateValue(superclassName); 203931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (!entry.getValue().name) { 204931d4c204390752b30d4459264f8786de95b36d8Bill Wendling const char *symbolName = entry.getKey().data(); 205931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.name = symbolName; 206931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 207931d4c204390752b30d4459264f8786de95b36d8Bill Wendling entry.setValue(info); 2083eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik } 209b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 210931d4c204390752b30d4459264f8786de95b36d8Bill Wendling 211931d4c204390752b30d4459264f8786de95b36d8Bill Wendling // third slot in __OBJC,__class is pointer to class name 212931d4c204390752b30d4459264f8786de95b36d8Bill Wendling std::string className; 213931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (objcClassNameFromExpression(c->getOperand(2), className)) { 214931d4c204390752b30d4459264f8786de95b36d8Bill Wendling StringSet::value_type &entry = _defines.GetOrCreateValue(className); 215931d4c204390752b30d4459264f8786de95b36d8Bill Wendling entry.setValue(1); 216931d4c204390752b30d4459264f8786de95b36d8Bill Wendling NameAndAttributes info; 217931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.name = entry.getKey().data(); 218931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.attributes = lto_symbol_attributes(LTO_SYMBOL_PERMISSIONS_DATA | 219931d4c204390752b30d4459264f8786de95b36d8Bill Wendling LTO_SYMBOL_DEFINITION_REGULAR | 220931d4c204390752b30d4459264f8786de95b36d8Bill Wendling LTO_SYMBOL_SCOPE_DEFAULT); 221931d4c204390752b30d4459264f8786de95b36d8Bill Wendling _symbols.push_back(info); 222931d4c204390752b30d4459264f8786de95b36d8Bill Wendling } 2233eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 2243eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 22562cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addObjCCategory - Parse i386/ppc ObjC category data structure. 226b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addObjCCategory(GlobalVariable *clgv) { 227931d4c204390752b30d4459264f8786de95b36d8Bill Wendling ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); 228931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (!c) return; 229cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 230931d4c204390752b30d4459264f8786de95b36d8Bill Wendling // second slot in __OBJC,__category is pointer to target class name 231931d4c204390752b30d4459264f8786de95b36d8Bill Wendling std::string targetclassName; 232931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (!objcClassNameFromExpression(c->getOperand(1), targetclassName)) 233931d4c204390752b30d4459264f8786de95b36d8Bill Wendling return; 234cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 235931d4c204390752b30d4459264f8786de95b36d8Bill Wendling NameAndAttributes info; 236931d4c204390752b30d4459264f8786de95b36d8Bill Wendling StringMap<NameAndAttributes>::value_type &entry = 237931d4c204390752b30d4459264f8786de95b36d8Bill Wendling _undefines.GetOrCreateValue(targetclassName); 238cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 239931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (entry.getValue().name) 240931d4c204390752b30d4459264f8786de95b36d8Bill Wendling return; 241931d4c204390752b30d4459264f8786de95b36d8Bill Wendling 242931d4c204390752b30d4459264f8786de95b36d8Bill Wendling const char *symbolName = entry.getKey().data(); 243931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.name = symbolName; 244931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 245931d4c204390752b30d4459264f8786de95b36d8Bill Wendling entry.setValue(info); 2463eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik} 2473eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 24862cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addObjCClassRef - Parse i386/ppc ObjC class list data structure. 249b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbarvoid LTOModule::addObjCClassRef(GlobalVariable *clgv) { 250b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar std::string targetclassName; 251931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) 252931d4c204390752b30d4459264f8786de95b36d8Bill Wendling return; 253cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 254931d4c204390752b30d4459264f8786de95b36d8Bill Wendling NameAndAttributes info; 255931d4c204390752b30d4459264f8786de95b36d8Bill Wendling StringMap<NameAndAttributes>::value_type &entry = 256931d4c204390752b30d4459264f8786de95b36d8Bill Wendling _undefines.GetOrCreateValue(targetclassName); 257931d4c204390752b30d4459264f8786de95b36d8Bill Wendling if (entry.getValue().name) 258931d4c204390752b30d4459264f8786de95b36d8Bill Wendling return; 259cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 260931d4c204390752b30d4459264f8786de95b36d8Bill Wendling const char *symbolName = entry.getKey().data(); 261931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.name = symbolName; 262931d4c204390752b30d4459264f8786de95b36d8Bill Wendling info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 263931d4c204390752b30d4459264f8786de95b36d8Bill Wendling entry.setValue(info); 26477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 26577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 26662cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addDefinedDataSymbol - Add a data symbol as defined to the list. 267a7280fd61933f1268f69045cfbea46edb739726dBill Wendlingvoid LTOModule::addDefinedDataSymbol(GlobalValue *v) { 268b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // Add to list of defined symbols. 269a7280fd61933f1268f69045cfbea46edb739726dBill Wendling addDefinedSymbol(v, false); 270b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 271b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // Special case i386/ppc ObjC data structures in magic sections: 272b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // The issue is that the old ObjC object format did some strange 273b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // contortions to avoid real linker symbols. For instance, the 274b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ObjC class data structure is allocated statically in the executable 275b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // that defines that class. That data structures contains a pointer to 276b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // its superclass. But instead of just initializing that part of the 277b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // struct to the address of its superclass, and letting the static and 278b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // dynamic linkers do the rest, the runtime works by having that field 279b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // instead point to a C-string that is the name of the superclass. 280b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // At runtime the objc initialization updates that pointer and sets 281b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // it to point to the actual super class. As far as the linker 282b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // knows it is just a pointer to a string. But then someone wanted the 283b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // linker to issue errors at build time if the superclass was not found. 284b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // So they figured out a way in mach-o object format to use an absolute 285b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // symbols (.objc_class_name_Foo = 0) and a floating reference 286b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // (.reference .objc_class_name_Bar) to cause the linker into erroring when 287b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // a class was missing. 288b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // The following synthesizes the implicit .objc_* symbols for the linker 289b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // from the ObjC data structures generated by the front end. 290b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (v->hasSection() /* && isTargetDarwin */) { 291b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // special case if this data blob is an ObjC class definition 292b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { 293b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 294b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addObjCClass(gv); 295b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 29677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 297b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 298b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // special case if this data blob is an ObjC category definition 299b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { 300b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 301b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addObjCCategory(gv); 302b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 3036a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen } 304b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 305b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // special case if this data blob is the list of referenced classes 306b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { 307b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { 308b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar addObjCClassRef(gv); 309b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 31077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 311b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 31277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 31377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 31462cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addDefinedFunctionSymbol - Add a function symbol as defined to the list. 31562cf01e4c5de703e7712c72d12f577153b373cbaBill Wendlingvoid LTOModule::addDefinedFunctionSymbol(Function *f) { 31662cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling // add to list of defined symbols 31762cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling addDefinedSymbol(f, true); 31862cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling} 31962cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling 32062cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addDefinedSymbol - Add a defined symbol to the list. 321a7280fd61933f1268f69045cfbea46edb739726dBill Wendlingvoid LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) { 322b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ignore all llvm.* symbols 323b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (def->getName().startswith("llvm.")) 324b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 325b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 326b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // string is owned by _defines 327ef1860a117b4a35918eb9793a7b94715e12a3a42Rafael Espindola SmallString<64> Buffer; 328a7280fd61933f1268f69045cfbea46edb739726dBill Wendling _mangler.getNameWithPrefix(Buffer, def, false); 329b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 330b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set alignment part log2() can have rounding errors 331b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar uint32_t align = def->getAlignment(); 332b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0; 333b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 334b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set permissions part 335b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (isFunction) 336b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_PERMISSIONS_CODE; 337b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else { 338b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar GlobalVariable *gv = dyn_cast<GlobalVariable>(def); 339b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (gv && gv->isConstant()) 340b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_PERMISSIONS_RODATA; 341b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 342b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_PERMISSIONS_DATA; 343b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 344b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 345b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set definition part 346563ef5ec911d219b54fdb508518abd02a8dd3cfdBill Wendling if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() || 347563ef5ec911d219b54fdb508518abd02a8dd3cfdBill Wendling def->hasLinkerPrivateWeakLinkage() || 3487afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling def->hasLinkerPrivateWeakDefAutoLinkage()) 349b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_DEFINITION_WEAK; 3507afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else if (def->hasCommonLinkage()) 351b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; 3527afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else 353b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_DEFINITION_REGULAR; 354b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 355b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // set scope part 356b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (def->hasHiddenVisibility()) 357b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_SCOPE_HIDDEN; 358b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else if (def->hasProtectedVisibility()) 359b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_SCOPE_PROTECTED; 3607afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else if (def->hasExternalLinkage() || def->hasWeakLinkage() || 3617afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling def->hasLinkOnceLinkage() || def->hasCommonLinkage() || 3627afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling def->hasLinkerPrivateWeakLinkage()) 3633eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik attr |= LTO_SYMBOL_SCOPE_DEFAULT; 3647afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling else if (def->hasLinkerPrivateWeakDefAutoLinkage()) 3657afea0cfc4abebaf4cadcc37acd30fb251a5faf3Bill Wendling attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; 366b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 367b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar attr |= LTO_SYMBOL_SCOPE_INTERNAL; 368b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 369b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // add to table of symbols 370b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 371bd35f27ce9ecf7a6e6e1028dfc8652023cab265bChad Rosier StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer); 372cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola entry.setValue(1); 373cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 374cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola StringRef Name = entry.getKey(); 375cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola info.name = Name.data(); 376cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola assert(info.name[Name.size()] == '\0'); 377b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = (lto_symbol_attributes)attr; 378b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _symbols.push_back(info); 379c2aec57c63a8551cef27025dc7f0d2d9e56db013Devang Patel} 38077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 38162cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the 38262cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// defined list. 38338c4e535493363b96eac47af9e7c056530137beaRafael Espindolavoid LTOModule::addAsmGlobalSymbol(const char *name, 38438c4e535493363b96eac47af9e7c056530137beaRafael Espindola lto_symbol_attributes scope) { 385cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola StringSet::value_type &entry = _defines.GetOrCreateValue(name); 386cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 387b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // only add new define if not already defined 388cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola if (entry.getValue()) 389b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 390b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 391cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola entry.setValue(1); 392cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola const char *symbolName = entry.getKey().data(); 393b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR; 39438c4e535493363b96eac47af9e7c056530137beaRafael Espindola attr |= scope; 395b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 396b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.name = symbolName; 397b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = (lto_symbol_attributes)attr; 398b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar _symbols.push_back(info); 399b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar} 4003eb445feb22647e867a339f4c59b0a716b03a21aNick Kledzik 40162cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the 40262cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// undefined list. 40338c4e535493363b96eac47af9e7c056530137beaRafael Espindolavoid LTOModule::addAsmGlobalSymbolUndef(const char *name) { 40438c4e535493363b96eac47af9e7c056530137beaRafael Espindola StringMap<NameAndAttributes>::value_type &entry = 40538c4e535493363b96eac47af9e7c056530137beaRafael Espindola _undefines.GetOrCreateValue(name); 40638c4e535493363b96eac47af9e7c056530137beaRafael Espindola 40738c4e535493363b96eac47af9e7c056530137beaRafael Espindola _asm_undefines.push_back(entry.getKey().data()); 40838c4e535493363b96eac47af9e7c056530137beaRafael Espindola 40938c4e535493363b96eac47af9e7c056530137beaRafael Espindola // we already have the symbol 41038c4e535493363b96eac47af9e7c056530137beaRafael Espindola if (entry.getValue().name) 41138c4e535493363b96eac47af9e7c056530137beaRafael Espindola return; 41238c4e535493363b96eac47af9e7c056530137beaRafael Espindola 41338c4e535493363b96eac47af9e7c056530137beaRafael Espindola uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED;; 41438c4e535493363b96eac47af9e7c056530137beaRafael Espindola attr |= LTO_SYMBOL_SCOPE_DEFAULT; 41538c4e535493363b96eac47af9e7c056530137beaRafael Espindola NameAndAttributes info; 41638c4e535493363b96eac47af9e7c056530137beaRafael Espindola info.name = entry.getKey().data(); 41738c4e535493363b96eac47af9e7c056530137beaRafael Espindola info.attributes = (lto_symbol_attributes)attr; 41838c4e535493363b96eac47af9e7c056530137beaRafael Espindola 41938c4e535493363b96eac47af9e7c056530137beaRafael Espindola entry.setValue(info); 42038c4e535493363b96eac47af9e7c056530137beaRafael Espindola} 42138c4e535493363b96eac47af9e7c056530137beaRafael Espindola 42262cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a 42362cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// list to be resolved later. 424a7280fd61933f1268f69045cfbea46edb739726dBill Wendlingvoid LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl) { 425b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ignore all llvm.* symbols 426b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (decl->getName().startswith("llvm.")) 427b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 428b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 429b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // ignore all aliases 430b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (isa<GlobalAlias>(decl)) 431b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 432b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 433ef1860a117b4a35918eb9793a7b94715e12a3a42Rafael Espindola SmallString<64> name; 434a7280fd61933f1268f69045cfbea46edb739726dBill Wendling _mangler.getNameWithPrefix(name, decl, false); 435b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 436cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola StringMap<NameAndAttributes>::value_type &entry = 437bd35f27ce9ecf7a6e6e1028dfc8652023cab265bChad Rosier _undefines.GetOrCreateValue(name); 438cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 439b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar // we already have the symbol 440cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola if (entry.getValue().name) 441b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar return; 442b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar 443b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar NameAndAttributes info; 444cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 445cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola info.name = entry.getKey().data(); 44662cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling 447b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar if (decl->hasExternalWeakLinkage()) 448b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; 449b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar else 450b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 451cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola 452cd6c93ec48937ab4f76dfd3bf5dc7e68ed781508Rafael Espindola entry.setValue(info); 453b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar} 454485ded0db71b2abe51da919bd58501cee345c443Nick Lewycky 45538c4e535493363b96eac47af9e7c056530137beaRafael Espindolanamespace { 45638c4e535493363b96eac47af9e7c056530137beaRafael Espindola class RecordStreamer : public MCStreamer { 45738c4e535493363b96eac47af9e7c056530137beaRafael Espindola public: 45838c4e535493363b96eac47af9e7c056530137beaRafael Espindola enum State { NeverSeen, Global, Defined, DefinedGlobal, Used}; 45938c4e535493363b96eac47af9e7c056530137beaRafael Espindola 46038c4e535493363b96eac47af9e7c056530137beaRafael Espindola private: 46138c4e535493363b96eac47af9e7c056530137beaRafael Espindola StringMap<State> Symbols; 46238c4e535493363b96eac47af9e7c056530137beaRafael Espindola 46338c4e535493363b96eac47af9e7c056530137beaRafael Espindola void markDefined(const MCSymbol &Symbol) { 46438c4e535493363b96eac47af9e7c056530137beaRafael Espindola State &S = Symbols[Symbol.getName()]; 46538c4e535493363b96eac47af9e7c056530137beaRafael Espindola switch (S) { 46638c4e535493363b96eac47af9e7c056530137beaRafael Espindola case DefinedGlobal: 46738c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Global: 46838c4e535493363b96eac47af9e7c056530137beaRafael Espindola S = DefinedGlobal; 46938c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 47038c4e535493363b96eac47af9e7c056530137beaRafael Espindola case NeverSeen: 47138c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Defined: 47238c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Used: 47338c4e535493363b96eac47af9e7c056530137beaRafael Espindola S = Defined; 47438c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 47538c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 47638c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 47738c4e535493363b96eac47af9e7c056530137beaRafael Espindola void markGlobal(const MCSymbol &Symbol) { 47838c4e535493363b96eac47af9e7c056530137beaRafael Espindola State &S = Symbols[Symbol.getName()]; 47938c4e535493363b96eac47af9e7c056530137beaRafael Espindola switch (S) { 48038c4e535493363b96eac47af9e7c056530137beaRafael Espindola case DefinedGlobal: 48138c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Defined: 48238c4e535493363b96eac47af9e7c056530137beaRafael Espindola S = DefinedGlobal; 48338c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 48438c4e535493363b96eac47af9e7c056530137beaRafael Espindola 48538c4e535493363b96eac47af9e7c056530137beaRafael Espindola case NeverSeen: 48638c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Global: 48738c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Used: 48838c4e535493363b96eac47af9e7c056530137beaRafael Espindola S = Global; 48938c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 49038c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 49138c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 49238c4e535493363b96eac47af9e7c056530137beaRafael Espindola void markUsed(const MCSymbol &Symbol) { 49338c4e535493363b96eac47af9e7c056530137beaRafael Espindola State &S = Symbols[Symbol.getName()]; 49438c4e535493363b96eac47af9e7c056530137beaRafael Espindola switch (S) { 49538c4e535493363b96eac47af9e7c056530137beaRafael Espindola case DefinedGlobal: 49638c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Defined: 49738c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Global: 49838c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 49938c4e535493363b96eac47af9e7c056530137beaRafael Espindola 50038c4e535493363b96eac47af9e7c056530137beaRafael Espindola case NeverSeen: 50138c4e535493363b96eac47af9e7c056530137beaRafael Espindola case Used: 50238c4e535493363b96eac47af9e7c056530137beaRafael Espindola S = Used; 50338c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 50438c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 50538c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 50638c4e535493363b96eac47af9e7c056530137beaRafael Espindola 50738c4e535493363b96eac47af9e7c056530137beaRafael Espindola // FIXME: mostly copied for the obj streamer. 50838c4e535493363b96eac47af9e7c056530137beaRafael Espindola void AddValueSymbols(const MCExpr *Value) { 50938c4e535493363b96eac47af9e7c056530137beaRafael Espindola switch (Value->getKind()) { 51038c4e535493363b96eac47af9e7c056530137beaRafael Espindola case MCExpr::Target: 51138c4e535493363b96eac47af9e7c056530137beaRafael Espindola // FIXME: What should we do in here? 51238c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 51338c4e535493363b96eac47af9e7c056530137beaRafael Espindola 51438c4e535493363b96eac47af9e7c056530137beaRafael Espindola case MCExpr::Constant: 51538c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 51638c4e535493363b96eac47af9e7c056530137beaRafael Espindola 51738c4e535493363b96eac47af9e7c056530137beaRafael Espindola case MCExpr::Binary: { 51838c4e535493363b96eac47af9e7c056530137beaRafael Espindola const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 51938c4e535493363b96eac47af9e7c056530137beaRafael Espindola AddValueSymbols(BE->getLHS()); 52038c4e535493363b96eac47af9e7c056530137beaRafael Espindola AddValueSymbols(BE->getRHS()); 52138c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 52238c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 52338c4e535493363b96eac47af9e7c056530137beaRafael Espindola 52438c4e535493363b96eac47af9e7c056530137beaRafael Espindola case MCExpr::SymbolRef: 52538c4e535493363b96eac47af9e7c056530137beaRafael Espindola markUsed(cast<MCSymbolRefExpr>(Value)->getSymbol()); 52638c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 52738c4e535493363b96eac47af9e7c056530137beaRafael Espindola 52838c4e535493363b96eac47af9e7c056530137beaRafael Espindola case MCExpr::Unary: 52938c4e535493363b96eac47af9e7c056530137beaRafael Espindola AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 53038c4e535493363b96eac47af9e7c056530137beaRafael Espindola break; 53138c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 53238c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 53338c4e535493363b96eac47af9e7c056530137beaRafael Espindola 53438c4e535493363b96eac47af9e7c056530137beaRafael Espindola public: 53538c4e535493363b96eac47af9e7c056530137beaRafael Espindola typedef StringMap<State>::const_iterator const_iterator; 53638c4e535493363b96eac47af9e7c056530137beaRafael Espindola 53738c4e535493363b96eac47af9e7c056530137beaRafael Espindola const_iterator begin() { 53838c4e535493363b96eac47af9e7c056530137beaRafael Espindola return Symbols.begin(); 53938c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 54038c4e535493363b96eac47af9e7c056530137beaRafael Espindola 54138c4e535493363b96eac47af9e7c056530137beaRafael Espindola const_iterator end() { 54238c4e535493363b96eac47af9e7c056530137beaRafael Espindola return Symbols.end(); 54338c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 5444136e7b90ea5ce8b4d708cdd54d0b052d520a96eGabor Greif 54538c4e535493363b96eac47af9e7c056530137beaRafael Espindola RecordStreamer(MCContext &Context) : MCStreamer(Context) {} 54677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 54738c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void ChangeSection(const MCSection *Section) {} 54838c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void InitSections() {} 54938c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitLabel(MCSymbol *Symbol) { 55038c4e535493363b96eac47af9e7c056530137beaRafael Espindola Symbol->setSection(*getCurrentSection()); 55138c4e535493363b96eac47af9e7c056530137beaRafael Espindola markDefined(*Symbol); 55238c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 55338c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {} 55438c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitThumbFunc(MCSymbol *Func) {} 55538c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 55638c4e535493363b96eac47af9e7c056530137beaRafael Espindola // FIXME: should we handle aliases? 55738c4e535493363b96eac47af9e7c056530137beaRafael Espindola markDefined(*Symbol); 55838c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 55938c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { 56038c4e535493363b96eac47af9e7c056530137beaRafael Espindola if (Attribute == MCSA_Global) 56138c4e535493363b96eac47af9e7c056530137beaRafael Espindola markGlobal(*Symbol); 56238c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 56338c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} 56438c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} 56538c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {} 56638c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitCOFFSymbolStorageClass(int StorageClass) {} 56738c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 56838c4e535493363b96eac47af9e7c056530137beaRafael Espindola unsigned Size , unsigned ByteAlignment) { 56938c4e535493363b96eac47af9e7c056530137beaRafael Espindola markDefined(*Symbol); 57038c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 57138c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitCOFFSymbolType(int Type) {} 57238c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EndCOFFSymbolDef() {} 57338c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 57438c4e535493363b96eac47af9e7c056530137beaRafael Espindola unsigned ByteAlignment) { 57538c4e535493363b96eac47af9e7c056530137beaRafael Espindola markDefined(*Symbol); 57638c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 57738c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} 57836a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 57936a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer unsigned ByteAlignment) {} 58038c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 58138c4e535493363b96eac47af9e7c056530137beaRafael Espindola uint64_t Size, unsigned ByteAlignment) {} 58238c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {} 58338c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, 584debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola unsigned AddrSpace) {} 585e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola virtual void EmitULEB128Value(const MCExpr *Value) {} 586e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola virtual void EmitSLEB128Value(const MCExpr *Value) {} 58738c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 58838c4e535493363b96eac47af9e7c056530137beaRafael Espindola unsigned ValueSize, 58938c4e535493363b96eac47af9e7c056530137beaRafael Espindola unsigned MaxBytesToEmit) {} 59038c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitCodeAlignment(unsigned ByteAlignment, 59138c4e535493363b96eac47af9e7c056530137beaRafael Espindola unsigned MaxBytesToEmit) {} 592ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach virtual bool EmitValueToOffset(const MCExpr *Offset, 593ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach unsigned char Value ) { return false; } 59438c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitFileDirective(StringRef Filename) {} 59538c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, 59638c4e535493363b96eac47af9e7c056530137beaRafael Espindola const MCSymbol *LastLabel, 597672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng const MCSymbol *Label, 598672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng unsigned PointerSize) {} 59938c4e535493363b96eac47af9e7c056530137beaRafael Espindola 60038c4e535493363b96eac47af9e7c056530137beaRafael Espindola virtual void EmitInstruction(const MCInst &Inst) { 60138c4e535493363b96eac47af9e7c056530137beaRafael Espindola // Scan for values. 60238c4e535493363b96eac47af9e7c056530137beaRafael Espindola for (unsigned i = Inst.getNumOperands(); i--; ) 60338c4e535493363b96eac47af9e7c056530137beaRafael Espindola if (Inst.getOperand(i).isExpr()) 60438c4e535493363b96eac47af9e7c056530137beaRafael Espindola AddValueSymbols(Inst.getOperand(i).getExpr()); 60538c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 60699b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindola virtual void FinishImpl() {} 60738c4e535493363b96eac47af9e7c056530137beaRafael Espindola }; 60838c4e535493363b96eac47af9e7c056530137beaRafael Espindola} 60938c4e535493363b96eac47af9e7c056530137beaRafael Espindola 61062cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// addAsmGlobalSymbols - Add global symbols from module-level ASM to the 61162cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// defined or undefined lists. 612b9bff969e96a24da18d6c5d0d623a7d790d41fa2Bill Wendlingbool LTOModule::addAsmGlobalSymbols(std::string &errMsg) { 61338c4e535493363b96eac47af9e7c056530137beaRafael Espindola const std::string &inlineAsm = _module->getModuleInlineAsm(); 6146d483c2b0712d0111b02d23cda7c65c0f43cf1f1Ivan Krasin if (inlineAsm.empty()) 6156d483c2b0712d0111b02d23cda7c65c0f43cf1f1Ivan Krasin return false; 61638c4e535493363b96eac47af9e7c056530137beaRafael Espindola 617b9bff969e96a24da18d6c5d0d623a7d790d41fa2Bill Wendling OwningPtr<RecordStreamer> Streamer(new RecordStreamer(_context)); 61838c4e535493363b96eac47af9e7c056530137beaRafael Espindola MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm); 61938c4e535493363b96eac47af9e7c056530137beaRafael Espindola SourceMgr SrcMgr; 62038c4e535493363b96eac47af9e7c056530137beaRafael Espindola SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); 6211b84cce77f8bccc905b4800927ce9016f76c1c40Jim Grosbach OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, 622b9bff969e96a24da18d6c5d0d623a7d790d41fa2Bill Wendling _context, *Streamer, 62338c4e535493363b96eac47af9e7c056530137beaRafael Espindola *_target->getMCAsmInfo())); 624ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng OwningPtr<MCSubtargetInfo> STI(_target->getTarget(). 625ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng createMCSubtargetInfo(_target->getTargetTriple(), 626ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng _target->getTargetCPU(), 627ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng _target->getTargetFeatureString())); 62894b9550a32d189704a8eae55505edf62662c0534Evan Cheng OwningPtr<MCTargetAsmParser> 62994b9550a32d189704a8eae55505edf62662c0534Evan Cheng TAP(_target->getTarget().createMCAsmParser(*STI, *Parser.get())); 630603e103988d98c0ea5d37e7cceaf5bbffe076f28Ivan Krasin if (!TAP) { 631603e103988d98c0ea5d37e7cceaf5bbffe076f28Ivan Krasin errMsg = "target " + std::string(_target->getTarget().getName()) + 632603e103988d98c0ea5d37e7cceaf5bbffe076f28Ivan Krasin " does not define AsmParser."; 633603e103988d98c0ea5d37e7cceaf5bbffe076f28Ivan Krasin return true; 634603e103988d98c0ea5d37e7cceaf5bbffe076f28Ivan Krasin } 635603e103988d98c0ea5d37e7cceaf5bbffe076f28Ivan Krasin 63638c4e535493363b96eac47af9e7c056530137beaRafael Espindola Parser->setTargetParser(*TAP); 63738c4e535493363b96eac47af9e7c056530137beaRafael Espindola int Res = Parser->Run(false); 63838c4e535493363b96eac47af9e7c056530137beaRafael Espindola if (Res) 63938c4e535493363b96eac47af9e7c056530137beaRafael Espindola return true; 64038c4e535493363b96eac47af9e7c056530137beaRafael Espindola 64138c4e535493363b96eac47af9e7c056530137beaRafael Espindola for (RecordStreamer::const_iterator i = Streamer->begin(), 64238c4e535493363b96eac47af9e7c056530137beaRafael Espindola e = Streamer->end(); i != e; ++i) { 64338c4e535493363b96eac47af9e7c056530137beaRafael Espindola StringRef Key = i->first(); 64438c4e535493363b96eac47af9e7c056530137beaRafael Espindola RecordStreamer::State Value = i->second; 64538c4e535493363b96eac47af9e7c056530137beaRafael Espindola if (Value == RecordStreamer::DefinedGlobal) 64638c4e535493363b96eac47af9e7c056530137beaRafael Espindola addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_DEFAULT); 64738c4e535493363b96eac47af9e7c056530137beaRafael Espindola else if (Value == RecordStreamer::Defined) 64838c4e535493363b96eac47af9e7c056530137beaRafael Espindola addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_INTERNAL); 64938c4e535493363b96eac47af9e7c056530137beaRafael Espindola else if (Value == RecordStreamer::Global || 65038c4e535493363b96eac47af9e7c056530137beaRafael Espindola Value == RecordStreamer::Used) 65138c4e535493363b96eac47af9e7c056530137beaRafael Espindola addAsmGlobalSymbolUndef(Key.data()); 65238c4e535493363b96eac47af9e7c056530137beaRafael Espindola } 65338c4e535493363b96eac47af9e7c056530137beaRafael Espindola return false; 65438c4e535493363b96eac47af9e7c056530137beaRafael Espindola} 65538c4e535493363b96eac47af9e7c056530137beaRafael Espindola 65662cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// isDeclaration - Return 'true' if the global value is a declaration. 657f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindolastatic bool isDeclaration(const GlobalValue &V) { 658f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola if (V.hasAvailableExternallyLinkage()) 659f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola return true; 660f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola if (V.isMaterializable()) 661f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola return false; 662f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola return V.isDeclaration(); 663f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola} 664f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola 66562cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// ParseSymbols - Parse the symbols from the module and model-level ASM and add 66662cf01e4c5de703e7712c72d12f577153b373cbaBill Wendling/// them to either the defined or undefined lists. 667603e103988d98c0ea5d37e7cceaf5bbffe076f28Ivan Krasinbool LTOModule::ParseSymbols(std::string &errMsg) { 668e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // add functions 669e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { 670f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola if (isDeclaration(*f)) 671a7280fd61933f1268f69045cfbea46edb739726dBill Wendling addPotentialUndefinedSymbol(f); 672e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar else 673a7280fd61933f1268f69045cfbea46edb739726dBill Wendling addDefinedFunctionSymbol(f); 674e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar } 675e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 676e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // add data 677e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar for (Module::global_iterator v = _module->global_begin(), 678e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar e = _module->global_end(); v != e; ++v) { 679f19d7a7af3f10b6d43f9e8b0271f0f836a33d52cRafael Espindola if (isDeclaration(*v)) 680a7280fd61933f1268f69045cfbea46edb739726dBill Wendling addPotentialUndefinedSymbol(v); 681e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar else 682a7280fd61933f1268f69045cfbea46edb739726dBill Wendling addDefinedDataSymbol(v); 683e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar } 684e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 685e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // add asm globals 686b9bff969e96a24da18d6c5d0d623a7d790d41fa2Bill Wendling if (addAsmGlobalSymbols(errMsg)) 68738c4e535493363b96eac47af9e7c056530137beaRafael Espindola return true; 688e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar 68902003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola // add aliases 69002003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola for (Module::alias_iterator i = _module->alias_begin(), 69102003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola e = _module->alias_end(); i != e; ++i) { 69261476d6f90b772c0e6c725308199afe10743ce0eBill Wendling if (isDeclaration(*i->getAliasedGlobal())) 69361476d6f90b772c0e6c725308199afe10743ce0eBill Wendling // Is an alias to a declaration. 694a7280fd61933f1268f69045cfbea46edb739726dBill Wendling addPotentialUndefinedSymbol(i); 69502003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola else 696a7280fd61933f1268f69045cfbea46edb739726dBill Wendling addDefinedDataSymbol(i); 69702003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola } 69802003caf2291ebb2d634e1938553e58e5dd0dce8Rafael Espindola 699e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // make symbols for all undefines 700e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar for (StringMap<NameAndAttributes>::iterator it=_undefines.begin(); 701e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar it != _undefines.end(); ++it) { 702e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // if this symbol also has a definition, then don't make an undefine 703e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar // because it is a tentative definition 704e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar if (_defines.count(it->getKey()) == 0) { 705e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar NameAndAttributes info = it->getValue(); 706e41d90094c9dbbabd6031957689f67ea504ed616Daniel Dunbar _symbols.push_back(info); 707b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 708b06913dd183fe4d294b88a166d4180d3de660135Daniel Dunbar } 70938c4e535493363b96eac47af9e7c056530137beaRafael Espindola return false; 710ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 711