archiveVersion = 1;
        classes = {
        };
-       objectVersion = 42;
+       objectVersion = 46;
        objects = {
 
 /* Begin PBXAggregateTarget section */
                F9023C3006D5A227001BBF46 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
+                               LastUpgradeCheck = 0600;
                                ORGANIZATIONNAME = "Apple Inc.";
                        };
                        buildConfigurationList = F933D92309291AC90083EAC8 /* Build configuration list for PBXProject "ld64" */;
-                       compatibilityVersion = "Xcode 2.4";
+                       compatibilityVersion = "Xcode 3.2";
                        developmentRegion = English;
                        hasScannedForEncodings = 0;
                        knownRegions = (
                F933D92409291AC90083EAC8 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
-                               ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               ONLY_ACTIVE_ARCH = YES;
                        };
                        name = Debug;
                };
                F933D92509291AC90083EAC8 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
-                               ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
                        };
                F9849FF810B5DE8E009E9878 /* Release-assert */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
-                               ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
                        };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
+                               COMBINE_HIDPI_IMAGES = YES;
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                GCC_ENABLE_FIX_AND_CONTINUE = NO;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
+                               COMBINE_HIDPI_IMAGES = YES;
                                COPY_PHASE_STRIP = NO;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_MODEL_TUNING = G5;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
+                               COMBINE_HIDPI_IMAGES = YES;
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                GCC_ENABLE_FIX_AND_CONTINUE = NO;
 
 
 
 // hack until arm64 headers are worked out
-#define CPU_TYPE_ARM64                 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
-#define CPU_SUBTYPE_ARM64_ALL  0
-#define CPU_SUBTYPE_ARM64_V8    1
+#ifndef CPU_TYPE_ARM64
+       #define CPU_TYPE_ARM64                  (CPU_TYPE_ARM | CPU_ARCH_ABI64)
+#endif
+#ifndef CPU_SUBTYPE_ARM64_ALL
+       #define CPU_SUBTYPE_ARM64_ALL   0
+#endif
+#ifndef CPU_SUBTYPE_ARM64_V8
+       #define CPU_SUBTYPE_ARM64_V8    1
+#endif
+
 
 #define ARM64_RELOC_UNSIGNED            0 // for pointers
 #define ARM64_RELOC_SUBTRACTOR          1 // must be followed by a ARM64_RELOC_UNSIGNED
 
 #define UNWIND_ARM64_DWARF_SECTION_OFFSET               0x00FFFFFF
 
+#define UNW_ARM_D31 287
+
 
 #ifndef LC_SOURCE_VERSION
        #define LC_SOURCE_VERSION 0x2A
        #define CPU_SUBTYPE_X86_64_H    ((cpu_subtype_t) 8) 
 #endif 
 
+#define UNWIND_ARM_MODE_MASK                          0x0F000000
+#define UNWIND_ARM_MODE_FRAME                         0x01000000
+#define UNWIND_ARM_MODE_FRAME_D                       0x02000000
+#define UNWIND_ARM_MODE_DWARF                         0x04000000
+ 
+#define  UNWIND_ARM_FRAME_STACK_ADJUST_MASK           0x00C00000
+
+#define UNWIND_ARM_FRAME_FIRST_PUSH_R4                0x00000001
+#define UNWIND_ARM_FRAME_FIRST_PUSH_R5                0x00000002
+#define UNWIND_ARM_FRAME_FIRST_PUSH_R6                0x00000004
+  
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R8               0x00000008
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R9               0x00000010
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R10              0x00000020
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R11              0x00000040
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R12              0x00000080
+ 
+#define UNWIND_ARM_FRAME_D_REG_COUNT_MASK             0x00000F00
+ 
+#define UNWIND_ARM_DWARF_SECTION_OFFSET               0x00FFFFFF
 
 struct ArchInfo {
        const char*                     archName;
        #define SUPPORT_ARCH_arm_any 1
 #endif
 #if SUPPORT_ARCH_arm64
-       { "arm64", CPU_TYPE_ARM64,   CPU_SUBTYPE_ARM64_ALL,  "arm64-",    "",   false,  false },
+       { "arm64", CPU_TYPE_ARM64,   CPU_SUBTYPE_ARM64_ALL,  "arm64-",  "aarch64-",  false,  false },
 #endif
 #if SUPPORT_ARCH_arm64v8
-       { "arm64v8", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8,   "arm64v8-",  "",   true,  false },
+       { "arm64v8", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8,   "arm64v8-",  "aarch64-",   true,  false },
 #endif
        { NULL, 0, 0, NULL, NULL, false, false }
 };
 
 fi
 
 if [ -z "${RC_SUPPORTED_ARCHS}" ]; then
