[llvm-commits] CVS: llvm/lib/Bytecode/Archive/Archive.cpp

Reid Spencer reid at x10sys.com
Sun Nov 14 13:56:50 PST 2004



Changes in directory llvm/lib/Bytecode/Archive:

Archive.cpp updated: 1.1 -> 1.2
---
Log message:

First working version

---
Diffs of the changes:  (+128 -2)

Index: llvm/lib/Bytecode/Archive/Archive.cpp
diff -u llvm/lib/Bytecode/Archive/Archive.cpp:1.1 llvm/lib/Bytecode/Archive/Archive.cpp:1.2
--- llvm/lib/Bytecode/Archive/Archive.cpp:1.1	Sat Nov  6 02:51:45 2004
+++ llvm/lib/Bytecode/Archive/Archive.cpp	Sun Nov 14 15:56:13 2004
@@ -7,18 +7,144 @@
 // 
 //===----------------------------------------------------------------------===//
 //
-// Builds up standard unix archive files (.a) containing LLVM bytecode.
+// This file contains the implementation of the Archive and ArchiveMember
+// classes that is common to both reading and writing archives..
 //
 //===----------------------------------------------------------------------===//
 
 #include "ArchiveInternals.h"
+#include "llvm/ModuleProvider.h"
 
 using namespace llvm;
 
-Archive::Archive() {
+// getMemberSize - compute the actual physical size of the file member as seen
+// on disk. This isn't the size of member's payload. Use getSize() for that.
+unsigned
+ArchiveMember::getMemberSize() const {
+  // Basically its the file size plus the header size
+  unsigned result =  info.fileSize + sizeof(ArchiveMemberHeader);
+
+  // If it has a long filename, include the name length
+  if (hasLongFilename())
+    result += path.get().length() + 1;
+
+  // If its now odd lengthed, include the padding byte
+  if (result % 2 != 0 ) 
+    result++;
+
+  return result;
+}
+
+// This default constructor is only use by the ilist when it creates its
+// sentry node. We give it specific static values to make it stand out a bit.
+ArchiveMember::ArchiveMember() 
+  : next(0), prev(0), parent(0), path("<invalid>"), flags(0), data(0)
+{
+  info.user = 1000;
+  info.group = 1000; 
+  info.mode = 0777; 
+  info.fileSize = 0; 
+  info.modTime = sys::TimeValue::now();
+}
+
+// This is the constructor that the Archive class uses when it is building or
+// reading an archive. It just defaults a few things and ensures the parent is
+// set for the iplist. The Archive class fills in the ArchiveMember's data. 
+// This is required because correctly setting the data may depend on other 
+// things in the Archive.
+ArchiveMember::ArchiveMember(Archive* PAR)
+  : next(0), prev(0), parent(PAR), path(), flags(0), data(0)
+{
+}
+
+// This method allows an ArchiveMember to be replaced with the data for a 
+// different file, presumably as an update to the member. It also makes sure
+// the flags are reset correctly.
+void ArchiveMember::replaceWith(const sys::Path& newFile) {
+  assert(newFile.exists() && "Can't replace with a non-existent file");
+  data = 0;
+  path = newFile;
+
+  // Foreign symbol tables have an empty name
+  if (path.get() == ARFILE_SYMTAB_NAME)
+    flags |= ForeignSymbolTableFlag;
+  else
+    flags &= ~ForeignSymbolTableFlag;
+
+  // LLVM symbol tables have a very specific name
+  if (path.get() == ARFILE_LLVM_SYMTAB_NAME)
+    flags |= LLVMSymbolTableFlag;
+  else
+    flags &= ~LLVMSymbolTableFlag;
+
+  // String table name
+  if (path.get() == ARFILE_STRTAB_NAME)
+    flags |= StringTableFlag;
+  else
+    flags &= ~StringTableFlag;
+
+  // If it has a slash then it has a path
+  bool hasSlash = path.get().find('/') != std::string::npos;
+  if (hasSlash)
+    flags |= HasPathFlag;
+  else
+    flags &= ~HasPathFlag;
+
+  // If it has a slash or its over 15 chars then its a long filename format
+  if (hasSlash || path.get().length() > 15)
+    flags |= HasLongFilenameFlag;
+  else
+    flags &= ~HasLongFilenameFlag;
+
+  // Get the signature and status info
+  std::string magic;
+  const char* signature = (const char*) data;
+  if (!signature) {
+    path.getMagicNumber(magic,4);
+    signature = magic.c_str();
+    path.getStatusInfo(info);
+  }
+
+  // Determine what kind of file it is
+  switch (sys::IdentifyFileType(signature,4)) {
+    case sys::BytecodeFileType:
+      flags |= BytecodeFlag;
+      break;
+    case sys::CompressedBytecodeFileType:
+      flags |= CompressedBytecodeFlag;
+      flags &= ~CompressedFlag;
+      break;
+    default:
+      flags &= ~(BytecodeFlag|CompressedBytecodeFlag);
+      break;
+  }
+}
+
+// Archive constructor - this is the only constructor that gets used for the
+// Archive class. Everything else (default,copy) is deprecated. This just 
+// initializes and maps the file into memory, if requested.
+Archive::Archive(const sys::Path& filename, bool map ) 
+  : archPath(filename), members(), mapfile(0), base(0), symTab(), symTabSize(0)
+{
+  if (map) {
+    mapfile = new sys::MappedFile(filename);
+    base = (char*) mapfile->map();
+  }
 }
 
+// Archive destructor - just clean up memory
 Archive::~Archive() {
+  // Shutdown the file mapping
+  if (mapfile) {
+    mapfile->unmap();
+    delete mapfile;
+  }
+  // Delete any ModuleProviders and ArchiveMember's we've allocated as a result
+  // of symbol table searches.
+  for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) {
+    delete I->second.first;
+    delete I->second.second;
+  }
 }
 
 // vim: sw=2 ai






More information about the llvm-commits mailing list