Changes necessary to enable linking of archives without LLVM symbol tables.
authorReid Spencer <rspencer@reidspencer.com>
Mon, 15 Nov 2004 01:20:11 +0000 (01:20 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Mon, 15 Nov 2004 01:20:11 +0000 (01:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17811 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bytecode/Reader.h
lib/Archive/ArchiveReader.cpp
lib/Archive/ArchiveWriter.cpp
lib/Bytecode/Archive/ArchiveReader.cpp
lib/Bytecode/Archive/ArchiveWriter.cpp
lib/Bytecode/Reader/ReaderWrappers.cpp

index a059ca4e933cd74258fbd7b4f0681b9868a5f777..4c0366330bd14137651ed238c11ad392d10ecb44 100644 (file)
@@ -77,11 +77,14 @@ bool GetBytecodeSymbols(const sys::Path& fileName,
 /// bytecode module defines. This is used for archiving and linking when only 
 /// the list of symbols the module defines is needed and the bytecode is
 /// already in memory.
-/// @returns true on success, false if the bytecode can't be parsed
+/// @returns the ModuleProvider on success, 0 if the bytecode can't be parsed
 /// @brief Get a bytecode file's externally visibile defined global symbols.
-bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
-                              const std::string& ModuleID,
-                              std::vector<std::string>& symbols);
+ModuleProvider* llvm::GetBytecodeSymbols(
+  const unsigned char*Buffer,        ///< The buffer to be parsed
+  unsigned Length,                   ///< The length of \p Buffer
+  const std::string& ModuleID,       ///< An identifier for the module
+  std::vector<std::string>& symbols  ///< The symbols defined in the module
+);
 
 } // End llvm namespace
 
index ae1a933078918a2fecfa834a21ced23b4ccab14a..794e1b271f373fa2ab753e96c30cff6c7978da6a 100644 (file)
@@ -391,13 +391,58 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) {
 // ModuleProviders that define those symbols.
 void
 Archive::findModulesDefiningSymbols(const std::set<std::string>& symbols,
-                                    std::set<ModuleProvider*>& modules)
+                                    std::set<ModuleProvider*>& result)
 {
+  assert(mapfile && base && "Can't findModulesDefiningSymbols on new archive");
+  if (symTab.empty()) {
+    // We don't have a symbol table, so we must build it now but lets also
+    // make sure that we populate the modules table as we do this to ensure
+    // that we don't load them twice when findModuleDefiningSymbol is called
+    // below.
+
+    // Get a pointer to the first file
+    const char* At  = ((const char*)base) + firstFileOffset;
+    const char* End = ((const char*)base) + mapfile->size();
+
+    while ( At < End) {
+      // Compute the offset to be put in the symbol table
+      unsigned offset = At - base - firstFileOffset;
+
+      // Parse the file's header
+      ArchiveMember* mbr = parseMemberHeader(At, End);
+
+      // If it contains symbols
+      if (mbr->isBytecode() || mbr->isCompressedBytecode()) {
+        // Get the symbols 
+        std::vector<std::string> symbols;
+        ModuleProvider* MP = GetBytecodeSymbols((const unsigned char*)At,
+            mbr->getSize(), mbr->getPath().get(),symbols);
+
+        if (MP) {
+          // Insert the module's symbols into the symbol table
+          for (std::vector<std::string>::iterator I = symbols.begin(), 
+               E=symbols.end(); I != E; ++I ) {
+            symTab.insert(std::make_pair(*I,offset));
+          }
+          // Insert the ModuleProvider and the ArchiveMember into the table of
+          // modules.
+          modules.insert(std::make_pair(offset,std::make_pair(MP,mbr)));
+        } else {
+          throw std::string("Can't parse bytecode member: ") +
+            mbr->getPath().get();
+        }
+      }
+    }
+  }
+
+  // At this point we have a valid symbol table (one way or another) so we 
+  // just use it to quickly find the symbols requested.
+
   for (std::set<std::string>::const_iterator I=symbols.begin(), 
        E=symbols.end(); I != E; ++I) {
     ModuleProvider* mp = findModuleDefiningSymbol(*I);
     if (mp) {
-      modules.insert(mp);
+      result.insert(mp);
     }
   }
 }