-       RC_SUPPORTED_ARCHS="i386 x86_64 x86_64h armv6 armv7 armv7s armv7m arm64"
+       RC_SUPPORTED_ARCHS="i386 x86_64 x86_64h armv6 armv7 armv7s armv7m armv7k arm64"
 fi
 
 for ANARCH in ${RC_SUPPORTED_ARCHS}
 
        objOpts.forceDwarfConversion= (_options.outputKind() == Options::kDyld);
        objOpts.neverConvertDwarf   = !_options.needsUnwindInfoSection();
        objOpts.verboseOptimizationHints = _options.verboseOptimizationHints();
+       objOpts.armUsesZeroCostExceptions = _options.armUsesZeroCostExceptions();
        objOpts.subType                         = _options.subArchitecture();
        ld::relocatable::File* objResult = mach_o::relocatable::parse(p, len, info.path, info.modTime, info.ordinal, objOpts);
        if ( objResult != NULL ) {
                                ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
                                if ( dylibReader != NULL ) {
                                        if ( ! dylibReader->installPathVersionSpecific() ) {
-                                               dylibReader->forEachAtom(handler);
                                                dylibReader->setImplicitlyLinked();
                                                this->addDylib(dylibReader, info);
                                        }
                                ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
                                ld::archive::File* archiveReader = dynamic_cast<ld::archive::File*>(reader);
                                if ( dylibReader != NULL ) {
-                                       dylibReader->forEachAtom(handler);
                                        dylibReader->setImplicitlyLinked();
                                        this->addDylib(dylibReader, info);
                                }
 
        fArchitectureName = "unknown architecture";
 }
 
+bool Options::armUsesZeroCostExceptions() const
+{
+       return ( (fArchitecture == CPU_TYPE_ARM) && (fSubArchitecture == CPU_SUBTYPE_ARM_V7K) );
+}
+
 void Options::parseArch(const char* arch)
 {
        if ( arch == NULL )
                        }
                        break;
                case CPU_TYPE_ARM:
-                       fAddCompactUnwindEncoding = false;
-                       fRemoveDwarfUnwindIfCompactExists = false;
+                       if ( armUsesZeroCostExceptions() )  {
+                               switch ( fOutputKind ) {
+                                       case Options::kObjectFile:
+                                       case Options::kStaticExecutable:
+                                       case Options::kPreload:
+                                       case Options::kKextBundle:
+                                               fAddCompactUnwindEncoding = false;
+                                               break;
+                                       case Options::kDyld:
+                                       case Options::kDynamicLibrary:
+                                       case Options::kDynamicBundle:
+                                       case Options::kDynamicExecutable:
+                                               fAddCompactUnwindEncoding = true;
+                                               break;
+                               }
+                       }
+                       else {
+                               fAddCompactUnwindEncoding = false;
+                               fRemoveDwarfUnwindIfCompactExists = false;
+                       }
                        break;
                case 0:
                        // if -arch is missing, assume we don't want compact unwind info
        // <rdar://problem/12258065> ARM64 needs 16KB page size for user land code
        // <rdar://problem/15974532> make armv7[s] use 16KB pages in user land code for iOS 8 or later
        if ( fSegmentAlignment == 4096 ) {
-               if ( (fArchitecture == CPU_TYPE_ARM64) 
-               || ((fArchitecture == CPU_TYPE_ARM) && (fIOSVersionMin >= ld::iOS_8_0) && 
-                       ((fSubArchitecture == CPU_SUBTYPE_ARM_V7S) || (fSubArchitecture == CPU_SUBTYPE_ARM_V7))) ) {
-                       switch ( fOutputKind ) {
-                               case Options::kDynamicExecutable:
-                               case Options::kDynamicLibrary:
-                               case Options::kDynamicBundle:
-                               case Options::kDyld:
+               switch ( fOutputKind ) {
+                       case Options::kDynamicExecutable:
+                       case Options::kDynamicLibrary:
+                       case Options::kDynamicBundle:
+                       case Options::kDyld:
+                               if ( (fArchitecture == CPU_TYPE_ARM64) 
+                               || ((fArchitecture == CPU_TYPE_ARM) && (fIOSVersionMin >= ld::iOS_8_0) && 
+                                       ((fSubArchitecture == CPU_SUBTYPE_ARM_V7S) || (fSubArchitecture == CPU_SUBTYPE_ARM_V7))) ) {
                                        fSegmentAlignment = 4096*4;
-                                       break;
-                               case Options::kStaticExecutable:
-                               case Options::kKextBundle:
-                               case Options::kObjectFile:
-                               case Options::kPreload:
-                                       break;
-                       }
+                               }
+                               break;
+                       case Options::kStaticExecutable:
+                       case Options::kKextBundle:
+                               // <rdar://problem/14676611> 16KB segments for arm64 kexts
+                               if ( (fArchitecture == CPU_TYPE_ARM64) && (fIOSVersionMin >= ld::iOS_9_0) ) {
+                                       fSegmentAlignment = 4096*4;
+                               }
+                               break;
+                       case Options::kObjectFile:
+                       case Options::kPreload:
+                               break;
                }
        }
 
+
+
        // <rdar://problem/13624134> linker should not convert dwarf unwind if .o file has compact unwind section
        switch ( fOutputKind ) {
                case Options::kDynamicExecutable:
                        break;
        }
        
+       // Make sure -image_base matches alignment
+       uint64_t alignedBaseAddress = (fBaseAddress+fSegmentAlignment-1) & (-fSegmentAlignment);
+       if ( alignedBaseAddress != fBaseAddress ) {
+               warning("base address 0x%llX is not properly aligned. Changing it to 0x%llX", fBaseAddress, alignedBaseAddress);
+               fBaseAddress = alignedBaseAddress;
+       }
+
 }
 
 void Options::checkIllegalOptionCombinations()
 
                                                                linkerOptions() const { return fLinkerOptions; }
        FileInfo                                        findFramework(const char* frameworkName) const;
        FileInfo                                        findLibrary(const char* rootName, bool dylibsOnly=false) const;
+       bool                                            armUsesZeroCostExceptions() const;
        const std::vector<SectionRename>& sectionRenames() const { return fSectionRenames; }
        const std::vector<SegmentRename>& segmentRenames() const { return fSegmentRenames; }
        bool                                            moveRoSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const;
 
        }
 }
 
