]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/parsers/macho_relocatable_file.cpp
ld64-128.2.tar.gz
[apple/ld64.git] / src / ld / parsers / macho_relocatable_file.cpp
index abd44fa106bd04b945f4ce801a42bc81b39bc3af..e79d2618c01215181f594fdcc15b39e98bc499d9 100644 (file)
@@ -168,7 +168,6 @@ protected:
                                                                _beginAtoms(NULL), _endAtoms(NULL), _hasAliases(false) { }
 
 
-       bool                                                    addRelocFixup_powerpc(class Parser<A>& parser,const macho_relocation_info<typename A::P>* reloc);
        Atom<A>*                                                findContentAtomByAddress(pint_t addr, class Atom<A>* start, class Atom<A>* end);
        uint32_t                                                x86_64PcRelOffset(uint8_t r_type);
        static const char*                              makeSegmentName(const macho_section<typename A::P>* s);
@@ -1128,31 +1127,6 @@ Parser<A>::Parser(const uint8_t* fileContent, uint64_t fileLength, const char* p
 {
 }
 
-template <>
-bool Parser<ppc>::validFile(const uint8_t* fileContent, bool, cpu_subtype_t)
-{
-       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_OBJECT )
-               return false;
-       return true;
-}
-
-template <>
-bool Parser<ppc64>::validFile(const uint8_t* fileContent, bool, cpu_subtype_t)
-{
-       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_OBJECT )
-               return false;
-       return true;
-}
 
 template <>
 bool Parser<x86>::validFile(const uint8_t* fileContent, bool, cpu_subtype_t)
@@ -1202,39 +1176,6 @@ bool Parser<arm>::validFile(const uint8_t* fileContent, bool subtypeMustMatch, c
 }
 
 
-template <>
-const char* Parser<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* Parser<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* Parser<x86>::fileKind(const uint8_t* fileContent)
@@ -1688,8 +1629,6 @@ ld::relocatable::File* Parser<A>::parse(const ParserOptions& opts)
 
 
 
-template <> uint8_t Parser<ppc>::loadCommandSizeMask()         { return 0x03; }
-template <> uint8_t Parser<ppc64>::loadCommandSizeMask()       { return 0x07; }
 template <> uint8_t Parser<x86>::loadCommandSizeMask()         { return 0x03; }
 template <> uint8_t Parser<x86_64>::loadCommandSizeMask()      { return 0x07; }
 template <> uint8_t Parser<arm>::loadCommandSizeMask()         { return 0x03; }
