1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- Archive.cpp - Generic LLVM archive functions ------------*- C++ -*-===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file contains the implementation of the Archive and ArchiveMember 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// classes that is common to both reading and writing archives.. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "ArchiveInternals.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Bitcode/ReaderWriter.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Module.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/FileSystem.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/MemoryBuffer.h" 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Process.h" 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/system_error.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <memory> 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <cstring> 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// getMemberSize - compute the actual physical size of the file member as seen 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// on disk. This isn't the size of member's payload. Use getSize() for that. 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanArchiveMember::getMemberSize() const { 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Basically its the file size plus the header size 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned result = info.fileSize + sizeof(ArchiveMemberHeader); 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If it has a long filename, include the name length 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (hasLongFilename()) 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result += path.str().length() + 1; 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If its now odd lengthed, include the padding byte 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (result % 2 != 0 ) 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman result++; 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return result; 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This default constructor is only use by the ilist when it creates its 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// sentry node. We give it specific static values to make it stand out a bit. 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanArchiveMember::ArchiveMember() 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : parent(0), path("--invalid--"), flags(0), data(0) 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman info.user = sys::Process::GetCurrentUserId(); 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman info.group = sys::Process::GetCurrentGroupId(); 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman info.mode = 0777; 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman info.fileSize = 0; 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman info.modTime = sys::TimeValue::now(); 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This is the constructor that the Archive class uses when it is building or 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// reading an archive. It just defaults a few things and ensures the parent is 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// set for the iplist. The Archive class fills in the ArchiveMember's data. 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This is required because correctly setting the data may depend on other 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// things in the Archive. 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanArchiveMember::ArchiveMember(Archive* PAR) 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : parent(PAR), path(), flags(0), data(0) 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This method allows an ArchiveMember to be replaced with the data for a 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// different file, presumably as an update to the member. It also makes sure 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// the flags are reset correctly. 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) { 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool Exists; 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (sys::fs::exists(newFile.str(), Exists) || !Exists) { 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ErrMsg) 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *ErrMsg = "Can not replace an archive member with a non-existent file"; 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman data = 0; 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman path = newFile; 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SVR4 symbol tables have an empty name 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (path.str() == ARFILE_SVR4_SYMTAB_NAME) 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags |= SVR4SymbolTableFlag; 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags &= ~SVR4SymbolTableFlag; 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // BSD4.4 symbol tables have a special name 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (path.str() == ARFILE_BSD4_SYMTAB_NAME) 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags |= BSD4SymbolTableFlag; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags &= ~BSD4SymbolTableFlag; 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // LLVM symbol tables have a very specific name 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (path.str() == ARFILE_LLVM_SYMTAB_NAME) 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags |= LLVMSymbolTableFlag; 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags &= ~LLVMSymbolTableFlag; 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // String table name 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (path.str() == ARFILE_STRTAB_NAME) 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags |= StringTableFlag; 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags &= ~StringTableFlag; 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If it has a slash then it has a path 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool hasSlash = path.str().find('/') != std::string::npos; 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (hasSlash) 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags |= HasPathFlag; 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags &= ~HasPathFlag; 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If it has a slash or its over 15 chars then its a long filename format 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (hasSlash || path.str().length() > 15) 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags |= HasLongFilenameFlag; 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags &= ~HasLongFilenameFlag; 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the signature and status info 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const char* signature = (const char*) data; 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<4> magic; 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!signature) { 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sys::fs::get_magic(path.str(), magic.capacity(), magic); 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman signature = magic.c_str(); 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const sys::FileStatus *FSinfo = path.getFileStatus(false, ErrMsg); 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FSinfo) 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman info = *FSinfo; 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Determine what kind of file it is. 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (sys::IdentifyFileType(signature,4)) { 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case sys::Bitcode_FileType: 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags |= BitcodeFlag; 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flags &= ~BitcodeFlag; 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Archive constructor - this is the only constructor that gets used for the 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Archive class. Everything else (default,copy) is deprecated. This just 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// initializes and maps the file into memory, if requested. 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanArchive::Archive(const sys::Path& filename, LLVMContext& C) 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(), 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman symTabSize(0), firstFileOffset(0), modules(), foreignST(0), Context(C) { 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanArchive::mapToMemory(std::string* ErrMsg) { 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OwningPtr<MemoryBuffer> File; 15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = MemoryBuffer::getFile(archPath.c_str(), File)) { 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ErrMsg) 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *ErrMsg = ec.message(); 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman mapfile = File.take(); 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman base = mapfile->getBufferStart(); 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid Archive::cleanUpMemory() { 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Shutdown the file mapping 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete mapfile; 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mapfile = 0; 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman base = 0; 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Forget the entire symbol table 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman symTab.clear(); 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman symTabSize = 0; 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman firstFileOffset = 0; 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Free the foreign symbol table member 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (foreignST) { 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete foreignST; 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman foreignST = 0; 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Delete any Modules and ArchiveMember's we've allocated as a result of 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // symbol table searches. 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) { 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete I->second.first; 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete I->second.second; 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Archive destructor - just clean up memory 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanArchive::~Archive() { 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cleanUpMemory(); 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic void getSymbols(Module*M, std::vector<std::string>& symbols) { 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Loop over global variables 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI) 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!GI->isDeclaration() && !GI->hasLocalLinkage()) 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!GI->getName().empty()) 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman symbols.push_back(GI->getName()); 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Loop over functions 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!FI->isDeclaration() && !FI->hasLocalLinkage()) 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!FI->getName().empty()) 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman symbols.push_back(FI->getName()); 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Loop over aliases 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end(); 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AI != AE; ++AI) { 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AI->hasName()) 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman symbols.push_back(AI->getName()); 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Get just the externally visible defined symbols from the bitcode 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool llvm::GetBitcodeSymbols(const sys::Path& fName, 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LLVMContext& Context, 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<std::string>& symbols, 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string* ErrMsg) { 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OwningPtr<MemoryBuffer> Buffer; 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = MemoryBuffer::getFileOrSTDIN(fName.c_str(), Buffer)) { 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ErrMsg) *ErrMsg = "Could not open file '" + fName.str() + "'" + ": " 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman + ec.message(); 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg); 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!M) 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the symbols 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getSymbols(M, symbols); 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Done with the module. 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete M; 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanModule* 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanllvm::GetBitcodeSymbols(const char *BufPtr, unsigned Length, 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string& ModuleID, 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LLVMContext& Context, 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<std::string>& symbols, 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string* ErrMsg) { 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the module. 24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OwningPtr<MemoryBuffer> Buffer( 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemoryBuffer::getMemBufferCopy(StringRef(BufPtr, Length),ModuleID.c_str())); 25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg); 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!M) 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the symbols 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getSymbols(M, symbols); 25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Done with the module. Note that it's the caller's responsibility to delete 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the Module. 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return M; 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 262