-static void userReadableSwiftVersion(uint8_t value, char versionString[64])
+static void userReadableSwiftVersion(uint8_t value, char versionString[32])
 {
        switch (value) {
                case 1:
                        strcpy(versionString, "1.0");
                        break;
-               case 2:
-                       strcpy(versionString, "1.1");
-                       break;
                default:
-                       sprintf(versionString, "unknown ABI version 0x%02X", value);
+                       sprintf(versionString, "0x%02X", value);
        }
 }
 
                                _internal.swiftVersion = file.swiftVersion();
                        }
                        else if ( file.swiftVersion() != _internal.swiftVersion ) {
-                               char fileVersion[64];
-                               char otherVersion[64];
+                               char fileVersion[32];
+                               char otherVersion[32];
                                userReadableSwiftVersion(file.swiftVersion(), fileVersion);
                                userReadableSwiftVersion(_internal.swiftVersion, otherVersion);
                                if ( file.swiftVersion() > _internal.swiftVersion ) {
                        if ( (_options.iOSVersionMin() != iOSVersionUnset) && (_options.iOSVersionMin() < iOS_8_0) ) {
                                // <rdar://problem/17598404> only warn about linking against embedded dylib if it is built for iOS 8 or later
                                if ( dylibFile->iOSMinVersion() >= iOS_8_0 )
-                                       throwf("embedded dylibs/frameworks are only supported on iOS 8.0 and later (%s)", depInstallName);
+                                       warning("embedded dylibs/frameworks are only supported on iOS 8.0 and later (%s)", depInstallName);
                        }
                }
                if ( _options.sharedRegionEligible() ) {
        optOpt.needsUnwindInfoSection           = _options.needsUnwindInfoSection();
        optOpt.keepDwarfUnwind                          = _options.keepDwarfUnwind();
        optOpt.verboseOptimizationHints     = _options.verboseOptimizationHints();
+       optOpt.armUsesZeroCostExceptions    = _options.armUsesZeroCostExceptions();
        optOpt.arch                                                     = _options.architecture();
        optOpt.mcpu                                                     = _options.mcpuLTO();
        optOpt.llvmOptions                                      = &_options.llvmOptions();
 
 enum IOSVersionMin { iOSVersionUnset=0, iOS_2_0=0x00020000, iOS_3_1=0x00030100, 
                                                iOS_4_2=0x00040200, iOS_4_3=0x00040300, iOS_5_0=0x00050000,
                                                iOS_6_0=0x00060000, iOS_7_0=0x00070000, iOS_8_0=0x00080000,
-                                               iOS_Future=0x10000000};
+                                               iOS_9_0=0x00090000, iOS_Future=0x10000000};
  
 namespace relocatable {
        //
 
                                                                                                const Registers_arm64&, const typename CFI_Parser<A>::PrologInfo& prolog,
                                                                                                char warningBuffer[1024]);
        
+  // arm specific variants
+       static bool   isReturnAddressRegister(int regNum, const Registers_arm&);
+       static pint_t getCFA(A& addressSpace, const typename CFI_Parser<A>::PrologInfo& prolog, const Registers_arm&);
+       static compact_unwind_encoding_t encodeToUseDwarf(const Registers_arm&);
+       static compact_unwind_encoding_t createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr,
+                                                                                               const Registers_arm&, const typename CFI_Parser<A>::PrologInfo& prolog,
+                                                                                               char warningBuffer[1024]);
+       
 };
 
 
 }
 
 