@@ -2524,9 +2463,6 @@ void Parser<A>::addFixups(const SourceLocation& src, ld::Fixup::Kind setKind, co
                        case ld::Fixup::kindStoreThumbBranch22:
                                firstKind = ld::Fixup::kindStoreTargetAddressThumbBranch22;
                                break;
-                       case ld::Fixup::kindStorePPCBranch24:
-                               firstKind = ld::Fixup::kindStoreTargetAddressPPCBranch24;
-                               break;
                        default:
                                combined = false;
                                cl = ld::Fixup::k1of2;
@@ -3626,6 +3562,8 @@ ld::Section::Type Section<A>::sectionType(const macho_section<typename A::P>* se
                                        return ld::Section::typeCode;
                                else if ( strcmp(sect->sectname(), "__StaticInit") == 0 )
                                        return ld::Section::typeCode;
+                               else if ( strcmp(sect->sectname(), "__constructor") == 0 )
+                                       return ld::Section::typeInitializerPointers;
                        }
                        else if ( strcmp(sect->segname(), "__DATA") == 0 ) {
                                if ( strcmp(sect->sectname(), "__cfstring") == 0 ) 
@@ -3705,8 +3643,6 @@ uint32_t Section<A>::sectionNum(class Parser<A>& parser) const
                return 1 + (this->_machOSection - parser.firstMachOSection());
 }
 
-// libunwind does not support ppc64
-template <> uint32_t CFISection<ppc64>::cfiCount() { return 0; }
 // arm does not have zero cost exceptions
 template <> uint32_t CFISection<arm>::cfiCount() { return 0; }
 
@@ -3827,32 +3763,7 @@ void CFISection<x86>::cfiParse(class Parser<x86>& parser, uint8_t* buffer,
 }
 
 
-// need to change libunwind parseCFIs() to work for ppc
-template <>
-void CFISection<ppc>::cfiParse(class Parser<ppc>& parser, uint8_t* buffer, 
-                                                                       libunwind::CFI_Atom_Info<CFISection<ppc>::OAS>::CFI_Atom_Info cfiArray[], 
-                                                                       uint32_t count)
-{
-       // create ObjectAddressSpace object for use by libunwind
-       OAS oas(*this, (uint8_t*)this->file().fileContent()+this->_machOSection->offset());
-       
-       // use libuwind to parse __eh_frame data into array of CFI_Atom_Info
-       const char* msg;
-       msg = libunwind::DwarfInstructions<OAS, libunwind::Registers_ppc>::parseCFIs(
-                                                       oas, this->_machOSection->addr(), this->_machOSection->size(), 
-                                                       cfiArray, count, (void*)&parser, warnFunc);
-       if ( msg != NULL ) 
-               throwf("malformed __eh_frame section: %s", msg);
-}
 
-template <>
-void CFISection<ppc64>::cfiParse(class Parser<ppc64>& parser, uint8_t* buffer, 
-                                                                       libunwind::CFI_Atom_Info<CFISection<ppc64>::OAS>::CFI_Atom_Info cfiArray[], 
-                                                                       uint32_t count)
-{
-       // libunwind does not support ppc64
-       assert(count == 0);
-}
 
 template <>
 void CFISection<arm>::cfiParse(class Parser<arm>& parser, uint8_t* buffer, 
@@ -3900,8 +3811,6 @@ uint32_t CFISection<A>::appendAtoms(class Parser<A>& parser, uint8_t* p,
 template <> bool CFISection<x86_64>::bigEndian() { return false; }
 template <> bool CFISection<x86>::bigEndian() { return false; }
 template <> bool CFISection<arm>::bigEndian() { return false; }
-template <> bool CFISection<ppc>::bigEndian() { return true; }
-template <> bool CFISection<ppc64>::bigEndian() { return true; }
 
 
 template <>
@@ -3951,30 +3860,6 @@ void CFISection<x86>::addCiePersonalityFixups(class Parser<x86>& parser, const C
 }
 
 
-template <>
-void CFISection<ppc>::addCiePersonalityFixups(class Parser<ppc>& parser, const CFI_Atom_Info* cieInfo)
-{
-       uint8_t personalityEncoding = cieInfo->u.cieInfo.personality.encodingOfTargetAddress;
-       if ( (personalityEncoding == 0x9B) || (personalityEncoding == 0x90) ) {
-               uint32_t offsetInCFI = cieInfo->u.cieInfo.personality.offsetInCFI;
-               uint32_t nlpAddr = cieInfo->u.cieInfo.personality.targetAddress;
-               Atom<ppc>* cieAtom = this->findAtomByAddress(cieInfo->address);
-               Atom<ppc>* nlpAtom = parser.findAtomByAddress(nlpAddr);
-               assert(nlpAtom->contentType() == ld::Atom::typeNonLazyPointer);
-               Parser<ppc>::SourceLocation src(cieAtom, cieInfo->u.cieInfo.personality.offsetInCFI);
-
-               parser.addFixup(src, ld::Fixup::k1of4, ld::Fixup::kindSetTargetAddress, ld::Fixup::bindingByContentBound, nlpAtom);
-               parser.addFixup(src, ld::Fixup::k2of4, ld::Fixup::kindSubtractTargetAddress, cieAtom);
-               parser.addFixup(src, ld::Fixup::k3of4, ld::Fixup::kindSubtractAddend, offsetInCFI);
-               parser.addFixup(src, ld::Fixup::k4of4, ld::Fixup::kindStoreBigEndian32);
-       }
-       else if ( personalityEncoding != 0 ) {
-               throwf("unsupported address encoding (%02X) of personality function in CIE", 
-                                       personalityEncoding);
-       }
-}
-
-
 template <typename A>
 void CFISection<A>::addCiePersonalityFixups(class Parser<A>& parser, const CFI_Atom_Info* cieInfo)
 {
@@ -4369,6 +4254,8 @@ SymboledSection<A>::SymboledSection(Parser<A>& parser, File<A>& f, const macho_s
                case S_REGULAR:
                        if ( strncmp(s->sectname(), "__gcc_except_tab", 16) == 0 )
                                _type = ld::Atom::typeLSDA;
+                       else if ( this->type() == ld::Section::typeInitializerPointers )
+                               _type = ld::Atom::typeInitializerPointers;
                        break;
        }
 }
@@ -4714,17 +4601,6 @@ ld::Fixup::Kind NonLazyPointerSection<arm>::fixupKind()
        return ld::Fixup::kindStoreLittleEndian32;
 }
 
-template <>
-ld::Fixup::Kind NonLazyPointerSection<ppc>::fixupKind()
-{
-       return ld::Fixup::kindStoreBigEndian32;
-}
-
-template <>
-ld::Fixup::Kind NonLazyPointerSection<ppc64>::fixupKind()
-{
-       return ld::Fixup::kindStoreBigEndian64;
-}
 
 template <>
 void NonLazyPointerSection<x86_64>::makeFixups(class Parser<x86_64>& parser, const struct Parser<x86_64>::CFI_CU_InfoArrays&)
@@ -5654,406 +5530,6 @@ bool Section<x86>::addRelocFixup(class Parser<x86>& parser, const macho_relocati
 
 
        
-//
-// ppc and ppc64 both use the same relocations, so process them in one common routine
-//
-template <typename A>
-bool Section<A>::addRelocFixup_powerpc(class Parser<A>& parser,
-                                                                                 const macho_relocation_info<typename A::P>* reloc)
-{
-       const macho_section<P>* sect = this->machoSection();
-       bool result = false;
-       uint32_t srcAddr;
-       uint32_t dstAddr;
-       uint32_t* fixUpPtr;
-       int32_t displacement = 0;
-       uint32_t instruction = 0;
-       int16_t lowBits;
-       pint_t contentValue = 0;
-       typename Parser<A>::SourceLocation      src;
-       typename Parser<A>::TargetDesc          target;
-       
-       if ( (reloc->r_address() & R_SCATTERED) == 0 ) {
-               srcAddr = sect->addr() + reloc->r_address();
-               src.atom = this->findAtomByAddress(srcAddr);
-               src.offsetInAtom = srcAddr - src.atom->_objAddress;
-               const macho_relocation_info<P>* nextReloc = &reloc[1];
-               fixUpPtr = (uint32_t*)(file().fileContent() + sect->offset() + reloc->r_address());
-               if ( reloc->r_type() != PPC_RELOC_PAIR )
-                       instruction = BigEndian::get32(*fixUpPtr);
-               if ( reloc->r_extern() ) {
-                       target.atom = NULL;
-                       const macho_nlist<P>& targetSymbol = parser.symbolFromIndex(reloc->r_symbolnum());
-                       target.name = parser.nameFromSymbol(targetSymbol);
-                       target.weakImport = parser.weakImportFromSymbol(targetSymbol);
-               }
-               switch ( reloc->r_type() ) {
-                       case PPC_RELOC_BR24:
-                               assert((instruction & 0x4C000000) == 0x48000000);
-                               displacement = (instruction & 0x03FFFFFC);
-                               if ( (displacement & 0x02000000) != 0 )
-                                       displacement |= 0xFC000000;
-                               if ( reloc->r_extern() ) {
-                                       target.addend = srcAddr + displacement;
-                               }
-                               else {
-                                       dstAddr = srcAddr + displacement;
-                                       parser.findTargetFromAddressAndSectionNum(dstAddr, reloc->r_symbolnum(), target);
-                               }
-                               // special case "calls" for dtrace 
-                               if ( (target.name != NULL) && (strncmp(target.name, "___dtrace_probe$", 16) == 0) ) {
-                                       parser.addFixup(src, ld::Fixup::k1of1,
-                                                                                                                       ld::Fixup::kindStorePPCDtraceCallSiteNop, false, target.name);
-                                       parser.addDtraceExtraInfos(src, &target.name[16]);
-                               }
-                               else if ( (target.name != NULL) && (strncmp(target.name, "___dtrace_isenabled$", 20) == 0) ) {
-                                       parser.addFixup(src, ld::Fixup::k1of1, 
-                                                                                                                       ld::Fixup::kindStorePPCDtraceIsEnableSiteClear, false, target.name);
-                                       parser.addDtraceExtraInfos(src, &target.name[20]);
-                               }
-                               else {
-                                       parser.addFixups(src, ld::Fixup::kindStorePPCBranch24, target);
-                               }
-                               break;
-                       case PPC_RELOC_BR14:
-                               displacement = (instruction & 0x0000FFFC);
-                               if ( (displacement & 0x00008000) != 0 )
-                                       displacement |= 0xFFFF0000;
-                               if ( reloc->r_extern() ) {
-                                       target.addend = srcAddr + displacement;
-                               }
-                               else {
-                                       dstAddr = srcAddr + displacement;
-                                       parser.findTargetFromAddressAndSectionNum(dstAddr, reloc->r_symbolnum(), target);
-                               }
-                               parser.addFixups(src, ld::Fixup::kindStorePPCBranch14, target);
-                               break;
-                       case PPC_RELOC_PAIR:
-                               // skip, processed by a previous look ahead
-                               break;
-                       case PPC_RELOC_LO16:
-                               if ( nextReloc->r_type() != PPC_RELOC_PAIR ) 
-                                       throw "PPC_RELOC_LO16 missing following pair";
-                               result = true;
-                               lowBits = (instruction & 0x0000FFFF);
-                               dstAddr = (nextReloc->r_address() << 16) + ((uint32_t)lowBits & 0x0000FFFF);
-                               if ( reloc->r_extern() ) {
-                                       target.addend = dstAddr;
-                               }
-                               else {
-                                       parser.findTargetFromAddressAndSectionNum(dstAddr, reloc->r_symbolnum(), target);
-                               }
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsLow16, target);
-                               break;
-                       case PPC_RELOC_LO14:
-                               if ( nextReloc->r_type() != PPC_RELOC_PAIR ) 
-                                       throw "PPC_RELOC_LO14 missing following pair";
-                               result = true;
-                               lowBits = (instruction & 0xFFFC);
-                               dstAddr = (nextReloc->r_address() << 16) + ((uint32_t)lowBits & 0x0000FFFF);
-                               if ( reloc->r_extern() ) {
-                                       target.addend = dstAddr;
-                               }
-                               else {
-                                       parser.findTargetFromAddressAndSectionNum(dstAddr, reloc->r_symbolnum(), target);
-                               }
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsLow14, target);
-                               break;
-                       case PPC_RELOC_HI16:
-                               if ( nextReloc->r_type() != PPC_RELOC_PAIR ) 
-                                       throw "PPC_RELOC_HI16 missing following pair";
-                               result = true;
-                               lowBits = (nextReloc->r_address() & 0xFFFF);
-                               dstAddr = ((instruction & 0xFFFF) << 16) | (lowBits & 0x0000FFFF);
-                               if ( reloc->r_extern() ) {
-                                       target.addend = dstAddr;
-                               }
-                               else {
-                                       parser.findTargetFromAddressAndSectionNum(dstAddr, reloc->r_symbolnum(), target);
-                               }
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsHigh16, target);
-                               break;
-                       case PPC_RELOC_HA16:
-                               if ( nextReloc->r_type() != PPC_RELOC_PAIR ) 
-                                       throw "PPC_RELOC_HA16 missing following pair";
-                               result = true;
-                               lowBits = (nextReloc->r_address() & 0x0000FFFF);
-                               dstAddr = ((instruction & 0xFFFF) << 16) + (int32_t)lowBits;
-                               if ( reloc->r_extern() ) {
-                                       target.addend = dstAddr;
-                               }
-                               else {
-                                       parser.findTargetFromAddressAndSectionNum(dstAddr, reloc->r_symbolnum(), target);
-                               }
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsHigh16AddLow, target);
-                               break;
-                       case PPC_RELOC_VANILLA:
-                               contentValue = P::getP(*((pint_t*)fixUpPtr));
-                               if ( reloc->r_extern() ) {
-                                       target.addend = contentValue;
-                               }
-                               else {
-                                       parser.findTargetFromAddressAndSectionNum(contentValue, reloc->r_symbolnum(), target);
-                               }
-                               switch ( reloc->r_length() ) {
-                                       case 0:
-                                       case 1:
-                                               throw "bad r_length in PPC_RELOC_VANILLA";
-                                       case 2:
-                                               parser.addFixups(src, ld::Fixup::kindStoreBigEndian32, target);
-                                               break;
-                                       case 3:
-                                               parser.addFixups(src, ld::Fixup::kindStoreBigEndian64, target);
-                                               break;
-                               }
-                               break;
-                       case PPC_RELOC_JBSR:
-                               // this is from -mlong-branch codegen.  We ignore the jump island and make reference to the real target
-                               if ( nextReloc->r_type() != PPC_RELOC_PAIR ) 
-                                       throw "PPC_RELOC_JBSR missing following pair";
-                               if ( !parser._hasLongBranchStubs )
-                                       warning("object file compiled with -mlong-branch which is no longer needed. "
-                                                       "To remove this warning, recompile without -mlong-branch: %s", parser._path);
-                               parser._hasLongBranchStubs = true;
-                               result = true;
-                               if ( reloc->r_extern() ) {
-                                       throw "PPC_RELOC_JBSR should not be using an external relocation";
-                               }
-                               parser.findTargetFromAddressAndSectionNum(nextReloc->r_address(), reloc->r_symbolnum(), target);
-                               parser.addFixups(src, ld::Fixup::kindStorePPCBranch24, target);
-                               break;
-                       default:
-                               warning("unknown relocation type %d", reloc->r_type());
-               }
-       }
-       else {
-               const macho_scattered_relocation_info<P>* sreloc = (macho_scattered_relocation_info<P>*)reloc;
-               // file format allows pair to be scattered or not
-               const macho_scattered_relocation_info<P>* nextSReloc = &sreloc[1];
-               const macho_relocation_info<P>* nextReloc = &reloc[1];
-               srcAddr = sect->addr() + sreloc->r_address();
-               dstAddr = sreloc->r_value();
-               fixUpPtr = (uint32_t*)(file().fileContent() + sect->offset() + sreloc->r_address());
-               instruction = BigEndian::get32(*fixUpPtr);
-               src.atom = this->findAtomByAddress(srcAddr);
-               src.offsetInAtom = srcAddr - src.atom->_objAddress;
-               typename Parser<A>::TargetDesc          picBase;
-               bool nextRelocIsPair = false;
-               uint32_t nextRelocAddress = 0;
-               uint32_t nextRelocValue = 0;
-               if ( (nextReloc->r_address() & R_SCATTERED) == 0 ) {
-                       if ( nextReloc->r_type() == PPC_RELOC_PAIR ) {
-                               nextRelocIsPair = true;
-                               nextRelocAddress = nextReloc->r_address();
-                               result = true;
-                       }
-               }
-               else {
-                       if ( nextSReloc->r_type() == PPC_RELOC_PAIR ) {
-                               nextRelocIsPair = true;
-                               nextRelocAddress = nextSReloc->r_address();
-                               nextRelocValue = nextSReloc->r_value();
-                               result = true;
-                       }
-               }
-               switch ( sreloc->r_type() ) {
-                       case PPC_RELOC_VANILLA:
-                               // with a scattered relocation we get both the target (sreloc->r_value()) and the target+offset (*fixUpPtr)
-                               target.atom = parser.findAtomByAddress(sreloc->r_value());
-                               switch ( sreloc->r_length() ) {
-                                       case 0:
-                                       case 1:
-                                               throw "unsuppored r_length < 2 for scattered PPC_RELOC_VANILLA";
-                                       case 2:
-                                               contentValue = BigEndian::get32(*(uint32_t*)fixUpPtr);
-                                               target.addend = contentValue - target.atom->_objAddress;
-                                               parser.addFixups(src, ld::Fixup::kindStoreBigEndian32, target);
-                                               break;
-                                       case 3:
-                                               contentValue = BigEndian::get64(*(uint64_t*)fixUpPtr);
-                                               target.addend = contentValue - target.atom->_objAddress;
-                                               parser.addFixups(src, ld::Fixup::kindStoreBigEndian64, target);
-                                               break;
-                               }
-                               break;
-                       case PPC_RELOC_BR14:
-                               displacement = (instruction & 0x0000FFFC);
-                               if ( (displacement & 0x00008000) != 0 )
-                                       displacement |= 0xFFFF0000;
-                               target.atom = parser.findAtomByAddress(sreloc->r_value());
-                               target.addend = (srcAddr + displacement) - target.atom->_objAddress;
-                               parser.addFixups(src, ld::Fixup::kindStorePPCBranch14, target);
-                               break;
-                       case PPC_RELOC_BR24:
-                               assert((instruction & 0x4C000000) == 0x48000000);
-                               displacement = (instruction & 0x03FFFFFC);
-                               if ( (displacement & 0x02000000) != 0 )
-                                       displacement |= 0xFC000000;
-                               target.atom = parser.findAtomByAddress(sreloc->r_value());
-                               target.addend = (srcAddr + displacement) - target.atom->_objAddress;
-                               parser.addFixups(src, ld::Fixup::kindStorePPCBranch24, target);
-                               break;
-                       case PPC_RELOC_LO16_SECTDIFF:
-                               if ( ! nextRelocIsPair ) 
-                                       throw "PPC_RELOC_LO16_SECTDIFF missing following pair";
-                               lowBits = (instruction & 0xFFFF);
-                               dstAddr = nextRelocValue + ((nextRelocAddress << 16) | ((uint32_t)lowBits & 0x0000FFFF));
-                               parser.findTargetFromAddress(sreloc->r_value(), target);
-                               if ( target.atom != NULL )
-                                       target.addend = dstAddr - target.atom->_objAddress;
-                               picBase.atom = parser.findAtomByAddress(nextRelocValue);
-                               picBase.addend = nextRelocValue - picBase.atom->_objAddress;
-                               picBase.weakImport = false;
-                               picBase.name = NULL;
-                               parser.addFixups(src, ld::Fixup::kindStorePPCPicLow16, target, picBase);
-                               break;
-                       case PPC_RELOC_LO14_SECTDIFF:
-                               if ( ! nextRelocIsPair ) 
-                                       throw "PPC_RELOC_LO14_SECTDIFF missing following pair";
-                               lowBits = (instruction & 0xFFFC);
-                               dstAddr = nextRelocValue + ((nextRelocAddress << 16) | ((uint32_t)lowBits & 0x0000FFFF));
-                               parser.findTargetFromAddress(sreloc->r_value(), target);
-                               if ( target.atom != NULL )
-                                       target.addend = dstAddr - target.atom->_objAddress;
-                               picBase.atom = parser.findAtomByAddress(nextRelocValue);
-                               picBase.addend = nextRelocValue - picBase.atom->_objAddress;
-                               picBase.weakImport = false;
-                               picBase.name = NULL;
-                               parser.addFixups(src, ld::Fixup::kindStorePPCPicLow14, target, picBase);
-                               break;
-                       case PPC_RELOC_HA16_SECTDIFF:
-                               if ( ! nextRelocIsPair ) 
-                                       throw "PPC_RELOC_HA16_SECTDIFF missing following pair";
-                               lowBits = (nextRelocAddress & 0x0000FFFF);
-                               dstAddr = nextRelocValue + (((instruction & 0x0000FFFF) << 16) + (int32_t)lowBits);
-                               parser.findTargetFromAddress(sreloc->r_value(), target);
-                               if ( target.atom != NULL )
-                                       target.addend = dstAddr - target.atom->_objAddress;
-                               picBase.atom = parser.findAtomByAddress(nextRelocValue);
-                               picBase.addend = nextRelocValue - picBase.atom->_objAddress;
-                               picBase.weakImport = false;
-                               picBase.name = NULL;
-                               parser.addFixups(src, ld::Fixup::kindStorePPCPicHigh16AddLow, target, picBase);
-                               break;
-                       case PPC_RELOC_LO14:
-                               if ( ! nextRelocIsPair )
-                                       throw "PPC_RELOC_LO14 missing following pair";
-                               lowBits = (instruction & 0xFFFC);
-                               dstAddr = ((nextRelocAddress << 16) + ((uint32_t)lowBits & 0x0000FFFF));
-                               parser.findTargetFromAddress(sreloc->r_value(), dstAddr, target);
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsLow14, target);
-                               break;
-                       case PPC_RELOC_LO16:
-                               if ( ! nextRelocIsPair )
-                                       throw "PPC_RELOC_LO16 missing following pair";
-                               lowBits = (instruction & 0xFFFF);
-                               dstAddr = ((nextRelocAddress << 16) + ((uint32_t)lowBits & 0x0000FFFF));
-                               parser.findTargetFromAddress(sreloc->r_value(), dstAddr, target);
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsLow16, target);
-                               break;
-                       case PPC_RELOC_HA16:
-                               if ( ! nextRelocIsPair ) 
-                                       throw "PPC_RELOC_HA16 missing following pair";
-                               lowBits = (nextRelocAddress & 0xFFFF);
-                               dstAddr = (((instruction & 0xFFFF) << 16) + (int32_t)lowBits);
-                               parser.findTargetFromAddress(sreloc->r_value(), dstAddr, target);
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsHigh16AddLow, target);
-                               break;
-                       case PPC_RELOC_HI16:
-                               if ( ! nextRelocIsPair )
-                                       throw "PPC_RELOC_HI16 missing following pair";
-                               lowBits = (nextRelocAddress & 0xFFFF);
-                               dstAddr = ((instruction & 0xFFFF) << 16) | (lowBits & 0x0000FFFF);
-                               parser.findTargetFromAddress(sreloc->r_value(), dstAddr, target);
-                               parser.addFixups(src, ld::Fixup::kindStorePPCAbsHigh16, target);
-                               break;
-                       case PPC_RELOC_SECTDIFF:
-                       case PPC_RELOC_LOCAL_SECTDIFF:
-                               {
-                                       if ( ! nextRelocIsPair ) 
-                                               throw "PPC_RELOC_SECTDIFF missing following pair";
-                                       ld::Fixup::Kind kind = ld::Fixup::kindNone;
-                                       switch ( sreloc->r_length() ) {
-                                               case 0:
-                                                       throw "bad length for PPC_RELOC_SECTDIFF";
-                                               case 1:
-                                                       contentValue = (int32_t)(int16_t)BigEndian::get16(*((uint16_t*)fixUpPtr));
-                                                       kind = ld::Fixup::kindStoreBigEndian16;
-                                                       break;
-                                               case 2:
-                                                       contentValue = BigEndian::get32(*((uint32_t*)fixUpPtr));
-                                                       kind = ld::Fixup::kindStoreBigEndian32;
-                                                       break;
-                                               case 3:
-                                                       contentValue = BigEndian::get64(*((uint64_t*)fixUpPtr));
-                                                       kind = ld::Fixup::kindStoreBigEndian64;
-                                                       break;
-                                               break;
-                                       }
-                                       Atom<A>* fromAtom  = parser.findAtomByAddress(nextRelocValue);
-                                       Atom<A>* targetAtom = parser.findAtomByAddress(sreloc->r_value());
-                                       uint32_t offsetInFrom = nextRelocValue - fromAtom->_objAddress;
-                                       uint32_t offsetInTarget = sreloc->r_value() - targetAtom->_objAddress;
-                                       // check for addend encoded in the section content
-                                       int32_t addend = contentValue - (sreloc->r_value() - nextRelocValue);
-                                       if ( addend < 0 ) {
-                                               if ( targetAtom->scope() == ld::Atom::scopeTranslationUnit ) {
-                                                       parser.addFixup(src, ld::Fixup::k1of5, ld::Fixup::kindSetTargetAddress, targetAtom);
-                                               }
-                                               else if ( (targetAtom->combine() == ld::Atom::combineByNameAndContent) || (targetAtom->combine() == ld::Atom::combineByNameAndReferences) ) {
-                                                       parser.addFixup(src, ld::Fixup::k1of5, ld::Fixup::kindSetTargetAddress, ld::Fixup::bindingByContentBound, targetAtom);
-                                               }
-                                               else {
-                                                       parser.addFixup(src, ld::Fixup::k1of5, ld::Fixup::kindSetTargetAddress, false, targetAtom->name());
-                                               }
-                                               parser.addFixup(src, ld::Fixup::k2of5, ld::Fixup::kindAddAddend, offsetInTarget);
-                                               parser.addFixup(src, ld::Fixup::k3of5, ld::Fixup::kindSubtractTargetAddress, fromAtom);
-                                               parser.addFixup(src, ld::Fixup::k4of5, ld::Fixup::kindSubtractAddend, offsetInFrom-addend);
-                                               parser.addFixup(src, ld::Fixup::k5of5, kind);
-                                       }
-                                       else {
-                                               if ( targetAtom->scope() == ld::Atom::scopeTranslationUnit ) {
-                                                       parser.addFixup(src, ld::Fixup::k1of5, ld::Fixup::kindSetTargetAddress, targetAtom);
-                                               }
-                                               else if ( (targetAtom->combine() == ld::Atom::combineByNameAndContent) || (targetAtom->combine() == ld::Atom::combineByNameAndReferences) ) {
-                                                       parser.addFixup(src, ld::Fixup::k1of5, ld::Fixup::kindSetTargetAddress, ld::Fixup::bindingByContentBound, targetAtom);
-                                               }
-                                               else {
-                                                       parser.addFixup(src, ld::Fixup::k1of5, ld::Fixup::kindSetTargetAddress, false, targetAtom->name());
-                                               }
-                                               parser.addFixup(src, ld::Fixup::k2of5, ld::Fixup::kindAddAddend, offsetInTarget+addend);
-                                               parser.addFixup(src, ld::Fixup::k3of5, ld::Fixup::kindSubtractTargetAddress, fromAtom);
-                                               parser.addFixup(src, ld::Fixup::k4of5, ld::Fixup::kindSubtractAddend, offsetInFrom);
-                                               parser.addFixup(src, ld::Fixup::k5of5, kind);
-                                       }
-                               }
-                               break;
-                       case PPC_RELOC_PAIR:
-                               break;
-                       case PPC_RELOC_HI16_SECTDIFF:
-                               warning("unexpected scattered relocation type PPC_RELOC_HI16_SECTDIFF");
-                               break;
-                       default:
-                               warning("unknown scattered relocation type %d", sreloc->r_type());
-               }
-       }
-       return result;
-}
-
-
-template <>
-bool Section<ppc>::addRelocFixup(class Parser<ppc>& parser, const macho_relocation_info<P>* reloc)
-{
-       return addRelocFixup_powerpc(parser, reloc);
-}
-
-
-template <>
-bool Section<ppc64>::addRelocFixup(class Parser<ppc64>& parser, const macho_relocation_info<P>* reloc)
-{
-       return addRelocFixup_powerpc(parser, reloc);
-}
-
 
 
 template <>
