]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/MachOReaderRelocatable.hpp
ld64-97.2.tar.gz
[apple/ld64.git] / src / ld / MachOReaderRelocatable.hpp
index e6a182c0aa056f0cb246d4d5c40d920eec970822..0792f51f9ccc4dce5efd95b6383cdbb2e0e4efb2 100644 (file)
@@ -1058,6 +1058,13 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                if ( !fOwner.fOptions.fNoEHLabels ) 
                                        fSymbolTableInclusion = ObjectFile::Atom::kSymbolTableIn;
                        }
+                       else if ( (strncmp(fSection->sectname(), "__objc_classrefs", 16) == 0) && (strcmp(fSection->segname(), "__DATA") == 0) ) {
+                               fSynthesizedName = "objc-class-pointer-name-PENDING";
+                               fScope = ObjectFile::Atom::scopeLinkageUnit;
+                               owner.fAtomsPendingAName.push_back(this);
+                               owner.fSectionsWithAtomsPendingAName.insert(fSection);
+                               fKind = ObjectFile::Atom::kWeakDefinition;
+                       }
                        else if ( section == owner.fUTF16Section ) {
                                if ( fOwner.fOptions.fForFinalLinkedImage ) {
                                        fDontDeadStrip = false;
@@ -1355,6 +1362,16 @@ void AnonymousAtom<A>::resolveName()
                if ( funcAtom != NULL )
                        asprintf((char**)&fSynthesizedName, "%s.lsda", funcAtom->getDisplayName());
        }
+       else if ( (strncmp(fSection->sectname(),  "__objc_classrefs", 16) == 0) && (strcmp(fSection->segname(), "__DATA") == 0) ) {
+               std::vector<ObjectFile::Reference*>& references = this->getReferences();
+               if ( references.size() != 1 )
+                       throwf("__objc_classrefs element missing reloc (count=%ld) for target class in %s", references.size(), fOwner.getPath());
+               const char* targetName = references[0]->getTargetName();
+               if ( strncmp(targetName, "_OBJC_CLASS_$_", 14) == 0 )
+                       asprintf((char**)&fSynthesizedName, "objc-class-ref-to-%s", &targetName[14]);
+               else
+                       asprintf((char**)&fSynthesizedName, "objc-class-ref-to-%s", targetName);
+       }
 }
 
 
@@ -1552,7 +1569,7 @@ public:
        virtual ObjectFile::Atom::Scope                         getScope() const                                { return ObjectFile::Atom::scopeLinkageUnit; }
        virtual ObjectFile::Atom::DefinitionKind        getDefinitionKind() const               { return ObjectFile::Atom::kWeakDefinition; }
        virtual ObjectFile::Atom::ContentType           getContentType() const                  { return fStart ? ObjectFile::Atom::kSectionStart : ObjectFile::Atom::kSectionEnd; }
-       virtual bool                                                            isZeroFill() const                              { return false; }
+       virtual bool                                                            isZeroFill() const                              { return fZeroFill; }
        virtual bool                                                            isThumb() const                                 { return false; }
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
        virtual bool                                                            dontDeadStrip() const                   { return false; }
@@ -1609,6 +1626,7 @@ protected:
        const char*                                                                     fSectionName;
        const char*                                                                     fDisplayName;
        bool                                                                            fStart;
+       bool                                                                            fZeroFill;
        static std::vector<ObjectFile::Reference*>      fgNoReferences;
 };
 
@@ -1620,7 +1638,7 @@ std::vector<ObjectFile::Reference*> SectionBoundaryAtom<A>::fgNoReferences;
 //                     section$end$__DATA$__my
 template <typename A>
 SectionBoundaryAtom<A>::SectionBoundaryAtom(Reader<A>& owner, bool start, const char* symbolName, const char* segSectName)