+
+
+//
+//     arm specific functions
+//
+
+template <typename A, typename R>
+compact_unwind_encoding_t DwarfInstructions<A,R>::encodeToUseDwarf(const Registers_arm&) 
+{
+       return UNWIND_ARM_MODE_DWARF;
+}
+
+
+template <typename A, typename R>
+compact_unwind_encoding_t DwarfInstructions<A,R>::createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr,
+                                                                                               const Registers_arm& r, const typename CFI_Parser<A>::PrologInfo& prolog,
+                                                                                               char warningBuffer[1024])
+{
+       warningBuffer[0] = '\0';
+       return UNWIND_ARM_MODE_DWARF;
+}
+
+
 } // namespace libunwind
 
 
 
        objOpts.forceDwarfConversion = false;
        objOpts.neverConvertDwarf   = false;
        objOpts.verboseOptimizationHints = options.verboseOptimizationHints;
+       objOpts.armUsesZeroCostExceptions = options.armUsesZeroCostExceptions;
 
        objOpts.subType                         = 0;
        
        switch ( severity ) {
 #if LTO_API_VERSION >= 10
                case LTO_DS_REMARK:
-                       fprintf(stderr, "ld: LTO remark: %s\n", message);
-                       break;
 #endif
                case LTO_DS_NOTE:
                case LTO_DS_WARNING:
 
        bool                                                            needsUnwindInfoSection; 
        bool                                                            keepDwarfUnwind; 
        bool                                                            verboseOptimizationHints;
+       bool                                                            armUsesZeroCostExceptions;
        cpu_type_t                                                      arch;
        const char*                                                     mcpu;
        const std::vector<const char*>*         llvmOptions;
 
        virtual unsigned long                   contentHash(const class Atom<A>* atom, const ld::IndirectBindingTable& ind) const;
        virtual bool                                    canCoalesceWith(const class Atom<A>* atom, const ld::Atom& rhs, 
                                                                                                        const ld::IndirectBindingTable& ind) const;
+       virtual bool                                    ignoreLabel(const char* label) const;
 };
 
 template <typename A>
        virtual unsigned long                   contentHash(const class Atom<A>* atom, const ld::IndirectBindingTable& ind) const;
        virtual bool                                    canCoalesceWith(const class Atom<A>* atom, const ld::Atom& rhs, 
                                                                                                        const ld::IndirectBindingTable& ind) const;
+       virtual bool                                    ignoreLabel(const char* label) const;
 };
 
 template <typename A>
        virtual unsigned long                   contentHash(const class Atom<A>* atom, const ld::IndirectBindingTable& ind) const;
        virtual bool                                    canCoalesceWith(const class Atom<A>* atom, const ld::Atom& rhs, 
                                                                                                        const ld::IndirectBindingTable& ind) const;
+       virtual bool                                    ignoreLabel(const char* label) const;
 };
 
 
        bool                                                                                    forceDwarfConversion() { return _forceDwarfConversion; }
        bool                                                                                    verboseOptimizationHints() { return _verboseOptimizationHints; }
        bool                                                                                    neverConvertDwarf() { return _neverConvertDwarf; }
+       bool                                                                                    armUsesZeroCostExceptions() { return _armUsesZeroCostExceptions; }
 
        macho_data_in_code_entry<P>*                                    dataInCodeStart() { return _dataInCodeStart; }
        macho_data_in_code_entry<P>*                                    dataInCodeEnd()   { return _dataInCodeEnd; }
        bool                                                                            _forceDwarfConversion;
        bool                                                                            _neverConvertDwarf;
        bool                                                                            _verboseOptimizationHints;
+       bool                                                                            _armUsesZeroCostExceptions;
        unsigned int                                                            _stubsSectionNum;
        const macho_section<P>*                                         _stubsMachOSection;
        std::vector<const char*>                                        _dtraceProviderInfo;
        // respond to -t option
        if ( opts.logAllFiles )
                printf("%s\n", _path);
