diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2004-11-20 07:29:40 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2004-11-20 07:29:40 +0000 |
commit | 9a29db43a7a906162b0fde012b5d16f3b0895023 (patch) | |
tree | 06fa06b97a97438781c98d21ac2bb84dcb7ac447 /lib/Bytecode | |
parent | e651c954aade4d23f4976af6ade3f767ca387976 (diff) |
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
Diffstat (limited to 'lib/Bytecode')
-rw-r--r-- | lib/Bytecode/Archive/Archive.cpp | 14 | ||||
-rw-r--r-- | lib/Bytecode/Archive/ArchiveInternals.h | 7 | ||||
-rw-r--r-- | lib/Bytecode/Archive/ArchiveReader.cpp | 66 | ||||
-rw-r--r-- | lib/Bytecode/Archive/ArchiveWriter.cpp | 19 |
4 files changed, 66 insertions, 40 deletions
diff --git a/lib/Bytecode/Archive/Archive.cpp b/lib/Bytecode/Archive/Archive.cpp index a3fb534c9c..8e405907e6 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 77d2d5481b..c924c437b4 100644 --- a/lib/Bytecode/Archive/ArchiveInternals.h +++ b/lib/Bytecode/Archive/ArchiveInternals.h @@ -20,9 +20,10 @@ #define ARFILE_MAGIC "!<arch>\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 6f9a75ae7a..ce94c8adfd 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<std::string>& symbols, // 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)); + 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 c3c7d12676..8651e95391 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); } |