@@ -6226,7 +5702,9 @@ bool Section<arm>::addRelocFixup(class Parser<arm>& parser, const macho_relocati
                                                dstAddr = ((instruction16 << 16) | other16);
                         if ( reloc->r_extern() ) {
                             target.addend = dstAddr;
-                        }
+                                                       if ( externSymbolIsThumbDef )
+                                                               target.addend &= -2; // remove thumb bit
+                                               }
                         else {
                             parser.findTargetFromAddress(dstAddr, target);
                             if ( target.atom->isThumb() )
@@ -6239,6 +5717,8 @@ bool Section<arm>::addRelocFixup(class Parser<arm>& parser, const macho_relocati
                                                dstAddr = (other16 << 16) | instruction16;
                         if ( reloc->r_extern() ) {
                             target.addend = dstAddr;
+                                                       if ( externSymbolIsThumbDef )
+                                                               target.addend &= -2; // remove thumb bit
                         }
                         else {
                             parser.findTargetFromAddress(dstAddr, target);
@@ -6552,41 +6032,6 @@ bool ObjC1ClassSection<x86>::addRelocFixup(class Parser<x86>& parser, const mach
        return FixedSizeSection<x86>::addRelocFixup(parser, reloc);
 }
 
-template <>
-bool ObjC1ClassSection<ppc>::addRelocFixup(class Parser<ppc>& parser, const macho_relocation_info<ppc::P>* reloc)
-{
-       // if this is the reloc for the super class name string, add implicit reference to super class
-       if ( ((reloc->r_address() & R_SCATTERED) == 0) && (reloc->r_type() == PPC_RELOC_VANILLA) ) {
-               assert( reloc->r_length() == 2 );
-               assert( ! reloc->r_pcrel() );
-       
-               const macho_section<P>* sect = this->machoSection();
-               Parser<ppc>::SourceLocation     src;
-               uint32_t srcAddr = sect->addr() + reloc->r_address();
-               src.atom = this->findAtomByAddress(srcAddr);
-               src.offsetInAtom = srcAddr - src.atom->objectAddress();
-               if ( src.offsetInAtom == 4 ) {
-                       Parser<ppc>::TargetDesc         stringTarget;
-                       const uint8_t* fixUpPtr = file().fileContent() + sect->offset() + reloc->r_address();
-                       uint32_t contentValue = BigEndian::get32(*((uint32_t*)fixUpPtr));
-                       parser.findTargetFromAddressAndSectionNum(contentValue, reloc->r_symbolnum(), stringTarget);
-                       
-                       assert(stringTarget.atom != NULL);
-                       assert(stringTarget.atom->contentType() == ld::Atom::typeCString);
-                       const char* superClassBaseName = (char*)stringTarget.atom->rawContentPointer();
-                       char* superClassName = new char[strlen(superClassBaseName) + 20];
-                       strcpy(superClassName, ".objc_class_name_");
-                       strcat(superClassName, superClassBaseName);
-                       
-                       parser.addFixup(src, ld::Fixup::k1of1, ld::Fixup::kindSetTargetAddress, false, superClassName);
-               }
-       }
-       
-       // inherited
-       return FixedSizeSection<ppc>::addRelocFixup(parser, reloc);
-}
-
-
 
 
 template <typename A>
@@ -6600,38 +6045,6 @@ bool Objc1ClassReferences<A>::addRelocFixup(class Parser<A>& parser, const macho
 }
 
 
-template <>
-bool Objc1ClassReferences<ppc>::addRelocFixup(class Parser<ppc>& parser, const macho_relocation_info<ppc::P>* reloc)
-{
-       // add implict class refs, fixups not usable yet, so look at relocations
-       assert( (reloc->r_address() & R_SCATTERED) == 0 );
-       assert( reloc->r_type() == PPC_RELOC_VANILLA );
-       assert( reloc->r_length() == 2 );
-       assert( ! reloc->r_pcrel() );
-       
-       const macho_section<P>* sect = this->machoSection();
-       Parser<ppc>::SourceLocation     src;
-       uint32_t srcAddr = sect->addr() + reloc->r_address();
-       src.atom = this->findAtomByAddress(srcAddr);
-       src.offsetInAtom = srcAddr - src.atom->objectAddress();
-       Parser<ppc>::TargetDesc         stringTarget;
-       const uint8_t* fixUpPtr = file().fileContent() + sect->offset() + reloc->r_address();
-       uint32_t contentValue = BigEndian::get32(*((uint32_t*)fixUpPtr));
-       parser.findTargetFromAddressAndSectionNum(contentValue, reloc->r_symbolnum(), stringTarget);
-       
-       assert(stringTarget.atom != NULL);
-       assert(stringTarget.atom->contentType() == ld::Atom::typeCString);
-       const char* baseClassName = (char*)stringTarget.atom->rawContentPointer();
-       char* objcClassName = new char[strlen(baseClassName) + 20];
-       strcpy(objcClassName, ".objc_class_name_");
-       strcat(objcClassName, baseClassName);
-
-       parser.addFixup(src, ld::Fixup::k1of1, ld::Fixup::kindSetTargetAddress, false, objcClassName);
-
-       // inherited
-       return PointerToCStringSection<ppc>::addRelocFixup(parser, reloc);
-}
-
 
 template <>
 bool Objc1ClassReferences<x86>::addRelocFixup(class Parser<x86>& parser, const macho_relocation_info<x86::P>* reloc)
@@ -6738,14 +6151,6 @@ ld::relocatable::File* parse(const uint8_t* fileContent, uint64_t fileLength,
                        if ( mach_o::relocatable::Parser<arm>::validFile(fileContent, opts.objSubtypeMustMatch, opts.subType) )
                                return mach_o::relocatable::Parser<arm>::parse(fileContent, fileLength, path, modTime, ordinal, opts);
                        break;
-               case CPU_TYPE_POWERPC:
-                       if ( mach_o::relocatable::Parser<ppc>::validFile(fileContent) )
-                               return mach_o::relocatable::Parser<ppc>::parse(fileContent, fileLength, path, modTime, ordinal, opts);
-                       break;
-               case CPU_TYPE_POWERPC64:
-                       if ( mach_o::relocatable::Parser<ppc64>::validFile(fileContent) )
-                               return mach_o::relocatable::Parser<ppc64>::parse(fileContent, fileLength, path, modTime, ordinal, opts);
-                       break;
        }
        return NULL;
 }
@@ -6762,10 +6167,6 @@ bool isObjectFile(const uint8_t* fileContent, uint64_t fileLength, const ParserO
                        return ( mach_o::relocatable::Parser<x86>::validFile(fileContent) );
                case CPU_TYPE_ARM:
                        return ( mach_o::relocatable::Parser<arm>::validFile(fileContent, opts.objSubtypeMustMatch, opts.subType) );
-               case CPU_TYPE_POWERPC:
-                       return ( mach_o::relocatable::Parser<ppc>::validFile(fileContent) );
-               case CPU_TYPE_POWERPC64:
-                       return ( mach_o::relocatable::Parser<ppc64>::validFile(fileContent) );
        }
        return false;
 }
@@ -6791,17 +6192,6 @@ bool isObjectFile(const uint8_t* fileContent, cpu_type_t* result, cpu_subtype_t*
                *subResult = header->cpusubtype();
                return true;
        }
-       if ( mach_o::relocatable::Parser<ppc>::validFile(fileContent) ) {
-               *result = CPU_TYPE_POWERPC;
-               const macho_header<Pointer32<BigEndian> >* header = (const macho_header<Pointer32<BigEndian> >*)fileContent;
-               *subResult = header->cpusubtype();
-               return true;
-       }
-       if ( mach_o::relocatable::Parser<ppc64>::validFile(fileContent) ) {
-               *result = CPU_TYPE_POWERPC64;
-               *subResult = CPU_SUBTYPE_POWERPC_ALL;
-               return true;
-       }
        return false;
 }                                      
 
@@ -6819,12 +6209,6 @@ const char* archName(const uint8_t* fileContent)
        if ( mach_o::relocatable::Parser<arm>::validFile(fileContent, false, 0) ) {
                return mach_o::relocatable::Parser<arm>::fileKind(fileContent);
        }
-       if ( mach_o::relocatable::Parser<ppc>::validFile(fileContent) ) {
-               return mach_o::relocatable::Parser<ppc>::fileKind(fileContent);
-       }
-       if ( mach_o::relocatable::Parser<ppc64>::validFile(fileContent) ) {
-               return mach_o::relocatable::Parser<ppc64>::fileKind(fileContent);
-       }
        return NULL;
 }