+               
+       _armUsesZeroCostExceptions = opts.armUsesZeroCostExceptions;
 
        // parse start of mach-o file
        if ( ! parseLoadCommands() )
 template <> 
 uint32_t CFISection<arm>::cfiCount(Parser<arm>& parser) 
 {
+       if ( parser.armUsesZeroCostExceptions() ) {
+               // create ObjectAddressSpace object for use by libunwind
+               OAS oas(*this, (uint8_t*)this->file().fileContent()+this->_machOSection->offset());
+               return libunwind::CFI_Parser<OAS>::getCFICount(oas, 
+                                                                                       this->_machOSection->addr(), this->_machOSection->size());
+       }
        return 0; 
 }
 
                                                                        libunwind::CFI_Atom_Info<CFISection<arm>::OAS>::CFI_Atom_Info cfiArray[], 
                                                                        uint32_t& count, const pint_t cuStarts[], uint32_t cuCount)
 {
-       // arm does not use zero cost exceptions
-       assert(count == 0);
+       if ( !parser.armUsesZeroCostExceptions() ) {
+               // most arm do not use zero cost exceptions
+               assert(count == 0);
+               return;
+       }
+       // 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_arm>::parseCFIs(
+                                                       oas, this->_machOSection->addr(), this->_machOSection->size(), 
+                                                       cuStarts, cuCount, parser.keepDwarfUnwind(), parser.forceDwarfConversion(), parser.neverConvertDwarf(),
+                                                       cfiArray, count, (void*)&parser, warnFunc);
+       if ( msg != NULL ) 
+               throwf("malformed __eh_frame section: %s", msg);
 }
 
 
 }
 #endif
 
+template <>
+void CFISection<arm>::addCiePersonalityFixups(class Parser<arm>& 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<arm>* cieAtom = this->findAtomByAddress(cieInfo->address);
+               Atom<arm>* nlpAtom = parser.findAtomByAddress(nlpAddr);
+               assert(nlpAtom->contentType() == ld::Atom::typeNonLazyPointer);
+               Parser<arm>::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::kindStoreLittleEndian32);
+       }
+       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)
 }
 #endif
 
+#if SUPPORT_ARCH_arm_any
+template <>
+const char* CUSection<arm>::personalityName(class Parser<arm>& parser, const macho_relocation_info<arm::P>* reloc)
+{
+       if ( reloc->r_extern() ) {
+               assert((reloc->r_type() == ARM_RELOC_VANILLA) && "wrong reloc type on personality column in __compact_unwind section");
+               const macho_nlist<P>& sym = parser.symbolFromIndex(reloc->r_symbolnum());
+               return parser.nameFromSymbol(sym);
+       }
+       else {
+               // support __LD, __compact_unwind personality entries which are pointer to personality non-lazy pointer
+               const pint_t* content = (pint_t*)(this->file().fileContent() + this->_machOSection->offset() + reloc->r_address());
+               pint_t nlPointerAddr = *content;
+               Section<arm>* nlSection = parser.sectionForAddress(nlPointerAddr);
+               if ( nlSection->type() == ld::Section::typeCode ) {
+                       // personality function is defined in this .o file, so this is a direct reference to it
+                       // atoms may not be constructed yet, so scan symbol table for labels
+                       const char* name = parser.scanSymbolTableForAddress(nlPointerAddr);
+                       return name;
+               }
+               else {
+                       uint32_t symIndex = parser.symbolIndexFromIndirectSectionAddress(nlPointerAddr, nlSection->machoSection());
+                       const macho_nlist<P>& nlSymbol = parser.symbolFromIndex(symIndex);
+                       return parser.nameFromSymbol(nlSymbol);
+               }
+       }
+}
+#endif
+
 
 template <typename A>
 const char* CUSection<A>::personalityName(class Parser<A>& parser, const macho_relocation_info<P>* reloc)
 template <>
 bool CUSection<arm>::encodingMeansUseDwarf(compact_unwind_encoding_t enc)
 {
-       return false;
+       return ((enc & UNWIND_ARM_MODE_MASK) == UNWIND_ARM_MODE_DWARF);
 }
 #endif
 
        return count;
 }
 
+template <typename A>
+bool Literal4Section<A>::ignoreLabel(const char* label) const
+{
+       return (label[0] == 'L') || (label[0] == 'l');
+}
 
 template <typename A>
 unsigned long Literal4Section<A>::contentHash(const class Atom<A>* atom, const ld::IndirectBindingTable& ind) const
 }
 
 
+template <typename A>
+bool Literal8Section<A>::ignoreLabel(const char* label) const
+{
+       return (label[0] == 'L') || (label[0] == 'l');
+}
+
 template <typename A>
 unsigned long Literal8Section<A>::contentHash(const class Atom<A>* atom, const ld::IndirectBindingTable& ind) const
 {
        return false;
 }
 
