]> git.saurik.com Git - apple/ld64.git/blobdiff - src/MachOReaderDylib.hpp
ld64-59.2.tar.gz
[apple/ld64.git] / src / MachOReaderDylib.hpp
index e9ff931afa4d802fc1bdb39435b710ab1b912318..9cadfbbe3c7446486ce33078bbb6ca03c610254e 100644 (file)
@@ -85,6 +85,7 @@ public:
        virtual Scope                                                           getScope() const                        { return ObjectFile::Atom::scopeGlobal; }
        virtual DefinitionKind                                          getDefinitionKind() const       { return fWeakDefinition ? kExternalWeakDefinition : kExternalDefinition; }
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableIn; }
+       virtual bool                                                            dontDeadStrip() const           { return false; }
        virtual bool                                                            isZeroFill() const                      { return false; }
        virtual uint64_t                                                        getSize() const                         { return 0; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const             { return fgEmptyReferenceList; }
@@ -131,10 +132,11 @@ template <typename A>
 class Reader : public ObjectFile::Reader
 {
 public:
-       static bool                                                                             validFile(const uint8_t* fileContent);
-       static Reader<A>*                                                               make(const uint8_t* fileContent, uint64_t fileLength, const char* path, const ObjectFile::ReaderOptions& options)
-                                                                                                               { return new Reader<A>(fileContent, fileLength, path, options); }
-       virtual                                                                         ~Reader() {}
+       static bool                                                                             validFile(const uint8_t* fileContent, bool executableOrDylib);
+       static Reader<A>*                                                               make(const uint8_t* fileContent, uint64_t fileLength, const char* path, 
+                                                                                                               bool executableOrDylib, const ObjectFile::ReaderOptions& options)
+                                                                                                               { return new Reader<A>(fileContent, fileLength, path, executableOrDylib, options); }
+       virtual                                                                                 ~Reader() {}
 
        virtual const char*                                                             getPath()                                       { return fPath; }
        virtual time_t                                                                  getModificationTime()           { return 0; }
@@ -168,7 +170,8 @@ private:
 
        struct PathAndFlag { const char* path; bool reExport; };
 
-                                                                                               Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path, const ObjectFile::ReaderOptions& options);
+                                                                                               Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path,
+                                                                                                               bool executableOrDylib, const ObjectFile::ReaderOptions& options);
 
        const char*                                                                     fPath;
        const char*                                                                     fParentUmbrella;
@@ -191,11 +194,11 @@ bool                                                                      Reader<A>::fgLogHashtable = false;
 
 
 template <typename A>
-Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path, const ObjectFile::ReaderOptions& options)
+Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path, bool executableOrDylib, const ObjectFile::ReaderOptions& options)
        : fParentUmbrella(NULL), fDylibInstallPath(NULL), fDylibTimeStamp(0), fDylibtCurrentVersion(0), fDylibCompatibilityVersion(0)
 {
        // sanity check
-       if ( ! validFile(fileContent) )
+       if ( ! validFile(fileContent, executableOrDylib) )
                throw "not a valid mach-o object file";
 
        fPath = strdup(path);
@@ -301,7 +304,7 @@ Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* p
        }
 
        // validate minimal load commands
-       if ( fDylibInstallPath == NULL ) 
+       if ( (fDylibInstallPath == NULL) && (header->filetype() != MH_EXECUTE) ) 
                throw "dylib missing LC_ID_DYLIB load command";
        if ( symbolTable == NULL )
                throw "dylib missing LC_SYMTAB load command";
@@ -404,8 +407,9 @@ bool Reader<A>::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 char* childInstallPath = child->getInstallPath();
        for (typename std::vector<PathAndFlag>::iterator it = fDependentLibraryPaths.begin(); it != fDependentLibraryPaths.end(); it++) {
-               if ( it->reExport && (strcmp(it->path, child->getPath()) == 0) )
+               if ( it->reExport && ((strcmp(it->path, child->getPath()) == 0) || ((childInstallPath!=NULL) && (strcmp(it->path, childInstallPath)==0))) )
                        return true;
        }
 
@@ -422,44 +426,80 @@ bool Reader<A>::reExports(ObjectFile::Reader* child)
 }
 
 template <>
-bool Reader<ppc>::validFile(const uint8_t* fileContent)
+bool Reader<ppc>::validFile(const uint8_t* fileContent, bool executableOrDylib)
 {
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        if ( header->magic() != MH_MAGIC )
                return false;
        if ( header->cputype() != CPU_TYPE_POWERPC )
                return false;
-       if ( (header->filetype() != MH_DYLIB) && (header->filetype() != MH_DYLIB_STUB)  )
-               return false;
-       return true;
+       switch ( header->filetype() ) {
+               case MH_DYLIB:
+               case MH_DYLIB_STUB:
+                       return true;
+               case MH_EXECUTE:
+                       return executableOrDylib;
+               default:
+                       return false;
+       }
 }
 
 template <>
-bool Reader<ppc64>::validFile(const uint8_t* fileContent)
+bool Reader<ppc64>::validFile(const uint8_t* fileContent, bool executableOrDylib)
 {
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        if ( header->magic() != MH_MAGIC_64 )
                return false;
        if ( header->cputype() != CPU_TYPE_POWERPC64 )
                return false;
-       if ( (header->filetype() != MH_DYLIB) && (header->filetype() != MH_DYLIB_STUB)  )
-               return false;
-       return true;
+       switch ( header->filetype() ) {
+               case MH_DYLIB:
+               case MH_DYLIB_STUB:
+                       return true;
+               case MH_EXECUTE:
+                       return executableOrDylib;
+               default:
+                       return false;
+       }
 }
 
 template <>
-bool Reader<x86>::validFile(const uint8_t* fileContent)
+bool Reader<x86>::validFile(const uint8_t* fileContent, bool executableOrDylib)
 {
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        if ( header->magic() != MH_MAGIC )
                return false;
        if ( header->cputype() != CPU_TYPE_I386 )
                return false;
-       if ( (header->filetype() != MH_DYLIB) && (header->filetype() != MH_DYLIB_STUB)  )
-               return false;
-       return true;
+       switch ( header->filetype() ) {
+               case MH_DYLIB:
+               case MH_DYLIB_STUB:
+                       return true;
+               case MH_EXECUTE:
+                       return executableOrDylib;
+               default:
+                       return false;
+       }
 }
 
+template <>
+bool Reader<x86_64>::validFile(const uint8_t* fileContent, bool executableOrDylib)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC_64 )
+               return false;
+       if ( header->cputype() != CPU_TYPE_X86_64 )
+               return false;
+       switch ( header->filetype() ) {
+               case MH_DYLIB:
+               case MH_DYLIB_STUB:
+                       return true;
+               case MH_EXECUTE:
+                       return executableOrDylib;
+               default:
+                       return false;
+       }
+}