]> git.saurik.com Git - apple/ld64.git/blobdiff - src/Readers/ObjectFileDylibMachO.cpp
ld64-47.2.tar.gz
[apple/ld64.git] / src / Readers / ObjectFileDylibMachO.cpp
diff --git a/src/Readers/ObjectFileDylibMachO.cpp b/src/Readers/ObjectFileDylibMachO.cpp
deleted file mode 100644 (file)
index fad4dcb..0000000
+++ /dev/null
@@ -1,485 +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 ObjectFileDylibMachO {
-
-class Reader : public ObjectFile::Reader 
-{
-public:
-                                                                                               Reader(const macho_header* header, 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();
-       virtual const char*                                                             getInstallPath();
-       virtual uint32_t                                                                getTimestamp();
-       virtual uint32_t                                                                getCurrentVersion();
-       virtual uint32_t                                                                getCompatibilityVersion();
-       virtual std::vector<const char*>*                               getDependentLibraryPaths();
-       virtual bool                                                                    reExports(ObjectFile::Reader*);
-       virtual bool                                                                    isDefinitionWeak(const ObjectFile::Atom&);
-       
-private:
-       struct CStringComparor
-       {
-                bool operator()(const char* left, const char* right) { return (strcmp(left, right) > 0); }
-       };
-       typedef std::map<const char*, ObjectFile::Atom*, CStringComparor> Mapper;
-
-
-       void                                                                            init(const macho_header* header,const char* path);
-       const macho_nlist*                                                      binarySearchWithToc(const char* key, const char stringPool[], const macho_nlist symbols[], const struct dylib_table_of_contents toc[], uint32_t symbolCount);
-       const macho_nlist*                                                      binarySearch(const char* key, const char stringPool[], const macho_nlist symbols[], uint32_t symbolCount);
-       bool                                                                            hasExport(const char* name);
-       const macho_nlist*                                                      findExport(const char* name);
-       
-       const char*                                                                     fPath;
-       const macho_header*                                                     fHeader;
-       const char*                                                                     fStrings;
-       const macho_dysymtab_command*                           fDynamicInfo;
-       const macho_dylib_command*                                      fDylibID;
-       const macho_nlist*                                                      fSymbols;
-       uint32_t                                                                        fSymbolCount;
-       Mapper                                                                          fAtoms;
-       std::vector<Reader*>                                            fReExportedDylibs;
-
-       static std::vector<class ObjectFile::Atom*>     fEmptyAtomList;
-};
-
-std::vector<class ObjectFile::Atom*>   Reader::fEmptyAtomList;
-
-
-class Segment : public ObjectFile::Segment
-{
-public:
-                                                               Segment(const char* name)               { fName = name; }
-       virtual const char*                     getName() const                                 { return fName; }
-       virtual bool                            isContentReadable() const               { return true; }
-       virtual bool                            isContentWritable() const               { return false; }
-       virtual bool                            isContentExecutable() const             { return false; }
-private:
-       const char*                                     fName;
-};
-
-
-class ExportAtom : public ObjectFile::Atom
-{
-public:
-       virtual ObjectFile::Reader*                                     getFile() const                         { return &fOwner; }
-       virtual const char*                                                     getName() const                         { return fName; }
-       virtual const char*                                                     getDisplayName() const;
-       virtual Scope                                                           getScope() const                        { return ObjectFile::Atom::scopeGlobal; }
-       virtual bool                                                            isTentativeDefinition() const { return false; }
-       virtual bool                                                            isWeakDefinition() const        { return false; }
-       virtual bool                                                            isCoalesableByName() const      { return false; }
-       virtual bool                                                            isCoalesableByValue() const { return false; }
-       virtual bool                                                            isZeroFill() const                      { return false; }
-       virtual bool                                                            dontDeadStrip() const           { return false; }
-       virtual bool                                                            dontStripName() const           { return false; }
-       virtual bool                                                            isImportProxy() const           { return true; }
-       virtual uint64_t                                                        getSize() const                         { return 0; }
-       virtual std::vector<ObjectFile::Reference*>&  getReferences() const             { return fgEmptyReferenceList; }
-       virtual bool                                                            mustRemainInSection() const { return false; }
-       virtual const char*                                                     getSectionName() const          { return "._imports"; }
-       virtual Segment&                                                        getSegment() const                      { return fgImportSegment; }
-       virtual bool                                                            requiresFollowOnAtom() const{ return false; }
-       virtual ObjectFile::Atom&                                       getFollowOnAtom() const         { return *((ObjectFile::Atom*)NULL); }
-       virtual std::vector<ObjectFile::StabsInfo>*     getStabsDebugInfo() const       { return NULL; }
-       virtual uint8_t                                                         getAlignment() const            { return 0; }
-       virtual WeakImportSetting                                       getImportWeakness() const       { return fWeakImportSetting; }
-       virtual void                                                            copyRawContent(uint8_t buffer[]) const  {}
-       virtual void                                                            writeContent(bool finalLinkedImage, ObjectFile::ContentWriter&) const {}
-
-       virtual void                                                            setScope(Scope)                         { }
-       virtual void                                                            setImportWeakness(bool weakImport) { fWeakImportSetting = weakImport ? kWeakImport : kNonWeakImport; }
-
-protected:
-       friend class Reader;
-       
-                                                                                       ExportAtom(Reader& owner, const char* name)  : fOwner(owner), fName(name), fWeakImportSetting(kWeakUnset) {}
-       virtual                                                                 ~ExportAtom() {}
-       
-       Reader&                                                                 fOwner;
-       const char*                                                             fName;
-       WeakImportSetting                                               fWeakImportSetting;
-       
-       static std::vector<ObjectFile::Reference*>      fgEmptyReferenceList;
-       static Segment                                                          fgImportSegment;
-};
-
-Segment                                                                ExportAtom::fgImportSegment("__LINKEDIT");
-std::vector<ObjectFile::Reference*>    ExportAtom::fgEmptyReferenceList;
-
-const char* ExportAtom::getDisplayName() const
-{
-       static char temp[300];
-       strcpy(temp, fName);
-       strcat(temp, "$import");
-       return temp;
-}
-
-
-
-Reader::Reader(const macho_header* header, const char* path, const ObjectFile::ReaderOptions& options)
- : fHeader(header), fStrings(NULL), fDylibID(NULL), fSymbols(NULL), fSymbolCount(0)
-{
-       typedef std::pair<const macho_dylib_command*, bool> DylibAndReExportFlag;
-       std::vector<DylibAndReExportFlag>               dependentDylibs;
-
-       fPath = strdup(path);
-       const uint32_t cmd_count = header->ncmds();
-       const macho_load_command* const cmds = (macho_load_command*)((char*)header + macho_header::size);
-       // get all dylib load commands
-       const macho_load_command* cmd = cmds;
-       for (uint32_t i = 0; i < cmd_count; ++i) {
-               switch (cmd->cmd()) {
-                       case LC_LOAD_DYLIB:
-                       case LC_LOAD_WEAK_DYLIB:
-                               {
-                                       DylibAndReExportFlag info;
-                                       info.first = (struct macho_dylib_command*)cmd;
-                                       info.second = options.fFlatNamespace;
-                                       dependentDylibs.push_back(info);
-                               }
-                               break;
-               }
-               cmd = (const macho_load_command*)(((char*)cmd)+cmd->cmdsize());
-       }
-       
-       // cache interesting pointers
-       cmd = cmds;
-       for (uint32_t i = 0; i < cmd_count; ++i) {
-               switch (cmd->cmd()) {
-                       case LC_SYMTAB:
-                               {
-                                       const macho_symtab_command* symtab = (macho_symtab_command*)cmd;
-                                       fSymbolCount = symtab->nsyms();
-                                       fSymbols = (const macho_nlist*)((char*)header + symtab->symoff());
-                                       fStrings = (char*)header + symtab->stroff();
-                               }
-                               break;
-                       case LC_DYSYMTAB:
-                               fDynamicInfo = (macho_dysymtab_command*)cmd;
-                               break;
-                       case LC_ID_DYLIB:
-                               fDylibID = (macho_dylib_command*)cmd;
-                               break;
-                       case LC_SUB_UMBRELLA:
-                               if ( !options.fFlatNamespace ) {
-                                       const char* frameworkLeafName = ((macho_sub_umbrella_command*)cmd)->name();
-                                       for (std::vector<DylibAndReExportFlag>::iterator it = dependentDylibs.begin(); it != dependentDylibs.end(); it++) {
-                                               const char* dylibName = it->first->name();
-                                               const char* lastSlash = strrchr(dylibName, '/');
-                                               if ( (lastSlash != NULL) && (strcmp(&lastSlash[1], frameworkLeafName) == 0) )
-                                                       it->second = true;
-                                       }
-                               }
-                               break;
-                       case LC_SUB_LIBRARY:
-                               if ( !options.fFlatNamespace ) {
-                                       const char* dylibBaseName = ((macho_sub_library_command*)cmd)->name();
-                                       for (std::vector<DylibAndReExportFlag>::iterator it = dependentDylibs.begin(); it != dependentDylibs.end(); it++) {
-                                               const char* dylibName = it->first->name();
-                                               const char* lastSlash = strrchr(dylibName, '/');
-                                               const char* leafStart = &lastSlash[1];
-                                               if ( lastSlash == NULL )
-                                                       leafStart = dylibName;
-                                               const char* firstDot = strchr(leafStart, '.');
-                                               int len = strlen(leafStart);
-                                               if ( firstDot != NULL )
-                                                       len = firstDot - leafStart;
-                                               if ( strncmp(leafStart, dylibBaseName, len) == 0 )
-                                                       it->second = true;
-                                       }
-                               }
-                               break;
-               }
-               cmd = (const macho_load_command*)(((char*)cmd)+cmd->cmdsize());
-       }
-       
-       // load dylibs we need to re-export
-       for (std::vector<DylibAndReExportFlag>::iterator it = dependentDylibs.begin(); it != dependentDylibs.end(); it++) {
-               if ( it->second ) {
-                       // printf("%s need to re-export %s\n", path, it->first->name());
-                       //fReExportedDylibs.push_back(
-               }
-       }
-}
-
-
-Reader::~Reader()
-{
-}
-
-const char*     Reader::getPath()
-{
-       return fPath;
-}
-
-
-std::vector<class ObjectFile::Atom*>&  Reader::getAtoms()
-{
-       return fEmptyAtomList;
-}
-
-
-
-const macho_nlist* Reader::binarySearchWithToc(const char* key, const char stringPool[], const macho_nlist symbols[], 
-                                                                                               const struct dylib_table_of_contents toc[], uint32_t symbolCount)
-{
-       int32_t high = symbolCount-1;
-       int32_t mid = symbolCount/2;
-               
-       for (int32_t low = 0; low <= high; mid = (low+high)/2) {
-               const uint32_t index = ENDIAN_READ32(toc[mid].symbol_index);
-               const macho_nlist* pivot = &symbols[index];
-               const char* pivotStr = &stringPool[pivot->n_strx()];
-               int cmp = strcmp(key, pivotStr);
-               if ( cmp == 0 )
-                       return pivot;
-               if ( cmp > 0 ) {
-                       // key > pivot 
-                       low = mid + 1;
-               }
-               else {
-                       // key < pivot 
-                       high = mid - 1;
-               }
-       }
-       return NULL;
-}
-
-
-const macho_nlist* Reader::binarySearch(const char* key, const char stringPool[], const macho_nlist symbols[], uint32_t symbolCount)
-{
-       const macho_nlist* base = symbols;
-       for (uint32_t n = symbolCount; n > 0; n /= 2) {
-               const macho_nlist* pivot = &base[n/2];
-               const char* pivotStr = &stringPool[pivot->n_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 macho_nlist* Reader::findExport(const char* name)
-{
-       if ( fDynamicInfo->tocoff() == 0 )
-               return binarySearch(name, fStrings, &fSymbols[fDynamicInfo->iextdefsym()], fDynamicInfo->nextdefsym());
-       else {
-               return binarySearchWithToc(name, fStrings, fSymbols, (dylib_table_of_contents*)((char*)fHeader + fDynamicInfo->tocoff()), 
-                                                               fDynamicInfo->nextdefsym());
-       }
-}
-
-bool Reader::hasExport(const char* name)
-{
-       return ( findExport(name) != NULL );
-}
-
-std::vector<class ObjectFile::Atom*>* Reader::getJustInTimeAtomsFor(const char* name)
-{
-       std::vector<class ObjectFile::Atom*>* atoms = NULL;
-       // search exports
-       if ( this->hasExport(name) ) {
-               // see if this atom already synthesized
-               ObjectFile::Atom* atom = NULL;
-               Mapper::iterator pos = fAtoms.find(name);
-               if ( pos != fAtoms.end() ) {
-                       atom = pos->second;
-               }
-               else {
-                       atom = new ExportAtom(*this, name);
-                       fAtoms[name] = atom;
-               }
-               // return a vector of one atom
-               atoms = new std::vector<class ObjectFile::Atom*>;
-               atoms->push_back(atom);
-               return atoms;
-       }
-       
-       // check re-exports
-       for (std::vector<Reader*>::iterator it = fReExportedDylibs.begin(); it != fReExportedDylibs.end(); it++) {
-               Reader* reExportedReader = *it;
-               atoms = reExportedReader->getJustInTimeAtomsFor(name);
-               if ( atoms != NULL )
-                       return atoms;
-       }
-       
-       return NULL;
-}
-
-
-std::vector<ObjectFile::StabsInfo>*    Reader::getStabsDebugInfo()
-{
-       return NULL;
-}
-
-const char*    Reader::getInstallPath()
-{
-       return fDylibID->name();
-}
-
-uint32_t Reader::getTimestamp()
-{
-       return fDylibID->timestamp();
-}
-
-uint32_t Reader::getCurrentVersion()
-{
-       return fDylibID->current_version();
-}
-
-uint32_t Reader::getCompatibilityVersion()
-{
-       return fDylibID->compatibility_version();
-}
-
-std::vector<const char*>* Reader::getDependentLibraryPaths()
-{
-       std::vector<const char*>* result = new std::vector<const char*>;
-       const uint32_t cmd_count = fHeader->ncmds();
-       const macho_load_command* const cmds = (macho_load_command*)((char*)fHeader + macho_header::size);
-       const macho_load_command* cmd = cmds;
-       for (uint32_t i = 0; i < cmd_count; ++i) {
-               switch (cmd->cmd()) {
-                       case LC_LOAD_DYLIB:
-                       case LC_LOAD_WEAK_DYLIB:
-                               {
-                                       result->push_back(((struct macho_dylib_command*)cmd)->name());
-                               }
-                               break;
-               }
-               cmd = (const macho_load_command*)(((char*)cmd)+cmd->cmdsize());
-       }
-       return result;
-}
-
-bool Reader::reExports(ObjectFile::Reader* child)
-{
-       // A dependent dylib is re-exported under two conditions:
-       //  1) parent contains LC_SUB_UMBRELLA or LC_SUB_LIBRARY with child name
-       {
-               const uint32_t cmd_count = fHeader->ncmds();
-               const macho_load_command* const cmds = (macho_load_command*)((char*)fHeader + macho_header::size);
-               const macho_load_command* cmd = cmds;
-               for (uint32_t i = 0; i < cmd_count; ++i) {
-                       switch (cmd->cmd()) {
-                               case LC_SUB_UMBRELLA:
-                                       {
-                                               const char* frameworkLeafName = ((macho_sub_umbrella_command*)cmd)->name();
-                                               const char* dylibName = child->getPath();
-                                               const char* lastSlash = strrchr(dylibName, '/');
-                                               if ( (lastSlash != NULL) && (strcmp(&lastSlash[1], frameworkLeafName) == 0) )
-                                                       return true;
-                                       }
-                                       break;
-                               case LC_SUB_LIBRARY:
-                                       {
-                                               const char* dylibBaseName = ((macho_sub_library_command*)cmd)->name();
-                                               const char* dylibName = child->getPath();
-                                               const char* lastSlash = strrchr(dylibName, '/');
-                                               const char* leafStart = &lastSlash[1];
-                                               if ( lastSlash == NULL )
-                                                       leafStart = dylibName;
-                                               const char* firstDot = strchr(leafStart, '.');
-                                               int len = strlen(leafStart);
-                                               if ( firstDot != NULL )
-                                                       len = firstDot - leafStart;
-                                               if ( strncmp(leafStart, dylibBaseName, len) == 0 )
-                                                       return true;
-                                       }
-                                       break;
-                       }
-                       cmd = (const macho_load_command*)(((char*)cmd)+cmd->cmdsize());
-               }
-       }
-       
-       //  2) child contains LC_SUB_FRAMEWORK with parent name 
-       {
-               const uint32_t cmd_count = ((Reader*)child)->fHeader->ncmds();
-               const macho_load_command* const cmds = (macho_load_command*)((char*)(((Reader*)child)->fHeader) + macho_header::size);
-               const macho_load_command* cmd = cmds;
-               for (uint32_t i = 0; i < cmd_count; ++i) {
-                       switch (cmd->cmd()) {
-                               case LC_SUB_FRAMEWORK:
-                                       {
-                                               const char* frameworkLeafName = ((macho_sub_framework_command*)cmd)->name();
-                                               const char* parentName = this->getPath();
-                                               const char* lastSlash = strrchr(parentName, '/');
-                                               if ( (lastSlash != NULL) && (strcmp(&lastSlash[1], frameworkLeafName) == 0) )
-                                                       return true;
-                                       }
-                                       break;
-                       }
-                       cmd = (const macho_load_command*)(((char*)cmd)+cmd->cmdsize());
-               }
-       }
-       
-       
-       return false;
-}
-
-bool Reader::isDefinitionWeak(const ObjectFile::Atom& atom)
-{
-       const macho_nlist* sym = findExport(atom.getName());
-       if ( sym != NULL ) {
-               if ( (sym->n_desc() & N_WEAK_DEF) != 0 )
-                       return true;
-       }
-       return false;
-}
-
-
-
-Reader* MakeReader(const macho_header* mh, const char* path, const ObjectFile::ReaderOptions& options)
-{
-       return new Reader(mh, path, options);
-}
-
-
-
-};
-
-
-
-
-
-
-