+template <typename A>
+bool Literal16Section<A>::ignoreLabel(const char* label) const
+{
+       return (label[0] == 'L') || (label[0] == 'l');
+}
 
 template <typename A>
 unsigned long Literal16Section<A>::contentHash(const class Atom<A>* atom, const ld::IndirectBindingTable& ind) const
                return ld::Atom::scopeLinkageUnit; 
 }
 
-
 template <typename A>
 const uint8_t* CFStringSection<A>::targetContent(const class Atom<A>* atom, const ld::IndirectBindingTable& ind,
                                                                                                        ContentType* ct, unsigned int* count)
 
        bool                    forceDwarfConversion;
        bool                    neverConvertDwarf;
        bool                    verboseOptimizationHints;
+       bool                    armUsesZeroCostExceptions;
        uint32_t                subType;
 };
 
 
        return ((enc & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF);
 }
 
+template <>
+bool UnwindInfoAtom<arm>::encodingMeansUseDwarf(compact_unwind_encoding_t enc)
+{
+       return ((enc & UNWIND_ARM_MODE_MASK) == UNWIND_ARM_MODE_DWARF);
+}
+
+
 template <typename A>
 void UnwindInfoAtom<A>::compressDuplicates(const std::vector<UnwindEntry>& entries, std::vector<UnwindEntry>& uniqueEntries)
 {
        _fixups.push_back(ld::Fixup(offset, ld::Fixup::k3of3, ld::Fixup::kindStoreLittleEndianLow24of32));
 }
 
+template <>
+void UnwindInfoAtom<arm>::addCompressedAddressOffsetFixup(uint32_t offset, const ld::Atom* func, const ld::Atom* fromFunc)
+{
+       if ( fromFunc->isThumb() ) {
+               _fixups.push_back(ld::Fixup(offset, ld::Fixup::k1of4, ld::Fixup::kindSetTargetAddress, func));
+               _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of4, ld::Fixup::kindSubtractTargetAddress, fromFunc));
+               _fixups.push_back(ld::Fixup(offset, ld::Fixup::k3of4, ld::Fixup::kindSubtractAddend, 1));
+               _fixups.push_back(ld::Fixup(offset, ld::Fixup::k4of4, ld::Fixup::kindStoreLittleEndianLow24of32));
+       }
+       else {
+               _fixups.push_back(ld::Fixup(offset, ld::Fixup::k1of3, ld::Fixup::kindSetTargetAddress, func));
+               _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of3, ld::Fixup::kindSubtractTargetAddress, fromFunc));
+               _fixups.push_back(ld::Fixup(offset, ld::Fixup::k3of3, ld::Fixup::kindStoreLittleEndianLow24of32));
+       }
+}
+
 template <>
 void UnwindInfoAtom<x86>::addCompressedEncodingFixup(uint32_t offset, const ld::Atom* fde)
 {
        _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndianLow24of32));
 }
 
+template <>
+void UnwindInfoAtom<arm>::addCompressedEncodingFixup(uint32_t offset, const ld::Atom* fde)
+{
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k1of2, ld::Fixup::kindSetTargetSectionOffset, fde));
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndianLow24of32));
+}
+
 template <>
 void UnwindInfoAtom<x86>::addRegularAddressFixup(uint32_t offset, const ld::Atom* func)
 {
        _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndian32));
 }
 
+template <>
+void UnwindInfoAtom<arm>::addRegularAddressFixup(uint32_t offset, const ld::Atom* func)
+{
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k1of2, ld::Fixup::kindSetTargetImageOffset, func));
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndian32));
+}
+
 template <>
 void UnwindInfoAtom<x86>::addRegularFDEOffsetFixup(uint32_t offset, const ld::Atom* fde)
 {
        _fixups.push_back(ld::Fixup(offset+4, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndianLow24of32));
 }
 
+template <>
+void UnwindInfoAtom<arm>::addRegularFDEOffsetFixup(uint32_t offset, const ld::Atom* fde)
+{
+       _fixups.push_back(ld::Fixup(offset+4, ld::Fixup::k1of2, ld::Fixup::kindSetTargetSectionOffset, fde));
+       _fixups.push_back(ld::Fixup(offset+4, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndianLow24of32));
+}
+
 template <>
 void UnwindInfoAtom<x86>::addImageOffsetFixup(uint32_t offset, const ld::Atom* targ)
 {
        _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndian32));
 }
 
+template <>
+void UnwindInfoAtom<arm>::addImageOffsetFixup(uint32_t offset, const ld::Atom* targ)
+{
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k1of2, ld::Fixup::kindSetTargetImageOffset, targ));
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of2, ld::Fixup::kindStoreLittleEndian32));
+}
+
 template <>
 void UnwindInfoAtom<x86>::addImageOffsetFixupPlusAddend(uint32_t offset, const ld::Atom* targ, uint32_t addend)
 {
        _fixups.push_back(ld::Fixup(offset, ld::Fixup::k3of3, ld::Fixup::kindStoreLittleEndian32));
 }
 
