]> git.saurik.com Git - apple/ld64.git/blobdiff - src/Readers/ObjectFileArchiveMachO.cpp
ld64-47.2.tar.gz
[apple/ld64.git] / src / Readers / ObjectFileArchiveMachO.cpp
diff --git a/src/Readers/ObjectFileArchiveMachO.cpp b/src/Readers/ObjectFileArchiveMachO.cpp
deleted file mode 100644 (file)
index b01d8a0..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
- *
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-
-namespace ObjectFileArchiveMachO {
-
-class Reader : public ObjectFile::Reader 
-{
-public:
-                                                                                               Reader(const uint8_t fileContent[], uint64_t fileLength, const char* path, const ObjectFile::ReaderOptions& options);
-       virtual                                                                         ~Reader();
-       
-       virtual const char*                                                             getPath();
-       virtual std::vector<class ObjectFile::Atom*>&   getAtoms();
-       virtual std::vector<class ObjectFile::Atom*>*   getJustInTimeAtomsFor(const char* name);
-       virtual std::vector<ObjectFile::StabsInfo>*             getStabsDebugInfo();
-
-private:
-       class Entry : ar_hdr
-       {
-       public:
-               const char*                     getName() const;
-               const uint8_t*          getContent() const;
-               uint32_t                        getContentSize() const;
-               const Entry*            getNext() const;
-       private:
-               bool                            hasLongName() const;
-               unsigned int            getLongNameSpace() const;
-               
-       };
-
-       const struct ranlib*                                                    ranlibBinarySearch(const char* name);
-       const struct ranlib*                                                    ranlibLinearSearch(const char* name);
-       ObjectFile::Reader*                                                             makeObjectReaderForMember(const Entry* member);
-       void                                                                                    dumpTableOfContents();
-       
-       const char*                                                                             fPath;
-       const ObjectFile::ReaderOptions&                                fOptions;
-       const uint8_t*                                                                  fFileContent;
-       uint64_t                                                                                fFileLength;
-       const struct ranlib*                                                    fTableOfContents;
-       uint32_t                                                                                fTableOfContentCount;
-       bool                                                                                    fSorted;
-       const char*                                                                             fStringPool;
-       std::vector<class ObjectFile::Atom*>                    fAllAtoms;
-       std::set<const class Entry*>                                    fInstantiatedEntries;
-       
-       static std::vector<class ObjectFile::Atom*>             fgEmptyList;
-};
-
-std::vector<class ObjectFile::Atom*>           Reader::fgEmptyList;
-
-#undef SwapArchToHostInt32
-#if defined(ARCH_PPC) || defined(ARCH_PPC64)
-       #define SwapArchToHostInt32(value) OSSwapBigToHostInt32(value)
-#elif defined(ARCH_I386)
-       #define SwapArchToHostInt32(value) OSSwapLittleToHostInt32(value)
-#endif
-
-
-
-bool Reader::Entry::hasLongName() const
-{
-       return ( strncmp(this->ar_name, AR_EFMT1, strlen(AR_EFMT1)) == 0 );
-}
-
-unsigned int Reader::Entry::getLongNameSpace() const
-{
-       char* endptr;
-       long result = strtol(&this->ar_name[strlen(AR_EFMT1)], &endptr, 10);
-       return result;
-}
-
-const char* Reader::Entry::getName() const
-{
-       if ( this->hasLongName() ) {
-               int len = this->getLongNameSpace();
-               static char longName[256];
-               strncpy(longName, ((char*)this)+sizeof(ar_hdr), len);
-               longName[len] = '\0';
-               return longName;
-       }
-       else {
-               static char shortName[20];
-               strncpy(shortName, this->ar_name, 16);
-               shortName[16] = '\0';
-               char* space = strchr(shortName, ' ');
-               if ( space != NULL )
-                       *space = '\0';
-               return shortName;
-       }
-}
-
-
-const uint8_t* Reader::Entry::getContent() const
-{
-       if ( this->hasLongName() ) 
-               return ((uint8_t*)this) + sizeof(ar_hdr) + this->getLongNameSpace();
-       else
-               return ((uint8_t*)this) + sizeof(ar_hdr);
-}
-
-
-uint32_t Reader::Entry::getContentSize() const
-{
-       char temp[12];
-       strncpy(temp, this->ar_size, 10);
-       temp[10] = '\0';
-       char* endptr;
-       long size = strtol(temp, &endptr, 10);
-       // long name is included in ar_size
-       if ( this->hasLongName() ) 
-               size -= this->getLongNameSpace();
-       return size;
-}
-
-const Reader::Entry*   Reader::Entry::getNext() const
-{
-       const uint8_t* p = this->getContent() + getContentSize();
-       p = (const uint8_t*)(((uintptr_t)p+3) & (-4));  // 4-byte align
-       return (Reader::Entry*)p;
-}
-
-
-
-Reader::Reader(const uint8_t fileContent[], uint64_t fileLength, const char* path, const ObjectFile::ReaderOptions& options)
- : fPath(NULL), fOptions(options), fFileContent(NULL), fTableOfContents(NULL), fTableOfContentCount(0),
-   fSorted(false), fStringPool(NULL)
-{
-       fPath = strdup(path);
-       fFileContent = fileContent;
-       fFileLength = fileLength;
-
-       if ( strncmp((const char*)fileContent, "!<arch>\n", 8) != 0 )
-               throw "not an archive";
-       
-       if ( !options.fFullyLoadArchives ) {
-               const Entry* const firstMember = (Entry*)&fFileContent[8];
-               if ( strcmp(firstMember->getName(), SYMDEF_SORTED) == 0 )
-                       fSorted = true;
-               else if ( strcmp(firstMember->getName(), SYMDEF) == 0 )
-                       fSorted = false;
-               else
-                       throw "archive has no table of contents";
-               const uint8_t* contents = firstMember->getContent();
-               uint32_t ranlibArrayLen = SwapArchToHostInt32(*((uint32_t*)contents));
-               fTableOfContents = (const struct ranlib*)&contents[4];
-               fTableOfContentCount = ranlibArrayLen / sizeof(struct ranlib);
-               fStringPool = (const char*)&contents[ranlibArrayLen+8];
-       }
-       
-       if ( options.fTraceArchives )
-               printf("[Logging for Build & Integration] Used static archive: %s\n", fPath);
-}
-
-Reader::~Reader()
-{
-}
-
-
-
-ObjectFile::Reader* Reader::makeObjectReaderForMember(const Entry* member)
-{
-       const char* memberName = member->getName();
-       char memberPath[strlen(fPath) + strlen(memberName)+4];
-       strcpy(memberPath, fPath);
-       strcat(memberPath, "(");
-       strcat(memberPath, memberName);
-       strcat(memberPath, ")");
-       //fprintf(stderr, "using %s from %s\n", memberName, fPath);
-       try {
-               return ObjectFileMachO::MakeReader((class macho_header*)member->getContent(), memberPath, fOptions);
-       }
-       catch (const char* msg) {
-               throwf("in %s, %s", memberPath, msg);
-       }
-}
-
-const char* Reader::getPath()
-{
-       return fPath;
-}
-
-std::vector<class ObjectFile::Atom*>&  Reader::getAtoms()
-{
-       if ( fOptions.fFullyLoadArchives ) {
-               // build vector of all atoms from all .o files in this archive
-               const Entry* const start = (Entry*)&fFileContent[8];
-               const Entry* const end = (Entry*)&fFileContent[fFileLength];
-               for (const Entry* p=start; p < end; p = p->getNext()) {
-                       const char* memberName = p->getName();
-                       if ( (p==start) && (strcmp(memberName, SYMDEF_SORTED) == 0) )
-                               continue;
-                       ObjectFile::Reader* r = this->makeObjectReaderForMember(p);
-                       std::vector<class ObjectFile::Atom*>&   atoms = r->getAtoms();
-                       fAllAtoms.insert(fAllAtoms.end(), atoms.begin(), atoms.end());
-               }
-               return fAllAtoms;
-       }
-       else {
-               // return nonthing for now, getJustInTimeAtomsFor() will return atoms as needed
-               return fgEmptyList;
-       }
-}
-
-
-const struct ranlib* Reader::ranlibBinarySearch(const char* key)
-{
-       const struct ranlib* base = fTableOfContents;
-       for (uint32_t n = fTableOfContentCount; n > 0; n /= 2) {
-               const struct ranlib* pivot = &base[n/2];
-               const char* pivotStr = &fStringPool[SwapArchToHostInt32(pivot->ran_un.ran_strx)];
-               int cmp = strcmp(key, pivotStr);
-               if ( cmp == 0 )
-                       return pivot;
-               if ( cmp > 0 ) {
-                       // key > pivot 
-                       // move base to symbol after pivot
-                       base = &pivot[1];
-                       --n; 
-               }
-               else {
-                       // key < pivot 
-                       // keep same base
-               }
-       }
-       return NULL;
-}
-
-const struct ranlib* Reader::ranlibLinearSearch(const char* key)
-{
-       for (uint32_t i = 0; i < fTableOfContentCount; ++i) {
-               const struct ranlib* entry = &fTableOfContents[i];
-               const char* entryName = &fStringPool[SwapArchToHostInt32(entry->ran_un.ran_strx)];
-               if ( strcmp(key, entryName) == 0 )
-                       return entry;
-       }
-       return NULL;
-}
-
-
-void Reader::dumpTableOfContents()
-{
-       for (unsigned int i=0; i < fTableOfContentCount; ++i) {
-               const struct ranlib* e = &fTableOfContents[i];
-               printf("%s in %s\n", &fStringPool[SwapArchToHostInt32(e->ran_un.ran_strx)], ((Entry*)&fFileContent[SwapArchToHostInt32(e->ran_off)])->getName());
-       }
-}
-
-std::vector<class ObjectFile::Atom*>* Reader::getJustInTimeAtomsFor(const char* name)
-{
-       if ( fOptions.fFullyLoadArchives ) {
-               return NULL;
-       }
-       else {
-               const struct ranlib* result = NULL;
-               if ( fSorted ) {
-                       // do a binary search of table of contents looking for requested symbol
-                       result = ranlibBinarySearch(name);
-               }
-               else {
-                       // do a linear search of table of contents looking for requested symbol
-                       result = ranlibLinearSearch(name);
-               }
-               if ( result != NULL ) {
-                       const Entry* member = (Entry*)&fFileContent[SwapArchToHostInt32(result->ran_off)];
-                       if ( fInstantiatedEntries.count(member) == 0 ) {
-                               // only return these atoms once
-                               fInstantiatedEntries.insert(member);
-                               ObjectFile::Reader* r = makeObjectReaderForMember(member);
-                               //fprintf(stderr, "%s found in %s\n", name, member->getName());
-                               return new std::vector<class ObjectFile::Atom*>(r->getAtoms());
-                       }
-               }
-               //fprintf(stderr, "%s NOT found in archive %s\n", name, fPath);
-               return NULL; 
-       }
-}
-
-
-std::vector<ObjectFile::StabsInfo>*    Reader::getStabsDebugInfo()
-{
-       return NULL;
-}
-
-
-
-Reader* MakeReader(const uint8_t fileContent[], uint64_t fileLength, const char* path, const ObjectFile::ReaderOptions& options)
-{
-       return new Reader(fileContent, fileLength, path, options);
-}
-
-
-
-};
-
-
-
-
-
-
-