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; }
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; }
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;
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);
}
// 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";
{
// 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;
}
}
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;
+ }
+}