index 727b2bfcdf41e562f2a567f0914918af25953ea0..fa4d9e64fde83d96212b928cb749d59a933f230a 100644 (file)
@@ -197,19 +197,28 @@ Archive::writeMember(
   if (CreateSymbolTable && 
       (member.isBytecode() || member.isCompressedBytecode())) {
     std::vector<std::string> symbols;
-    GetBytecodeSymbols((const unsigned char*)data,fSize,member.getPath().get(), 
-                       symbols);
-    for (std::vector<std::string>::iterator SI = symbols.begin(), 
-         SE = symbols.end(); SI != SE; ++SI) {
-
-      std::pair<SymTabType::iterator,bool> Res = 
-        symTab.insert(std::make_pair(*SI,filepos));
-
-      if (Res.second) {
-        symTabSize += SI->length() + 
-                      numVbrBytes(SI->length()) + 
-                      numVbrBytes(filepos);
+    ModuleProvider* MP = GetBytecodeSymbols(
+      (const unsigned char*)data,fSize,member.getPath().get(), symbols);
+
+    // If the bytecode parsed successfully
+    if ( MP ) {
+      for (std::vector<std::string>::iterator SI = symbols.begin(), 
+           SE = symbols.end(); SI != SE; ++SI) {
+
+        std::pair<SymTabType::iterator,bool> Res = 
+          symTab.insert(std::make_pair(*SI,filepos));
+
+        if (Res.second) {
+          symTabSize += SI->length() + 
+                        numVbrBytes(SI->length()) + 
+                        numVbrBytes(filepos);
+        }
       }
+      // We don't need this module any more.
+      delete MP;
+    } else {
+      throw std::string("Can't parse bytecode member: ") + 
+             member.getPath().get();
     }
   }
 
index ae1a933078918a2fecfa834a21ced23b4ccab14a..794e1b271f373fa2ab753e96c30cff6c7978da6a 100644 (file)
@@ -391,13 +391,58 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) {
 // ModuleProviders that define those symbols.
 void
 Archive::findModulesDefiningSymbols(const std::set<std::string>& symbols,
-                                    std::set<ModuleProvider*>& modules)
+                                    std::set<ModuleProvider*>& result)
 {
+  assert(mapfile && base && "Can't findModulesDefiningSymbols on new archive");
+  if (symTab.empty()) {
+    // We don't have a symbol table, so we must build it now but lets also
+    // make sure that we populate the modules table as we do this to ensure
+    // that we don't load them twice when findModuleDefiningSymbol is called
+    // below.
+
+    // Get a pointer to the first file
+    const char* At  = ((const char*)base) + firstFileOffset;
+    const char* End = ((const char*)base) + mapfile->size();
+
+    while ( At < End) {
+      // Compute the offset to be put in the symbol table
+      unsigned offset = At - base - firstFileOffset;
+
+      // Parse the file's header
+      ArchiveMember* mbr = parseMemberHeader(At, End);
+
+      // If it contains symbols
+      if (mbr->isBytecode() || mbr->isCompressedBytecode()) {
+        // Get the symbols 
+        std::vector<std::string> symbols;
+        ModuleProvider* MP = GetBytecodeSymbols((const unsigned char*)At,
+            mbr->getSize(), mbr->getPath().get(),symbols);
+
+        if (MP) {
+          // Insert the module's symbols into the symbol table
+          for (std::vector<std::string>::iterator I = symbols.begin(), 
+               E=symbols.end(); I != E; ++I ) {
+            symTab.insert(std::make_pair(*I,offset));
+          }
+          // Insert the ModuleProvider and the ArchiveMember into the table of
+          // modules.
+          modules.insert(std::make_pair(offset,std::make_pair(MP,mbr)));
+        } else {
+          throw std::string("Can't parse bytecode member: ") +
+            mbr->getPath().get();
+        }
+      }
+    }
+  }
+
+  // At this point we have a valid symbol table (one way or another) so we 
+  // just use it to quickly find the symbols requested.
+
   for (std::set<std::string>::const_iterator I=symbols.begin(), 
        E=symbols.end(); I != E; ++I) {
     ModuleProvider* mp = findModuleDefiningSymbol(*I);
     if (mp) {
-      modules.insert(mp);
+      result.insert(mp);
     }
   }
 }
index 727b2bfcdf41e562f2a567f0914918af25953ea0..fa4d9e64fde83d96212b928cb749d59a933f230a 100644 (file)
@@ -197,19 +197,28 @@ Archive::writeMember(
   if (CreateSymbolTable && 
       (member.isBytecode() || member.isCompressedBytecode())) {
     std::vector<std::string> symbols;
-    GetBytecodeSymbols((const unsigned char*)data,fSize,member.getPath().get(), 
-                       symbols);
-    for (std::vector<std::string>::iterator SI = symbols.begin(), 
-         SE = symbols.end(); SI != SE; ++SI) {
-
-      std::pair<SymTabType::iterator,bool> Res = 
-        symTab.insert(std::make_pair(*SI,filepos));
-
-      if (Res.second) {
-        symTabSize += SI->length() + 
-                      numVbrBytes(SI->length()) + 
-                      numVbrBytes(filepos);
+    ModuleProvider* MP = GetBytecodeSymbols(
+      (const unsigned char*)data,fSize,member.getPath().get(), symbols);
+
+    // If the bytecode parsed successfully
+    if ( MP ) {
+      for (std::vector<std::string>::iterator SI = symbols.begin(), 
+           SE = symbols.end(); SI != SE; ++SI) {
+
+        std::pair<SymTabType::iterator,bool> Res = 
+          symTab.insert(std::make_pair(*SI,filepos));
+
+        if (Res.second) {
+          symTabSize += SI->length() + 
+                        numVbrBytes(SI->length()) + 
+                        numVbrBytes(filepos);
+        }
       }
+      // We don't need this module any more.
+      delete MP;
+    } else {
+      throw std::string("Can't parse bytecode member: ") + 
+             member.getPath().get();
     }
   }
 
index de2fd030e8bb9ce28d893801e30c1c9688a159c9..7cdcf64de1ebee16bb6bd8e39109061f5586eee4 100644 (file)
@@ -391,26 +391,27 @@ bool llvm::GetBytecodeSymbols(const sys::Path& fName,
   }
 }
 
-bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
+ModuleProvider* 
+llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
                               const std::string& ModuleID,
                               std::vector<std::string>& symbols) {
 
   try {
-    std::auto_ptr<ModuleProvider>
-      AMP(getBytecodeBufferModuleProvider(Buffer, Length, ModuleID));
+    ModuleProvider* MP = 
+      getBytecodeBufferModuleProvider(Buffer, Length, ModuleID);
 
     // Get the module from the provider
-    Module* M = AMP->releaseModule();
+    Module* M = MP->materializeModule();
 
     // Get the symbols
     getSymbols(M, symbols);
 
     // Done with the module
-    delete M;
-    return true;
+    return MP;
 
   } catch (...) {
-    return false;
+    // Fall through
   }
+  return 0;
 }
 // vim: sw=2 ai