+template <>
+void UnwindInfoAtom<arm>::addImageOffsetFixupPlusAddend(uint32_t offset, const ld::Atom* targ, uint32_t addend)
+{
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k1of3, ld::Fixup::kindSetTargetImageOffset, targ));
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k2of3, ld::Fixup::kindAddAddend, addend));
+       _fixups.push_back(ld::Fixup(offset, ld::Fixup::k3of3, ld::Fixup::kindStoreLittleEndian32));
+}
+
 
 
 
                case CPU_TYPE_ARM64:
                        state.addAtom(*new UnwindInfoAtom<arm64>(entries, ehFrameSize));
                        break;
+#endif
+#if SUPPORT_ARCH_arm_any
+               case CPU_TYPE_ARM:
+                       if ( opts.armUsesZeroCostExceptions() )
+                               state.addAtom(*new UnwindInfoAtom<arm>(entries, ehFrameSize));
+                       break;
 #endif
                default:
                        assert(0 && "no compact unwind for arch");
 template <> ld::Fixup::Kind CompactUnwindAtom<arm64>::_s_pointerKind = ld::Fixup::kindStoreLittleEndian64;
 template <> ld::Fixup::Kind CompactUnwindAtom<arm64>::_s_pointerStoreKind = ld::Fixup::kindStoreTargetAddressLittleEndian64;
 #endif
+template <> ld::Fixup::Kind CompactUnwindAtom<arm>::_s_pointerKind = ld::Fixup::kindStoreLittleEndian32;
+template <> ld::Fixup::Kind CompactUnwindAtom<arm>::_s_pointerStoreKind = ld::Fixup::kindStoreTargetAddressLittleEndian32;
 
 template <typename A>
 CompactUnwindAtom<A>::CompactUnwindAtom(ld::Internal& state,const ld::Atom* funcAtom, uint32_t startOffset,
                        state.addAtom(*new CompactUnwindAtom<arm64>(state, atom, startOffset, endOffset-startOffset, cui));
                        break;
 #endif
+               case CPU_TYPE_ARM:
+                       state.addAtom(*new CompactUnwindAtom<arm>(state, atom, startOffset, endOffset-startOffset, cui));
+                       break;
        }
 }
 
 
        objOpts.keepDwarfUnwind         = false;
        objOpts.forceDwarfConversion = false;
        objOpts.verboseOptimizationHints = true;
+       objOpts.armUsesZeroCostExceptions = true;
        objOpts.subType                         = sPreferredSubArch;
 #if 1
        if ( ! foundFatSlice ) {
 
 }
 #endif
 
+template <>
+bool UnwindPrinter<arm>::validFile(const uint8_t* fileContent)
+{      
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return false;
+       if ( header->cputype() != CPU_TYPE_ARM )
+               return false;
+       switch (header->filetype()) {
+               case MH_EXECUTE:
+               case MH_DYLIB:
+               case MH_BUNDLE:
+               case MH_DYLINKER:
+               case MH_OBJECT:
+                       return true;
+       }
+       return false;
+}
+
 template <typename A>
 UnwindPrinter<A>::UnwindPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool showFunctionNames)
  : fHeader(NULL), fLength(fileLength), fUnwindSection(NULL),
 }
 #endif
 
