Archive.cpp revision 1fce09125cb46c91407668ca29915c450a482811
1//===-- Archive.cpp - Generic LLVM archive functions ------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Reid Spencer and is distributed under the 6// University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the implementation of the Archive and ArchiveMember 11// classes that is common to both reading and writing archives.. 12// 13//===----------------------------------------------------------------------===// 14 15#include "ArchiveInternals.h" 16#include "llvm/ModuleProvider.h" 17 18using namespace llvm; 19 20// getMemberSize - compute the actual physical size of the file member as seen 21// on disk. This isn't the size of member's payload. Use getSize() for that. 22unsigned 23ArchiveMember::getMemberSize() const { 24 // Basically its the file size plus the header size 25 unsigned result = info.fileSize + sizeof(ArchiveMemberHeader); 26 27 // If it has a long filename, include the name length 28 if (hasLongFilename()) 29 result += path.toString().length() + 1; 30 31 // If its now odd lengthed, include the padding byte 32 if (result % 2 != 0 ) 33 result++; 34 35 return result; 36} 37 38// This default constructor is only use by the ilist when it creates its 39// sentry node. We give it specific static values to make it stand out a bit. 40ArchiveMember::ArchiveMember() 41 : next(0), prev(0), parent(0), path("<invalid>"), flags(0), data(0) 42{ 43 info.user = 1000; 44 info.group = 1000; 45 info.mode = 0777; 46 info.fileSize = 0; 47 info.modTime = sys::TimeValue::now(); 48} 49 50// This is the constructor that the Archive class uses when it is building or 51// reading an archive. It just defaults a few things and ensures the parent is 52// set for the iplist. The Archive class fills in the ArchiveMember's data. 53// This is required because correctly setting the data may depend on other 54// things in the Archive. 55ArchiveMember::ArchiveMember(Archive* PAR) 56 : next(0), prev(0), parent(PAR), path(), flags(0), data(0) 57{ 58} 59 60// This method allows an ArchiveMember to be replaced with the data for a 61// different file, presumably as an update to the member. It also makes sure 62// the flags are reset correctly. 63void ArchiveMember::replaceWith(const sys::Path& newFile) { 64 assert(newFile.exists() && "Can't replace with a non-existent file"); 65 data = 0; 66 path = newFile; 67 68 // SVR4 symbol tables have an empty name 69 if (path.toString() == ARFILE_SVR4_SYMTAB_NAME) 70 flags |= SVR4SymbolTableFlag; 71 else 72 flags &= ~SVR4SymbolTableFlag; 73 74 // BSD4.4 symbol tables have a special name 75 if (path.toString() == ARFILE_BSD4_SYMTAB_NAME) 76 flags |= BSD4SymbolTableFlag; 77 else 78 flags &= ~BSD4SymbolTableFlag; 79 80 // LLVM symbol tables have a very specific name 81 if (path.toString() == ARFILE_LLVM_SYMTAB_NAME) 82 flags |= LLVMSymbolTableFlag; 83 else 84 flags &= ~LLVMSymbolTableFlag; 85 86 // String table name 87 if (path.toString() == ARFILE_STRTAB_NAME) 88 flags |= StringTableFlag; 89 else 90 flags &= ~StringTableFlag; 91 92 // If it has a slash then it has a path 93 bool hasSlash = path.toString().find('/') != std::string::npos; 94 if (hasSlash) 95 flags |= HasPathFlag; 96 else 97 flags &= ~HasPathFlag; 98 99 // If it has a slash or its over 15 chars then its a long filename format 100 if (hasSlash || path.toString().length() > 15) 101 flags |= HasLongFilenameFlag; 102 else 103 flags &= ~HasLongFilenameFlag; 104 105 // Get the signature and status info 106 std::string magic; 107 const char* signature = (const char*) data; 108 if (!signature) { 109 path.getMagicNumber(magic,4); 110 signature = magic.c_str(); 111 path.getStatusInfo(info); 112 } 113 114 // Determine what kind of file it is 115 switch (sys::IdentifyFileType(signature,4)) { 116 case sys::BytecodeFileType: 117 flags |= BytecodeFlag; 118 break; 119 case sys::CompressedBytecodeFileType: 120 flags |= CompressedBytecodeFlag; 121 flags &= ~CompressedFlag; 122 break; 123 default: 124 flags &= ~(BytecodeFlag|CompressedBytecodeFlag); 125 break; 126 } 127} 128 129// Archive constructor - this is the only constructor that gets used for the 130// Archive class. Everything else (default,copy) is deprecated. This just 131// initializes and maps the file into memory, if requested. 132Archive::Archive(const sys::Path& filename, bool map ) 133 : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(), 134 symTabSize(0), firstFileOffset(0), modules(), foreignST(0) 135{ 136 if (map) { 137 mapfile = new sys::MappedFile(filename); 138 base = (char*) mapfile->map(); 139 } 140} 141 142// Archive destructor - just clean up memory 143Archive::~Archive() { 144 // Shutdown the file mapping 145 if (mapfile) { 146 mapfile->unmap(); 147 delete mapfile; 148 } 149 // Delete any ModuleProviders and ArchiveMember's we've allocated as a result 150 // of symbol table searches. 151 for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) { 152 delete I->second.first; 153 delete I->second.second; 154 } 155} 156 157// vim: sw=2 ai 158