Changes necessary to enable linking of archives without LLVM symbol tables.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17811 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer
2004-11-15 01:20:11 +00:00
parent 6238a85e4f
commit 766b793143
6 changed files with 147 additions and 35 deletions

View 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);
}
}
}

View 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) {
ModuleProvider* MP = GetBytecodeSymbols(
(const unsigned char*)data,fSize,member.getPath().get(), symbols);
std::pair<SymTabType::iterator,bool> Res =
symTab.insert(std::make_pair(*SI,filepos));
// If the bytecode parsed successfully
if ( MP ) {
for (std::vector<std::string>::iterator SI = symbols.begin(),
SE = symbols.end(); SI != SE; ++SI) {
if (Res.second) {
symTabSize += SI->length() +
numVbrBytes(SI->length()) +
numVbrBytes(filepos);
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();
}
}