From: Reid Spencer Date: Sat, 20 Nov 2004 07:29:40 +0000 (+0000) Subject: Distinguish between BSD4.4 and SVR4 symbol tables X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9a29db43a7a906162b0fde012b5d16f3b0895023;p=oota-llvm.git Distinguish between BSD4.4 and SVR4 symbol tables git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18044 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Bytecode/Archive.h b/include/llvm/Bytecode/Archive.h index 943d979cac3..41c931150da 100644 --- a/include/llvm/Bytecode/Archive.h +++ b/include/llvm/Bytecode/Archive.h @@ -49,12 +49,13 @@ class ArchiveMember { /// access to the flags. The flags are not user settable. enum Flags { CompressedFlag = 1, ///< Member is a normal compressed file - ForeignSymbolTableFlag = 2, ///< Member is a foreign symbol table - LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table - BytecodeFlag = 8, ///< Member is uncompressed bytecode - CompressedBytecodeFlag = 16, ///< Member is compressed bytecode - HasPathFlag = 32, ///< Member has a full or partial path - HasLongFilenameFlag = 64, ///< Member uses the long filename syntax + SVR4SymbolTableFlag = 2, ///< Member is a SVR4 symbol table + BSD4SymbolTableFlag = 4, ///< Member is a BSD4 symbol table + LLVMSymbolTableFlag = 8, ///< Member is an LLVM symbol table + BytecodeFlag = 16, ///< Member is uncompressed bytecode + CompressedBytecodeFlag = 32, ///< Member is compressed bytecode + HasPathFlag = 64, ///< Member has a full or partial path + HasLongFilenameFlag = 128, ///< Member uses the long filename syntax StringTableFlag = 256, ///< Member is an ar(1) format string table }; @@ -117,9 +118,13 @@ class ArchiveMember { /// @brief Determine if the member is a compressed regular file. bool isCompressed() const { return flags&CompressedFlag; } - /// @returns true iff the member is a foreign (non-LLVM) symbol table - /// @brief Determine if this member is a foreign symbol table. - bool isForeignSymbolTable() const { return flags&ForeignSymbolTableFlag; } + /// @returns true iff the member is a SVR4 (non-LLVM) symbol table + /// @brief Determine if this member is a SVR4 symbol table. + bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; } + + /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table + /// @brief Determine if this member is a BSD4.4 symbol table. + bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; } /// @returns true iff the archive member is the LLVM symbol table /// @brief Determine if this member is the LLVM symbol table. diff --git a/lib/Archive/Archive.cpp b/lib/Archive/Archive.cpp index a3fb534c9c3..8e405907e62 100644 --- a/lib/Archive/Archive.cpp +++ b/lib/Archive/Archive.cpp @@ -65,11 +65,17 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) { data = 0; path = newFile; - // Foreign symbol tables have an empty name - if (path.get() == ARFILE_SYMTAB_NAME) - flags |= ForeignSymbolTableFlag; + // SVR4 symbol tables have an empty name + if (path.get() == ARFILE_SVR4_SYMTAB_NAME) + flags |= SVR4SymbolTableFlag; else - flags &= ~ForeignSymbolTableFlag; + flags &= ~SVR4SymbolTableFlag; + + // BSD4.4 symbol tables have a special name + if (path.get() == ARFILE_BSD4_SYMTAB_NAME) + flags |= BSD4SymbolTableFlag; + else + flags &= ~BSD4SymbolTableFlag; // LLVM symbol tables have a very specific name if (path.get() == ARFILE_LLVM_SYMTAB_NAME) diff --git a/lib/Archive/ArchiveInternals.h b/lib/Archive/ArchiveInternals.h index 77d2d5481bc..c924c437b4b 100644 --- a/lib/Archive/ArchiveInternals.h +++ b/lib/Archive/ArchiveInternals.h @@ -20,9 +20,10 @@ #define ARFILE_MAGIC "!\n" ///< magic string #define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string -#define ARFILE_SYMTAB_NAME "/ " ///< regular symtab entry -#define ARFILE_STRTAB_NAME "// " ///< Name of string table -#define ARFILE_LLVM_SYMTAB_NAME "#_LLVM_SYM_TAB_#" ///< LLVM's symtab entry +#define ARFILE_SVR4_SYMTAB_NAME "/ " ///< SVR4 symtab entry name +#define ARFILE_LLVM_SYMTAB_NAME "#_LLVM_SYM_TAB_#" ///< LLVM symtab entry name +#define ARFILE_BSD4_SYMTAB_NAME "__.SYMDEF SORTED" ///< BSD4 symtab entry name +#define ARFILE_STRTAB_NAME "// " ///< Name of string table #define ARFILE_PAD "\n" ///< inter-file align padding #define ARFILE_MEMBER_MAGIC "`\n" ///< fmag field magic # diff --git a/lib/Archive/ArchiveReader.cpp b/lib/Archive/ArchiveReader.cpp index 6f9a75ae7aa..ce94c8adfd7 100644 --- a/lib/Archive/ArchiveReader.cpp +++ b/lib/Archive/ArchiveReader.cpp @@ -41,7 +41,7 @@ Archive::parseSymbolTable(const void* data, unsigned size) { if (At + length > End) throw std::string("malformed symbol table"); // we don't care if it can't be inserted (duplicate entry) - symTab.insert(std::make_pair(std::string(At,length),offset)); + symTab.insert(std::make_pair(std::string(At, length), offset)); At += length; } symTabSize = size; @@ -96,14 +96,14 @@ Archive::parseMemberHeader(const char*& At, const char* End) { if (Hdr->name[1] == '1' && Hdr->name[2] == '/') { if (isdigit(Hdr->name[3])) { unsigned len = atoi(&Hdr->name[3]); - pathname.assign(At,len); + pathname.assign(At, len); At += len; MemberSize -= len; flags |= ArchiveMember::HasLongFilenameFlag; } else throw std::string("invalid long filename"); } else if (Hdr->name[1] == '_' && - (0==memcmp(Hdr->name,ARFILE_LLVM_SYMTAB_NAME,16))) { + (0 == memcmp(Hdr->name, ARFILE_LLVM_SYMTAB_NAME, 16))) { // The member is using a long file name (>15 chars) format. // This format is standard for 4.4BSD and Mac OSX operating // systems. LLVM uses it similarly. In this format, the @@ -116,18 +116,18 @@ Archive::parseMemberHeader(const char*& At, const char* End) { break; case '/': if (Hdr->name[1]== '/') { - if (0==memcmp(Hdr->name,ARFILE_STRTAB_NAME,16)) { + if (0 == memcmp(Hdr->name, ARFILE_STRTAB_NAME, 16)) { pathname.assign(ARFILE_STRTAB_NAME); flags |= ArchiveMember::StringTableFlag; } else { throw std::string("invalid string table name"); } } else if (Hdr->name[1] == ' ') { - if (0==memcmp(Hdr->name,ARFILE_SYMTAB_NAME,16)) { - pathname.assign(ARFILE_SYMTAB_NAME); - flags |= ArchiveMember::ForeignSymbolTableFlag; + if (0 == memcmp(Hdr->name, ARFILE_SVR4_SYMTAB_NAME, 16)) { + pathname.assign(ARFILE_SVR4_SYMTAB_NAME); + flags |= ArchiveMember::SVR4SymbolTableFlag; } else { - throw std::string("invalid foreign symbol table name"); + throw std::string("invalid SVR4 symbol table name"); } } else if (isdigit(Hdr->name[1])) { unsigned index = atoi(&Hdr->name[1]); @@ -138,7 +138,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { const char* last_p = p; while (p < endp) { if (*p == '\n' && *last_p == '/') { - pathname.assign(namep,last_p-namep); + pathname.assign(namep, last_p - namep); flags |= ArchiveMember::HasLongFilenameFlag; break; } @@ -152,17 +152,24 @@ Archive::parseMemberHeader(const char*& At, const char* End) { } } break; + case '_': + if (Hdr->name[1] == '_' && + (0 == memcmp(Hdr->name, ARFILE_BSD4_SYMTAB_NAME, 16))) { + pathname.assign(ARFILE_BSD4_SYMTAB_NAME); + flags |= ArchiveMember::BSD4SymbolTableFlag; + } + break; default: - char* slash = (char*) memchr(Hdr->name,'/',16); + char* slash = (char*) memchr(Hdr->name, '/', 16); if (slash == 0) slash = Hdr->name + 16; - pathname.assign(Hdr->name,slash-Hdr->name); + pathname.assign(Hdr->name, slash - Hdr->name); break; } // Determine if this is a bytecode file - switch (sys::IdentifyFileType(At,4)) { + switch (sys::IdentifyFileType(At, 4)) { case sys::BytecodeFileType: flags |= ArchiveMember::BytecodeFlag; break; @@ -183,7 +190,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { member->path.setFile(pathname); member->info.fileSize = MemberSize; member->info.modTime.fromEpochTime(atoi(Hdr->date)); - sscanf(Hdr->mode,"%o",&(member->info.mode)); + sscanf(Hdr->mode, "%o", &(member->info.mode)); member->info.user = atoi(Hdr->uid); member->info.group = atoi(Hdr->gid); member->flags = flags; @@ -195,7 +202,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { void Archive::checkSignature() { // Check the magic string at file's header - if (mapfile->size() < 8 || memcmp(base, ARFILE_MAGIC,8)) + if (mapfile->size() < 8 || memcmp(base, ARFILE_MAGIC, 8)) throw std::string("invalid signature for an archive file"); } @@ -222,9 +229,14 @@ Archive::loadArchive() { ArchiveMember* mbr = parseMemberHeader(At, End); // check if this is the foreign symbol table - if (mbr->isForeignSymbolTable()) { + if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) { // We just save this but don't do anything special // with it. It doesn't count as the "first file". + if (foreignST) { + // What? Multiple foreign symbol tables? Just chuck it + // and retain the last one found. + delete foreignST; + } foreignST = mbr; At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) @@ -234,7 +246,7 @@ Archive::loadArchive() { // variable. This will be used to get the names of the // members that use the "/ddd" format for their names // (SVR4 style long names). - strtab.assign(At,mbr->getSize()); + strtab.assign(At, mbr->getSize()); At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) At++; @@ -244,7 +256,7 @@ Archive::loadArchive() { // already, its an error. Otherwise, parse the symbol table and move on. if (seenSymbolTable) throw std::string("invalid archive: multiple symbol tables"); - parseSymbolTable(mbr->getData(),mbr->getSize()); + parseSymbolTable(mbr->getData(), mbr->getSize()); seenSymbolTable = true; At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) @@ -269,7 +281,7 @@ Archive::loadArchive() { Archive* Archive::OpenAndLoad(const sys::Path& file) { - Archive* result = new Archive(file,true); + Archive* result = new Archive(file, true); result->loadArchive(); @@ -314,7 +326,7 @@ Archive::loadSymbolTable() { const char* FirstFile = At; ArchiveMember* mbr = parseMemberHeader(At, End); - if (mbr->isForeignSymbolTable()) { + if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) { // Skip the foreign symbol table, we don't do anything with it At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) @@ -323,24 +335,24 @@ Archive::loadSymbolTable() { // Read the next one FirstFile = At; - mbr = parseMemberHeader(At,End); + mbr = parseMemberHeader(At, End); } if (mbr->isStringTable()) { // Process the string table entry - strtab.assign((const char*)mbr->getData(),mbr->getSize()); + strtab.assign((const char*)mbr->getData(), mbr->getSize()); At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) At++; delete mbr; // Get the next one FirstFile = At; - mbr = parseMemberHeader(At,End); + mbr = parseMemberHeader(At, End); } // See if its the symbol table if (mbr->isLLVMSymbolTable()) { - parseSymbolTable(mbr->getData(),mbr->getSize()); + parseSymbolTable(mbr->getData(), mbr->getSize()); FirstFile = At + mbr->getSize(); if ((intptr_t(At) & 1) == 1) FirstFile++; @@ -358,7 +370,7 @@ Archive::loadSymbolTable() { // Open the archive and load just the symbol tables Archive* Archive::OpenAndLoadSymbols(const sys::Path& file) { - Archive* result = new Archive(file,true); + Archive* result = new Archive(file, true); result->loadSymbolTable(); @@ -399,7 +411,7 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) { (const unsigned char*) mbr->getData(), mbr->getSize(), FullMemberName, 0); - modules.insert(std::make_pair(fileOffset,std::make_pair(mp,mbr))); + modules.insert(std::make_pair(fileOffset, std::make_pair(mp, mbr))); return mp; } @@ -441,11 +453,11 @@ Archive::findModulesDefiningSymbols(std::set& symbols, // Insert the module's symbols into the symbol table for (std::vector::iterator I = symbols.begin(), E=symbols.end(); I != E; ++I ) { - symTab.insert(std::make_pair(*I,offset)); + 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))); + modules.insert(std::make_pair(offset, std::make_pair(MP, mbr))); } else { throw std::string("Can't parse bytecode member: ") + mbr->getPath().get(); diff --git a/lib/Archive/ArchiveWriter.cpp b/lib/Archive/ArchiveWriter.cpp index c3c7d12676e..8651e95391f 100644 --- a/lib/Archive/ArchiveWriter.cpp +++ b/lib/Archive/ArchiveWriter.cpp @@ -105,8 +105,10 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, bool writeLongName = false; if (mbr.isStringTable()) { memcpy(hdr.name,ARFILE_STRTAB_NAME,16); - } else if (mbr.isForeignSymbolTable()) { - memcpy(hdr.name,ARFILE_SYMTAB_NAME,16); + } else if (mbr.isSVR4SymbolTable()) { + memcpy(hdr.name,ARFILE_SVR4_SYMTAB_NAME,16); + } else if (mbr.isBSD4SymbolTable()) { + memcpy(hdr.name,ARFILE_BSD4_SYMTAB_NAME,16); } else if (mbr.isLLVMSymbolTable()) { memcpy(hdr.name,ARFILE_LLVM_SYMTAB_NAME,16); } else if (TruncateNames) { @@ -240,10 +242,11 @@ Archive::writeMember( // Determine if we actually should compress this member bool willCompress = (ShouldCompress && - !member.isForeignSymbolTable() && - !member.isLLVMSymbolTable() && !member.isCompressed() && - !member.isCompressedBytecode()); + !member.isCompressedBytecode() && + !member.isLLVMSymbolTable() && + !member.isSVR4SymbolTable() && + !member.isBSD4SymbolTable()); // Perform the compression. Note that if the file is uncompressed bytecode // then we turn the file into compressed bytecode rather than treating it as @@ -418,7 +421,11 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress){ // Write the file magic number FinalFile << ARFILE_MAGIC; - // If there is a foreign symbol table, put it into the file now. + // If there is a foreign symbol table, put it into the file now. Most + // ar(1) implementations require the symbol table to be first but llvm-ar + // can deal with it being after a foreign symbol table. This ensures + // compatibility with other ar(1) implementations as well as allowing the + // archive to store both native .o and LLVM .bc files, both indexed. if (foreignST) { writeMember(*foreignST, FinalFile, false, false, false); } diff --git a/lib/Bytecode/Archive/Archive.cpp b/lib/Bytecode/Archive/Archive.cpp index a3fb534c9c3..8e405907e62 100644 --- a/lib/Bytecode/Archive/Archive.cpp +++ b/lib/Bytecode/Archive/Archive.cpp @@ -65,11 +65,17 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) { data = 0; path = newFile; - // Foreign symbol tables have an empty name - if (path.get() == ARFILE_SYMTAB_NAME) - flags |= ForeignSymbolTableFlag; + // SVR4 symbol tables have an empty name + if (path.get() == ARFILE_SVR4_SYMTAB_NAME) + flags |= SVR4SymbolTableFlag; else - flags &= ~ForeignSymbolTableFlag; + flags &= ~SVR4SymbolTableFlag; + + // BSD4.4 symbol tables have a special name + if (path.get() == ARFILE_BSD4_SYMTAB_NAME) + flags |= BSD4SymbolTableFlag; + else + flags &= ~BSD4SymbolTableFlag; // LLVM symbol tables have a very specific name if (path.get() == ARFILE_LLVM_SYMTAB_NAME) diff --git a/lib/Bytecode/Archive/ArchiveInternals.h b/lib/Bytecode/Archive/ArchiveInternals.h index 77d2d5481bc..c924c437b4b 100644 --- a/lib/Bytecode/Archive/ArchiveInternals.h +++ b/lib/Bytecode/Archive/ArchiveInternals.h @@ -20,9 +20,10 @@ #define ARFILE_MAGIC "!\n" ///< magic string #define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string -#define ARFILE_SYMTAB_NAME "/ " ///< regular symtab entry -#define ARFILE_STRTAB_NAME "// " ///< Name of string table -#define ARFILE_LLVM_SYMTAB_NAME "#_LLVM_SYM_TAB_#" ///< LLVM's symtab entry +#define ARFILE_SVR4_SYMTAB_NAME "/ " ///< SVR4 symtab entry name +#define ARFILE_LLVM_SYMTAB_NAME "#_LLVM_SYM_TAB_#" ///< LLVM symtab entry name +#define ARFILE_BSD4_SYMTAB_NAME "__.SYMDEF SORTED" ///< BSD4 symtab entry name +#define ARFILE_STRTAB_NAME "// " ///< Name of string table #define ARFILE_PAD "\n" ///< inter-file align padding #define ARFILE_MEMBER_MAGIC "`\n" ///< fmag field magic # diff --git a/lib/Bytecode/Archive/ArchiveReader.cpp b/lib/Bytecode/Archive/ArchiveReader.cpp index 6f9a75ae7aa..ce94c8adfd7 100644 --- a/lib/Bytecode/Archive/ArchiveReader.cpp +++ b/lib/Bytecode/Archive/ArchiveReader.cpp @@ -41,7 +41,7 @@ Archive::parseSymbolTable(const void* data, unsigned size) { if (At + length > End) throw std::string("malformed symbol table"); // we don't care if it can't be inserted (duplicate entry) - symTab.insert(std::make_pair(std::string(At,length),offset)); + symTab.insert(std::make_pair(std::string(At, length), offset)); At += length; } symTabSize = size; @@ -96,14 +96,14 @@ Archive::parseMemberHeader(const char*& At, const char* End) { if (Hdr->name[1] == '1' && Hdr->name[2] == '/') { if (isdigit(Hdr->name[3])) { unsigned len = atoi(&Hdr->name[3]); - pathname.assign(At,len); + pathname.assign(At, len); At += len; MemberSize -= len; flags |= ArchiveMember::HasLongFilenameFlag; } else throw std::string("invalid long filename"); } else if (Hdr->name[1] == '_' && - (0==memcmp(Hdr->name,ARFILE_LLVM_SYMTAB_NAME,16))) { + (0 == memcmp(Hdr->name, ARFILE_LLVM_SYMTAB_NAME, 16))) { // The member is using a long file name (>15 chars) format. // This format is standard for 4.4BSD and Mac OSX operating // systems. LLVM uses it similarly. In this format, the @@ -116,18 +116,18 @@ Archive::parseMemberHeader(const char*& At, const char* End) { break; case '/': if (Hdr->name[1]== '/') { - if (0==memcmp(Hdr->name,ARFILE_STRTAB_NAME,16)) { + if (0 == memcmp(Hdr->name, ARFILE_STRTAB_NAME, 16)) { pathname.assign(ARFILE_STRTAB_NAME); flags |= ArchiveMember::StringTableFlag; } else { throw std::string("invalid string table name"); } } else if (Hdr->name[1] == ' ') { - if (0==memcmp(Hdr->name,ARFILE_SYMTAB_NAME,16)) { - pathname.assign(ARFILE_SYMTAB_NAME); - flags |= ArchiveMember::ForeignSymbolTableFlag; + if (0 == memcmp(Hdr->name, ARFILE_SVR4_SYMTAB_NAME, 16)) { + pathname.assign(ARFILE_SVR4_SYMTAB_NAME); + flags |= ArchiveMember::SVR4SymbolTableFlag; } else { - throw std::string("invalid foreign symbol table name"); + throw std::string("invalid SVR4 symbol table name"); } } else if (isdigit(Hdr->name[1])) { unsigned index = atoi(&Hdr->name[1]); @@ -138,7 +138,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { const char* last_p = p; while (p < endp) { if (*p == '\n' && *last_p == '/') { - pathname.assign(namep,last_p-namep); + pathname.assign(namep, last_p - namep); flags |= ArchiveMember::HasLongFilenameFlag; break; } @@ -152,17 +152,24 @@ Archive::parseMemberHeader(const char*& At, const char* End) { } } break; + case '_': + if (Hdr->name[1] == '_' && + (0 == memcmp(Hdr->name, ARFILE_BSD4_SYMTAB_NAME, 16))) { + pathname.assign(ARFILE_BSD4_SYMTAB_NAME); + flags |= ArchiveMember::BSD4SymbolTableFlag; + } + break; default: - char* slash = (char*) memchr(Hdr->name,'/',16); + char* slash = (char*) memchr(Hdr->name, '/', 16); if (slash == 0) slash = Hdr->name + 16; - pathname.assign(Hdr->name,slash-Hdr->name); + pathname.assign(Hdr->name, slash - Hdr->name); break; } // Determine if this is a bytecode file - switch (sys::IdentifyFileType(At,4)) { + switch (sys::IdentifyFileType(At, 4)) { case sys::BytecodeFileType: flags |= ArchiveMember::BytecodeFlag; break; @@ -183,7 +190,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { member->path.setFile(pathname); member->info.fileSize = MemberSize; member->info.modTime.fromEpochTime(atoi(Hdr->date)); - sscanf(Hdr->mode,"%o",&(member->info.mode)); + sscanf(Hdr->mode, "%o", &(member->info.mode)); member->info.user = atoi(Hdr->uid); member->info.group = atoi(Hdr->gid); member->flags = flags; @@ -195,7 +202,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { void Archive::checkSignature() { // Check the magic string at file's header - if (mapfile->size() < 8 || memcmp(base, ARFILE_MAGIC,8)) + if (mapfile->size() < 8 || memcmp(base, ARFILE_MAGIC, 8)) throw std::string("invalid signature for an archive file"); } @@ -222,9 +229,14 @@ Archive::loadArchive() { ArchiveMember* mbr = parseMemberHeader(At, End); // check if this is the foreign symbol table - if (mbr->isForeignSymbolTable()) { + if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) { // We just save this but don't do anything special // with it. It doesn't count as the "first file". + if (foreignST) { + // What? Multiple foreign symbol tables? Just chuck it + // and retain the last one found. + delete foreignST; + } foreignST = mbr; At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) @@ -234,7 +246,7 @@ Archive::loadArchive() { // variable. This will be used to get the names of the // members that use the "/ddd" format for their names // (SVR4 style long names). - strtab.assign(At,mbr->getSize()); + strtab.assign(At, mbr->getSize()); At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) At++; @@ -244,7 +256,7 @@ Archive::loadArchive() { // already, its an error. Otherwise, parse the symbol table and move on. if (seenSymbolTable) throw std::string("invalid archive: multiple symbol tables"); - parseSymbolTable(mbr->getData(),mbr->getSize()); + parseSymbolTable(mbr->getData(), mbr->getSize()); seenSymbolTable = true; At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) @@ -269,7 +281,7 @@ Archive::loadArchive() { Archive* Archive::OpenAndLoad(const sys::Path& file) { - Archive* result = new Archive(file,true); + Archive* result = new Archive(file, true); result->loadArchive(); @@ -314,7 +326,7 @@ Archive::loadSymbolTable() { const char* FirstFile = At; ArchiveMember* mbr = parseMemberHeader(At, End); - if (mbr->isForeignSymbolTable()) { + if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) { // Skip the foreign symbol table, we don't do anything with it At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) @@ -323,24 +335,24 @@ Archive::loadSymbolTable() { // Read the next one FirstFile = At; - mbr = parseMemberHeader(At,End); + mbr = parseMemberHeader(At, End); } if (mbr->isStringTable()) { // Process the string table entry - strtab.assign((const char*)mbr->getData(),mbr->getSize()); + strtab.assign((const char*)mbr->getData(), mbr->getSize()); At += mbr->getSize(); if ((intptr_t(At) & 1) == 1) At++; delete mbr; // Get the next one FirstFile = At; - mbr = parseMemberHeader(At,End); + mbr = parseMemberHeader(At, End); } // See if its the symbol table if (mbr->isLLVMSymbolTable()) { - parseSymbolTable(mbr->getData(),mbr->getSize()); + parseSymbolTable(mbr->getData(), mbr->getSize()); FirstFile = At + mbr->getSize(); if ((intptr_t(At) & 1) == 1) FirstFile++; @@ -358,7 +370,7 @@ Archive::loadSymbolTable() { // Open the archive and load just the symbol tables Archive* Archive::OpenAndLoadSymbols(const sys::Path& file) { - Archive* result = new Archive(file,true); + Archive* result = new Archive(file, true); result->loadSymbolTable(); @@ -399,7 +411,7 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) { (const unsigned char*) mbr->getData(), mbr->getSize(), FullMemberName, 0); - modules.insert(std::make_pair(fileOffset,std::make_pair(mp,mbr))); + modules.insert(std::make_pair(fileOffset, std::make_pair(mp, mbr))); return mp; } @@ -441,11 +453,11 @@ Archive::findModulesDefiningSymbols(std::set& symbols, // Insert the module's symbols into the symbol table for (std::vector::iterator I = symbols.begin(), E=symbols.end(); I != E; ++I ) { - symTab.insert(std::make_pair(*I,offset)); + 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))); + modules.insert(std::make_pair(offset, std::make_pair(MP, mbr))); } else { throw std::string("Can't parse bytecode member: ") + mbr->getPath().get(); diff --git a/lib/Bytecode/Archive/ArchiveWriter.cpp b/lib/Bytecode/Archive/ArchiveWriter.cpp index c3c7d12676e..8651e95391f 100644 --- a/lib/Bytecode/Archive/ArchiveWriter.cpp +++ b/lib/Bytecode/Archive/ArchiveWriter.cpp @@ -105,8 +105,10 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, bool writeLongName = false; if (mbr.isStringTable()) { memcpy(hdr.name,ARFILE_STRTAB_NAME,16); - } else if (mbr.isForeignSymbolTable()) { - memcpy(hdr.name,ARFILE_SYMTAB_NAME,16); + } else if (mbr.isSVR4SymbolTable()) { + memcpy(hdr.name,ARFILE_SVR4_SYMTAB_NAME,16); + } else if (mbr.isBSD4SymbolTable()) { + memcpy(hdr.name,ARFILE_BSD4_SYMTAB_NAME,16); } else if (mbr.isLLVMSymbolTable()) { memcpy(hdr.name,ARFILE_LLVM_SYMTAB_NAME,16); } else if (TruncateNames) { @@ -240,10 +242,11 @@ Archive::writeMember( // Determine if we actually should compress this member bool willCompress = (ShouldCompress && - !member.isForeignSymbolTable() && - !member.isLLVMSymbolTable() && !member.isCompressed() && - !member.isCompressedBytecode()); + !member.isCompressedBytecode() && + !member.isLLVMSymbolTable() && + !member.isSVR4SymbolTable() && + !member.isBSD4SymbolTable()); // Perform the compression. Note that if the file is uncompressed bytecode // then we turn the file into compressed bytecode rather than treating it as @@ -418,7 +421,11 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress){ // Write the file magic number FinalFile << ARFILE_MAGIC; - // If there is a foreign symbol table, put it into the file now. + // If there is a foreign symbol table, put it into the file now. Most + // ar(1) implementations require the symbol table to be first but llvm-ar + // can deal with it being after a foreign symbol table. This ensures + // compatibility with other ar(1) implementations as well as allowing the + // archive to store both native .o and LLVM .bc files, both indexed. if (foreignST) { writeMember(*foreignST, FinalFile, false, false, false); }