- : fOwner(owner), fSymbolName(symbolName), fSectionName(NULL), fStart(start)
+ : fOwner(owner), fSymbolName(symbolName), fSectionName(NULL), fStart(start), fZeroFill(false)
 {
        const char* segSectDividor = strrchr(segSectName, '$');
        if ( segSectDividor == NULL )
@@ -1633,8 +1651,11 @@ SectionBoundaryAtom<A>::SectionBoundaryAtom(Reader<A>& owner, bool start, const
        strlcpy(segName, segSectName, segNameLen+1);
        if ( strcmp(segName, "__TEXT") == 0 )
                fSegment = new Segment("__TEXT", true, false, true);
-       else if ( strcmp(segName, "__DATA") == 0 ) 
+       else if ( strcmp(segName, "__DATA") == 0 ) {
                fSegment = new Segment("__DATA", true, true, false);
+               if ( (strcmp(fSectionName, "__bss") == 0) || (strcmp(fSectionName, "__common") == 0) )
+                       fZeroFill = true;
+       }       
        else 
                fSegment = new Segment(strdup(segName), true, true, false);
 
@@ -1801,6 +1822,7 @@ class Reader : public ObjectFile::Reader
 {
 public:
        static bool                                                                             validFile(const uint8_t* fileContent, bool subtypeMustMatch=false, cpu_subtype_t subtype=0);
+       static const char*                                                              fileKind(const uint8_t* fileContent);
                                                                                                        Reader(const uint8_t* fileContent, const char* path, time_t modTime, 
                                                                                                                const ObjectFile::ReaderOptions& options, uint32_t ordinalBase);
        virtual                                                                                 ~Reader() {}
@@ -2268,6 +2290,10 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                else if ((strcmp(sect->sectname(), "__cfstring") == 0) && (strcmp(sect->segname(), "__DATA") == 0)) {
                                        atomSize = 4 * sizeof(pint_t);
                                }
+                               // special case class reference sections
+                               else if ( (strncmp(sect->sectname(), "__objc_classrefs", 16) == 0) && (strcmp(sect->segname(), "__DATA") == 0) ) {
+                                       atomSize = sizeof(pint_t);;
+                               }
                                break;
                }
                if ( atomSize != 0 ) {
@@ -3214,7 +3240,9 @@ typename A::P::uint_t ObjectFileAddressSpace<A>::getEncodedP(pint_t& addr, pint_
                        // do nothing
                        break;
                case DW_EH_PE_pcrel:
-                       result += startAddr;
+                       // <rdar://problem/7200658> pc-rel sdata4 should return zero if content is zero
+                       if ( (result != 0) || ((encoding & DW_EH_PE_indirect) != 0) )
+                               result += startAddr;
                        break;
                case DW_EH_PE_textrel:
                        throw "DW_EH_PE_textrel pointer encoding not supported";
@@ -4127,6 +4155,85 @@ bool Reader<arm>::validFile(const uint8_t* fileContent, bool subtypeMustMatch, c
        return true;
 }
 
+
+template <>
+const char* Reader<ppc>::fileKind(const uint8_t* fileContent)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return NULL;
+       if ( header->cputype() != CPU_TYPE_POWERPC )
+               return NULL;
+       switch ( header->cpusubtype() ) {
+               case CPU_SUBTYPE_POWERPC_750:
+                       return "ppc750";
+               case CPU_SUBTYPE_POWERPC_7400:
+                       return "ppc7400";
+               case CPU_SUBTYPE_POWERPC_7450:
+                       return "ppc7450";
+               case CPU_SUBTYPE_POWERPC_970:
+                       return "ppc970";
+               case CPU_SUBTYPE_POWERPC_ALL:
+                       return "ppc";
+       }
+       return "ppc???";
+}
+
+template <>
+const char* Reader<ppc64>::fileKind(const uint8_t* fileContent)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return NULL;
+       if ( header->cputype() != CPU_TYPE_POWERPC64 )
+               return NULL;
+       return "ppc64";
+}
+
+template <>
+const char* Reader<x86>::fileKind(const uint8_t* fileContent)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return NULL;
+       if ( header->cputype() != CPU_TYPE_I386 )
+               return NULL;
+       return "i386";
+}
+
+template <>
+const char* Reader<x86_64>::fileKind(const uint8_t* fileContent)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return NULL;
+       if ( header->cputype() != CPU_TYPE_X86_64 )
+               return NULL;
+       return "x86_64";
+}
+
+template <>
+const char* Reader<arm>::fileKind(const uint8_t* fileContent)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return NULL;
+       if ( header->cputype() != CPU_TYPE_ARM )
+               return NULL;
+       switch ( header->cpusubtype() ) {
+               case CPU_SUBTYPE_ARM_V4T:
+                       return "armv4t";
+               case CPU_SUBTYPE_ARM_V5TEJ:
+                       return "armv5";
+               case CPU_SUBTYPE_ARM_V6:
+                       return "armv6";
+               case CPU_SUBTYPE_ARM_V7:
+                       return "armv7";
+       }
+       return "arm???";
+}
+
+
 template <typename A>
 bool Reader<A>::isWeakImportSymbol(const macho_nlist<P>* sym)
 {