diff --git a/lib/Bytecode/Archive/Archive.cpp b/lib/Bytecode/Archive/Archive.cpp
new file mode 100644
index 0000000..e9fcd2e
--- /dev/null
+++ b/lib/Bytecode/Archive/Archive.cpp
@@ -0,0 +1,24 @@
+//===-- Archive.cpp - Generic LLVM archive functions ------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// Builds up standard unix archive files (.a) containing LLVM bytecode.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ArchiveInternals.h"
+
+using namespace llvm;
+
+Archive::Archive() {
+}
+
+Archive::~Archive() {
+}
+
+// vim: sw=2 ai
diff --git a/lib/Bytecode/Archive/ArchiveInternals.h b/lib/Bytecode/Archive/ArchiveInternals.h
new file mode 100644
index 0000000..dde8358
--- /dev/null
+++ b/lib/Bytecode/Archive/ArchiveInternals.h
@@ -0,0 +1,158 @@
+//===-- lib/Bytecode/ArchiveInternals.h -------------------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// Internal implementation header for LLVM Archive files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIB_BYTECODE_ARCHIVEINTERNALS_H
+#define LIB_BYTECODE_ARCHIVEINTERNALS_H
+
+#include "llvm/Bytecode/Archive.h"
+#include "llvm/System/TimeValue.h"
+
+#define ARFILE_MAGIC "!<arch>\n"                   ///< magic string 
+#define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1)  ///< length of magic string 
+#define ARFILE_SYMTAB_NAME "/"                     ///< name of symtab entry
+#define ARFILE_STRTAB_NAME "//"                    ///< name of strtab entry
+#define ARFILE_PAD '\n'                            ///< inter-file align padding
+
+namespace llvm {
+
+  /// The ArchiveMemberHeader structure is used internally for bytecode archives. 
+  /// The header precedes each file member in the archive. This structure is 
+  /// defined using character arrays for direct and correct interpretation
+  /// regardless of the endianess of the machine that produced it.
+  /// @brief Archive File Member Header
+  class ArchiveMemberHeader {
+    public:
+    void init() {
+      memset(name,' ',16);
+      memset(date,' ',12);
+      memset(uid,' ',6);
+      memset(gid,' ',6);
+      memset(mode,' ',8);
+      memset(size,' ',10);
+      fmag[0] = '`';
+      fmag[1] = '\n';
+    }
+    void setDate( int secondsSinceEpoch = 0 ) {
+      if (secondsSinceEpoch == 0) {
+        sys::TimeValue tv = sys::TimeValue::now();
+        uint64_t secs; uint32_t nanos;
+        tv.GetTimespecTime(secs,nanos);
+        secondsSinceEpoch = (int) secs;
+      }
+      char buffer[20];
+      sprintf(buffer,"%d", secondsSinceEpoch);
+      memcpy(date,buffer,strlen(buffer));
+    }
+
+    void setSize(size_t sz) {
+      char buffer[20];
+      sprintf(buffer, "%u", (unsigned)sz);
+      memcpy(size,buffer,strlen(buffer));
+    }
+
+    void setMode(int m) {
+      char buffer[20];
+      sprintf(buffer, "%o", m);
+      memcpy(mode,buffer,strlen(buffer));
+    }
+
+    void setUid(unsigned u) {
+      char buffer[20];
+      sprintf(buffer, "%u", u);
+      memcpy(uid,buffer,strlen(buffer));
+    }
+
+    void setGid(unsigned g) {
+      char buffer[20];
+      sprintf(buffer, "%u", g);
+      memcpy(gid,buffer,strlen(buffer));
+    }
+
+    bool setName(const std::string& nm) {
+      if (nm.length() > 0 && nm.length() <= 16) {
+        memcpy(name,nm.c_str(),nm.length());
+        for (int i = nm.length()+1; i < 16; i++ ) name[i] = ' ';
+        return true;
+      }
+      return false;
+    }
+
+    private:
+    char name[16];  ///< Name of the file member. The filename is terminated with '/'
+                    ///< and blanks. The empty name (/ and 15 blanks) is for the 
+                    ///< symbol table. The special name "//" and 15 blanks is for
+                    ///< the string table, used for long file names. It must be
+                    ///< first in the archive.
+    char date[12];  ///< File date, decimal seconds since Epoch
+    char uid[6];    ///< user id in ASCII decimal
+    char gid[6];    ///< group id in ASCII decimal
+    char mode[8];   ///< file mode in ASCII octal
+    char size[10];  ///< file size in ASCII decimal
+    char fmag[2];   ///< Always contains ARFILE_MAGIC_TERMINATOR
+
+  };
+
+  /// The ArchiveInternals class is used to hold the content of the archive
+  /// while it is in memory. It also provides the bulk of the implementation for
+  /// the llvm:Archive class's interface.
+  class Archive::ArchiveInternals {
+    /// @name Types
+    /// @{
+    public:
+      typedef std::vector<std::string> StrTab;
+
+      /// This structure holds information for one member in the archive. It is
+      /// used temporarily while the contents of the archive are being
+      /// determined.
+      struct MemberInfo {
+        MemberInfo() {}
+        sys::Path path;
+        std::string name;
+        sys::Path::StatusInfo status;
+        StrTab symbols;
+        unsigned offset;
+      };
+
+    /// @}
+    /// @name Methods
+    /// @{
+    public:
+      /// @brief Add a file member to the archive.
+      void addFileMember(
+        const sys::Path& path,         ///< The path to the file to be added
+        const std::string& name,       ///< The name for the member
+        const StrTab* syms = 0         ///< The symbol table of the member
+      );
+
+      /// @brief Write the accumulated archive information to an archive file
+      void writeArchive();
+      void writeMember(const MemberInfo& member,std::ofstream& ARFile);
+      void writeSymbolTable(std::ofstream& ARFile);
+      void writeInteger(int num, std::ofstream& ARFile);
+
+    /// @}
+    /// @name  Data
+    /// @{
+    private:
+      friend class Archive;            ///< Parent class is a friend
+      sys::Path       fname;           ///< Path to the archive file
+      std::vector<MemberInfo> members; ///< Info about member files
+      Archive::SymTab* symtab;         ///< User's symbol table
+
+    /// @}
+  };
+}
+
+#endif
+
+// vim: sw=2 ai
diff --git a/lib/Bytecode/Archive/ArchiveWriter.cpp b/lib/Bytecode/Archive/ArchiveWriter.cpp
new file mode 100644
index 0000000..e3e2df4
--- /dev/null
+++ b/lib/Bytecode/Archive/ArchiveWriter.cpp
@@ -0,0 +1,284 @@
+//===-- ArchiveWriter.cpp - LLVM archive writing --------------------------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencerand is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// Builds up standard unix archive files (.a) containing LLVM bytecode.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ArchiveInternals.h"
+#include "llvm/Module.h"
+#include "llvm/Bytecode/Reader.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/System/MappedFile.h"
+#include <fstream>
+#include <iostream>
+
+using namespace llvm;
+
+Archive* 
+Archive::CreateEmpty(const sys::Path& Filename) {
+  Archive* result = new Archive;
+  Archive::ArchiveInternals* impl = result->impl = new Archive::ArchiveInternals;
+  impl->fname = Filename;
+  return result;
+}
+
+Archive*
+Archive::CreateFromFiles(
+  const sys::Path& Filename,
+  const PathList& Files,
+  const std::string& StripName
+) {
+  Archive* result = new Archive;
+  Archive::ArchiveInternals* impl = result->impl = new Archive::ArchiveInternals;
+  impl->fname = Filename;
+
+  try {
+    size_t strip_len = StripName.length();
+    for (PathList::const_iterator P = Files.begin(), E = Files.end(); P != E ;++P)
+    {
+      if (P->readable()) {
+        std::string name(P->get());
+        if (strip_len > 0 && StripName == name.substr(0,strip_len)) {
+          name.erase(0,strip_len);
+        }
+        if (P->isBytecodeFile()) {
+          std::vector<std::string> syms;
+          if (!GetBytecodeSymbols(*P, syms))
+            throw std::string("Can not get symbols from: ") + P->get();
+          impl->addFileMember(*P, name, &syms);
+        } else {
+          impl->addFileMember(*P, name);
+        }
+      }
+      else
+        throw std::string("Can not read: ") + P->get();
+    }
+
+    // Now that we've collected everything, write the archive
+    impl->writeArchive();
+
+  } catch(...) {
+    delete impl;
+    result->impl = 0;
+    delete result;
+    throw;
+  }
+
+  return result;
+}
+
+void
+Archive::ArchiveInternals::addFileMember(
+  const sys::Path& filePath,
+  const std::string& memberName,
+  const StrTab* symbols
+) {
+  MemberInfo info;
+  info.path = filePath;
+  info.name = memberName;
+  filePath.getStatusInfo(info.status);
+  if (symbols)
+    info.symbols = *symbols;
+  info.offset = 0;
+  members.push_back(info);
+}
+
+void
+Archive::ArchiveInternals::writeInteger(int num, std::ofstream& ARFile) {
+  char buff[4];
+  buff[0] = (num >> 24) & 255;
+  buff[1] = (num >> 16) & 255;
+  buff[2] = (num >> 8) & 255;
+  buff[3] = num & 255;
+  ARFile.write(buff, sizeof(buff));
+}
+
+void
+Archive::ArchiveInternals::writeSymbolTable( std::ofstream& ARFile ) {
+ 
+  // Compute the number of symbols in the symbol table and the
+  // total byte size of the string pool. While we're traversing,
+  // build the string pool for supporting long file names. Also,
+  // build the table of file offsets for the symbol table and 
+  // the 
+  typedef std::map<std::string,unsigned> SymbolMap;
+  StrTab stringPool;
+  SymbolMap symbolTable;
+  std::vector<unsigned> fileOffsets;
+  std::string symTabStrings;
+  unsigned fileOffset = 0;
+  unsigned spOffset = 0;
+  unsigned numSymbols = 0;
+  unsigned numSymBytes = 0;
+  for (unsigned i = 0; i < members.size(); i++ ) {
+    MemberInfo& mi = members[i];
+    StrTab& syms = mi.symbols;
+    size_t numSym = syms.size();
+    numSymbols += numSym;
+    for (unsigned j = 0; j < numSym; j++ ) {
+      numSymBytes += syms[j].size() + 1;
+      symbolTable[syms[i]] = i;
+    }
+    if (mi.name.length() > 15 || std::string::npos != mi.name.find('/')) {
+      stringPool.push_back(mi.name + "/\n");
+      mi.name = std::string("/") + utostr(spOffset);
+      spOffset += mi.name.length() + 2;
+    } else if (mi.name[mi.name.length()-1] != '/') {
+      mi.name += "/";
+    }
+    fileOffsets.push_back(fileOffset);
+    fileOffset += sizeof(ArchiveMemberHeader) + mi.status.fileSize;
+  }
+
+
+  // Compute the size of the symbol table file member
+  unsigned symTabSize = 0;
+  if (numSymbols != 0) 
+    symTabSize = 
+      sizeof(ArchiveMemberHeader) + // Size of the file header
+      4 +                           // Size of "number of entries"
+      (4 * numSymbols) +            // Size of member file indices
+      numSymBytes;                  // Size of the string table
+
+  // Compute the size of the string pool
+  unsigned strPoolSize = 0;
+  if (spOffset != 0 )
+    strPoolSize = 
+      sizeof(ArchiveMemberHeader) + // Size of the file header
+      spOffset;                     // Number of bytes in the string pool
+
+  // Compute the byte index offset created by symbol table and string pool
+  unsigned firstFileOffset = symTabSize + strPoolSize;
+
+  // Create header for symbol table. This must be first if there is
+  // a symbol table and must have a special name.
+  if ( symTabSize > 0 ) {
+    ArchiveMemberHeader Hdr;
+    Hdr.init();
+
+    // Name of symbol table is '/               ' but "" is passed in
+    // because the setName method always terminates with a /
+    Hdr.setName(ARFILE_SYMTAB_NAME);
+    Hdr.setDate();
+    Hdr.setSize(symTabSize - sizeof(ArchiveMemberHeader));
+    Hdr.setMode(0);
+    Hdr.setUid(0);
+    Hdr.setGid(0);
+    
+    // Write header to archive file
+    ARFile.write((char*)&Hdr, sizeof(Hdr));
+    
+    // Write the number of entries in the symbol table
+    this->writeInteger(numSymbols, ARFile);
+
+    // Write the file offset indices for each symbol and build the
+    // symbol table string pool
+    std::string symTabStrPool;
+    symTabStrPool.reserve(256 * 1024); // Reserve 256KBytes for symbols
+    for (SymbolMap::iterator I = symbolTable.begin(), E = symbolTable.end();
+         I != E; ++I ) {
+      this->writeInteger(firstFileOffset + fileOffsets[I->second], ARFile);
+      symTabStrPool += I->first;
+      symTabStrPool += "\0";
+    }
+
+    // Write the symbol table's string pool
+    ARFile.write(symTabStrPool.data(), symTabStrPool.size());
+  }
+
+  //============== DONE WITH SYMBOL TABLE 
+
+  if (strPoolSize > 0) {
+    // Initialize the header for the string pool
+    ArchiveMemberHeader Hdr;
+    Hdr.init();
+    Hdr.setName(ARFILE_STRTAB_NAME); 
+    Hdr.setDate();
+    Hdr.setSize(spOffset);
+    Hdr.setMode(0);
+    Hdr.setUid(0);
+    Hdr.setGid(0);
+
+    // Write the string pool header
+    ARFile.write((char*)&Hdr, sizeof(Hdr));
+
+    // Write the string pool
+    for (unsigned i = 0; i < stringPool.size(); i++) {
+      ARFile.write(stringPool[i].data(), stringPool[i].size());
+    }
+  }
+}
+
+void
+Archive::ArchiveInternals::writeMember(
+  const MemberInfo& member,
+  std::ofstream& ARFile
+) {
+
+  // Map the file into memory. We do this early for two reasons. First,
+  // if there's any kind of error, we want to know about it. Second, we
+  // want to ensure we're using the most recent size for this file.
+  sys::MappedFile mFile(member.path);
+  mFile.map();
+
+  // Header for the archive member
+  ArchiveMemberHeader Hdr;
+  Hdr.init();
+
+  // Set the name. If its longer than 15 chars, it will have already
+  // been reduced by the writeSymbolTable.
+  Hdr.setName(member.name);
+
+  // Set the other header members
+  Hdr.setSize( mFile.size() );
+  Hdr.setMode( member.status.mode);
+  Hdr.setUid ( member.status.user);
+  Hdr.setGid ( member.status.group);
+  Hdr.setDate( member.status.modTime.ToPosixTime() );
+
+  // Write header to archive file
+  ARFile.write((char*)&Hdr, sizeof(Hdr));
+  
+  //write to archive file
+  ARFile.write(mFile.charBase(),mFile.size());
+
+  mFile.unmap();
+}
+
+void
+Archive::ArchiveInternals::writeArchive() {
+  
+  // Create archive file for output.
+  std::ofstream ArchiveFile(fname.get().c_str());
+  
+  // Check for errors opening or creating archive file.
+  if ( !ArchiveFile.is_open() || ArchiveFile.bad() ) {
+    throw std::string("Error opening archive file: ") + fname.get();
+  }
+
+  // Write magic string to archive.
+  ArchiveFile << ARFILE_MAGIC;
+
+  // Write the symbol table and string pool
+  writeSymbolTable(ArchiveFile);
+
+  //Loop over all member files, and add to the archive.
+  for ( unsigned i = 0; i < members.size(); ++i) {
+    if(ArchiveFile.tellp() % 2 != 0)
+      ArchiveFile << ARFILE_PAD;
+    writeMember(members[i],ArchiveFile);
+  }
+
+  //Close archive file.
+  ArchiveFile.close();
+}
+
+// vim: sw=2 ai
