LLVM API Documentation
00001 //===-- Archive.cpp - Generic LLVM archive functions ------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the implementation of the Archive and ArchiveMember 00011 // classes that is common to both reading and writing archives.. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "ArchiveInternals.h" 00016 #include "llvm/Bitcode/ReaderWriter.h" 00017 #include "llvm/ModuleProvider.h" 00018 #include "llvm/Module.h" 00019 #include "llvm/Support/MemoryBuffer.h" 00020 #include "llvm/System/Process.h" 00021 #include <memory> 00022 #include <cstring> 00023 using namespace llvm; 00024 00025 // getMemberSize - compute the actual physical size of the file member as seen 00026 // on disk. This isn't the size of member's payload. Use getSize() for that. 00027 unsigned 00028 ArchiveMember::getMemberSize() const { 00029 // Basically its the file size plus the header size 00030 unsigned result = info.fileSize + sizeof(ArchiveMemberHeader); 00031 00032 // If it has a long filename, include the name length 00033 if (hasLongFilename()) 00034 result += path.toString().length() + 1; 00035 00036 // If its now odd lengthed, include the padding byte 00037 if (result % 2 != 0 ) 00038 result++; 00039 00040 return result; 00041 } 00042 00043 // This default constructor is only use by the ilist when it creates its 00044 // sentry node. We give it specific static values to make it stand out a bit. 00045 ArchiveMember::ArchiveMember() 00046 : parent(0), path("--invalid--"), flags(0), data(0) 00047 { 00048 info.user = sys::Process::GetCurrentUserId(); 00049 info.group = sys::Process::GetCurrentGroupId(); 00050 info.mode = 0777; 00051 info.fileSize = 0; 00052 info.modTime = sys::TimeValue::now(); 00053 } 00054 00055 // This is the constructor that the Archive class uses when it is building or 00056 // reading an archive. It just defaults a few things and ensures the parent is 00057 // set for the iplist. The Archive class fills in the ArchiveMember's data. 00058 // This is required because correctly setting the data may depend on other 00059 // things in the Archive. 00060 ArchiveMember::ArchiveMember(Archive* PAR) 00061 : parent(PAR), path(), flags(0), data(0) 00062 { 00063 } 00064 00065 // This method allows an ArchiveMember to be replaced with the data for a 00066 // different file, presumably as an update to the member. It also makes sure 00067 // the flags are reset correctly. 00068 bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) { 00069 if (!newFile.exists()) { 00070 if (ErrMsg) 00071 *ErrMsg = "Can not replace an archive member with a non-existent file"; 00072 return true; 00073 } 00074 00075 data = 0; 00076 path = newFile; 00077 00078 // SVR4 symbol tables have an empty name 00079 if (path.toString() == ARFILE_SVR4_SYMTAB_NAME) 00080 flags |= SVR4SymbolTableFlag; 00081 else 00082 flags &= ~SVR4SymbolTableFlag; 00083 00084 // BSD4.4 symbol tables have a special name 00085 if (path.toString() == ARFILE_BSD4_SYMTAB_NAME) 00086 flags |= BSD4SymbolTableFlag; 00087 else 00088 flags &= ~BSD4SymbolTableFlag; 00089 00090 // LLVM symbol tables have a very specific name 00091 if (path.toString() == ARFILE_LLVM_SYMTAB_NAME) 00092 flags |= LLVMSymbolTableFlag; 00093 else 00094 flags &= ~LLVMSymbolTableFlag; 00095 00096 // String table name 00097 if (path.toString() == ARFILE_STRTAB_NAME) 00098 flags |= StringTableFlag; 00099 else 00100 flags &= ~StringTableFlag; 00101 00102 // If it has a slash then it has a path 00103 bool hasSlash = path.toString().find('/') != std::string::npos; 00104 if (hasSlash) 00105 flags |= HasPathFlag; 00106 else 00107 flags &= ~HasPathFlag; 00108 00109 // If it has a slash or its over 15 chars then its a long filename format 00110 if (hasSlash || path.toString().length() > 15) 00111 flags |= HasLongFilenameFlag; 00112 else 00113 flags &= ~HasLongFilenameFlag; 00114 00115 // Get the signature and status info 00116 const char* signature = (const char*) data; 00117 std::string magic; 00118 if (!signature) { 00119 path.getMagicNumber(magic,4); 00120 signature = magic.c_str(); 00121 std::string err; 00122 const sys::FileStatus *FSinfo = path.getFileStatus(false, ErrMsg); 00123 if (FSinfo) 00124 info = *FSinfo; 00125 else 00126 return true; 00127 } 00128 00129 // Determine what kind of file it is 00130 switch (sys::IdentifyFileType(signature,4)) { 00131 default: 00132 flags &= ~BitcodeFlag; 00133 break; 00134 } 00135 return false; 00136 } 00137 00138 // Archive constructor - this is the only constructor that gets used for the 00139 // Archive class. Everything else (default,copy) is deprecated. This just 00140 // initializes and maps the file into memory, if requested. 00141 Archive::Archive(const sys::Path& filename) 00142 : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(), 00143 symTabSize(0), firstFileOffset(0), modules(), foreignST(0) { 00144 } 00145 00146 bool 00147 Archive::mapToMemory(std::string* ErrMsg) { 00148 mapfile = MemoryBuffer::getFile(archPath.c_str(), ErrMsg); 00149 if (mapfile == 0) 00150 return true; 00151 base = mapfile->getBufferStart(); 00152 return false; 00153 } 00154 00155 void Archive::cleanUpMemory() { 00156 // Shutdown the file mapping 00157 delete mapfile; 00158 mapfile = 0; 00159 base = 0; 00160 00161 // Forget the entire symbol table 00162 symTab.clear(); 00163 symTabSize = 0; 00164 00165 firstFileOffset = 0; 00166 00167 // Free the foreign symbol table member 00168 if (foreignST) { 00169 delete foreignST; 00170 foreignST = 0; 00171 } 00172 00173 // Delete any ModuleProviders and ArchiveMember's we've allocated as a result 00174 // of symbol table searches. 00175 for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) { 00176 delete I->second.first; 00177 delete I->second.second; 00178 } 00179 } 00180 00181 // Archive destructor - just clean up memory 00182 Archive::~Archive() { 00183 cleanUpMemory(); 00184 } 00185 00186 00187 00188 static void getSymbols(Module*M, std::vector<std::string>& symbols) { 00189 // Loop over global variables 00190 for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI) 00191 if (!GI->isDeclaration() && !GI->hasLocalLinkage()) 00192 if (!GI->getName().empty()) 00193 symbols.push_back(GI->getName()); 00194 00195 // Loop over functions 00196 for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) 00197 if (!FI->isDeclaration() && !FI->hasLocalLinkage()) 00198 if (!FI->getName().empty()) 00199 symbols.push_back(FI->getName()); 00200 00201 // Loop over aliases 00202 for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end(); 00203 AI != AE; ++AI) { 00204 if (AI->hasName()) 00205 symbols.push_back(AI->getName()); 00206 } 00207 } 00208 00209 // Get just the externally visible defined symbols from the bitcode 00210 bool llvm::GetBitcodeSymbols(const sys::Path& fName, 00211 std::vector<std::string>& symbols, 00212 std::string* ErrMsg) { 00213 std::auto_ptr<MemoryBuffer> Buffer( 00214 MemoryBuffer::getFileOrSTDIN(fName.c_str())); 00215 if (!Buffer.get()) { 00216 if (ErrMsg) *ErrMsg = "Could not open file '" + fName.toString() + "'"; 00217 return true; 00218 } 00219 00220 ModuleProvider *MP = getBitcodeModuleProvider(Buffer.get(), ErrMsg); 00221 if (!MP) 00222 return true; 00223 00224 // Get the module from the provider 00225 Module* M = MP->materializeModule(); 00226 if (M == 0) { 00227 delete MP; 00228 return true; 00229 } 00230 00231 // Get the symbols 00232 getSymbols(M, symbols); 00233 00234 // Done with the module. 00235 delete MP; 00236 return true; 00237 } 00238 00239 ModuleProvider* 00240 llvm::GetBitcodeSymbols(const unsigned char *BufPtr, unsigned Length, 00241 const std::string& ModuleID, 00242 std::vector<std::string>& symbols, 00243 std::string* ErrMsg) { 00244 // Get the module provider 00245 MemoryBuffer *Buffer =MemoryBuffer::getNewMemBuffer(Length, ModuleID.c_str()); 00246 memcpy((char*)Buffer->getBufferStart(), BufPtr, Length); 00247 00248 ModuleProvider *MP = getBitcodeModuleProvider(Buffer, ErrMsg); 00249 if (!MP) 00250 return 0; 00251 00252 // Get the module from the provider 00253 Module* M = MP->materializeModule(); 00254 if (M == 0) { 00255 delete MP; 00256 return 0; 00257 } 00258 00259 // Get the symbols 00260 getSymbols(M, symbols); 00261 00262 // Done with the module. Note that ModuleProvider will delete the 00263 // Module when it is deleted. Also note that its the caller's responsibility 00264 // to delete the ModuleProvider. 00265 return MP; 00266 }