+template <>
+void UnwindPrinter<arm>::decode(uint32_t encoding, const uint8_t* funcStart, char* str)
+{
+       *str = '\0';
+       switch ( encoding & UNWIND_ARM_MODE_MASK ) {
+               case UNWIND_ARM_MODE_DWARF:
+                       sprintf(str, "dwarf offset 0x%08X, ", encoding & UNWIND_ARM_DWARF_SECTION_OFFSET);
+                       break;
+               case UNWIND_ARM_MODE_FRAME:
+               case UNWIND_ARM_MODE_FRAME_D:
+                       switch ( encoding & UNWIND_ARM_FRAME_STACK_ADJUST_MASK ) {
+                               case 0x00000000:
+                                       strcpy(str, "std frame: ");
+                                       break;
+                               case 0x00400000:
+                                       strcat(str, "std frame(sp adj 4): ");
+                                       break;
+                               case 0x00800000:
+                                       strcat(str, "std frame(sp adj 8): ");
+                                       break;
+                               case 0x00C00000:
+                                       strcat(str, "std frame(sp adj 12): ");
+                                       break;
+                       }
+                       if ( encoding & UNWIND_ARM_FRAME_FIRST_PUSH_R4 )
+                               strcat(str, "r4 ");
+                       if ( encoding & UNWIND_ARM_FRAME_FIRST_PUSH_R5 )
+                               strcat(str, "r5 ");
+                       if ( encoding & UNWIND_ARM_FRAME_FIRST_PUSH_R6 )
+                               strcat(str, "r6 ");
+                               
+                       if ( encoding & 0x000000F8) 
+                               strcat(str, " / ");
+                       if ( encoding & UNWIND_ARM_FRAME_SECOND_PUSH_R8 )
+                               strcat(str, "r8 ");
+                       if ( encoding & UNWIND_ARM_FRAME_SECOND_PUSH_R9 )
+                               strcat(str, "r9 ");
+                       if ( encoding & UNWIND_ARM_FRAME_SECOND_PUSH_R10 )
+                               strcat(str, "r10 ");
+                       if ( encoding & UNWIND_ARM_FRAME_SECOND_PUSH_R11 )
+                               strcat(str, "r11 ");
+                       if ( encoding & UNWIND_ARM_FRAME_SECOND_PUSH_R12 )
+                               strcat(str, "r12 ");
+                       
+                       if ( (encoding & UNWIND_ARM_MODE_MASK) == UNWIND_ARM_MODE_FRAME_D ) {
+                               switch ( encoding & UNWIND_ARM_FRAME_D_REG_COUNT_MASK ) {
+                                       case 0x00000000:
+                                               strcat(str, " / d8 ");
+                                               break;
+                                       case 0x00000100:
+                                               strcat(str, " / d8,d10 ");
+                                               break;
+                                       case 0x00000200:
+                                               strcat(str, " / d8,d10,d12 ");
+                                               break;
+                                       case 0x00000300:
+                                               strcat(str, " / d8,d10,d12,d14 ");
+                                               break;
+                                       case 0x00000400:
+                                               strcat(str, " / d12,d14 / d8,d9,d10 ");
+                                               break;
+                                       case 0x00000500:
+                                               strcat(str, " / d14 / d8,d9,d10,d11,d12");
+                                               break;
+                                       case 0x00000600:
+                                               strcat(str, " / d8,d9,d10,d11,d12,d13,d14 ");
+                                               break;
+                                       case 0x00000700:
+                                               strcat(str, " / d8,d9,d10,d11,d12,d13,d14 ");
+                                               break;
+                                       default:
+                                               strcat(str, " / unknown D register usage ");
+                                               break;
+                               }
+                       }
+                       
+                       break;
+               default:
+                       if ( encoding == 0 )
+                               strcpy(str, "no unwind information");
+                       else
+                               strcpy(str, "unsupported compact unwind");
+                       break;
+       }
+}
 
 
 template <>
 }
 #endif
 
+template <>
+const char* UnwindPrinter<arm>::personalityName(const macho_relocation_info<arm::P>* reloc)
+{
+       //assert(reloc->r_extern() && "reloc not extern on personality column in __compact_unwind section");
+       //assert((reloc->r_type() == GENERIC_RELOC_VANILLA) && "wrong reloc type on personality column in __compact_unwind section");
+       const macho_nlist<P>& sym = fSymbols[reloc->r_symbolnum()];
+       return &fStrings[sym.n_strx()];
+}
 
 template <typename A>
 bool UnwindPrinter<A>::hasExernReloc(uint64_t sectionOffset, const char** personalityStr, pint_t* addr)
                                                        throw "in universal file, arm64 slice does not contain arm64 mach-o";
                                                break;
 #endif
+                                       case CPU_TYPE_ARM:
+                                               if ( UnwindPrinter<arm>::validFile(p + offset) )
+                                                       UnwindPrinter<arm>::make(p + offset, size, path, showFunctionNames);
+                                               else
+                                                       throw "in universal file, arm slice does not contain arm mach-o";
+                                               break;
                                        default:
                                                        throwf("in universal file, unknown architecture slice 0x%x\n", cputype);
                                        }
                        UnwindPrinter<arm64>::make(p, length, path, showFunctionNames);
                }
 #endif         
+               else if ( UnwindPrinter<arm>::validFile(p) && onlyArchs.count(CPU_TYPE_ARM) ) {
+                       UnwindPrinter<arm>::make(p, length, path, showFunctionNames);
+               }
                else {
                        throw "not a known file type";
                }
                                        else if ( strcmp(arch, "arm64") == 0 )
                                                onlyArchs.insert(CPU_TYPE_ARM64);
 #endif
+                                       else if ( strcmp(arch, "armv7k") == 0 )
+                                               onlyArchs.insert(CPU_TYPE_ARM);
                                        else 
                                                throwf("unknown architecture %s", arch);
                                }