]> git.saurik.com Git - apple/ld64.git/commitdiff
ld64-128.2.tar.gz developer-tools-43 v128.2
authorApple <opensource@apple.com>
Tue, 3 Jan 2012 22:27:18 +0000 (22:27 +0000)
committerApple <opensource@apple.com>
Tue, 3 Jan 2012 22:27:18 +0000 (22:27 +0000)
58 files changed:
ChangeLog
doc/man/man1/ld.1
ld64.xcodeproj/project.pbxproj
src/abstraction/MachOFileAbstraction.hpp
src/ld/HeaderAndLoadCommands.hpp
src/ld/InputFiles.cpp
src/ld/LinkEdit.hpp
src/ld/LinkEditClassic.hpp
src/ld/Options.cpp
src/ld/Options.h
src/ld/OutputFile.cpp
src/ld/OutputFile.h
src/ld/Resolver.cpp
src/ld/Resolver.h
src/ld/SymbolTable.cpp
src/ld/ld.cpp
src/ld/ld.hpp
src/ld/parsers/archive_file.cpp
src/ld/parsers/lto_file.cpp
src/ld/parsers/macho_dylib_file.cpp
src/ld/parsers/macho_relocatable_file.cpp
src/ld/passes/branch_island.cpp
src/ld/passes/dtrace_dof.cpp
src/ld/passes/got.cpp
src/ld/passes/objc.cpp
src/ld/passes/order.cpp [new file with mode: 0644]
src/ld/passes/order.h [new file with mode: 0644]
src/ld/passes/order_file.cpp [deleted file]
src/ld/passes/order_file.h [deleted file]
src/ld/passes/stubs/stub_ppc_classic.hpp [deleted file]
src/ld/passes/stubs/stubs.cpp
src/other/ObjectDump.cpp
src/other/dyldinfo.cpp
src/other/machochecker.cpp
src/other/rebase.cpp
src/other/unwinddump.cpp
unit-tests/test-cases/archive-init-order/Makefile [new file with mode: 0644]
unit-tests/test-cases/archive-init-order/bar.c [new file with mode: 0644]
unit-tests/test-cases/archive-init-order/bar2.c [new file with mode: 0644]
unit-tests/test-cases/archive-init-order/bar3.c [new file with mode: 0644]
unit-tests/test-cases/archive-init-order/foo.c [new file with mode: 0644]
unit-tests/test-cases/archive-init-order/foo2.c [new file with mode: 0644]
unit-tests/test-cases/archive-init-order/foo3.c [new file with mode: 0644]
unit-tests/test-cases/archive-init-order/main.c [new file with mode: 0644]
unit-tests/test-cases/dead_strip-initializers/Makefile [new file with mode: 0644]
unit-tests/test-cases/dead_strip-initializers/main.cxx [new file with mode: 0644]
unit-tests/test-cases/dead_strip-initializers/other.cxx [new file with mode: 0644]
unit-tests/test-cases/dso_handle/Makefile [new file with mode: 0644]
unit-tests/test-cases/dso_handle/test.c [new file with mode: 0644]
unit-tests/test-cases/fatal_warning/Makefile [new file with mode: 0644]
unit-tests/test-cases/fatal_warning/main.c [new file with mode: 0644]
unit-tests/test-cases/lto-dead_strip-unused/Makefile
unit-tests/test-cases/order_file-zero-fill/Makefile [new file with mode: 0644]
unit-tests/test-cases/order_file-zero-fill/foo.c [new file with mode: 0644]
unit-tests/test-cases/order_file-zero-fill/main.c [new file with mode: 0644]
unit-tests/test-cases/order_file-zero-fill/main.expected [new file with mode: 0644]
unit-tests/test-cases/order_file-zero-fill/main.order [new file with mode: 0644]
unit-tests/test-cases/tlv-dead_strip/Makefile

index fd449c8e84271e20e17be723d9b405ce7d961496..0514d7f599f29cbd83e1864fbd81fe05c5d79425 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,88 @@
 
+-------- tagged ld64-128.1
+
+2011-09-13    Nick Kledzik    <kledzik@apple.com>
+
+    <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
+
+2011-09-13    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/10100056> Fix "using ld_classic" warning for i386 kexts
+
+2011-09-13    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/10052396> LTO many have eliminated need for some undefines
+
+-------- tagged ld64-128
+
+2011-09-08    Nick Kledzik    <kledzik@apple.com>
+
+       Rework 8924157 fix to sort all sections
+
+2011-09-07    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/10089743> ER: -current_version should allow 64-bit a.b.c.d.e tuple
+
+2011-09-06    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/10038370> -mdynamic-no-pic broke with movw of weak thumb symbol
+
+2011-09-01    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/10057157> Turn crash into a warning if __dso_handle is defined in user code
+       Added test case: unit-tests/test-cases/dso_handle
+
+2011-08-31    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/6780050> Add -fatal_warnings
+
+2011-08-30    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/8482298> Support .weak_def_can_be_hidden via LTO interface
+
+2011-08-29    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/10043807> improve performance of zerofill->data ordering
+
+2011-08-29    Nick Kledzik    <kledzik@apple.com>
+
+       Implement -print_statistics
+
+2011-08-25    Nick Kledzik    <kledzik@apple.com>
+
+       check for overlaps between pinned segments and regular segments
+
+2011-08-23    Nick Kledzik    <kledzik@apple.com>
+
+       do got elimination more aggressively in static and preload mode
+
+2011-08-22    Nick Kledzik    <kledzik@apple.com>
+
+       enable __dso_handle in -preload
+
+2011-08-22    Nick Kledzik    <kledzik@apple.com>
+
+       fix section$end to sort to end of __mod_init_func section
+
+2011-08-18    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/9737570> __constructor section removed with -dead_strip
+
+2011-08-11    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/8828975> remove ld support for PowerPC
+
+2011-08-11    Nick Kledzik    <kledzik@apple.com>
+
+       Fix spurious -segaddr alignment warning
+
+-------- tagged ld64-127.3
+
+2011-08-31    Nick Kledzik    <kledzik@apple.com>
+
+       <rdar://problem/8924157> [regression] C++ Initializers from archives not sorted
+       Added test case: unit-tests/test-cases/archive-init-order
+
 -------- tagged ld64-127.2
 
 2011-08-15    Nick Kledzik    <kledzik@apple.com>
index 03f257ad95a8750fe0f2f17845d2b50c3d3efbba..dc2a5019cb809e0003a3b7009213a0261b639b25 100644 (file)
@@ -515,6 +515,8 @@ Prints the version of the linker.
 Normally i386 main executables will be marked so that the Mac OS X 10.7 and later kernel 
 will only allow pages with the x-bit to execute instructions. This option overrides that
 behavior and allows instructions on any page to be executed.
+.It Fl fatal_warnings
+Causes the linker to exit with a non-zero value if any warnings were emitted.
 .It Fl no_eh_labels
 Normally in -r mode, the linker produces .eh labels on all FDEs in the __eh_frame section.
 This option suppresses those labels.  Those labels are not needed by the Mac OS X 10.6
@@ -576,7 +578,7 @@ Specifies the minimum space for future expansion of the load commands.  Only use
 install_name_tool to alter the load commands later. Size is a hexadecimal number.
 .It Fl headerpad_max_install_names
 Automatically adds space for future expansion of load commands such that all paths could expand to MAXPATHLEN. 
-Only useful if intend to run install_name_tool to alter the load commands later. Size is a hexadecimal number.
+Only useful if intend to run install_name_tool to alter the load commands later.
 .It Fl bind_at_load
 Sets a bit in the mach header of the resulting binary which tells dyld to bind all symbols when the binary is loaded, rather than lazily.
 .It Fl force_flat_namespace
index ad733949154f803ca94e3efa02d19f696545bc2c..65f20a7967e86f0647de23ce304940c466a38ee1 100644 (file)
@@ -49,7 +49,7 @@
                F97F5029070D0BB200B9FCD7 /* ld.1 in copy man page */ = {isa = PBXBuildFile; fileRef = F97F5028070D0BB200B9FCD7 /* ld.1 */; };
                F98498A310AE2159009E9878 /* compact_unwind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9BA963310A2545C0097A440 /* compact_unwind.cpp */; };
                F98498A410AE2159009E9878 /* got.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9AB1063107D380700E54C9E /* got.cpp */; };
-               F9849E3610B38EF5009E9878 /* order_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9849E3410B38EF5009E9878 /* order_file.cpp */; };
+               F9849E3610B38EF5009E9878 /* order.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9849E3410B38EF5009E9878 /* order.cpp */; };
                F984A38210BB4B0D009E9878 /* branch_island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F984A38010BB4B0D009E9878 /* branch_island.cpp */; };
                F989D30D106826020014B60C /* OutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F989D30B106826020014B60C /* OutputFile.cpp */; };
                F9A3DDD30ED762E400C590B9 /* PruneTrie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9A3DDD20ED762E400C590B9 /* PruneTrie.cpp */; };
                F971EED306D5ACF60041D381 /* ObjectDump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ObjectDump; sourceTree = BUILT_PRODUCTS_DIR; };
                F971EED706D5AD240041D381 /* ObjectDump.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectDump.cpp; path = src/other/ObjectDump.cpp; sourceTree = "<group>"; };
                F97F5028070D0BB200B9FCD7 /* ld.1 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.man; name = ld.1; path = doc/man/man1/ld.1; sourceTree = "<group>"; };
-               F984963310AB9318009E9878 /* stub_ppc_classic.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = stub_ppc_classic.hpp; sourceTree = "<group>"; };
-               F9849E3410B38EF5009E9878 /* order_file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = order_file.cpp; sourceTree = "<group>"; };
-               F9849E3510B38EF5009E9878 /* order_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = order_file.h; sourceTree = "<group>"; };
+               F9849E3410B38EF5009E9878 /* order.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = order.cpp; sourceTree = "<group>"; };
+               F9849E3510B38EF5009E9878 /* order.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = order.h; sourceTree = "<group>"; };
                F984A13B10B614CF009E9878 /* stub_arm_classic.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = stub_arm_classic.hpp; sourceTree = "<group>"; };
                F984A38010BB4B0D009E9878 /* branch_island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = branch_island.cpp; sourceTree = "<group>"; };
                F984A38110BB4B0D009E9878 /* branch_island.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = branch_island.h; sourceTree = "<group>"; };
                                F984A38110BB4B0D009E9878 /* branch_island.h */,
                                F9AA44DA1294885F00CB8390 /* branch_shim.cpp */,
                                F9AA44DB1294885F00CB8390 /* branch_shim.h */,
-                               F9849E3410B38EF5009E9878 /* order_file.cpp */,
-                               F9849E3510B38EF5009E9878 /* order_file.h */,
+                               F9849E3410B38EF5009E9878 /* order.cpp */,
+                               F9849E3510B38EF5009E9878 /* order.h */,
                                F9BA963310A2545C0097A440 /* compact_unwind.cpp */,
                                F9BA963410A2545C0097A440 /* compact_unwind.h */,
                                F9AA67B410570C41003E3539 /* dtrace_dof.h */,
                                F9BA8A7E1096150F0097A440 /* stub_x86_classic.hpp */,
                                F989D0391062E6350014B60C /* stub_x86_64.hpp */,
                                F92D9C2710657AAB00FF369B /* stub_x86_64_classic.hpp */,
-                               F984963310AB9318009E9878 /* stub_ppc_classic.hpp */,
                        );
                        path = stubs;
                        sourceTree = "<group>";
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = /bin/sh;
-                       shellScript = "\nif [ -n \"${RC_PURPLE}\" ]; then\n\techo \"here\"\n\tmkdir -p  ${DSTROOT}/Developer/Platforms/iPhoneOS.platform/Developer/\n\tmv ${DSTROOT}/usr ${DSTROOT}/Developer/Platforms/iPhoneOS.platform/Developer\nfi\n";
+                       shellScript = "\nif [ -n \"${DT_TOOLCHAIN_DIR}\" ]\nthen\n\tmkdir -p  \"${DSTROOT}/${DT_TOOLCHAIN_DIR}\"\n\tmv ${DSTROOT}/usr \"${DSTROOT}/${DT_TOOLCHAIN_DIR}\"\nelse\n\tif [ -n \"${RC_PURPLE}\" ]\n\tthen\n\t\tmkdir -p  ${DSTROOT}/Developer/Platforms/iPhoneOS.platform/Developer/\n\t\tmv ${DSTROOT}/usr ${DSTROOT}/Developer/Platforms/iPhoneOS.platform/Developer\n\tfi\nfi\n\n";
                        showEnvVarsInLog = 0;
                };
                F9E8DB4D11921594007B4D6A /* make config.h */ = {
                                F98498A310AE2159009E9878 /* compact_unwind.cpp in Sources */,
                                F98498A410AE2159009E9878 /* got.cpp in Sources */,
                                F9BA955E10A233000097A440 /* huge.cpp in Sources */,
-                               F9849E3610B38EF5009E9878 /* order_file.cpp in Sources */,
+                               F9849E3610B38EF5009E9878 /* order.cpp in Sources */,
                                F984A38210BB4B0D009E9878 /* branch_island.cpp in Sources */,
                                F9A4DB9110F816FF00BD8423 /* objc.cpp in Sources */,
                                F9AE20FF1107D1440007ED5D /* dylibs.cpp in Sources */,
                                ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
                                COPY_PHASE_STRIP = NO;
                                CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
-                               DEAD_CODE_STRIPPING = NO;
+                               DEAD_CODE_STRIPPING = YES;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
                                COPY_PHASE_STRIP = NO;
                                CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
+                               DEAD_CODE_STRIPPING = YES;
                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
                                COPY_PHASE_STRIP = NO;
                                CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
+                               DEAD_CODE_STRIPPING = YES;
                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
index f5f073b6691a41ac3a48c2e6d072a36264b9f68c..f4d136f95eb172e92eb1cbf34df4eb2620d56840 100644 (file)
@@ -30,7 +30,6 @@
 #include <mach-o/fat.h>
 #include <mach-o/stab.h>
 #include <mach-o/reloc.h>
-#include <mach-o/ppc/reloc.h>
 #include <mach-o/x86_64/reloc.h>
 #include <mach-o/arm/reloc.h>
 #include <mach-o/compact_unwind_encoding.h>
@@ -1279,8 +1278,13 @@ public:
        uint32_t                version() const                                                 INLINE { return fields.version; }
        void                    set_version(uint32_t value)                             INLINE { E::set32(fields.version, value); }
 
-       uint32_t                reserved() const                                                INLINE { return fields.reserved; }
-       void                    set_reserved(uint32_t value)                    INLINE { E::set32(fields.reserved, value); }
+#ifdef LC_SOURCE_VERSION
+       uint32_t                sdk() const                                                             INLINE { return fields.sdk; }
+       void                    set_sdk(uint32_t value)                                 INLINE { E::set32(fields.sdk, value); }
+#else
+       uint32_t                sdk() const                                                             INLINE { return fields.reserved; }
+       void                    set_sdk(uint32_t value)                                 INLINE { E::set32(fields.reserved, value); }
+#endif
 
        typedef typename P::E           E;
 private:
index 395fc99e95054958857413a2f8e0e5821e3f0fd2..903a2bfb37dcda15fe6a8bb93114e353e81f3402 100644 (file)
@@ -519,33 +519,15 @@ uint32_t HeaderAndLoadCommandsAtom<A>::flags() const
        return bits;
 }
 
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc>::magic() const             { return MH_MAGIC; }
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc64>::magic() const           { return MH_MAGIC_64; }
 template <> uint32_t HeaderAndLoadCommandsAtom<x86>::magic() const             { return MH_MAGIC; }
 template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::magic() const  { return MH_MAGIC_64; }
 template <> uint32_t HeaderAndLoadCommandsAtom<arm>::magic() const             { return MH_MAGIC; }
 
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc>::cpuType() const   { return CPU_TYPE_POWERPC; }
-template <> uint32_t HeaderAndLoadCommandsAtom<ppc64>::cpuType() const { return CPU_TYPE_POWERPC64; }
 template <> uint32_t HeaderAndLoadCommandsAtom<x86>::cpuType() const   { return CPU_TYPE_I386; }
 template <> uint32_t HeaderAndLoadCommandsAtom<x86_64>::cpuType() const        { return CPU_TYPE_X86_64; }
 template <> uint32_t HeaderAndLoadCommandsAtom<arm>::cpuType() const   { return CPU_TYPE_ARM; }
 
 
-template <>
-uint32_t HeaderAndLoadCommandsAtom<ppc>::cpuSubType() const
-{
-       return _state.cpuSubType;
-}
-
-template <>
-uint32_t HeaderAndLoadCommandsAtom<ppc64>::cpuSubType() const
-{
-       if ( (_options.outputKind() == Options::kDynamicExecutable) && (_options.macosxVersionMin() >= ld::mac10_5) )
-               return (CPU_SUBTYPE_POWERPC_ALL | 0x80000000);
-       else
-               return CPU_SUBTYPE_POWERPC_ALL;
-}
 
 template <>
 uint32_t HeaderAndLoadCommandsAtom<x86>::cpuSubType() const
@@ -973,7 +955,7 @@ uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibIDLoadCommand(uint8_t* p) const
        cmd->set_cmdsize(sz);
        cmd->set_name_offset();
        cmd->set_timestamp(1);  // needs to be some constant value that is different than DylibLoadCommandsAtom uses
-       cmd->set_current_version(_options.currentVersion());
+       cmd->set_current_version(_options.currentVersion32());
        cmd->set_compatibility_version(_options.compatibilityVersion());
        strcpy((char*)&p[sizeof(macho_dylib_command<P>)], _options.installPath());
        return p + sz;
@@ -1024,62 +1006,18 @@ uint8_t* HeaderAndLoadCommandsAtom<A>::copyVersionLoadCommand(uint8_t* p) const
                cmd->set_cmd(LC_VERSION_MIN_MACOSX);
                cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
                cmd->set_version((uint32_t)macVersion);
-               cmd->set_reserved(0);
+               cmd->set_sdk(0);
        }
        else {
                cmd->set_cmd(LC_VERSION_MIN_IPHONEOS);
                cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
                cmd->set_version((uint32_t)iOSVersion);
-               cmd->set_reserved(0);
+               cmd->set_sdk(0);
        }
        return p + sizeof(macho_version_min_command<P>);
 }
 
 
-template <>
-uint32_t HeaderAndLoadCommandsAtom<ppc>::threadLoadCommandSize() const
-{
-       return this->alignedSize(16 + 40*4);    // base size + PPC_THREAD_STATE_COUNT * 4
-}
-
-
-template <>
-uint8_t* HeaderAndLoadCommandsAtom<ppc>::copyThreadsLoadCommand(uint8_t* p) const
-{
-       assert(_state.entryPoint != NULL);
-       pint_t start = _state.entryPoint->finalAddress(); 
-       macho_thread_command<ppc::P>* cmd = (macho_thread_command<ppc::P>*)p;
-       cmd->set_cmd(LC_UNIXTHREAD);
-       cmd->set_cmdsize(threadLoadCommandSize());
-       cmd->set_flavor(1);                             // PPC_THREAD_STATE
-       cmd->set_count(40);                             // PPC_THREAD_STATE_COUNT;
-       cmd->set_thread_register(0, start);
-       if ( _options.hasCustomStack() )
-               cmd->set_thread_register(3, _options.customStackAddr());        // r1
-       return p + threadLoadCommandSize();
-}
-
-template <>
-uint32_t HeaderAndLoadCommandsAtom<ppc64>::threadLoadCommandSize() const
-{
-       return this->alignedSize(16 + 76*4);    // base size + PPC_THREAD_STATE64_COUNT * 4
-}
-
-template <>
-uint8_t* HeaderAndLoadCommandsAtom<ppc64>::copyThreadsLoadCommand(uint8_t* p) const
-{
-       assert(_state.entryPoint != NULL);
-       pint_t start = _state.entryPoint->finalAddress(); 
-       macho_thread_command<ppc::P>* cmd = (macho_thread_command<ppc::P>*)p;
-       cmd->set_cmd(LC_UNIXTHREAD);
-       cmd->set_cmdsize(threadLoadCommandSize());
-       cmd->set_flavor(5);                             // PPC_THREAD_STATE64
-       cmd->set_count(76);                             // PPC_THREAD_STATE64_COUNT;
-       cmd->set_thread_register(0, start);
-       if ( _options.hasCustomStack() )
-               cmd->set_thread_register(3, _options.customStackAddr());        // r1
-       return p + threadLoadCommandSize();
-}
 
 template <>
 uint32_t HeaderAndLoadCommandsAtom<x86>::threadLoadCommandSize() const
index 84a2297bb72949c50ea45614d6df55711e14516b..7b05a963511d92771d018df9b8048802d9a2db50 100644 (file)
@@ -627,12 +627,8 @@ void InputFiles::inferArchitecture(Options& opts, const char** archName)
 
        // no thin .o files found, so default to same architecture this tool was built as
        warning("-arch not specified");
-#if __ppc__
-       opts.setArchitecture(CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL);
-#elif __i386__
+#if __i386__
        opts.setArchitecture(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL);
-#elif __ppc64__
-       opts.setArchitecture(CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_ALL);
 #elif __x86_64__
        opts.setArchitecture(CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL);
 #elif __arm__
@@ -811,6 +807,7 @@ bool InputFiles::forEachInitialAtom(ld::File::AtomHandler& handler) const
                        case Options::kPreload:
                                // add implicit __mh_preload_header label
                                handler.doAtom(DSOHandleAtom::_s_atomPreload);
+                               handler.doAtom(DSOHandleAtom::_s_atomAll);
                                break;
                        case Options::kObjectFile:
                                handler.doAtom(DSOHandleAtom::_s_atomObjectFile);
index bf9026b5bf0cc93295934f48cd195b7d5265ebf8..7bca2e309a0f69ddc87905f168eddb6332e0d745 100644 (file)
@@ -1063,7 +1063,6 @@ private:
 
        mutable std::vector<uint64_t>                           _32bitPointerLocations;
        mutable std::vector<uint64_t>                           _64bitPointerLocations;
-       mutable std::vector<uint64_t>                           _ppcHi16Locations;
        mutable std::vector<uint64_t>                           _thumbLo16Locations;
        mutable std::vector<uint64_t>                           _thumbHi16Locations[16];
        mutable std::vector<uint64_t>                           _armLo16Locations;
@@ -1146,36 +1145,6 @@ void SplitSegInfoAtom<arm>::addSplitSegInfo(uint64_t address, ld::Fixup::Kind ki
 }
 
 
-template <>
-void SplitSegInfoAtom<ppc>::addSplitSegInfo(uint64_t address, ld::Fixup::Kind kind, uint32_t extra) const
-{
-       switch (kind) {
-               case ld::Fixup::kindStorePPCPicHigh16AddLow:
-                       _ppcHi16Locations.push_back(address);
-                       break;
-               case ld::Fixup::kindStoreBigEndian32:
-                       _32bitPointerLocations.push_back(address);
-                       break;
-               default:
-                       warning("codegen at address 0x%08llX prevents image from working in dyld shared cache", address);
-                       break;
-       }
-}
-
-
-template <>
-void SplitSegInfoAtom<ppc64>::addSplitSegInfo(uint64_t address, ld::Fixup::Kind kind, uint32_t extra) const
-{
-       switch (kind) {
-               case ld::Fixup::kindStorePPCPicHigh16AddLow:
-                       _ppcHi16Locations.push_back(address);
-                       break;
-               default:
-                       warning("codegen at address 0x%08llX prevents image from working in dyld shared cache", address);
-                       break;
-       }
-}
-
 
 template <typename A>
 void SplitSegInfoAtom<A>::uleb128EncodeAddresses(const std::vector<uint64_t>& locations) const
@@ -1231,14 +1200,6 @@ void SplitSegInfoAtom<A>::encode() const
                this->_encodedData.append_byte(0); // terminator
        }
 
-       if ( _ppcHi16Locations.size() != 0 ) {
-               this->_encodedData.append_byte(3);
-               //fprintf(stderr, "type 3:\n");
-               std::sort(_ppcHi16Locations.begin(), _ppcHi16Locations.end());
-               this->uleb128EncodeAddresses(_ppcHi16Locations);
-               this->_encodedData.append_byte(0); // terminator
-       }
-
        if ( _thumbLo16Locations.size() != 0 ) {
                this->_encodedData.append_byte(5);
                //fprintf(stderr, "type 5:\n");
@@ -1286,7 +1247,6 @@ void SplitSegInfoAtom<A>::encode() const
        // clean up temporaries
        _32bitPointerLocations.clear();
        _64bitPointerLocations.clear();
-       _ppcHi16Locations.clear();
 }
 
 
index 1429d95128735a89e31a6447fda153e8e00fcefb..7fbc7550e92751185320fab3a08ffd1f3321f706 100644 (file)
@@ -798,52 +798,6 @@ void LocalRelocationsAtom<A>::addPointerReloc(uint64_t addr, uint32_t symNum)
 template <typename A>
 void LocalRelocationsAtom<A>::addTextReloc(uint64_t addr, ld::Fixup::Kind kind, uint64_t targetAddr, uint32_t symNum)
 {
-       macho_relocation_info<P> reloc1;
-       macho_relocation_info<P> reloc2;
-       switch ( kind ) {
-               case ld::Fixup::kindStorePPCAbsLow14:
-               case ld::Fixup::kindStorePPCAbsLow16:
-                       // a reference to the absolute address of something in this same linkage unit can be 
-                       // encoded as a local text reloc in a dylib or bundle 
-                       if ( _options.outputSlidable() ) {
-                               reloc1.set_r_address(addr);
-                               reloc1.set_r_symbolnum(symNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(false);
-                               reloc1.set_r_type(kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14);
-                               reloc2.set_r_address(targetAddr >> 16);
-                               reloc2.set_r_symbolnum(0);
-                               reloc2.set_r_pcrel(false);
-                               reloc2.set_r_length(2);
-                               reloc2.set_r_extern(false);
-                               reloc2.set_r_type(PPC_RELOC_PAIR);
-                               _relocs.push_back(reloc1);
-                               _relocs.push_back(reloc2);
-                       }
-                       break;
-               case ld::Fixup::kindStorePPCAbsHigh16AddLow:
-               case ld::Fixup::kindStorePPCAbsHigh16:
-                       if ( _options.outputSlidable() ) {
-                               reloc1.set_r_address(addr);
-                               reloc1.set_r_symbolnum(symNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(false);
-                               reloc1.set_r_type(kind==ld::Fixup::kindStorePPCAbsHigh16AddLow ? PPC_RELOC_HA16 : PPC_RELOC_HI16);
-                               reloc2.set_r_address(targetAddr & 0xFFFF);
-                               reloc2.set_r_symbolnum(0);
-                               reloc2.set_r_pcrel(false);
-                               reloc2.set_r_length(2);
-                               reloc2.set_r_extern(false);
-                               reloc2.set_r_type(PPC_RELOC_PAIR);
-                               _relocs.push_back(reloc1);
-                               _relocs.push_back(reloc2);
-                       }
-                       break;
-               default:
-                       break;
-       }
 }
 
 
@@ -967,9 +921,7 @@ uint64_t ExternalRelocationsAtom<A>::size() const
 
 template <> uint32_t ExternalRelocationsAtom<arm>::pointerReloc() { return ARM_RELOC_VANILLA; }
 template <> uint32_t ExternalRelocationsAtom<x86>::pointerReloc() { return GENERIC_RELOC_VANILLA; }
-template <> uint32_t ExternalRelocationsAtom<ppc>::pointerReloc() { return PPC_RELOC_VANILLA; }
 template <> uint32_t ExternalRelocationsAtom<x86_64>::pointerReloc() { return X86_64_RELOC_UNSIGNED; }
-template <> uint32_t ExternalRelocationsAtom<ppc64>::pointerReloc() { return PPC_RELOC_VANILLA; }
 
 
 template <> uint32_t ExternalRelocationsAtom<x86_64>::callReloc() { return X86_64_RELOC_BRANCH; }
@@ -1664,582 +1616,6 @@ void SectionRelocationsAtom<arm>::encodeSectionReloc(ld::Internal::FinalSection*
 }
 
 
-template <>
-void SectionRelocationsAtom<ppc>::encodeSectionReloc(ld::Internal::FinalSection* sect, 
-                                                                                                       const Entry& entry, std::vector<macho_relocation_info<P> >& relocs)
-{
-       macho_relocation_info<P> reloc1;
-       macho_relocation_info<P> reloc2;
-       macho_scattered_relocation_info<P>* sreloc1 = (macho_scattered_relocation_info<P>*)&reloc1;
-       macho_scattered_relocation_info<P>* sreloc2 = (macho_scattered_relocation_info<P>*)&reloc2;
-       uint64_t address = entry.inAtom->finalAddress()+entry.offsetInAtom - sect->address;
-       bool external = entry.toTargetUsesExternalReloc;
-       uint32_t symbolNum = sectSymNum(external, entry.toTarget);
-       bool fromExternal = false;
-       uint32_t fromSymbolNum = 0;
-       if ( entry.fromTarget != NULL ) {
-               fromExternal = entry.fromTargetUsesExternalReloc;
-               fromSymbolNum= sectSymNum(fromExternal, entry.fromTarget);
-       }
-       uint32_t toAddr;
-       uint32_t fromAddr;
-       
-       switch ( entry.kind ) {
-       
-               case ld::Fixup::kindStorePPCBranch24:
-               case ld::Fixup::kindStoreTargetAddressPPCBranch24:
-               case ld::Fixup::kindStorePPCDtraceCallSiteNop:
-               case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(true);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_BR24);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(true);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_BR24);
-                       }
-                       relocs.push_back(reloc1);
-                       break;
-
-               case ld::Fixup::kindStorePPCBranch14:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(true);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_BR14);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(true);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_BR14);
-                       }
-                       relocs.push_back(reloc1);
-                       break;
-
-               case ld::Fixup::kindStoreBigEndian32:
-               case ld::Fixup::kindStoreTargetAddressBigEndian32:
-                       if ( entry.fromTarget != NULL ) {
-                               // this is a pointer-diff
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               if ( entry.toTarget->scope() == ld::Atom::scopeTranslationUnit )
-                                       sreloc1->set_r_type(PPC_RELOC_LOCAL_SECTDIFF);
-                               else
-                                       sreloc1->set_r_type(PPC_RELOC_SECTDIFF);
-                               sreloc1->set_r_address(address);
-                               if ( entry.toTarget == entry.inAtom )
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress()+entry.toAddend);
-                               else
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                               sreloc2->set_r_scattered(true);
-                               sreloc2->set_r_pcrel(false);
-                               sreloc2->set_r_length(2);
-                               sreloc2->set_r_type(PPC_RELOC_PAIR);
-                               sreloc2->set_r_address(0);
-                               if ( entry.fromTarget == entry.inAtom ) {
-                                       if ( entry.fromAddend > entry.fromTarget->size() )
-                                               sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.offsetInAtom);
-                                       else
-                                               sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.fromAddend);
-                               }
-                               else
-                                       sreloc2->set_r_value(entry.fromTarget->finalAddress());
-                               relocs.push_back(reloc1);
-                               relocs.push_back(reloc2);
-                       }
-                       else {
-                               // regular pointer
-                               if ( !external && (entry.toAddend != 0) ) {
-                                       // use scattered reloc is target offset is non-zero
-                                       sreloc1->set_r_scattered(true);
-                                       sreloc1->set_r_pcrel(false);
-                                       sreloc1->set_r_length(2);
-                                       sreloc1->set_r_type(GENERIC_RELOC_VANILLA);
-                                       sreloc1->set_r_address(address);
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                               }
-                               else {
-                                       reloc1.set_r_address(address);
-                                       reloc1.set_r_symbolnum(symbolNum);
-                                       reloc1.set_r_pcrel(false);
-                                       reloc1.set_r_length(2);
-                                       reloc1.set_r_extern(external);
-                                       reloc1.set_r_type(GENERIC_RELOC_VANILLA);
-                               }
-                               relocs.push_back(reloc1);
-                       }
-                       break;
-                       
-               case ld::Fixup::kindStorePPCAbsLow14:
-               case ld::Fixup::kindStorePPCAbsLow16:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14);
-                       }
-                       if ( external )
-                               reloc2.set_r_address(entry.toAddend >> 16);
-                       else
-                               reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) >> 16);
-                       reloc2.set_r_symbolnum(0);
-                       reloc2.set_r_pcrel(false);
-                       reloc2.set_r_length(2);
-                       reloc2.set_r_extern(false);
-                       reloc2.set_r_type(PPC_RELOC_PAIR);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCAbsHigh16:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_HI16);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_HI16);
-                       }
-                       if ( external )
-                               reloc2.set_r_address(entry.toAddend & 0x0000FFFF);
-                       else
-                               reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF);
-                       reloc2.set_r_symbolnum(0);
-                       reloc2.set_r_pcrel(false);
-                       reloc2.set_r_length(2);
-                       reloc2.set_r_extern(false);
-                       reloc2.set_r_type(PPC_RELOC_PAIR);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCAbsHigh16AddLow:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_HA16);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_HA16);
-                       }
-                       if ( external )
-                               reloc2.set_r_address(entry.toAddend & 0x0000FFFF);
-                       else
-                               reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF);
-                       reloc2.set_r_symbolnum(0);
-                       reloc2.set_r_pcrel(false);
-                       reloc2.set_r_length(2);
-                       reloc2.set_r_extern(false);
-                       reloc2.set_r_type(PPC_RELOC_PAIR);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCPicLow14:
-               case ld::Fixup::kindStorePPCPicLow16:
-                       fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend;
-                       toAddr = entry.toTarget->finalAddress() + entry.toAddend;
-                       sreloc1->set_r_scattered(true);
-                       sreloc1->set_r_pcrel(false);
-                       sreloc1->set_r_length(2);
-                       sreloc1->set_r_type(entry.kind == ld::Fixup::kindStorePPCPicLow16 ? PPC_RELOC_LO16_SECTDIFF : PPC_RELOC_LO14_SECTDIFF);
-                       sreloc1->set_r_address(address);
-                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       sreloc2->set_r_scattered(true);
-                       sreloc2->set_r_pcrel(false);
-                       sreloc2->set_r_length(2);
-                       sreloc2->set_r_type(PPC_RELOC_PAIR);
-                       sreloc2->set_r_address(((toAddr-fromAddr) >> 16) & 0xFFFF);
-                       sreloc2->set_r_value(fromAddr);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCPicHigh16AddLow:
-                       fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend;
-                       toAddr = entry.toTarget->finalAddress() + entry.toAddend;
-                       sreloc1->set_r_scattered(true);
-                       sreloc1->set_r_pcrel(false);
-                       sreloc1->set_r_length(2);
-                       sreloc1->set_r_type(PPC_RELOC_HA16_SECTDIFF);
-                       sreloc1->set_r_address(address);
-                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       sreloc2->set_r_scattered(true);
-                       sreloc2->set_r_pcrel(false);
-                       sreloc2->set_r_length(2);
-                       sreloc2->set_r_type(PPC_RELOC_PAIR);
-                       sreloc2->set_r_address((toAddr-fromAddr) & 0xFFFF);
-                       sreloc2->set_r_value(fromAddr);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               default:
-                       assert(0 && "need to handle -r reloc");
-               
-       }
-}
-
-template <>
-void SectionRelocationsAtom<ppc64>::encodeSectionReloc(ld::Internal::FinalSection* sect, 
-                                                                                                       const Entry& entry, std::vector<macho_relocation_info<P> >& relocs)
-{
-       macho_relocation_info<P> reloc1;
-       macho_relocation_info<P> reloc2;
-       macho_scattered_relocation_info<P>* sreloc1 = (macho_scattered_relocation_info<P>*)&reloc1;
-       macho_scattered_relocation_info<P>* sreloc2 = (macho_scattered_relocation_info<P>*)&reloc2;
-       uint64_t address = entry.inAtom->finalAddress()+entry.offsetInAtom - sect->address;
-       bool external = entry.toTargetUsesExternalReloc;
-       uint32_t symbolNum = sectSymNum(external, entry.toTarget);
-       bool fromExternal = false;
-       uint32_t fromSymbolNum = 0;
-       if ( entry.fromTarget != NULL ) {
-               fromExternal = entry.fromTargetUsesExternalReloc;
-               fromSymbolNum= sectSymNum(fromExternal, entry.fromTarget);
-       }
-       uint32_t toAddr;
-       uint32_t fromAddr;
-       
-       switch ( entry.kind ) {
-       
-               case ld::Fixup::kindStorePPCBranch24:
-               case ld::Fixup::kindStoreTargetAddressPPCBranch24:
-               case ld::Fixup::kindStorePPCDtraceCallSiteNop:
-               case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(true);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_BR24);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(true);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_BR24);
-                       }
-                       relocs.push_back(reloc1);
-                       break;
-
-               case ld::Fixup::kindStorePPCBranch14:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(true);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_BR14);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(true);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_BR14);
-                       }
-                       relocs.push_back(reloc1);
-                       break;
-
-               case ld::Fixup::kindStoreBigEndian32:
-               case ld::Fixup::kindStoreTargetAddressBigEndian32:
-                       if ( entry.fromTarget != NULL ) {
-                               // this is a pointer-diff
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               if ( entry.toTarget->scope() == ld::Atom::scopeTranslationUnit )
-                                       sreloc1->set_r_type(PPC_RELOC_LOCAL_SECTDIFF);
-                               else
-                                       sreloc1->set_r_type(PPC_RELOC_SECTDIFF);
-                               sreloc1->set_r_address(address);
-                               if ( entry.toTarget == entry.inAtom )
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress()+entry.toAddend);
-                               else
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                               sreloc2->set_r_scattered(true);
-                               sreloc2->set_r_pcrel(false);
-                               sreloc2->set_r_length(2);
-                               sreloc2->set_r_type(PPC_RELOC_PAIR);
-                               sreloc2->set_r_address(0);
-                               if ( entry.fromTarget == entry.inAtom ) {
-                                       if ( entry.fromAddend > entry.fromTarget->size() )
-                                               sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.offsetInAtom);
-                                       else
-                                               sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.fromAddend);
-                               }
-                               else
-                                       sreloc2->set_r_value(entry.fromTarget->finalAddress());
-                               relocs.push_back(reloc1);
-                               relocs.push_back(reloc2);
-                       }
-                       else {
-                               // regular pointer
-                               if ( !external && (entry.toAddend != 0) ) {
-                                       // use scattered reloc is target offset is non-zero
-                                       sreloc1->set_r_scattered(true);
-                                       sreloc1->set_r_pcrel(false);
-                                       sreloc1->set_r_length(2);
-                                       sreloc1->set_r_type(GENERIC_RELOC_VANILLA);
-                                       sreloc1->set_r_address(address);
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                               }
-                               else {
-                                       reloc1.set_r_address(address);
-                                       reloc1.set_r_symbolnum(symbolNum);
-                                       reloc1.set_r_pcrel(false);
-                                       reloc1.set_r_length(2);
-                                       reloc1.set_r_extern(external);
-                                       reloc1.set_r_type(GENERIC_RELOC_VANILLA);
-                               }
-                               relocs.push_back(reloc1);
-                       }
-                       break;
-                       
-               case ld::Fixup::kindStoreBigEndian64:
-               case ld::Fixup::kindStoreTargetAddressBigEndian64:
-                       if ( entry.fromTarget != NULL ) {
-                               // this is a pointer-diff
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(3);
-                               if ( entry.toTarget->scope() == ld::Atom::scopeTranslationUnit )
-                                       sreloc1->set_r_type(PPC_RELOC_LOCAL_SECTDIFF);
-                               else
-                                       sreloc1->set_r_type(PPC_RELOC_SECTDIFF);
-                               sreloc1->set_r_address(address);
-                               if ( entry.toTarget == entry.inAtom )
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress()+entry.toAddend);
-                               else
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                               sreloc2->set_r_scattered(true);
-                               sreloc2->set_r_pcrel(false);
-                               sreloc2->set_r_length(3);
-                               sreloc2->set_r_type(PPC_RELOC_PAIR);
-                               sreloc2->set_r_address(0);
-                               if ( entry.fromTarget == entry.inAtom ) {
-                                       if ( entry.fromAddend > entry.fromTarget->size() )
-                                               sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.offsetInAtom);
-                                       else
-                                               sreloc2->set_r_value(entry.fromTarget->finalAddress()+entry.fromAddend);
-                               }
-                               else
-                                       sreloc2->set_r_value(entry.fromTarget->finalAddress());
-                               relocs.push_back(reloc1);
-                               relocs.push_back(reloc2);
-                       }
-                       else {
-                               // regular pointer
-                               if ( !external && (entry.toAddend != 0) ) {
-                                       // use scattered reloc is target offset is non-zero
-                                       sreloc1->set_r_scattered(true);
-                                       sreloc1->set_r_pcrel(false);
-                                       sreloc1->set_r_length(3);
-                                       sreloc1->set_r_type(GENERIC_RELOC_VANILLA);
-                                       sreloc1->set_r_address(address);
-                                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                               }
-                               else {
-                                       reloc1.set_r_address(address);
-                                       reloc1.set_r_symbolnum(symbolNum);
-                                       reloc1.set_r_pcrel(false);
-                                       reloc1.set_r_length(3);
-                                       reloc1.set_r_extern(external);
-                                       reloc1.set_r_type(GENERIC_RELOC_VANILLA);
-                               }
-                               relocs.push_back(reloc1);
-                       }
-                       break;
-
-               case ld::Fixup::kindStorePPCAbsLow14:
-               case ld::Fixup::kindStorePPCAbsLow16:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(entry.kind==ld::Fixup::kindStorePPCAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14);
-                       }
-                       if ( external )
-                               reloc2.set_r_address(entry.toAddend >> 16);
-                       else
-                               reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) >> 16);
-                       reloc2.set_r_symbolnum(0);
-                       reloc2.set_r_pcrel(false);
-                       reloc2.set_r_length(2);
-                       reloc2.set_r_extern(false);
-                       reloc2.set_r_type(PPC_RELOC_PAIR);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCAbsHigh16:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_HI16);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_HI16);
-                       }
-                       if ( external )
-                               reloc2.set_r_address(entry.toAddend & 0x0000FFFF);
-                       else
-                               reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF);
-                       reloc2.set_r_symbolnum(0);
-                       reloc2.set_r_pcrel(false);
-                       reloc2.set_r_length(2);
-                       reloc2.set_r_extern(false);
-                       reloc2.set_r_type(PPC_RELOC_PAIR);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCAbsHigh16AddLow:
-                       if ( !external && (entry.toAddend != 0) ) {
-                               // use scattered reloc if target offset is non-zero
-                               sreloc1->set_r_scattered(true);
-                               sreloc1->set_r_pcrel(false);
-                               sreloc1->set_r_length(2);
-                               sreloc1->set_r_type(PPC_RELOC_HA16);
-                               sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       }
-                       else {
-                               reloc1.set_r_address(address);
-                               reloc1.set_r_symbolnum(symbolNum);
-                               reloc1.set_r_pcrel(false);
-                               reloc1.set_r_length(2);
-                               reloc1.set_r_extern(external);
-                               reloc1.set_r_type(PPC_RELOC_HA16);
-                       }
-                       if ( external )
-                               reloc2.set_r_address(entry.toAddend & 0x0000FFFF);
-                       else
-                               reloc2.set_r_address((entry.toTarget->finalAddress()+entry.toAddend) & 0x0000FFFF);
-                       reloc2.set_r_symbolnum(0);
-                       reloc2.set_r_pcrel(false);
-                       reloc2.set_r_length(2);
-                       reloc2.set_r_extern(false);
-                       reloc2.set_r_type(PPC_RELOC_PAIR);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCPicLow14:
-               case ld::Fixup::kindStorePPCPicLow16:
-                       fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend;
-                       toAddr = entry.toTarget->finalAddress() + entry.toAddend;
-                       sreloc1->set_r_scattered(true);
-                       sreloc1->set_r_pcrel(false);
-                       sreloc1->set_r_length(2);
-                       sreloc1->set_r_type(entry.kind == ld::Fixup::kindStorePPCPicLow16 ? PPC_RELOC_LO16_SECTDIFF : PPC_RELOC_LO14_SECTDIFF);
-                       sreloc1->set_r_address(address);
-                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       sreloc2->set_r_scattered(true);
-                       sreloc2->set_r_pcrel(false);
-                       sreloc2->set_r_length(2);
-                       sreloc2->set_r_type(PPC_RELOC_PAIR);
-                       sreloc2->set_r_address(((toAddr-fromAddr) >> 16) & 0xFFFF);
-                       sreloc2->set_r_value(fromAddr);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               case ld::Fixup::kindStorePPCPicHigh16AddLow:
-                       fromAddr = entry.fromTarget->finalAddress() + entry.fromAddend;
-                       toAddr = entry.toTarget->finalAddress() + entry.toAddend;
-                       sreloc1->set_r_scattered(true);
-                       sreloc1->set_r_pcrel(false);
-                       sreloc1->set_r_length(2);
-                       sreloc1->set_r_type(PPC_RELOC_HA16_SECTDIFF);
-                       sreloc1->set_r_address(address);
-                       sreloc1->set_r_value(entry.toTarget->finalAddress());
-                       sreloc2->set_r_scattered(true);
-                       sreloc2->set_r_pcrel(false);
-                       sreloc2->set_r_length(2);
-                       sreloc2->set_r_type(PPC_RELOC_PAIR);
-                       sreloc2->set_r_address((toAddr-fromAddr) & 0xFFFF);
-                       sreloc2->set_r_value(fromAddr);
-                       relocs.push_back(reloc1);
-                       relocs.push_back(reloc2);
-                       break;
-                       
-               default:
-                       assert(0 && "need to handle -r reloc");
-               
-       }
-}
 
 template <typename A>
 void SectionRelocationsAtom<A>::addSectionReloc(ld::Internal::FinalSection*    sect, ld::Fixup::Kind kind, 
index 3f5b054eca1e76c35fbaecec88e6ebdbe97d4973..629903f89a082f5b3cc51e1c726156da9f1f0a99 100644 (file)
@@ -48,11 +48,14 @@ static char crashreporterBuffer[crashreporterBufferSize];
 char* __crashreporter_info__ = crashreporterBuffer;
 
 static bool                    sEmitWarnings = true;
+static bool                    sFatalWarnings = false;
 static const char*     sWarningsSideFilePath = NULL;
 static FILE*           sWarningsSideFile = NULL;
+static int                     sWarningsCount = 0;
 
 void warning(const char* format, ...)
 {
+       ++sWarningsCount;
        if ( sEmitWarnings ) {
                va_list list;
                if ( sWarningsSideFilePath != NULL ) {
@@ -146,6 +149,10 @@ Options::~Options()
 }
 
 
+bool Options::errorBecauseOfWarnings() const
+{
+       return (sFatalWarnings && (sWarningsCount > 0));
+}
 
 
 const char*    Options::installPath() const
@@ -475,50 +482,6 @@ void Options::setArchitecture(cpu_type_t type, cpu_subtype_t subtype)
        fArchitecture = type;
        fSubArchitecture = subtype;
        switch ( type ) {
-       case CPU_TYPE_POWERPC:
-               switch ( subtype ) {
-               case CPU_SUBTYPE_POWERPC_750:
-                       fArchitectureName = "ppc750";
-                       fHasPreferredSubType = true;
-                       break;
-               case CPU_SUBTYPE_POWERPC_7400:
-                       fArchitectureName = "ppc7400";
-                       fHasPreferredSubType = true;
-                       break;
-               case CPU_SUBTYPE_POWERPC_7450:
-                       fArchitectureName = "ppc7450";
-                       fHasPreferredSubType = true;
-                       break;
-               case CPU_SUBTYPE_POWERPC_970:
-                       fArchitectureName = "ppc970";
-                       fHasPreferredSubType = true;
-                       break;
-               case CPU_SUBTYPE_POWERPC_ALL:
-                       fArchitectureName = "ppc";
-                       fHasPreferredSubType = false;
-                       break;
-               default:
-                       assert(0 && "unknown ppc subtype");
-                       fArchitectureName = "ppc";
-                       break;
-               }
-               if ( (fMacVersionMin == ld::macVersionUnset) && (fOutputKind != Options::kObjectFile) ) {
-       #ifdef DEFAULT_MACOSX_MIN_VERSION
-                       warning("-macosx_version_min not specificed, assuming " DEFAULT_MACOSX_MIN_VERSION);
-                       setMacOSXVersionMin(DEFAULT_MACOSX_MIN_VERSION);
-       #else
-                       warning("-macosx_version_min not specificed, assuming 10.6");
-                       fMacVersionMin = ld::mac10_6;
-       #endif          
-               }
-               break;
-       case CPU_TYPE_POWERPC64:
-               fArchitectureName = "ppc64";
-               if ( (fMacVersionMin == ld::macVersionUnset) && (fOutputKind != Options::kObjectFile) ) {
-                       warning("-macosx_version_min not specificed, assuming 10.5");
-                       fMacVersionMin = ld::mac10_5;
-               }
-               break;
        case CPU_TYPE_I386:
                fArchitectureName = "i386";
                if ( (fMacVersionMin == ld::macVersionUnset) && (fOutputKind != Options::kObjectFile) ) {
@@ -583,15 +546,7 @@ void Options::parseArch(const char* arch)
        if ( arch == NULL )
                throw "-arch must be followed by an architecture string";
        fArchitectureName = arch;
-       if ( strcmp(arch, "ppc") == 0 ) {
-               fArchitecture = CPU_TYPE_POWERPC;
-               fSubArchitecture = CPU_SUBTYPE_POWERPC_ALL;
-       }
-       else if ( strcmp(arch, "ppc64") == 0 ) {
-               fArchitecture = CPU_TYPE_POWERPC64;
-               fSubArchitecture = CPU_SUBTYPE_POWERPC_ALL;
-       }
-       else if ( strcmp(arch, "i386") == 0 ) {
+       if ( strcmp(arch, "i386") == 0 ) {
                fArchitecture = CPU_TYPE_I386;
                fSubArchitecture = CPU_SUBTYPE_I386_ALL;
        }
@@ -603,27 +558,6 @@ void Options::parseArch(const char* arch)
                fArchitecture = CPU_TYPE_ARM;
                fSubArchitecture = CPU_SUBTYPE_ARM_ALL;
        }
-       // compatibility support for cpu-sub-types
-       else if ( strcmp(arch, "ppc750") == 0 ) {
-               fArchitecture = CPU_TYPE_POWERPC;
-               fSubArchitecture = CPU_SUBTYPE_POWERPC_750;
-               fHasPreferredSubType = true;
-       }
-       else if ( strcmp(arch, "ppc7400") == 0 ) {
-               fArchitecture = CPU_TYPE_POWERPC;
-               fSubArchitecture = CPU_SUBTYPE_POWERPC_7400;
-               fHasPreferredSubType = true;
-       }
-       else if ( strcmp(arch, "ppc7450") == 0 ) {
-               fArchitecture = CPU_TYPE_POWERPC;
-               fSubArchitecture = CPU_SUBTYPE_POWERPC_7450;
-               fHasPreferredSubType = true;
-       }
-       else if ( strcmp(arch, "ppc970") == 0 ) {
-               fArchitecture = CPU_TYPE_POWERPC;
-               fSubArchitecture = CPU_SUBTYPE_POWERPC_970;
-               fHasPreferredSubType = true;
-       }
        else {
                for (const ARMSubType* t=ARMSubTypes; t->subTypeName != NULL; ++t) {
                        if ( strcmp(t->subTypeName,arch) == 0 ) {
@@ -1418,16 +1352,67 @@ uint32_t Options::parseProtection(const char* prot)
 }
 
 
+//
+// Parses number of form A[.B[.B[.D[.E]]]] into a uint64_t where the bits are a24.b10.c10.d10.e10
+//
+uint64_t Options::parseVersionNumber64(const char* versionString)
+{
+       uint64_t a = 0;
+       uint64_t b = 0;
+       uint64_t c = 0;
+       uint64_t d = 0;
+       uint64_t e = 0;
+       char* end;
+       a = strtoul(versionString, &end, 10);
+       if ( *end == '.' ) {
+               b = strtoul(&end[1], &end, 10);
+               if ( *end == '.' ) {
+                       c = strtoul(&end[1], &end, 10);
+                       if ( *end == '.' ) {
+                               d = strtoul(&end[1], &end, 10);
+                               if ( *end == '.' ) {
+                                       e = strtoul(&end[1], &end, 10);
+                               }
+                       }
+               }
+       }
+       if ( (*end != '\0') || (a > 0xFFFFFF) || (b > 0x3FF) || (c > 0x3FF) || (d > 0x3FF)  || (e > 0x3FF) )
+               throwf("malformed 64-bit a.b.c.d.e version number: %s", versionString);
+
+       return (a << 40) | ( b << 30 ) | ( c << 20 ) | ( d << 10 ) | e;
+}
+
+
+uint32_t Options::currentVersion32() const
+{
+       // warn if it does not fit into 32 bit vers number
+       uint32_t a = (fDylibCurrentVersion >> 40) & 0xFFFF;
+       uint32_t b = (fDylibCurrentVersion >> 30) & 0xFF;
+       uint32_t c = (fDylibCurrentVersion >> 20) & 0xFF;
+       uint64_t rep32 = ((uint64_t)a << 40) |  ((uint64_t)b << 30) | ((uint64_t)c << 20);
+       if ( rep32 != fDylibCurrentVersion ) {
+               warning("truncating -current_version to fit in 32-bit space used by old mach-o format");
+               a = (fDylibCurrentVersion >> 40) & 0xFFFFFF;            
+               if ( a > 0xFFFF )
+                       a = 0xFFFF;
+               b = (fDylibCurrentVersion >> 30) & 0x3FF;
+               if ( b > 0xFF )
+                       b = 0xFF;
+               c = (fDylibCurrentVersion >> 20) & 0x3FF;
+               if ( c > 0xFF )
+                       c = 0xFF;
+       }
+       return (a << 16) | ( b << 8 ) | c;
+}
 
 //
 // Parses number of form X[.Y[.Z]] into a uint32_t where the nibbles are xxxx.yy.zz
 //
-//
-uint32_t Options::parseVersionNumber(const char* versionString)
+uint32_t Options::parseVersionNumber32(const char* versionString)
 {
-       unsigned long x = 0;
-       unsigned long y = 0;
-       unsigned long z = 0;
+       uint32_t x = 0;
+       uint32_t y = 0;
+       uint32_t z = 0;
        char* end;
        x = strtoul(versionString, &end, 10);
        if ( *end == '.' ) {
@@ -1437,7 +1422,7 @@ uint32_t Options::parseVersionNumber(const char* versionString)
                }
        }
        if ( (*end != '\0') || (x > 0xffff) || (y > 0xff) || (z > 0xff) )
-               throwf("malformed version number: %s", versionString);
+               throwf("malformed 32-bit x.y.z version number: %s", versionString);
 
        return (x << 16) | ( y << 8 ) | z;
 }
@@ -1565,18 +1550,12 @@ void Options::parseOrderFile(const char* path, bool cstring)
                                        *last = '\0';
                                        --last;
                                }
+                               // if there is an architecture prefix, only use this symbol it if matches current arch
                                if ( strncmp(symbolStart, "ppc:", 4) == 0 ) {
-                                       if ( fArchitecture == CPU_TYPE_POWERPC )
-                                               symbolStart = &symbolStart[4];
-                                       else
-                                               symbolStart = NULL;
+                                       symbolStart = NULL;
                                }
-                               // if there is an architecture prefix, only use this symbol it if matches current arch
                                else if ( strncmp(symbolStart, "ppc64:", 6) == 0 ) {
-                                       if ( fArchitecture == CPU_TYPE_POWERPC64 )
-                                               symbolStart = &symbolStart[6];
-                                       else
-                                               symbolStart = NULL;
+                                       symbolStart = NULL;
                                }
                                else if ( strncmp(symbolStart, "i386:", 5) == 0 ) {
                                        if ( fArchitecture == CPU_TYPE_I386 )
@@ -1860,14 +1839,14 @@ void Options::parse(int argc, const char* argv[])
                                 const char* vers = argv[++i];
                                 if ( vers == NULL )
                                        throw "-dylib_compatibility_version missing <version>";
-                               fDylibCompatVersion = parseVersionNumber(vers);
+                               fDylibCompatVersion = parseVersionNumber32(vers);
                        }
                        else if ( (strcmp(arg, "-dylib_current_version") == 0)
                                          || (strcmp(arg, "-current_version") == 0)) {
                                 const char* vers = argv[++i];
                                 if ( vers == NULL )
                                        throw "-dylib_current_version missing <version>";
-                               fDylibCurrentVersion = parseVersionNumber(vers);
+                               fDylibCurrentVersion = parseVersionNumber64(vers);
                        }
                        else if ( strcmp(arg, "-sectorder") == 0 ) {
                                 if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) )
@@ -2127,9 +2106,9 @@ void Options::parse(int argc, const char* argv[])
                                 if ( (seg.name == NULL) || (argv[i+1] == NULL) )
                                        throw "-segaddr missing segName Adddress";
                                seg.address = parseAddress(argv[++i]);
-                               uint64_t temp = seg.address & (-4096); // page align
-                               if ( (seg.address != temp)  )
-                                       warning("-segaddr %s not page aligned, rounding down", seg.name);
+                               uint64_t temp = ((seg.address+fSegmentAlignment-1) & (-fSegmentAlignment)); 
+                               if ( seg.address != temp )
+                                       warning("-segaddr %s not %lld byte aligned", seg.name, fSegmentAlignment);
                                fCustomSegmentAddresses.push_back(seg);
                        }
                        // ??? Deprecate when we deprecate split-seg.
@@ -2313,6 +2292,9 @@ void Options::parse(int argc, const char* argv[])
                        else if ( strcmp(arg, "-w") == 0 ) {
                                // previously handled by buildSearchPaths()
                        }
+                       else if ( strcmp(arg, "-fatal_warnings") == 0 ) {
+                               // previously handled by buildSearchPaths()
+                       }
                        else if ( strcmp(arg, "-arch_errors_fatal") == 0 ) {
                                fErrorOnOtherArchFiles = true;
                        }
@@ -2787,6 +2769,9 @@ void Options::buildSearchPaths(int argc, const char* argv[])
                else if ( strcmp(argv[i], "-w") == 0 ) {
                        sEmitWarnings = false;
                }
+               else if ( strcmp(argv[i], "-fatal_warnings") == 0 ) {
+                       sFatalWarnings = true;
+               }
        }
        int standardLibraryPathsStartIndex = libraryPaths.size();
        int standardFrameworkPathsStartIndex = frameworkPaths.size();
@@ -3032,7 +3017,6 @@ void Options::reconfigureDefaults()
                        switch ( fArchitecture ) {
                                case CPU_TYPE_I386:
                                case CPU_TYPE_X86_64:
-                               case CPU_TYPE_POWERPC:                  
                                        if ( (fOutputKind != Options::kObjectFile) && (fOutputKind != Options::kPreload) ) {
                        #ifdef DEFAULT_MACOSX_MIN_VERSION
                                                warning("-macosx_version_min not specificed, assuming " DEFAULT_MACOSX_MIN_VERSION);
@@ -3073,12 +3057,6 @@ void Options::reconfigureDefaults()
                                fMacVersionMin = ld::mac10_4;
                        }
                        break;
-               case CPU_TYPE_POWERPC64:
-                       if ( fMacVersionMin < ld::mac10_4 ) {
-                               //warning("-macosx_version_min should be 10.4 or later for ppc64");
-                               fMacVersionMin = ld::mac10_4;
-                       }
-                       break;
                case CPU_TYPE_X86_64:
                        if ( fMacVersionMin < ld::mac10_4 ) {
                                //warning("-macosx_version_min should be 10.4 or later for x86_64");
@@ -3107,7 +3085,6 @@ void Options::reconfigureDefaults()
                                        break;
                                }
                                // else use object file
-                       case CPU_TYPE_POWERPC:
                        case CPU_TYPE_I386:
                                // use .o files
                                fOutputKind = kObjectFile;
@@ -3150,9 +3127,8 @@ void Options::reconfigureDefaults()
        
        // split segs only allowed for dylibs
        if ( fSplitSegs ) {
-        // split seg only supported for ppc, i386, and arm.
+        // split seg only supported for i386, and arm.
         switch ( fArchitecture ) {
-            case CPU_TYPE_POWERPC:
             case CPU_TYPE_I386:
                 if ( fOutputKind != Options::kDynamicLibrary )
                     fSplitSegs = false;
@@ -3179,11 +3155,9 @@ void Options::reconfigureDefaults()
 
        // set too-large size
        switch ( fArchitecture ) {
-               case CPU_TYPE_POWERPC:
                case CPU_TYPE_I386:
                        fMaxAddress = 0xFFFFFFFF;
                        break;
-               case CPU_TYPE_POWERPC64:
                case CPU_TYPE_X86_64:
                        break;
                case CPU_TYPE_ARM:
@@ -3217,7 +3191,6 @@ void Options::reconfigureDefaults()
        // disable prebinding depending on arch and min OS version
        if ( fPrebind ) {
                switch ( fArchitecture ) {
-                       case CPU_TYPE_POWERPC:
                        case CPU_TYPE_I386:
                                if ( fMacVersionMin == ld::mac10_4 ) {
                                        // in 10.4 only split seg dylibs are prebound
@@ -3251,7 +3224,6 @@ void Options::reconfigureDefaults()
                                        }
                                }
                                break;
-                       case CPU_TYPE_POWERPC64:
                        case CPU_TYPE_X86_64:
                                fPrebind = false;
                                break;
@@ -3287,17 +3259,17 @@ void Options::reconfigureDefaults()
                                        || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
                                        fSharedRegionEligible = true;
        }
-       
+       else if ( fOutputKind == Options::kDyld ) {
+        // <rdar://problem/10111122> Enable dyld to be put into the dyld shared cache
+        fSharedRegionEligible = true;
+       }
+    
        // figure out if module table is needed for compatibility with old ld/dyld
        if ( fOutputKind == Options::kDynamicLibrary ) {
                switch ( fArchitecture ) {
                        case CPU_TYPE_I386:
                                if ( fIOSVersionMin != ld::iOSVersionUnset ) // simulator never needs modules
                                        break;
-                       case CPU_TYPE_POWERPC:  // 10.3 and earlier dyld requires a module table
-                               if ( fMacVersionMin <= ld::mac10_5 )
-                                       fNeedsModuleTable = true;
-                               break;
                        case CPU_TYPE_ARM:
                                if ( fPrebind )
                                        fNeedsModuleTable = true; // redo_prebinding requires a module table
@@ -3329,8 +3301,6 @@ void Options::reconfigureDefaults()
                                        break;
                        }
                        break;
-               case CPU_TYPE_POWERPC:
-               case CPU_TYPE_POWERPC64:                
                case CPU_TYPE_ARM:
                        fAddCompactUnwindEncoding = false;
                        fRemoveDwarfUnwindIfCompactExists = false;
@@ -3402,8 +3372,6 @@ void Options::reconfigureDefaults()
                                if ( !minOS(ld::mac10_6, ld::iOS_3_1) )
                                        fMakeCompressedDyldInfo = false;
                                break;
-                       case CPU_TYPE_POWERPC:
-                       case CPU_TYPE_POWERPC64:
                        default:
                                fMakeCompressedDyldInfo = false;
                }
@@ -3629,12 +3597,10 @@ void Options::checkIllegalOptionCombinations()
        if ( fStackAddr != 0 ) {
                switch (fArchitecture) {
                        case CPU_TYPE_I386:
-                       case CPU_TYPE_POWERPC:
             case CPU_TYPE_ARM:
                                if ( fStackAddr > 0xFFFFFFFF )
                                        throw "-stack_addr must be < 4G for 32-bit processes";
                                break;
-                       case CPU_TYPE_POWERPC64:
                        case CPU_TYPE_X86_64:
                                break;
                }
@@ -3648,7 +3614,6 @@ void Options::checkIllegalOptionCombinations()
        if ( fStackSize != 0 ) {
                switch (fArchitecture) {
                        case CPU_TYPE_I386:
-                       case CPU_TYPE_POWERPC:
                                if ( fStackSize > 0xFFFFFFFF )
                                        throw "-stack_size must be < 4G for 32-bit processes";
                                if ( fStackAddr == 0 ) {
@@ -3664,7 +3629,6 @@ void Options::checkIllegalOptionCombinations()
                                        fStackAddr = 0x2F000000;
                 if ( fStackAddr > 0x30000000)
                     throw "-stack_addr must be < 0x30000000 for arm";
-                       case CPU_TYPE_POWERPC64:
                        case CPU_TYPE_X86_64:
                                if ( fStackAddr == 0 ) {
                                        fStackAddr = 0x00007FFF5C000000LL;
@@ -3774,7 +3738,6 @@ void Options::checkIllegalOptionCombinations()
                        if ( fObjCABIVersion2Override )
                                alterObjC1ClassNamesToObjC2 = true;
                        break;
-               case CPU_TYPE_POWERPC64:
                case CPU_TYPE_X86_64:
                case CPU_TYPE_ARM:
                        alterObjC1ClassNamesToObjC2 = true;
@@ -3868,18 +3831,10 @@ void Options::checkIllegalOptionCombinations()
                // zero page size not specified on command line, set default
                switch (fArchitecture) {
                        case CPU_TYPE_I386:
-                       case CPU_TYPE_POWERPC:
             case CPU_TYPE_ARM:
                                // first 4KB for 32-bit architectures
                                fZeroPageSize = 0x1000;
                                break;
-                       case CPU_TYPE_POWERPC64:
-                               // first 4GB for ppc64 on 10.5
-                               if ( fMacVersionMin >= ld::mac10_5 )
-                                       fZeroPageSize = 0x100000000ULL;
-                               else
-                                       fZeroPageSize = 0x1000; // 10.4 dyld may not be able to handle >4GB zero page
-                               break;
                        case CPU_TYPE_X86_64:
                                // first 4GB for x86_64 on all OS's
                                fZeroPageSize = 0x100000000ULL;
@@ -4053,6 +4008,7 @@ void Options::checkForClassic(int argc, const char* argv[])
                                // ld_classic does not understand this option, so remove it
                                for(int j=i; j < argc; ++j)
                                        argv[j] = argv[j+1];
+                               warning("using ld_classic");
                                this->gotoClassicLinker(argc-1, argv);
                        }
                        else if ( strcmp(arg, "-o") == 0 ) {
@@ -4070,7 +4026,6 @@ void Options::checkForClassic(int argc, const char* argv[])
        if( archFound ) {
                switch ( fArchitecture ) {
                case CPU_TYPE_I386:
-               case CPU_TYPE_POWERPC:
                        if ( (staticFound || kextFound) && !newLinker ) {
                                // this environment variable will disable use of ld_classic for -static links
                                if ( getenv("LD_NO_CLASSIC_LINKER_STATIC") == NULL ) {
@@ -4082,15 +4037,16 @@ void Options::checkForClassic(int argc, const char* argv[])
        }
        else {
                // work around for VSPTool
-               if ( staticFound )
+               if ( staticFound ) {
+                       warning("using ld_classic");
                        this->gotoClassicLinker(argc, argv);
+               }
        }
 
 }
 
 void Options::gotoClassicLinker(int argc, const char* argv[])
 {
-       warning("using ld_classic");
        argv[0] = "ld_classic";
        // ld_classic does not support -iphoneos_version_min, so change
        for(int j=0; j < argc; ++j) {
index d9becf3296c5a2358572d4bd199542ed2c53d35b..5a8a7e0fa43ef3ecc52829246b3dc233c4fb08fb 100644 (file)
@@ -156,7 +156,8 @@ public:
        bool                                            bindAtLoad() const { return fBindAtLoad; }
        NameSpace                                       nameSpace() const { return fNameSpace; }
        const char*                                     installPath() const;                    // only for kDynamicLibrary
-       uint32_t                                        currentVersion() const { return fDylibCurrentVersion; }         // only for kDynamicLibrary
+       uint64_t                                        currentVersion() const { return fDylibCurrentVersion; }         // only for kDynamicLibrary
+       uint32_t                                        currentVersion32() const;               // only for kDynamicLibrary
        uint32_t                                        compatibilityVersion() const { return fDylibCompatVersion; }    // only for kDynamicLibrary
        const char*                                     entryName() const { return fEntryName; }                // only for kDynamicExecutable or kStaticExecutable
        const char*                                     executablePath();
@@ -293,6 +294,7 @@ public:
        bool                                            forceNotWeak(const char* symbolName) const;
        bool                                            forceWeakNonWildCard(const char* symbolName) const;
        bool                                            forceNotWeakNonWildcard(const char* symbolName) const;
+       bool                                            errorBecauseOfWarnings() const;
 
 private:
        class CStringEquals
@@ -335,7 +337,8 @@ private:
        FileInfo                                        findFramework(const char* rootName, const char* suffix);
        bool                                            checkForFile(const char* format, const char* dir, const char* rootName,
                                                                                         FileInfo& result) const;
-       uint32_t                                        parseVersionNumber(const char*);
+       uint64_t                                        parseVersionNumber64(const char*);
+       uint32_t                                        parseVersionNumber32(const char*);
        void                                            parseSectionOrderFile(const char* segment, const char* section, const char* path);
        void                                            parseOrderFile(const char* path, bool cstring);
        void                                            addSection(const char* segment, const char* section, const char* path);
@@ -384,7 +387,7 @@ private:
        bool                                                            fDeadStrip;
        NameSpace                                                       fNameSpace;
        uint32_t                                                        fDylibCompatVersion;
-       uint32_t                                                        fDylibCurrentVersion;
+       uint64_t                                                        fDylibCurrentVersion;
        const char*                                                     fDylibInstallName;
        const char*                                                     fFinalName;
        const char*                                                     fEntryName;
index 65e8b8c985907831a2ba95cd73dc73746f7b75ff..f217eb0675d13d391d8c47b215a5bb4e645a82fa 100644 (file)
@@ -516,6 +516,8 @@ void OutputFile::assignFileOffsets(ld::Internal& state)
        // second pass, assign section address to sections in segments that are contiguous with previous segment
        address = floatingAddressStart;
        lastSegName = "";
+       ld::Internal::FinalSection* overlappingFixedSection = NULL;
+       ld::Internal::FinalSection* overlappingFlowSection = NULL;
        if ( log ) fprintf(stderr, "Regular layout segments:\n");
        for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
                ld::Internal::FinalSection* sect = *it;
@@ -550,6 +552,25 @@ void OutputFile::assignFileOffsets(ld::Internal& state)
                                                                                                                          && (_options.outputKind() != Options::kStaticExecutable) )
                                throwf("section %s (address=0x%08llX, size=%llu) would make the output executable exceed available address range", 
                                                sect->sectionName(), address, sect->size);
+
+               // sanity check it does not overlap a fixed address segment
+               for (std::vector<ld::Internal::FinalSection*>::iterator sit = state.sections.begin(); sit != state.sections.end(); ++sit) {
+                       ld::Internal::FinalSection* otherSect = *sit;
+                       if ( ! _options.hasCustomSegmentAddress(otherSect->segmentName()) ) 
+                               continue;
+                       if ( sect->address > otherSect->address ) {
+                               if ( (otherSect->address+otherSect->size) > sect->address ) {
+                                       overlappingFixedSection = otherSect;
+                                       overlappingFlowSection = sect;
+                               }
+                       }
+                       else {
+                               if ( (sect->address+sect->size) > otherSect->address ) {
+                                       overlappingFixedSection = otherSect;
+                                       overlappingFlowSection = sect;
+                               }
+                       }
+               }
                
                if ( log ) fprintf(stderr, "  address=0x%08llX, hidden=%d, alignment=%02d, padBytes=%d, section=%s,%s\n",
                                                        sect->address, sect->isSectionHidden(), sect->alignment, sect->alignmentPaddingBytes, 
@@ -558,6 +579,21 @@ void OutputFile::assignFileOffsets(ld::Internal& state)
                if ( !sect->isSectionHidden() || hiddenSectionsOccupyAddressSpace )
                        address += sect->size;
        }
+       if ( overlappingFixedSection != NULL ) {
+               fprintf(stderr, "Section layout:\n");
+               for (std::vector<ld::Internal::FinalSection*>::iterator it = state.sections.begin(); it != state.sections.end(); ++it) {
+                       ld::Internal::FinalSection* sect = *it;
+                       if ( sect->isSectionHidden() )
+                               continue;
+                       fprintf(stderr, "  address:0x%08llX, alignment:2^%d, size:0x%08llX, padBytes:%d, section:%s/%s\n",
+                                                       sect->address, sect->alignment, sect->size, sect->alignmentPaddingBytes, 
+                                                       sect->segmentName(), sect->sectionName());
+       
+               }
+               throwf("Section (%s/%s) overlaps fixed address section (%s/%s)", 
+                       overlappingFlowSection->segmentName(), overlappingFlowSection->sectionName(),
+                       overlappingFixedSection->segmentName(), overlappingFixedSection->sectionName());
+       }
        
        
        // third pass, assign section file offsets 
@@ -898,33 +934,6 @@ void OutputFile::rangeCheckThumbBranch22(int64_t displacement, ld::Internal& sta
        }
 }
 
-void OutputFile::rangeCheckPPCBranch24(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
-{
-       const int64_t bl_eightMegLimit = 0x00FFFFFF;
-       if ( (displacement > bl_eightMegLimit) || (displacement < (-bl_eightMegLimit)) ) {
-               // show layout of final image
-               printSectionLayout(state);
-               
-               const ld::Atom* target; 
-               throwf("bl PPC branch out of range (%lld max is +/-16MB): from %s (0x%08llX) to %s (0x%08llX)", 
-                               displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup), 
-                               addressOf(state, fixup, &target));
-       }
-}
-
-void OutputFile::rangeCheckPPCBranch14(int64_t displacement, ld::Internal& state, const ld::Atom* atom, const ld::Fixup* fixup)
-{
-       const int64_t b_sixtyFourKiloLimit = 0x0000FFFF;
-       if ( (displacement > b_sixtyFourKiloLimit) || (displacement < (-b_sixtyFourKiloLimit)) ) {
-               // show layout of final image
-               printSectionLayout(state);
-               
-               const ld::Atom* target; 
-               throwf("bcc PPC branch out of range (%lld max is +/-64KB): from %s (0x%08llX) to %s (0x%08llX)", 
-                               displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup), 
-                               addressOf(state, fixup, &target));
-       }
-}
 
 
 
@@ -956,7 +965,6 @@ void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::
        int64_t delta;
        uint32_t instruction;
        uint32_t newInstruction;
-       uint16_t instructionLowHalf;
        bool is_bl;
        bool is_blx;
        bool is_b;
@@ -1145,41 +1153,6 @@ void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::
                                }
                                set32LE(fixUpLocation, newInstruction);
                                break;
-                       case ld::Fixup::kindStorePPCBranch14:
-                               delta = accumulator - (atom->finalAddress() + fit->offsetInAtom);
-                               rangeCheckPPCBranch14(delta, state, atom, fit);
-                               instruction = get32BE(fixUpLocation);
-                               newInstruction = (instruction & 0xFFFF0003) | ((uint32_t)delta & 0x0000FFFC);
-                               set32BE(fixUpLocation, newInstruction);
-                               break;
-                       case ld::Fixup::kindStorePPCPicLow14:
-                       case ld::Fixup::kindStorePPCAbsLow14:
-                               instruction = get32BE(fixUpLocation);
-                               if ( (accumulator & 0x3) != 0 )
-                                       throwf("bad offset (0x%08X) for lo14 instruction pic-base fix-up", (uint32_t)accumulator);
-                               newInstruction = (instruction & 0xFFFF0003) | (accumulator & 0xFFFC);
-                               set32BE(fixUpLocation, newInstruction);
-                               break;
-                       case ld::Fixup::kindStorePPCAbsLow16:
-                       case ld::Fixup::kindStorePPCPicLow16:
-                               instruction = get32BE(fixUpLocation);
-                               newInstruction = (instruction & 0xFFFF0000) | (accumulator & 0xFFFF);
-                               set32BE(fixUpLocation, newInstruction);
-                               break;
-                       case ld::Fixup::kindStorePPCAbsHigh16AddLow:
-                       case ld::Fixup::kindStorePPCPicHigh16AddLow:
-                               instructionLowHalf = (accumulator >> 16) & 0xFFFF;
-                               if ( accumulator & 0x00008000 )
-                                       ++instructionLowHalf;
-                               instruction = get32BE(fixUpLocation);
-                               newInstruction = (instruction & 0xFFFF0000) | instructionLowHalf;
-                               set32BE(fixUpLocation, newInstruction);
-                               break;
-                       case ld::Fixup::kindStorePPCAbsHigh16:
-                               instruction = get32BE(fixUpLocation);
-                               newInstruction = (instruction & 0xFFFF0000) | ((accumulator >> 16) & 0xFFFF);
-                               set32BE(fixUpLocation, newInstruction);
-                               break;
                        case ld::Fixup::kindDtraceExtra:
                                break;
                        case ld::Fixup::kindStoreX86DtraceCallSiteNop:
@@ -1202,18 +1175,6 @@ void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::
                                        fixUpLocation[3] = 0x90;                // 1-byte nop
                                }
                                break;
-                       case ld::Fixup::kindStorePPCDtraceCallSiteNop:
-                               if ( _options.outputKind() != Options::kObjectFile ) {
-                                       // change call site to a NOP
-                                       set32BE(fixUpLocation, 0x60000000);
-                               }
-                               break;
-                       case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
-                               if ( _options.outputKind() != Options::kObjectFile ) {
-                                       // change call site to a li r3,0
-                                       set32BE(fixUpLocation, 0x38600000);
-                               }
-                               break;
                        case ld::Fixup::kindStoreARMDtraceCallSiteNop:
                                if ( _options.outputKind() != Options::kObjectFile ) {
                                        // change call site to a NOP
@@ -1506,18 +1467,6 @@ void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::
                                        set32LE(fixUpLocation, newInstruction);         
                                }
                                break;
-                       case ld::Fixup::kindStoreTargetAddressPPCBranch24:
-                               accumulator = addressOf(state, fit, &toTarget);
-                               if ( fit->contentDetlaToAddendOnly )
-                                       accumulator = 0;
-                               // fall into kindStorePPCBranch24 case
-                       case ld::Fixup::kindStorePPCBranch24:
-                               delta = accumulator - (atom->finalAddress() + fit->offsetInAtom);
-                               rangeCheckPPCBranch24(delta, state, atom, fit);
-                               instruction = get32BE(fixUpLocation);
-                               newInstruction = (instruction & 0xFC000003) | ((uint32_t)delta & 0x03FFFFFC);
-                               set32BE(fixUpLocation, newInstruction);
-                               break;
                }
        }
 }
@@ -1525,10 +1474,6 @@ void OutputFile::applyFixUps(ld::Internal& state, uint64_t mhAddress, const ld::
 void OutputFile::copyNoOps(uint8_t* from, uint8_t* to, bool thumb)
 {
        switch ( _options.architecture() ) {
-               case CPU_TYPE_POWERPC:
-                       for (uint8_t* p=from; p < to; p += 4)
-                               OSWriteBigInt32((uint32_t*)p, 0, 0x60000000);
-                       break;
                case CPU_TYPE_I386:
                case CPU_TYPE_X86_64:
                        for (uint8_t* p=from; p < to; ++p)
@@ -2002,54 +1947,6 @@ void OutputFile::addLinkEdit(ld::Internal& state)
                return addPreloadLinkEdit(state);
        
        switch ( _options.architecture() ) {
-               case CPU_TYPE_POWERPC:
-                       if ( _hasSectionRelocations ) {
-                               _sectionsRelocationsAtom = new SectionRelocationsAtom<ppc>(_options, state, *this);
-                               sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
-                       }
-                       if ( _hasDyldInfo ) {
-                               _rebasingInfoAtom = new RebaseInfoAtom<ppc>(_options, state, *this);
-                               rebaseSection = state.addAtom(*_rebasingInfoAtom);
-                               
-                               _bindingInfoAtom = new BindingInfoAtom<ppc>(_options, state, *this);
-                               bindingSection = state.addAtom(*_bindingInfoAtom);
-                               
-                               _weakBindingInfoAtom = new WeakBindingInfoAtom<ppc>(_options, state, *this);
-                               weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
-                               
-                               _lazyBindingInfoAtom = new LazyBindingInfoAtom<ppc>(_options, state, *this);
-                               lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
-                               
-                               _exportInfoAtom = new ExportInfoAtom<ppc>(_options, state, *this);
-                               exportSection = state.addAtom(*_exportInfoAtom);
-                       }
-                       if ( _hasLocalRelocations ) {
-                               _localRelocsAtom = new LocalRelocationsAtom<ppc>(_options, state, *this);
-                               localRelocationsSection = state.addAtom(*_localRelocsAtom);
-                       }
-                       if ( _hasSplitSegInfo ) {
-                               _splitSegInfoAtom = new SplitSegInfoAtom<ppc>(_options, state, *this);
-                               splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
-                       }
-                       if ( _hasFunctionStartsInfo ) {
-                               _functionStartsAtom = new FunctionStartsAtom<ppc>(_options, state, *this);
-                               functionStartsSection = state.addAtom(*_functionStartsAtom);
-                       }
-                       if ( _hasSymbolTable ) {
-                               _symbolTableAtom = new SymbolTableAtom<ppc>(_options, state, *this);
-                               symbolTableSection = state.addAtom(*_symbolTableAtom);
-                       }
-                       if ( _hasExternalRelocations ) {
-                               _externalRelocsAtom = new ExternalRelocationsAtom<ppc>(_options, state, *this);
-                               externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
-                       }
-                       if ( _hasSymbolTable ) {
-                               _indirectSymbolTableAtom = new IndirectSymbolTableAtom<ppc>(_options, state, *this);
-                               indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
-                               _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
-                               stringPoolSection = state.addAtom(*_stringPoolAtom);
-                       }
-                       break;
                case CPU_TYPE_I386:
                        if ( _hasSectionRelocations ) {
                                _sectionsRelocationsAtom = new SectionRelocationsAtom<x86>(_options, state, *this);
@@ -2194,54 +2091,6 @@ void OutputFile::addLinkEdit(ld::Internal& state)
                                stringPoolSection = state.addAtom(*_stringPoolAtom);
                        }
                        break;
-               case CPU_TYPE_POWERPC64:
-                       if ( _hasSectionRelocations ) {
-                               _sectionsRelocationsAtom = new SectionRelocationsAtom<ppc64>(_options, state, *this);
-                               sectionRelocationsSection = state.addAtom(*_sectionsRelocationsAtom);
-                       }
-                       if ( _hasDyldInfo ) {
-                               _rebasingInfoAtom = new RebaseInfoAtom<ppc64>(_options, state, *this);
-                               rebaseSection = state.addAtom(*_rebasingInfoAtom);
-                               
-                               _bindingInfoAtom = new BindingInfoAtom<ppc64>(_options, state, *this);
-                               bindingSection = state.addAtom(*_bindingInfoAtom);
-                               
-                               _weakBindingInfoAtom = new WeakBindingInfoAtom<ppc64>(_options, state, *this);
-                               weakBindingSection = state.addAtom(*_weakBindingInfoAtom);
-                               
-                               _lazyBindingInfoAtom = new LazyBindingInfoAtom<ppc64>(_options, state, *this);
-                               lazyBindingSection = state.addAtom(*_lazyBindingInfoAtom);
-                               
-                               _exportInfoAtom = new ExportInfoAtom<ppc64>(_options, state, *this);
-                               exportSection = state.addAtom(*_exportInfoAtom);
-                       }
-                       if ( _hasLocalRelocations ) {
-                               _localRelocsAtom = new LocalRelocationsAtom<ppc64>(_options, state, *this);
-                               localRelocationsSection = state.addAtom(*_localRelocsAtom);
-                       }
-                       if  ( _hasSplitSegInfo ) {
-                               _splitSegInfoAtom = new SplitSegInfoAtom<ppc64>(_options, state, *this);
-                               splitSegInfoSection = state.addAtom(*_splitSegInfoAtom);
-                       }
-                       if ( _hasFunctionStartsInfo ) {
-                               _functionStartsAtom = new FunctionStartsAtom<ppc64>(_options, state, *this);
-                               functionStartsSection = state.addAtom(*_functionStartsAtom);
-                       }
-                       if ( _hasSymbolTable ) {
-                               _symbolTableAtom = new SymbolTableAtom<ppc64>(_options, state, *this);
-                               symbolTableSection = state.addAtom(*_symbolTableAtom);
-                       }
-                       if ( _hasExternalRelocations ) {
-                               _externalRelocsAtom = new ExternalRelocationsAtom<ppc64>(_options, state, *this);
-                               externalRelocationsSection = state.addAtom(*_externalRelocsAtom);
-                       }
-                       if ( _hasSymbolTable ) {
-                               _indirectSymbolTableAtom = new IndirectSymbolTableAtom<ppc64>(_options, state, *this);
-                               indirectSymbolTableSection = state.addAtom(*_indirectSymbolTableAtom);
-                               _stringPoolAtom = new StringPoolAtom(_options, state, *this, 4);
-                               stringPoolSection = state.addAtom(*_stringPoolAtom);
-                       }
-                       break;
                default:
                        throw "unknown architecture";
        }
@@ -2262,14 +2111,6 @@ void OutputFile::addLoadCommands(ld::Internal& state)
                        _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<x86>(_options, state, *this);
                        headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
                        break;
-               case CPU_TYPE_POWERPC:
-                       _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<ppc>(_options, state, *this);
-                       headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
-                       break;
-               case CPU_TYPE_POWERPC64:
-                       _headersAndLoadCommandAtom = new HeaderAndLoadCommandsAtom<ppc64>(_options, state, *this);
-                       headerAndLoadCommandsSection = state.addAtom(*_headersAndLoadCommandAtom);
-                       break;
                default:
                        throw "unknown architecture";
        }
@@ -2425,18 +2266,12 @@ bool OutputFile::isPcRelStore(ld::Fixup::Kind kind)
                case ld::Fixup::kindStoreARMBranch24:
                case ld::Fixup::kindStoreThumbBranch22:
                case ld::Fixup::kindStoreARMLoad12:
-               case ld::Fixup::kindStorePPCBranch24:
-               case ld::Fixup::kindStorePPCBranch14:
-               case ld::Fixup::kindStorePPCPicLow14:
-               case ld::Fixup::kindStorePPCPicLow16:
-               case ld::Fixup::kindStorePPCPicHigh16AddLow:
                case ld::Fixup::kindStoreTargetAddressX86PCRel32:
                case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
                case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
                case ld::Fixup::kindStoreTargetAddressARMBranch24:
                case ld::Fixup::kindStoreTargetAddressThumbBranch22:
                case ld::Fixup::kindStoreTargetAddressARMLoad12:
-               case ld::Fixup::kindStoreTargetAddressPPCBranch24:
                        return true;
                case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
                        return (_options.outputKind() != Options::kKextBundle);
@@ -2485,7 +2320,6 @@ bool OutputFile::setsTarget(ld::Fixup::Kind kind)
                case ld::Fixup::kindStoreTargetAddressARMBranch24:
                case ld::Fixup::kindStoreTargetAddressThumbBranch22:
                case ld::Fixup::kindStoreTargetAddressARMLoad12:
-               case ld::Fixup::kindStoreTargetAddressPPCBranch24:
                        return true;
                case ld::Fixup::kindStoreX86DtraceCallSiteNop:
                case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear:
@@ -2493,8 +2327,6 @@ bool OutputFile::setsTarget(ld::Fixup::Kind kind)
                case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear:
                case ld::Fixup::kindStoreThumbDtraceCallSiteNop:
                case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear:
-               case ld::Fixup::kindStorePPCDtraceCallSiteNop:
-               case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
                        return (_options.outputKind() == Options::kObjectFile);
                default:
                        break;
@@ -3026,25 +2858,6 @@ void OutputFile::addClassicRelocs(ld::Internal& state, ld::Internal::FinalSectio
                                sect->hasLocalRelocs = true;
                        }
                        break;
-               case ld::Fixup::kindStorePPCAbsLow14:
-               case ld::Fixup::kindStorePPCAbsLow16:
-               case ld::Fixup::kindStorePPCAbsHigh16AddLow:
-               case ld::Fixup::kindStorePPCAbsHigh16:
-                       {
-                               assert(target != NULL);
-                               if ( target->definition() == ld::Atom::definitionProxy )
-                                       throwf("half word text relocs not supported in %s", atom->name());
-                               if ( _options.outputSlidable() ) {
-                                       if ( inReadOnlySeg )
-                                               noteTextReloc(atom, target);
-                                       uint32_t machoSectionIndex = (target->definition() == ld::Atom::definitionAbsolute) 
-                                                                                                       ? R_ABS : target->machoSection();
-                                       _localRelocsAtom->addTextReloc(relocAddress, fixupWithTarget->kind,  
-                                                                                                       target->finalAddress(), machoSectionIndex);
-                                       sect->hasLocalRelocs = true;
-                               }
-                       }
-                       break;
                case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
                        if ( _options.outputKind() == Options::kKextBundle ) {
                                assert(target != NULL);
@@ -3228,7 +3041,6 @@ void OutputFile::makeSplitSegInfo(ld::Internal& state)
                                        case ld::Fixup::kindStoreX86PCRel32GOTLoad:
                                        case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA:
                                        case ld::Fixup::kindStoreX86PCRel32GOT:
-                                       case ld::Fixup::kindStorePPCPicHigh16AddLow:
                                        case ld::Fixup::kindStoreTargetAddressX86PCRel32:
                                        case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad:
                                        case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA:
index 415d24b29383ad2f6fa86f75d84fd4eb5905f891..84017169c39dd6a865a5abc58e7c6b1cb06d9a00 100644 (file)
@@ -65,7 +65,7 @@ public:
        uint32_t                                        encryptedTextStartOffset()      { return _encryptedTEXTstartOffset; }
        uint32_t                                        encryptedTextEndOffset()        { return _encryptedTEXTendOffset; }
        int                                                     compressedOrdinalForAtom(const ld::Atom* target);
-       
+       uint64_t                                        fileSize() const { return _fileSize; }
        
        
        bool                                            hasWeakExternalSymbols;
@@ -210,10 +210,6 @@ private:
                                                                                                                                                                                        const ld::Fixup* fixup);
        void                                            rangeCheckThumbBranch22(int64_t delta, ld::Internal& state, const ld::Atom* atom, 
                                                                                                                                                                                        const ld::Fixup* fixup);
-       void                                            rangeCheckPPCBranch24(int64_t delta, ld::Internal& state, const ld::Atom* atom, 
-                                                                                                                                                                                       const ld::Fixup* fixup);
-       void                                            rangeCheckPPCBranch14(int64_t delta, ld::Internal& state, const ld::Atom* atom, 
-                                                                                                                                                                                       const ld::Fixup* fixup);
        uint64_t                                        sectionOffsetOf(const ld::Internal& state, const ld::Fixup* fixup);
        uint64_t                                        tlvTemplateOffsetOf(const ld::Internal& state, const ld::Fixup* fixup);
        void                                            dumpAtomsBySection(ld::Internal& state, bool);
index a56cefe78d8585b9bcf3d5cff1c1e65d66356e48..2502820c01b6a5210bdbe225cf4a0249eb427cbf 100644 (file)
@@ -297,26 +297,6 @@ void Resolver::buildAtomList()
        //_symbolTable.printStatistics();
 }
 
-unsigned int Resolver::ppcSubTypeIndex(uint32_t subtype)
-{
-       switch ( subtype ) {
-               case CPU_SUBTYPE_POWERPC_ALL:
-                       return 0;
-               case CPU_SUBTYPE_POWERPC_750:
-                       // G3
-                       return 1;
-               case CPU_SUBTYPE_POWERPC_7400:
-               case CPU_SUBTYPE_POWERPC_7450:
-                       // G4
-                       return 2;
-               case CPU_SUBTYPE_POWERPC_970:
-                       // G5 can run everything
-                       return 3;
-               default:
-                       throw "Unhandled PPC cpu subtype!";
-                       break;
-       }
-}
 
 void Resolver::doFile(const ld::File& file)
 {
@@ -363,29 +343,6 @@ void Resolver::doFile(const ld::File& file)
                // update cpu-sub-type
                cpu_subtype_t nextObjectSubType = file.cpuSubType();
                switch ( _options.architecture() ) {
-                       case CPU_TYPE_POWERPC:
-                               // no checking when -force_cpusubtype_ALL is used
-                               if ( _options.forceCpuSubtypeAll() )
-                                       return;
-                               if ( _options.preferSubArchitecture() ) {
-                                       // warn if some .o file is not compatible with desired output sub-type
-                                       if ( _options.subArchitecture() != nextObjectSubType ) {
-                                               if ( ppcSubTypeIndex(nextObjectSubType) > ppcSubTypeIndex(_options.subArchitecture()) ) {
-                                                       if ( !_inputFiles.inferredArch() )
-                                                               warning("cpu-sub-type of %s is not compatible with command line cpu-sub-type", file.path());
-                                                       _internal.cpuSubType = nextObjectSubType;
-                                               }
-                                       }
-                               }
-                               else {
-                                       // command line to linker just had -arch ppc
-                                       // figure out final sub-type based on sub-type of all .o files
-                                       if ( ppcSubTypeIndex(nextObjectSubType) > ppcSubTypeIndex(_internal.cpuSubType) ) {
-                                               _internal.cpuSubType = nextObjectSubType;
-                                       }
-                               }
-                               break;
-                       
                        case CPU_TYPE_ARM:
                                if ( _options.subArchitecture() != nextObjectSubType ) {
                                        if ( (_options.subArchitecture() == CPU_SUBTYPE_ARM_ALL) && _options.forceCpuSubtypeAll() ) {
@@ -405,9 +362,6 @@ void Resolver::doFile(const ld::File& file)
                                }
                                break;
                        
-                       case CPU_TYPE_POWERPC64:
-                               break;
-                               
                        case CPU_TYPE_I386:
                                _internal.cpuSubType = CPU_SUBTYPE_I386_ALL;
                                break;
@@ -567,8 +521,6 @@ bool Resolver::isDtraceProbe(ld::Fixup::Kind kind)
                case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear:
                case ld::Fixup::kindStoreThumbDtraceCallSiteNop:
                case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear:
-               case ld::Fixup::kindStorePPCDtraceCallSiteNop:
-               case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
                case ld::Fixup::kindDtraceExtra:
                        return true;
                default: 
@@ -770,7 +722,6 @@ void Resolver::markLive(const ld::Atom& atom, WhyLiveBackChain* previous)
                        case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA:
                        case ld::Fixup::kindStoreTargetAddressARMBranch24:
                        case ld::Fixup::kindStoreTargetAddressThumbBranch22:
-                       case ld::Fixup::kindStoreTargetAddressPPCBranch24:
                                if ( fit->binding == ld::Fixup::bindingByContentBound ) {
                                        // normally this was done in convertReferencesToIndirect()
                                        // but a archive loaded .o file may have a forward reference
@@ -1078,7 +1029,8 @@ void Resolver::checkUndefines(bool force)
                        break;
        }
        std::vector<const char*> unresolvableUndefines;
-       if ( _options.deadCodeStrip() ) 
+       // <rdar://problem/10052396> LTO many have eliminated need for some undefines
+       if ( _options.deadCodeStrip() || _haveLLVMObjs ) 
                this->liveUndefines(unresolvableUndefines);
        else    
                _symbolTable.undefines(unresolvableUndefines);
index 1202fc7e759b45c5160c4a86a484737585caf11f..65e20065740032287ba2f7b15cc3cae317f6ba9d 100644 (file)
@@ -94,7 +94,6 @@ private:
        void                                    markLive(const ld::Atom& atom, WhyLiveBackChain* previous);
        bool                                    isDtraceProbe(ld::Fixup::Kind kind);
        void                                    liveUndefines(std::vector<const char*>&);
-       static unsigned int             ppcSubTypeIndex(uint32_t subtype);
        bool                                    printReferencedBy(const char* name, SymbolTable::IndirectBindingSlot slot);
                        
 
index 2716ccfb66e798fc0c5267cbc288ce41cadf8fab..66ff3588955c46a45743abf88cc503183ac7b4f7 100644 (file)
@@ -179,22 +179,32 @@ bool SymbolTable::addByName(const ld::Atom& newAtom, bool ignoreDuplicates)
                                                        }
                                                        else {
                                                                // existing not-weak, new is not-weak
-                                                               if ( ignoreDuplicates ) {
+                                                               if ( newAtom.section().type() == ld::Section::typeMachHeader ) {
+                                                                       warning("ignoring override of built-in symbol %s from %s", newAtom.name(), existingAtom->file()->path());
+                                                                       useNew = true;
+                                                               } 
+                                                               else if ( existingAtom->section().type() == ld::Section::typeMachHeader ) {
+                                                                       warning("ignoring override of built-in symbol %s from %s", newAtom.name(), newAtom.file()->path());
                                                                        useNew = false;
-                                                                       static bool fullWarning = false;
-                                                                       if ( ! fullWarning ) {
-                                                                               warning("-dead_strip with lazy loaded static (library) archives "
-                                                                                               "has resulted in a duplicate symbol.  You can change your "
-                                                                                               "source code to rename symbols to avoid the collision.  "
-                                                                                               "This will be an error in a future linker.");
-                                                                               fullWarning = true;
-                                                                       }
-                                                                       warning("duplicate symbol %s originally in %s now lazily loaded from %s",
-                                                                                       SymbolTable::demangle(name), existingAtom->file()->path(), newAtom.file()->path());
-                                                               }
+                                                               } 
                                                                else {
-                                                                       throwf("duplicate symbol %s in %s and %s", 
-                                                                                       SymbolTable::demangle(name), newAtom.file()->path(), existingAtom->file()->path());
+                                                                       if ( ignoreDuplicates ) {
+                                                                               useNew = false;
+                                                                               static bool fullWarning = false;
+                                                                               if ( ! fullWarning ) {
+                                                                                       warning("-dead_strip with lazy loaded static (library) archives "
+                                                                                                       "has resulted in a duplicate symbol.  You can change your "
+                                                                                                       "source code to rename symbols to avoid the collision.  "
+                                                                                                       "This will be an error in a future linker.");
+                                                                                       fullWarning = true;
+                                                                               }
+                                                                               warning("duplicate symbol %s originally in %s now lazily loaded from %s",
+                                                                                               SymbolTable::demangle(name), existingAtom->file()->path(), newAtom.file()->path());
+                                                                       }
+                                                                       else {
+                                                                               throwf("duplicate symbol %s in %s and %s", 
+                                                                                               SymbolTable::demangle(name), newAtom.file()->path(), existingAtom->file()->path());
+                                                                       }
                                                                }
                                                        }
                                                }
@@ -222,17 +232,27 @@ bool SymbolTable::addByName(const ld::Atom& newAtom, bool ignoreDuplicates)
                                switch ( newAtom.definition() ) {
                                        case ld::Atom::definitionRegular:
                                                // replace existing tentative atom with regular one
-                                               checkVisibilityMismatch = true;
-                                               if ( newAtom.size() < existingAtom->size() ) {
-                                                       warning("for symbol %s tentative definition of size %llu from %s is "
-                                                                                       "being replaced by a real definition of size %llu from %s",
-                                                                                       newAtom.name(), existingAtom->size(), existingAtom->file()->path(),
-                                                                                       newAtom.size(), newAtom.file()->path());
+                                               if ( newAtom.section().type() == ld::Section::typeMachHeader ) {
+                                                       // silently replace tentative __dso_handle with real linker created symbol
+                                                       useNew = true;
+                                               }
+                                               else if ( existingAtom->section().type() == ld::Section::typeMachHeader ) {
+                                                       // silently replace tentative __dso_handle with real linker created symbol
+                                                       useNew = false;
                                                }
-                                               if ( newAtom.section().type() == ld::Section::typeCode ) {
-                                                       warning("for symbol %s tentative (data) defintion from %s is "
-                                                                       "being replaced by code from %s", newAtom.name(), existingAtom->file()->path(),
-                                                                       newAtom.file()->path());
+                                               else {
+                                                       checkVisibilityMismatch = true;
+                                                       if ( newAtom.size() < existingAtom->size() ) {
+                                                               warning("for symbol %s tentative definition of size %llu from %s is "
+                                                                                               "being replaced by a real definition of size %llu from %s",
+                                                                                               newAtom.name(), existingAtom->size(), existingAtom->file()->path(),
+                                                                                               newAtom.size(), newAtom.file()->path());
+                                                       }
+                                                       if ( newAtom.section().type() == ld::Section::typeCode ) {
+                                                               warning("for symbol %s tentative (data) defintion from %s is "
+                                                                               "being replaced by code from %s", newAtom.name(), existingAtom->file()->path(),
+                                                                               newAtom.file()->path());
+                                                       }
                                                }
                                                break;
                                        case ld::Atom::definitionTentative:
index 5b21c63c1d260a2d48f7c147fd6bd53bf77bce1f..ce49e73463db5ed6418b2d23a0b0bf7c207ccbca 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
  *
- * Copyright (c) 2005-2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -74,7 +74,7 @@ extern "C" double log2 ( double );
 #include "passes/tlvp.h"
 #include "passes/huge.h"
 #include "passes/compact_unwind.h"
-#include "passes/order_file.h"
+#include "passes/order.h"
 #include "passes/branch_island.h"
 #include "passes/branch_shim.h"
 #include "passes/objc.h"
@@ -87,14 +87,31 @@ extern "C" double log2 ( double );
 #include "parsers/opaque_section_file.h"
 
 
+struct PerformanceStatistics {
+       uint64_t                                                startTool;
+       uint64_t                                                startInputFileProcessing;
+       uint64_t                                                startResolver;
+       uint64_t                                                startDylibs;
+       uint64_t                                                startPasses;
+       uint64_t                                                startOutput;
+       uint64_t                                                startDone;
+       vm_statistics_data_t                    vmStart;
+       vm_statistics_data_t                    vmEnd;
+};
+
+
+
+
+
 class InternalState : public ld::Internal
 {
 public:
-                                                                                       InternalState(const Options& opts) : _options(opts) { }
+                                                                                       InternalState(const Options& opts) : _options(opts), _atomsOrderedInSections(false) { }
        virtual ld::Internal::FinalSection*             addAtom(const ld::Atom& atom);
        virtual ld::Internal::FinalSection*             getFinalSection(const ld::Section&);
        
        void                                                                    sortSections();
+       void                                                                    markAtomsOrdered() { _atomsOrderedInSections = true; }
        virtual                                                                 ~InternalState() {}
 private:
 
@@ -134,6 +151,7 @@ private:
 
        SectionInToOut                  _sectionInToFinalMap;
        const Options&                  _options;
+       bool                                    _atomsOrderedInSections;
 };
 
 ld::Section    InternalState::FinalSection::_s_DATA_data( "__DATA", "__data",  ld::Section::typeUnclassified);
@@ -440,32 +458,28 @@ static void validateFixups(const ld::Atom& atom)
 ld::Internal::FinalSection* InternalState::addAtom(const ld::Atom& atom)
 {
        ld::Internal::FinalSection* fs = this->getFinalSection(atom.section());
-
-       // <rdar://problem/8612550> When order file used on data, turn ordered zero fill symbols into zero data
-       switch ( atom.section().type() ) {
-               case ld::Section::typeZeroFill:
-               case ld::Section::typeTentativeDefs:
-                       if ( (atom.symbolTableInclusion() == ld::Atom::symbolTableIn) 
-                                       && (atom.size() <= 512) && (_options.orderedSymbolsCount() != 0) ) {
-                               for(Options::OrderedSymbolsIterator it = _options.orderedSymbolsBegin(); it != _options.orderedSymbolsEnd(); ++it) {
-                                       if ( (it->objectFileName == NULL) && (strcmp(it->symbolName, atom.name()) == 0) ) {
-                                               // found in order file, move to __data section
-                                               fs = getFinalSection(InternalState::FinalSection::_s_DATA_data);\
-                                               //fprintf(stderr, "moved %s to __data section\n", atom.name());
-                                               break;
-                                       }
-                               }
-                       }
-                       break;
-               default:
-                       break;
-       }
-       
        //fprintf(stderr, "InternalState::doAtom(%p), name=%s, sect=%s, finalsect=%p\n", &atom, atom.name(), atom.section().sectionName(), fs);
 #ifndef NDEBUG
        validateFixups(atom);
 #endif
-       fs->atoms.push_back(&atom);
+       if ( _atomsOrderedInSections ) {
+               // make sure this atom is placed before any trailing section$end$ atom
+               if ( (fs->atoms.size() > 1) && (fs->atoms.back()->contentType() == ld::Atom::typeSectionEnd) ) {
+                       // last atom in section$end$ atom, insert before it
+                       const ld::Atom* endAtom = fs->atoms.back();
+                       fs->atoms.pop_back();
+                       fs->atoms.push_back(&atom);
+                       fs->atoms.push_back(endAtom);
+               }
+               else {
+                       // not end atom, just append new atom
+                       fs->atoms.push_back(&atom);
+               }
+       }
+       else {
+               // normal case
+               fs->atoms.push_back(&atom);
+       }
        return fs;
 }
 
@@ -552,6 +566,49 @@ void InternalState::sortSections()
        
 }
 
+static char* commatize(uint64_t in, char* out)
+{
+       char* result = out;
+       char rawNum[30];
+       sprintf(rawNum, "%llu", in);
+       const int rawNumLen = strlen(rawNum);
+       for(int i=0; i < rawNumLen-1; ++i) {
+               *out++ = rawNum[i];
+               if ( ((rawNumLen-i) % 3) == 1 )
+                       *out++ = ',';
+       }
+       *out++ = rawNum[rawNumLen-1];
+       *out = '\0';
+       return result;
+}
+
+static void printTime(const char* msg, uint64_t partTime, uint64_t totalTime)
+{
+       static uint64_t sUnitsPerSecond = 0;
+       if ( sUnitsPerSecond == 0 ) {
+               struct mach_timebase_info timeBaseInfo;
+               if ( mach_timebase_info(&timeBaseInfo) == KERN_SUCCESS ) {
+                       sUnitsPerSecond = 1000000000ULL * timeBaseInfo.denom / timeBaseInfo.numer;
+                       //fprintf(stderr, "sUnitsPerSecond=%llu\n", sUnitsPerSecond);
+               }
+       }
+       if ( partTime < sUnitsPerSecond ) {
+               uint32_t milliSecondsTimeTen = (partTime*10000)/sUnitsPerSecond;
+               uint32_t milliSeconds = milliSecondsTimeTen/10;
+               uint32_t percentTimesTen = (partTime*1000)/totalTime;
+               uint32_t percent = percentTimesTen/10;
+               fprintf(stderr, "%24s: % 4d.%d milliseconds (% 4d.%d%%)\n", msg, milliSeconds, milliSecondsTimeTen-milliSeconds*10, percent, percentTimesTen-percent*10);
+       }
+       else {
+               uint32_t secondsTimeTen = (partTime*10)/sUnitsPerSecond;
+               uint32_t seconds = secondsTimeTen/10;
+               uint32_t percentTimesTen = (partTime*1000)/totalTime;
+               uint32_t percent = percentTimesTen/10;
+               fprintf(stderr, "%24s: % 4d.%d seconds (% 4d.%d%%)\n", msg, seconds, secondsTimeTen-seconds*10, percent, percentTimesTen-percent*10);
+       }
+}
+
+
 static void getVMInfo(vm_statistics_data_t& info)
 {
        mach_msg_type_number_t count = sizeof(vm_statistics_data_t) / sizeof(natural_t);
@@ -564,23 +621,20 @@ static void getVMInfo(vm_statistics_data_t& info)
 
 int main(int argc, const char* argv[])
 {
-#if DEBUG
-       usleep(1000000);
-#endif
        const char* archName = NULL;
        bool showArch = false;
        bool archInferred = false;
        try {
-               vm_statistics_data_t vmStart;
-               vm_statistics_data_t vmEnd;
-               getVMInfo(vmStart);
-       
+               PerformanceStatistics statistics;
+               statistics.startTool = mach_absolute_time();
+               
                // create object to track command line arguments
                Options options(argc, argv);
+               InternalState state(options);
                
-               // gather stats
+               // gather vm stats
                if ( options.printStatistics() )
-                       getVMInfo(vmStart);
+                       getVMInfo(statistics.vmStart);
 
                // update strings for error messages
                showArch = options.printArchPrefix();
@@ -588,46 +642,71 @@ int main(int argc, const char* argv[])
                archInferred = (options.architecture() == 0);
                
                // open and parse input files
+               statistics.startInputFileProcessing = mach_absolute_time();
                ld::tool::InputFiles inputFiles(options, &archName);
                
                // load and resolve all references
-               InternalState state(options);
+               statistics.startResolver = mach_absolute_time();
                ld::tool::Resolver resolver(options, inputFiles, state);
                resolver.resolve();
                                
                // add dylibs used
+               statistics.startDylibs = mach_absolute_time();
                inputFiles.dylibs(state);
        
                // do initial section sorting so passes have rough idea of the layout
                state.sortSections();
 
                // run passes
+               statistics.startPasses = mach_absolute_time();
                ld::passes::objc::doPass(options, state);
                ld::passes::stubs::doPass(options, state);
                ld::passes::huge::doPass(options, state);
                ld::passes::got::doPass(options, state);
                ld::passes::tlvp::doPass(options, state);
                ld::passes::dylibs::doPass(options, state);     // must be after stubs and GOT passes
-               ld::passes::order_file::doPass(options, state);
+               ld::passes::order::doPass(options, state);
+               state.markAtomsOrdered();
                ld::passes::branch_shim::doPass(options, state);        // must be after stubs 
-               ld::passes::branch_island::doPass(options, state);      // must be after stubs and order_file pass
+               ld::passes::branch_island::doPass(options, state);      // must be after stubs and order pass
                ld::passes::dtrace::doPass(options, state);
-               ld::passes::compact_unwind::doPass(options, state);  // must be after order-file pass
+               ld::passes::compact_unwind::doPass(options, state);  // must be after order pass
                
                // sort final sections
                state.sortSections();
 
                // write output file
+               statistics.startOutput = mach_absolute_time();
                ld::tool::OutputFile out(options);
                out.write(state);
+               statistics.startDone = mach_absolute_time();
                
                // print statistics
                //mach_o::relocatable::printCounts();
                if ( options.printStatistics() ) {
-                       getVMInfo(vmEnd);
-                       fprintf(stderr, "pageins=%u, pageouts=%u, faults=%u\n", vmEnd.pageins-vmStart.pageins,
-                                                                               vmEnd.pageouts-vmStart.pageouts, vmEnd.faults-vmStart.faults);
-                       
+                       getVMInfo(statistics.vmEnd);
+                       uint64_t totalTime = statistics.startDone - statistics.startTool;
+                       printTime("ld total time", totalTime, totalTime);
+                       printTime(" option parsing time", statistics.startInputFileProcessing  -        statistics.startTool,                           totalTime);
+                       printTime(" object file processing", statistics.startResolver                    -      statistics.startInputFileProcessing,totalTime);
+                       printTime(" resolve symbols", statistics.startDylibs                             -      statistics.startResolver,                       totalTime);
+                       printTime(" build atom list", statistics.startPasses                             -      statistics.startDylibs,                         totalTime);
+                       printTime(" passess", statistics.startOutput                             -      statistics.startPasses,                         totalTime);
+                       printTime(" write output", statistics.startDone                          -      statistics.startOutput,                         totalTime);
+                       fprintf(stderr, "pageins=%u, pageouts=%u, faults=%u\n", 
+                                                               statistics.vmEnd.pageins-statistics.vmStart.pageins,
+                                                               statistics.vmEnd.pageouts-statistics.vmStart.pageouts, 
+                                                               statistics.vmEnd.faults-statistics.vmStart.faults);
+                       char temp[40];
+                       fprintf(stderr, "processed %3u object files,  totaling %15s bytes\n", inputFiles._totalObjectLoaded, commatize(inputFiles._totalObjectSize, temp));
+                       fprintf(stderr, "processed %3u archive files, totaling %15s bytes\n", inputFiles._totalArchivesLoaded, commatize(inputFiles._totalArchiveSize, temp));
+                       fprintf(stderr, "processed %3u dylib files\n", inputFiles._totalDylibsLoaded);
+                       fprintf(stderr, "wrote output file            totaling %15s bytes\n", commatize(out.fileSize(), temp));
+               }
+               // <rdar://problem/6780050> Would like linker warning to be build error.
+               if ( options.errorBecauseOfWarnings() ) {
+                       fprintf(stderr, "ld: fatal warning(s) induced error (-fatal_warnings)\n");
+                       return 1;
                }
        }
        catch (const char* msg) {
index 96075a7398967a98c9447c8b47af804d0fa3b238..b615046effa1cbec74fbe1fbfee20d1cac0a5267 100644 (file)
@@ -318,16 +318,11 @@ struct Fixup
                                        kindStoreARMLoad12,
                                        kindStoreARMLow16, kindStoreARMHigh16, 
                                        kindStoreThumbLow16, kindStoreThumbHigh16, 
-                                       // PowerPC specific store kinds
-                                       kindStorePPCBranch24, kindStorePPCBranch14,
-                                       kindStorePPCPicLow14, kindStorePPCPicLow16, kindStorePPCPicHigh16AddLow, 
-                                       kindStorePPCAbsLow14, kindStorePPCAbsLow16, kindStorePPCAbsHigh16AddLow, kindStorePPCAbsHigh16, 
                                        // dtrace probes
                                        kindDtraceExtra,
                                        kindStoreX86DtraceCallSiteNop, kindStoreX86DtraceIsEnableSiteClear,
                                        kindStoreARMDtraceCallSiteNop, kindStoreARMDtraceIsEnableSiteClear,
                                        kindStoreThumbDtraceCallSiteNop, kindStoreThumbDtraceIsEnableSiteClear,
-                                       kindStorePPCDtraceCallSiteNop, kindStorePPCDtraceIsEnableSiteClear,
                                        // lazy binding
                                        kindLazyTarget, kindSetLazyOffset,
                                        // pointer store combinations
@@ -350,8 +345,6 @@ struct Fixup
                                        kindStoreTargetAddressARMBranch24,              // kindSetTargetAddress + kindStoreARMBranch24
                                        kindStoreTargetAddressThumbBranch22,    // kindSetTargetAddress + kindStoreThumbBranch22
                                        kindStoreTargetAddressARMLoad12,                // kindSetTargetAddress + kindStoreARMLoad12
-                                       // PowerPC value calculation and store combinations
-                                       kindStoreTargetAddressPPCBranch24,              // kindSetTargetAddress + kindStorePPCBranch24
                        };
 
        union {
index 66f9432af5f203c01d4df8bd2575b02ee0384e08..cf0a05854dcc23e617db67441bcd47caeb0b7470 100644 (file)
@@ -226,8 +226,6 @@ const class File<A>::Entry* File<A>::Entry::next() const
 }
 
 
-template <> cpu_type_t File<ppc>::architecture()    { return CPU_TYPE_POWERPC; }
-template <> cpu_type_t File<ppc64>::architecture()  { return CPU_TYPE_POWERPC64; }
 template <> cpu_type_t File<x86>::architecture()    { return CPU_TYPE_I386; }
 template <> cpu_type_t File<x86_64>::architecture() { return CPU_TYPE_X86_64; }
 template <> cpu_type_t File<arm>::architecture()    { return CPU_TYPE_ARM; }
@@ -314,12 +312,6 @@ bool File<x86>::memberHasObjCCategories(const Entry* member) const
        }
 }
 
-template <>
-bool File<ppc>::memberHasObjCCategories(const Entry* member) const
-{
-       // ppc uses ObjC1 ABI which has .objc_category* global symbols
-       return false;
-}
 
 
 template <typename A>
@@ -581,14 +573,6 @@ ld::archive::File* parse(const uint8_t* fileContent, uint64_t fileLength,
                        if ( archive::Parser<arm>::validFile(fileContent, fileLength, opts.objOpts) )
                                return archive::Parser<arm>::parse(fileContent, fileLength, path, modTime, ordinal, opts);
                        break;
-               case CPU_TYPE_POWERPC:
-                       if ( archive::Parser<ppc>::validFile(fileContent, fileLength, opts.objOpts) )
-                               return archive::Parser<ppc>::parse(fileContent, fileLength, path, modTime, ordinal, opts);
-                       break;
-               case CPU_TYPE_POWERPC64:
-                       if ( archive::Parser<ppc64>::validFile(fileContent, fileLength, opts.objOpts) )
-                               return archive::Parser<ppc64>::parse(fileContent, fileLength, path, modTime, ordinal, opts);
-                       break;
        }
        return NULL;
 }
index 46d350df801f5af86106e39dceacc92ea48085cb..3a11c18176dfb53d81abdb9d709b692da12826cb 100644 (file)
@@ -147,7 +147,7 @@ class Atom : public ld::Atom
 {
 public:
                                                                                Atom(File& f, const char* name, ld::Atom::Scope s, 
-                                                                                               ld::Atom::Definition d, ld::Atom::Combine c, ld::Atom::Alignment a);
+                                                                                               ld::Atom::Definition d, ld::Atom::Combine c, ld::Atom::Alignment a, bool ah);
 
        // overrides of ld::Atom
        virtual ld::File*                                       file() const            { return &_file; }
@@ -257,8 +257,6 @@ bool Parser::validFile(const uint8_t* fileContent, uint64_t fileLength, cpu_type
                                        return ::lto_module_is_object_file_in_memory_for_target(fileContent, fileLength, t->llvmTriplePrefix);
                        }
                        break;
-               case CPU_TYPE_POWERPC:
-                       return ::lto_module_is_object_file_in_memory_for_target(fileContent, fileLength, "powerpc-");
        }
        return false;
 }
@@ -268,8 +266,6 @@ const char* Parser::fileKind(const uint8_t* p, uint64_t fileLength)
        if ( (p[0] == 0xDE) && (p[1] == 0xC0) && (p[2] == 0x17) && (p[3] == 0x0B) ) {
                uint32_t arch = LittleEndian::get32(*((uint32_t*)(&p[16])));
                switch (arch) {
-                       case CPU_TYPE_POWERPC:
-                               return "ppc";
                        case CPU_TYPE_I386:
                                return "i386";
                        case CPU_TYPE_X86_64:
@@ -377,6 +373,7 @@ File::File(const char* pth, time_t mTime, const uint8_t* content, uint32_t conte
                // make LLVM atoms for definitions and a reference for undefines
                if ( def != ld::Atom::definitionProxy ) {
                        ld::Atom::Scope scope;
+                       bool autohide = false;
                        switch ( attr & LTO_SYMBOL_SCOPE_MASK) {
                                case LTO_SYMBOL_SCOPE_INTERNAL:
                                        scope = ld::Atom::scopeTranslationUnit;
@@ -387,6 +384,12 @@ File::File(const char* pth, time_t mTime, const uint8_t* content, uint32_t conte
                                case LTO_SYMBOL_SCOPE_DEFAULT:
                                        scope = ld::Atom::scopeGlobal;
                                        break;
+#if LTO_API_VERSION >= 4
+                               case LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN:
+                                       scope = ld::Atom::scopeGlobal;
+                                       autohide = true;
+                                       break;
+#endif
                                default:
                                        throwf("unknown scope for symbol %s in bitcode file %s", name, pth);
                        }
@@ -395,7 +398,7 @@ File::File(const char* pth, time_t mTime, const uint8_t* content, uint32_t conte
                                continue;
                        uint8_t alignment = (attr & LTO_SYMBOL_ALIGNMENT_MASK);
                        // make Atom using placement new operator
-                       new (&_atomArray[_atomArrayCount++]) Atom(*this, name, scope, def, combine, alignment);
+                       new (&_atomArray[_atomArrayCount++]) Atom(*this, name, scope, def, combine, alignment, autohide);
                        if ( scope == ld::Atom::scopeLinkageUnit )
                                _internalAtom.addReference(name);
                        if ( log ) fprintf(stderr, "\t0x%08X %s\n", attr, name);
@@ -430,11 +433,14 @@ InternalAtom::InternalAtom(File& f)
 {
 }
 
-Atom::Atom(File& f, const char* nm, ld::Atom::Scope s, ld::Atom::Definition d, ld::Atom::Combine c, ld::Atom::Alignment a)
+Atom::Atom(File& f, const char* nm, ld::Atom::Scope s, ld::Atom::Definition d, ld::Atom::Combine c, 
+                       ld::Atom::Alignment a, bool ah)
        : ld::Atom(f._section, d, c, s, ld::Atom::typeLTOtemporary, 
                                ld::Atom::symbolTableIn, false, false, false, a),
                _file(f), _name(nm), _compiledAtom(NULL)
 {
+       if ( ah )
+               this->setAutoHide();
 }
 
 void Atom::setCompiledAtom(const ld::Atom& atom)
index 436f3e6ab9c142114ea2f7078737d5ee36c31ec7..39cebfb92260c4c07ff197efd8df04e933a84f42 100644 (file)
@@ -855,60 +855,6 @@ public:
 
 
 
-template <>
-bool Parser<ppc>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
-{
-       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;
-       switch ( header->filetype() ) {
-               case MH_DYLIB:
-               case MH_DYLIB_STUB:
-                       return true;
-               case MH_BUNDLE:
-                       if ( executableOrDyliborBundle )
-                               return true;
-                       else
-                               throw "can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)";
-               case MH_EXECUTE:
-                       if ( executableOrDyliborBundle )
-                               return true;
-                       else
-                               throw "can't link with a main executable";
-               default:
-                       return false;
-       }
-}
-
-template <>
-bool Parser<ppc64>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
-{
-       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;
-       switch ( header->filetype() ) {
-               case MH_DYLIB:
-               case MH_DYLIB_STUB:
-                       return true;
-               case MH_BUNDLE:
-                       if ( executableOrDyliborBundle )
-                               return true;
-                       else
-                               throw "can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)";
-               case MH_EXECUTE:
-                       if ( executableOrDyliborBundle )
-                               return true;
-                       else
-                               throw "can't link with a main executable";
-               default:
-                       return false;
-       }
-}
-
 template <>
 bool Parser<x86>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
 {
@@ -1012,14 +958,6 @@ ld::dylib::File* parse(const uint8_t* fileContent, uint64_t fileLength,
                        if ( Parser<arm>::validFile(fileContent, bundleLoader) )
                                return Parser<arm>::parse(fileContent, fileLength, path, modTime, ordinal, opts, indirectDylib);
                        break;
-               case CPU_TYPE_POWERPC:
-                       if ( Parser<ppc>::validFile(fileContent, bundleLoader) )
-                               return Parser<ppc>::parse(fileContent, fileLength, path, modTime, ordinal, opts, indirectDylib);
-                       break;
-               case CPU_TYPE_POWERPC64:
-                       if ( Parser<ppc64>::validFile(fileContent, bundleLoader) )
-                               return Parser<ppc64>::parse(fileContent, fileLength, path, modTime, ordinal, opts, indirectDylib);
-                       break;
        }
        return NULL;
 }
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;
 }
 
index 99b3eb8f4b70eacb8b6d263f3ceba6219e2d57fe..773031e6f843128a1bd9aea694c23eeb2c777e21 100644 (file)
@@ -59,42 +59,6 @@ public:
 static bool _s_log = false;
 static ld::Section _s_text_section("__TEXT", "__text", ld::Section::typeCode);
 
-class PPCBranchIslandAtom : public ld::Atom {
-public:
-                                                                                       PPCBranchIslandAtom(const char* nm, const ld::Atom* target, TargetAndOffset finalTarget)
-                               : ld::Atom(_s_text_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
-                                                       ld::Atom::scopeLinkageUnit, ld::Atom::typeBranchIsland, 
-                                                       ld::Atom::symbolTableIn, false, false, false, ld::Atom::Alignment(2)), 
-                               _name(nm),
-                               _target(target),
-                               _finalTarget(finalTarget) { }
-
-       virtual const ld::File*                                 file() const                                    { return NULL; }
-       virtual bool                                                    translationUnitSource(const char** dir, const char**) const 
-                                                                                                                                                       { return false; }
-       virtual const char*                                             name() const                                    { return _name; }
-       virtual uint64_t                                                size() const                                    { return 4; }
-       virtual uint64_t                                                objectAddress() const                   { return 0; }
-       virtual void                                                    copyRawContent(uint8_t buffer[]) const {
-               int64_t displacement = _target->finalAddress() - this->finalAddress();
-               const int64_t bl_sixteenMegLimit = 0x00FFFFFF;
-               if ( _target->contentType() == ld::Atom::typeBranchIsland ) {
-                       // try optimizing away intermediate islands
-                       int64_t skipToFinalDisplacement = _finalTarget.atom->finalAddress() + _finalTarget.offset - this->finalAddress();
-                       if ( (skipToFinalDisplacement > bl_sixteenMegLimit) && (skipToFinalDisplacement < (-bl_sixteenMegLimit)) ) {
-                               displacement = skipToFinalDisplacement;
-                       }
-               }
-               int32_t branchInstruction = 0x48000000 | ((uint32_t)displacement & 0x03FFFFFC);
-               OSWriteBigInt32(buffer, 0, branchInstruction);
-       }
-       virtual void                                                    setScope(Scope)                                 { }
-
-private:
-       const char*                                                             _name;
-       const ld::Atom*                                                 _target;
-       TargetAndOffset                                                 _finalTarget;
-};
 
 
 class ARMtoARMBranchIslandAtom : public ld::Atom {
@@ -303,10 +267,6 @@ static ld::Atom* makeBranchIsland(const Options& opts, ld::Fixup::Kind kind, int
        }
 
        switch ( kind ) {
-               case ld::Fixup::kindStorePPCBranch24:
-               case ld::Fixup::kindStoreTargetAddressPPCBranch24:
-                       return new PPCBranchIslandAtom(name, nextTarget, finalTarget);
-                       break;
                case ld::Fixup::kindStoreARMBranch24:
                case ld::Fixup::kindStoreThumbBranch22:
                case ld::Fixup::kindStoreTargetAddressARMBranch24:
@@ -337,10 +297,6 @@ static ld::Atom* makeBranchIsland(const Options& opts, ld::Fixup::Kind kind, int
 static uint64_t textSizeWhenMightNeedBranchIslands(const Options& opts, bool seenThumbBranch)
 {
        switch ( opts.architecture() ) {
-               case CPU_TYPE_POWERPC:
-               case CPU_TYPE_POWERPC64:
-                       return 16000000;
-                       break;
                case CPU_TYPE_ARM:
                        if ( ! seenThumbBranch )
                                return 32000000;  // ARM can branch +/- 32MB
@@ -358,10 +314,6 @@ static uint64_t textSizeWhenMightNeedBranchIslands(const Options& opts, bool see
 static uint64_t maxDistanceBetweenIslands(const Options& opts, bool seenThumbBranch)
 {
        switch ( opts.architecture() ) {
-               case CPU_TYPE_POWERPC:
-               case CPU_TYPE_POWERPC64:
-                               return 14*1024*1024;
-                       break;
                case CPU_TYPE_ARM:
                        if ( ! seenThumbBranch )
                                return 30*1024*1024;    // 2MB of branch islands per 32MB
@@ -405,10 +357,8 @@ void doPass(const Options& opts, ld::Internal& state)
        if ( opts.outputKind() == Options::kObjectFile )
                return;
 
-       // only PowerPC and ARM need branch islands
+       // only ARM needs branch islands
        switch ( opts.architecture() ) {
-               case CPU_TYPE_POWERPC:
-               case CPU_TYPE_POWERPC64:
                case CPU_TYPE_ARM:
                        break;
                default:
@@ -506,8 +456,6 @@ void doPass(const Options& opts, ld::Internal& state)
                                case ld::Fixup::kindAddAddend:
                                        addend = fit->u.addend;
                                        break;
-                               case ld::Fixup::kindStorePPCBranch24:
-                               case ld::Fixup::kindStoreTargetAddressPPCBranch24:
                                case ld::Fixup::kindStoreARMBranch24:
                                case ld::Fixup::kindStoreThumbBranch22:
                                case ld::Fixup::kindStoreTargetAddressARMBranch24:
index f847cc009fc3f8bc722ac28d67b25fe884e3a89d..665e3ae3861072c1151bfd946ff6303855cb292f 100644 (file)
@@ -143,13 +143,11 @@ void doPass(const Options& opts, ld::Internal& internal)
                        for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
                                switch ( fit->kind ) {
                                        case ld::Fixup::kindStoreX86DtraceCallSiteNop:
-                                       case ld::Fixup::kindStorePPCDtraceCallSiteNop:
                                        case ld::Fixup::kindStoreARMDtraceCallSiteNop:
                                        case ld::Fixup::kindStoreThumbDtraceCallSiteNop:
                                                probeSites.push_back(DTraceProbeInfo(atom, fit->offsetInAtom, fit->u.name));
                                                break;
                                        case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear:
-                                       case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
                                        case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear:
                                        case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear:
                                                isEnabledSites.push_back(DTraceProbeInfo(atom, fit->offsetInAtom, fit->u.name));
@@ -170,10 +168,6 @@ void doPass(const Options& opts, ld::Internal& internal)
        
        ld::Fixup::Kind storeKind = ld::Fixup::kindNone;
        switch ( opts.architecture() ) {
-               case CPU_TYPE_POWERPC:
-               case CPU_TYPE_POWERPC64:
-                       storeKind = ld::Fixup::kindStoreBigEndian32;
-                       break;
                case CPU_TYPE_I386:
                case CPU_TYPE_X86_64:
                case CPU_TYPE_ARM:
index bb94ddff4df855b55fb0760f39dcca5e1236b919..08eeb731861c31d44577c95e5b93123dae5948e1 100644 (file)
@@ -89,8 +89,21 @@ static bool gotFixup(const Options& opts, ld::Internal& internal, const ld::Atom
                        }
                        if ( targetOfGOT->scope() == ld::Atom::scopeGlobal ) {  
                                // cannot do LEA optimization if target is weak exported symbol
-                               if ( (targetOfGOT->definition() == ld::Atom::definitionRegular) && (targetOfGOT->combine() == ld::Atom::combineByName) )
-                                       *optimizable = false;
+                               if ( (targetOfGOT->definition() == ld::Atom::definitionRegular) && (targetOfGOT->combine() == ld::Atom::combineByName) ) {
+                                       switch ( opts.outputKind() ) {
+                                               case Options::kDynamicExecutable:
+                                               case Options::kDynamicLibrary:
+                                               case Options::kDynamicBundle:
+                                               case Options::kKextBundle:
+                                                       *optimizable = false;
+                                                       break;
+                                               case Options::kStaticExecutable:
+                                               case Options::kDyld:
+                                               case Options::kPreload:
+                                               case Options::kObjectFile:
+                                                       break;
+                                       }
+                               }
                                // cannot do LEA optimization if target is interposable
                                if ( opts.interposable(targetOfGOT->name()) ) 
                                        *optimizable = false;
index ed591931062eeedc62609763025b924e0de6144f..b209b1dd61217066c1c92958fce8991a97cb866b 100644 (file)
@@ -1153,18 +1153,10 @@ void doPass(const Options& opts, ld::Internal& state)
                                state.addAtom(*new ObjCImageInfoAtom<x86>(state.objcObjectConstraint, compaction, 
                                                        state.hasObjcReplacementClasses, opts.objCABIVersion2POverride() ? true : false));
                                break;
-                       case CPU_TYPE_POWERPC:
-                               state.addAtom(*new ObjCImageInfoAtom<ppc>(state.objcObjectConstraint, compaction, 
-                                                       state.hasObjcReplacementClasses, false));
-                               break;
                        case CPU_TYPE_ARM:
                                state.addAtom(*new ObjCImageInfoAtom<arm>(state.objcObjectConstraint, compaction, 
                                                        state.hasObjcReplacementClasses, true));
                                break;
-                       case CPU_TYPE_POWERPC64:
-                               state.addAtom(*new ObjCImageInfoAtom<ppc64>(state.objcObjectConstraint, compaction, 
-                                                       state.hasObjcReplacementClasses, true));
-                               break;
                        default:
                                assert(0 && "unknown objc arch");
                }       
@@ -1185,9 +1177,6 @@ void doPass(const Options& opts, ld::Internal& state)
                                // disable optimization until fully tested
                                //OptimizeCategories<arm>::doit(opts, state);
                                break;
-                       case CPU_TYPE_POWERPC64:
-                       case CPU_TYPE_POWERPC:
-                               break;
                        default:
                                assert(0 && "unknown objc arch");
                }       
diff --git a/src/ld/passes/order.cpp b/src/ld/passes/order.cpp
new file mode 100644 (file)
index 0000000..ce17a35
--- /dev/null
@@ -0,0 +1,568 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+#include <stdint.h>
+#include <math.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <mach/machine.h>
+
+#include <vector>
+#include <map>
+
+#include "ld.hpp"
+#include "order.h"
+
+namespace ld {
+namespace passes {
+namespace order {
+
+//
+// The purpose of this pass is to take the graph of all Atoms and produce an ordered
+// sequence of atoms.  The constraints are that: 1) all Atoms of the same Segment must
+// be contiguous, 2)  all Atoms of the same Section must be contigous, 3) Atoms specified
+// in an order are sequenced as in the order file and before Atoms not specified,
+// 4) Atoms in the same section from the same .o file should be contiguous and sequenced
+// in the same order they were in the .o file, 5) Atoms in the same Section but which came
+// from different .o files should be sequenced in the same order that the .o files
+// were passed to the linker (i.e. command line order).
+//
+// The way this is implemented is that the linker passes a "base ordinal" to each File
+// as it is constructed. Add each atom has an objectAddress() method. Then
+// sorting is just sorting by section, then by file ordinal, then by object address.
+//
+// If an -order_file is specified, it gets more complicated.  First, an override-ordinal map
+// is created.  It causes the sort routine to ignore the value returned by ordinal() and objectAddress() 
+// and use the override value instead.  Next some Atoms must be laid out consecutively
+// (e.g. hand written assembly that does not end with return, but rather falls into
+// the next label).  This is modeled in via a kindNoneFollowOn fixup.  The use of
+// kindNoneFollowOn fixups produces "clusters" of atoms that must stay together.
+// If an order_file tries to move one atom, it may need to move a whole cluster.  The
+// algorithm to do this models clusters using two maps.  The "starts" maps maps any
+// atom in a cluster to the first Atom in the cluster.  The "nexts" maps an Atom in a
+// cluster to the next Atom in the cluster.  With this in place, while processing an
+// order_file, if any entry is in a cluster (in "starts" map), then the entire cluster is
+// given ordinal overrides.
+//
+
+class Layout
+{
+public:
+                               Layout(const Options& opts, ld::Internal& state);
+       void            doPass();
+private:
+
+       class Comparer {
+       public:
+                                       Comparer(const Layout& l) : _layout(l) {}
+               bool            operator()(const ld::Atom* left, const ld::Atom* right);
+       private:
+               const Layout&   _layout;
+       };
+                               
+       class CStringEquals {
+       public:
+               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
+       };
+       typedef __gnu_cxx::hash_map<const char*, const ld::Atom*, __gnu_cxx::hash<const char*>, CStringEquals> NameToAtom;
+       
+       typedef std::map<const ld::Atom*, const ld::Atom*> AtomToAtom;
+       
+       typedef std::map<const ld::Atom*, uint32_t> AtomToOrdinal;
+       
+       const ld::Atom*         findAtom(const Options::OrderedSymbol& orderedSymbol);
+       void                            buildNameTable();
+       void                            buildFollowOnTables();
+       void                            buildOrdinalOverrideMap();
+       const ld::Atom*         follower(const ld::Atom* atom);
+       static bool                     matchesObjectFile(const ld::Atom* atom, const char* objectFileLeafName);
+                       bool            possibleToOrder(const ld::Internal::FinalSection*);
+       
+       const Options&                                          _options;
+       ld::Internal&                                           _state;
+       AtomToAtom                                                      _followOnStarts;
+       AtomToAtom                                                      _followOnNexts;
+       NameToAtom                                                      _nameTable;
+       std::vector<const ld::Atom*>            _nameCollisionAtoms;
+       AtomToOrdinal                                           _ordinalOverrideMap;
+       Comparer                                                        _comparer;
+       bool                                                            _haveOrderFile;
+
+       static bool                                                     _s_log;
+};
+
+bool Layout::_s_log = false;
+
+Layout::Layout(const Options& opts, ld::Internal& state)
+       : _options(opts), _state(state), _comparer(*this), _haveOrderFile(opts.orderedSymbolsCount() != 0)
+{
+}
+
+
+bool Layout::Comparer::operator()(const ld::Atom* left, const ld::Atom* right)
+{
+       if ( left == right )
+               return false;
+       
+       // magic section$start symbol always sorts to the start of its section
+       if ( left->contentType() == ld::Atom::typeSectionStart )
+               return true;
+       if ( right->contentType() == ld::Atom::typeSectionStart )
+               return false;
+
+       // if an -order_file is specified, then sorting is altered to sort those symbols first
+       if ( _layout._haveOrderFile ) {
+               AtomToOrdinal::const_iterator leftPos  = _layout._ordinalOverrideMap.find(left);
+               AtomToOrdinal::const_iterator rightPos = _layout._ordinalOverrideMap.find(right);
+               AtomToOrdinal::const_iterator end = _layout._ordinalOverrideMap.end();
+               if ( leftPos != end ) {
+                       if ( rightPos != end ) {
+                               // both left and right are overridden, so compare overridden ordinals
+                               return leftPos->second < rightPos->second;
+                       }
+                       else {
+                               // left is overridden and right is not, so left < right
+                               return true;
+                       }
+               }
+               else {
+                       if ( rightPos != end ) {
+                               // right is overridden and left is not, so right < left
+                               return false;
+                       }
+                       else {
+                               // neither are overridden, 
+                               // fall into default sorting below
+                       }
+               }
+       }
+
+       // magic section$end symbol always sorts to the end of its section
+       if ( left->contentType() == ld::Atom::typeSectionEnd )
+               return false;
+       if ( right->contentType() == ld::Atom::typeSectionEnd )
+               return true;
+
+       // the __common section can have real or tentative definitions
+       // we want the real ones to sort before tentative ones
+       bool leftIsTent  =  (left->definition() == ld::Atom::definitionTentative);
+       bool rightIsTent =  (right->definition() == ld::Atom::definitionTentative);
+       if ( leftIsTent != rightIsTent )
+               return rightIsTent; 
+
+#if 0  
+       // initializers are auto sorted to start of section
+       if ( !fInitializerSet.empty() ) {
+               bool leftFirst  = (fInitializerSet.count(left) != 0);
+               bool rightFirst = (fInitializerSet.count(right) != 0);
+               if ( leftFirst != rightFirst ) 
+                       return leftFirst;
+       }
+
+       // terminators are auto sorted to end of section
+       if ( !fTerminatorSet.empty() ) {
+               bool leftLast  = (fTerminatorSet.count(left) != 0);
+               bool rightLast = (fTerminatorSet.count(right) != 0);
+               if ( leftLast != rightLast ) 
+                       return rightLast;
+       }
+#endif
+       
+       // sort by .o order
+       const ld::File* leftFile = left->file();
+       const ld::File* rightFile = right->file();
+       uint32_t leftFileOrdinal = (leftFile != NULL) ? leftFile->ordinal() : 0;
+       uint32_t rightFileOrdinal = (rightFile != NULL) ? rightFile->ordinal() : 0;
+       if ( leftFileOrdinal != rightFileOrdinal )
+               return leftFileOrdinal< rightFileOrdinal;
+
+       // tentative defintions have no address in .o file, they are traditionally laid out by name
+       if ( leftIsTent && rightIsTent ) 
+               return (strcmp(left->name(), right->name()) < 0);
+
+       // lastly sort by atom address
+       int64_t addrDiff = left->objectAddress() - right->objectAddress();
+       if ( addrDiff == 0 ) {
+               // have same address so one might be an alias, and aliases need to sort before target
+               bool leftIsAlias = left->isAlias();
+               bool rightIsAlias = right->isAlias();
+               if ( leftIsAlias != rightIsAlias )
+                       return leftIsAlias;
+
+               // both at same address, sort by name 
+               return (strcmp(left->name(), right->name()) < 0);
+       }
+       return (addrDiff < 0);
+}
+
+bool Layout::matchesObjectFile(const ld::Atom* atom, const char* objectFileLeafName)
+{
+       if ( objectFileLeafName == NULL )
+               return true;
+       const char* atomFullPath = atom->file()->path();
+       const char* lastSlash = strrchr(atomFullPath, '/');
+       if ( lastSlash != NULL ) {
+               if ( strcmp(&lastSlash[1], objectFileLeafName) == 0 )
+                       return true;
+       }
+       else {
+               if ( strcmp(atomFullPath, objectFileLeafName) == 0 )
+                       return true;
+       }
+       return false;
+}
+
+
+bool Layout::possibleToOrder(const ld::Internal::FinalSection* sect)
+{
+       // atoms in only some sections can have order_file applied
+       switch ( sect->type() ) {
+               case ld::Section::typeUnclassified:
+               case ld::Section::typeCode:
+               case ld::Section::typeZeroFill:
+                       return true;
+               case ld::Section::typeImportProxies:
+                       return false;
+               default:
+                       // if section has command line aliases, then we must apply ordering so aliases layout before targets
+                       if ( _options.haveCmdLineAliases() ) {
+                               for (std::vector<const ld::Atom*>::const_iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
+                                       const ld::Atom* atom = *ait;
+                                       if ( atom->isAlias() )
+                                               return true;
+                               }
+                       }
+                       break;
+       }
+       return false;
+}
+
+void Layout::buildNameTable()
+{
+       for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
+               ld::Internal::FinalSection* sect = *sit;
+               // some sections are not worth scanning for names
+               if ( ! possibleToOrder(sect) )
+                       continue;
+               for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
+                       const ld::Atom* atom = *ait;
+                       if ( atom->symbolTableInclusion() == ld::Atom::symbolTableIn ) {
+                               const char* name = atom->name();
+                               if ( name != NULL) {
+                                       // static function or data
+                                       NameToAtom::iterator pos = _nameTable.find(name);
+                                       if ( pos == _nameTable.end() )
+                                               _nameTable[name] = atom;
+                                       else {
+                                               const ld::Atom* existing = _nameTable[name];
+                                               if ( existing != NULL ) {
+                                                       _nameCollisionAtoms.push_back(existing);
+                                                       _nameTable[name] = NULL;        // collision, denote with NULL
+                                               }
+                                               _nameCollisionAtoms.push_back(atom);
+                                       }
+                               }
+                       }
+               }
+       }
+       if ( _s_log ) {
+               fprintf(stderr, "buildNameTable() _nameTable:\n");
+               for(NameToAtom::iterator it=_nameTable.begin(); it != _nameTable.end(); ++it)
+                       fprintf(stderr, "  %p <- %s\n", it->second, it->first);
+               fprintf(stderr, "buildNameTable() _nameCollisionAtoms:\n");
+               for(std::vector<const ld::Atom*>::iterator it=_nameCollisionAtoms.begin(); it != _nameCollisionAtoms.end(); ++it)
+                       fprintf(stderr, "  %p, %s\n", *it, (*it)->name());
+       }
+}
+
+
+const ld::Atom* Layout::findAtom(const Options::OrderedSymbol& orderedSymbol)
+{
+       // look for name in _nameTable
+       NameToAtom::iterator pos = _nameTable.find(orderedSymbol.symbolName);
+       if ( pos != _nameTable.end() ) {
+               if ( (pos->second != NULL) && matchesObjectFile(pos->second, orderedSymbol.objectFileName) ) {
+                       //fprintf(stderr, "found %s in hash table\n", orderedSymbol.symbolName);
+                       return pos->second;
+               }
+               if ( pos->second == NULL ) {
+                       // name is in hash table, but atom is NULL, so that means there are duplicates, so we use super slow way
+                       if ( ( orderedSymbol.objectFileName == NULL) && _options.printOrderFileStatistics() ) {
+                               warning("%s specified in order_file but it exists in multiple .o files. "
+                                               "Prefix symbol with .o filename in order_file to disambiguate", orderedSymbol.symbolName);
+                       }
+                       for (std::vector<const ld::Atom*>::iterator it=_nameCollisionAtoms.begin(); it != _nameCollisionAtoms.end(); it++) {
+                               const ld::Atom* atom = *it;
+                               if ( strcmp(atom->name(), orderedSymbol.symbolName) == 0 ) {
+                                       if ( matchesObjectFile(atom, orderedSymbol.objectFileName) ) {
+                                               return atom;
+                                       }
+                               }
+                       }
+               }
+       }
+               
+       return NULL;
+}
+
+const ld::Atom* Layout::follower(const ld::Atom* atom)
+{
+       for (const ld::Atom* a = _followOnStarts[atom]; a != NULL; a = _followOnNexts[a]) {
+               assert(a != NULL);
+               if ( _followOnNexts[a] == atom ) {
+                       return a;
+               }
+       }
+       // no follower, first in chain
+       return NULL;
+}
+
+void Layout::buildFollowOnTables()
+{
+       // if no -order_file, then skip building follow on table
+       if ( ! _haveOrderFile )
+               return;
+
+       // first make a pass to find all follow-on references and build start/next maps
+       // which are a way to represent clusters of atoms that must layout together
+       for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
+               ld::Internal::FinalSection* sect = *sit;
+               if ( !possibleToOrder(sect) ) 
+                       continue;
+               for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
+                       const ld::Atom* atom = *ait;
+                       for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
+                               if ( fit->kind == ld::Fixup::kindNoneFollowOn ) {
+                                       assert(fit->binding == ld::Fixup::bindingDirectlyBound);
+                                       const ld::Atom* followOnAtom = fit->u.target;
+                                       if ( _s_log ) fprintf(stderr, "ref %p %s -> %p %s\n", atom, atom->name(), followOnAtom, followOnAtom->name());
+                                       assert(_followOnNexts.count(atom) == 0);
+                                       _followOnNexts[atom] = followOnAtom;
+                                       if ( _followOnStarts.count(atom) == 0 ) {
+                                               // first time atom has been seen, make it start of chain
+                                               _followOnStarts[atom] = atom;
+                                               if ( _s_log ) fprintf(stderr, "  start %s -> %s\n", atom->name(), atom->name());
+                                       }
+                                       if ( _followOnStarts.count(followOnAtom) == 0 ) {
+                                               // first time followOnAtom has been seen, make atom start of chain
+                                               _followOnStarts[followOnAtom] = _followOnStarts[atom];
+                                               if ( _s_log ) fprintf(stderr, "  start %s -> %s\n", followOnAtom->name(), _followOnStarts[atom]->name());
+                                       }
+                                       else {
+                                               if ( _followOnStarts[followOnAtom] == followOnAtom ) {
+                                                       // followOnAtom atom already start of another chain, hook together 
+                                                       // and change all to use atom as start
+                                                       const ld::Atom* a = followOnAtom;
+                                                       while ( true ) {
+                                                               assert(_followOnStarts[a] == followOnAtom);
+                                                               _followOnStarts[a] = _followOnStarts[atom];
+                                                               if ( _s_log ) fprintf(stderr, "  adjust start for %s -> %s\n", a->name(), _followOnStarts[atom]->name());
+                                                               AtomToAtom::iterator pos = _followOnNexts.find(a);
+                                                               if ( pos != _followOnNexts.end() )
+                                                                       a = pos->second;
+                                                               else
+                                                                       break;
+                                                       }
+                                               }
+                                               else {
+                                                       // attempt to insert atom into existing followOn chain
+                                                       const ld::Atom* curPrevToFollowOnAtom = this->follower(followOnAtom);
+                                                       assert(curPrevToFollowOnAtom != NULL);
+                                                       assert((atom->size() == 0) || (curPrevToFollowOnAtom->size() == 0));
+                                                       if ( atom->size() == 0 ) {
+                                                               // insert alias into existing chain right before followOnAtom
+                                                               _followOnNexts[curPrevToFollowOnAtom] = atom;
+                                                               _followOnNexts[atom] = followOnAtom;
+                                                               _followOnStarts[atom] = _followOnStarts[followOnAtom];
+                                                       }
+                                                       else {
+                                                               // insert real atom into existing chain right before alias of followOnAtom
+                                                               const ld::Atom* curPrevPrevToFollowOn = this->follower(curPrevToFollowOnAtom);
+                                                               if ( curPrevPrevToFollowOn == NULL ) {
+                                                                       // nothing previous, so make this a start of a new chain
+                                                                       _followOnNexts[atom] = curPrevToFollowOnAtom;
+                                                                       for (const ld::Atom* a = atom; a != NULL; a = _followOnNexts[a]) {
+                                                                               if ( _s_log ) fprintf(stderr, "  adjust start for %s -> %s\n", a->name(), atom->name());
+                                                                               _followOnStarts[a] = atom;
+                                                                       }
+                                                               }
+                                                               else {
+                                                                       // is previous, insert into existing chain before previous
+                                                                       _followOnNexts[curPrevPrevToFollowOn] = atom;
+                                                                       _followOnNexts[atom] = curPrevToFollowOnAtom;
+                                                                       _followOnStarts[atom] = _followOnStarts[curPrevToFollowOnAtom];
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if ( _s_log ) {
+               for(AtomToAtom::iterator it = _followOnStarts.begin(); it != _followOnStarts.end(); ++it)
+                       fprintf(stderr, "start %s -> %s\n", it->first->name(), it->second->name());
+
+               for(AtomToAtom::iterator it = _followOnNexts.begin(); it != _followOnNexts.end(); ++it)
+                       fprintf(stderr, "next %s -> %s\n", it->first->name(), (it->second != NULL) ? it->second->name() : "null");
+       }
+}
+
+
+class InSet
+{
+public:
+       InSet(const std::set<const ld::Atom*>& theSet) : _set(theSet)  {}
+
+       bool operator()(const ld::Atom* atom) const {
+               return ( _set.count(atom) != 0 );
+       }
+private:
+       const std::set<const ld::Atom*>&  _set;
+};
+
+
+void Layout::buildOrdinalOverrideMap()
+{
+       // if no -order_file, then skip building override map
+       if ( ! _haveOrderFile )
+               return;
+
+       // build fast name->atom table
+       this->buildNameTable();
+
+       // handle .o files that cannot have their atoms rearranged
+       // with the start/next maps of follow-on atoms we can process the order file and produce override ordinals
+       uint32_t index = 0;
+       uint32_t matchCount = 0;
+       std::set<const ld::Atom*> moveToData;
+       for(Options::OrderedSymbolsIterator it = _options.orderedSymbolsBegin(); it != _options.orderedSymbolsEnd(); ++it) {
+               const ld::Atom* atom = this->findAtom(*it);
+               if ( atom != NULL ) {
+                       // <rdar://problem/8612550> When order file used on data, turn ordered zero fill symbols into zero data
+                       switch ( atom->section().type() ) {
+                               case ld::Section::typeZeroFill:
+                               case ld::Section::typeTentativeDefs:
+                                       if ( atom->size() <= 512 ) 
+                                               moveToData.insert(atom);
+                                       break;
+                               default:
+                                       break;
+                       }
+               
+                       AtomToAtom::iterator start = _followOnStarts.find(atom);
+                       if ( start != _followOnStarts.end() ) {
+                               // this symbol for the order file corresponds to an atom that is in a cluster that must lay out together
+                               for(const ld::Atom* nextAtom = start->second; nextAtom != NULL; nextAtom = _followOnNexts[nextAtom]) {
+                                       AtomToOrdinal::iterator pos = _ordinalOverrideMap.find(nextAtom);
+                                       if ( pos == _ordinalOverrideMap.end() ) {
+                                               _ordinalOverrideMap[nextAtom] = index++;
+                                               if (_s_log ) fprintf(stderr, "override ordinal %u assigned to %s in cluster from %s\n", index, nextAtom->name(), nextAtom->file()->path());
+                                       }
+                                       else {
+                                               if (_s_log ) fprintf(stderr, "could not order %s as %u because it was already laid out earlier by %s as %u\n",
+                                                                               atom->name(), index, _followOnStarts[atom]->name(), _ordinalOverrideMap[atom] );
+                                       }
+                               }
+                       }
+                       else {
+                               _ordinalOverrideMap[atom] = index;
+                               if (_s_log ) fprintf(stderr, "override ordinal %u assigned to %s from %s\n", index, atom->name(), atom->file()->path());
+                       }
+                       ++matchCount;
+               }
+               else {
+                       if ( _options.printOrderFileStatistics() ) {
+                               if ( it->objectFileName == NULL )
+                                       warning("can't find match for order_file entry: %s", it->symbolName);
+                               else
+                                       warning("can't find match for order_file entry: %s/%s", it->objectFileName, it->symbolName);
+                       }
+               }
+                ++index;
+       }
+       if ( _options.printOrderFileStatistics() && (_options.orderedSymbolsCount() != matchCount) ) {
+               warning("only %u out of %lu order_file symbols were applicable", matchCount, _options.orderedSymbolsCount() );
+       }
+
+
+       // <rdar://problem/8612550> When order file used on data, turn ordered zero fill symbols into zeroed data
+       if ( ! moveToData.empty() ) {
+               for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
+                       ld::Internal::FinalSection* sect = *sit;
+                       switch ( sect->type() ) {
+                               case ld::Section::typeZeroFill:
+                               case ld::Section::typeTentativeDefs:
+                                       sect->atoms.erase(std::remove_if(sect->atoms.begin(), sect->atoms.end(), InSet(moveToData)), sect->atoms.end());
+                                       break;
+                               case ld::Section::typeUnclassified:
+                                       if ( (strcmp(sect->sectionName(), "__data") == 0) && (strcmp(sect->segmentName(), "__DATA") == 0) )
+                                               sect->atoms.insert(sect->atoms.end(), moveToData.begin(), moveToData.end());
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       }
+
+}
+
+void Layout::doPass()
+{
+       // handle .o files that cannot have their atoms rearranged
+       this->buildFollowOnTables();
+
+       // assign new ordinal value to all ordered atoms
+       this->buildOrdinalOverrideMap();
+
+       // sort atoms in each section
+       for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
+               ld::Internal::FinalSection* sect = *sit;
+               std::sort(sect->atoms.begin(), sect->atoms.end(), _comparer);
+       }
+
+       //fprintf(stderr, "Sorted atoms:\n");
+       //for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
+       //      ld::Internal::FinalSection* sect = *sit;
+       //      for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
+       //              const ld::Atom* atom = *ait;
+       //              fprintf(stderr, "\t%s\t%s\n", sect->sectionName(), atom->name());
+       //      }
+       //}
+
+}
+
+
+void doPass(const Options& opts, ld::Internal& state)
+{
+       Layout layout(opts, state);
+       layout.doPass();
+}
+
+
+} // namespace order_file
+} // namespace passes 
+} // namespace ld 
diff --git a/src/ld/passes/order.h b/src/ld/passes/order.h
new file mode 100644 (file)
index 0000000..a3608e1
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+#ifndef __ORDER_H__
+#define __ORDER_H__
+
+#include "Options.h"
+#include "ld.hpp"
+
+
+namespace ld {
+namespace passes {
+namespace order {
+
+// called by linker to re-arrange atoms to improve locality and performance
+extern void doPass(const Options& opts, ld::Internal& internal);
+
+
+} // namespace order
+} // namespace passes 
+} // namespace ld 
+
+#endif // __ORDER_H__
diff --git a/src/ld/passes/order_file.cpp b/src/ld/passes/order_file.cpp
deleted file mode 100644 (file)
index 5e814bd..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
- *
- * Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-#include <stdint.h>
-#include <math.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <mach/machine.h>
-
-#include <vector>
-#include <map>
-
-#include "ld.hpp"
-#include "order_file.h"
-
-namespace ld {
-namespace passes {
-namespace order_file {
-
-//
-// The purpose of this pass is to take the graph of all Atoms and produce an ordered
-// sequence of atoms.  The constraints are that: 1) all Atoms of the same Segment must
-// be contiguous, 2)  all Atoms of the same Section must be contigous, 3) Atoms specified
-// in an order_file are sequenced as in the order_file and before Atoms not specified,
-// 4) Atoms in the same section from the same .o file should be contiguous and sequenced
-// in the same order they were in the .o file, 5) Atoms in the same Section but which came
-// from different .o files should be sequenced in the same order that the .o files
-// were passed to the linker (i.e. command line order).
-//
-// The way this is implemented is that the linker passes a "base ordinal" to each File
-// as it is constructed. Add each atom has an objectAddress() method. Then
-// sorting is just sorting by section, then by file ordinal, then by object address.
-//
-// If an order_file is specified, it gets more complicated.  First, an override-ordinal map
-// is created.  It causes the sort routine to ignore the value returned by ordinal() and objectAddress() 
-// and use the override value instead.  Next some Atoms must be layed out consecutively
-// (e.g. hand written assembly that does not end with return, but rather falls into
-// the next label).  This is modeled in via a kindNoneFollowOn fixup.  The use of
-// kindNoneFollowOn fixups produces "clusters" of atoms that must stay together.
-// If an order_file tries to move one atom, it may need to move a whole cluster.  The
-// algorithm to do this models clusters using two maps.  The "starts" maps maps any
-// atom in a cluster to the first Atom in the cluster.  The "nexts" maps an Atom in a
-// cluster to the next Atom in the cluster.  With this in place, while processing an
-// order_file, if any entry is in a cluster (in "starts" map), then the entire cluster is
-// given ordinal overrides.
-//
-
-class Layout
-{
-public:
-                               Layout(const Options& opts, ld::Internal& state);
-       void            doPass();
-private:
-
-       class Comparer {
-       public:
-                                       Comparer(const Layout& l) : _layout(l) {}
-               bool            operator()(const ld::Atom* left, const ld::Atom* right);
-       private:
-               const Layout&   _layout;
-       };
-                               
-       class CStringEquals {
-       public:
-               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
-       };
-       typedef __gnu_cxx::hash_map<const char*, const ld::Atom*, __gnu_cxx::hash<const char*>, CStringEquals> NameToAtom;
-       
-       typedef std::map<const ld::Atom*, const ld::Atom*> AtomToAtom;
-       
-       typedef std::map<const ld::Atom*, uint32_t> AtomToOrdinal;
-       
-       const ld::Atom*         findAtom(const Options::OrderedSymbol& orderedSymbol);
-       void                            buildNameTable();
-       void                            buildFollowOnTables();
-       void                            buildOrdinalOverrideMap();
-       const ld::Atom*         follower(const ld::Atom* atom);
-       static bool                     matchesObjectFile(const ld::Atom* atom, const char* objectFileLeafName);
-                       bool            orderableSection(const ld::Internal::FinalSection*);
-       
-       const Options&                                          _options;
-       ld::Internal&                                           _state;
-       AtomToAtom                                                      _followOnStarts;
-       AtomToAtom                                                      _followOnNexts;
-       NameToAtom                                                      _nameTable;
-       std::vector<const ld::Atom*>            _nameCollisionAtoms;
-       AtomToOrdinal                                           _ordinalOverrideMap;
-       Comparer                                                        _comparer;
-       bool                                                            _haveOrderFile;
-
-       static bool                                                     _s_log;
-};
-
-bool Layout::_s_log = false;
-
-Layout::Layout(const Options& opts, ld::Internal& state)
-       : _options(opts), _state(state), _comparer(*this), _haveOrderFile(opts.orderedSymbolsCount() != 0)
-{
-}
-
-
-bool Layout::Comparer::operator()(const ld::Atom* left, const ld::Atom* right)
-{
-       if ( left == right )
-               return false;
-       
-       // magic section$start symbol always sorts to the start of its section
-       if ( left->contentType() == ld::Atom::typeSectionStart )
-               return true;
-       if ( right->contentType() == ld::Atom::typeSectionStart )
-               return false;
-
-       // if a -order_file is specified, then sorting is altered to sort those symbols first
-       if ( _layout._haveOrderFile ) {
-               AtomToOrdinal::const_iterator leftPos  = _layout._ordinalOverrideMap.find(left);
-               AtomToOrdinal::const_iterator rightPos = _layout._ordinalOverrideMap.find(right);
-               AtomToOrdinal::const_iterator end = _layout._ordinalOverrideMap.end();
-               if ( leftPos != end ) {
-                       if ( rightPos != end ) {
-                               // both left and right are overridden, so compare overridden ordinals
-                               return leftPos->second < rightPos->second;
-                       }
-                       else {
-                               // left is overridden and right is not, so left < right
-                               return true;
-                       }
-               }
-               else {
-                       if ( rightPos != end ) {
-                               // right is overridden and left is not, so right < left
-                               return false;
-                       }
-                       else {
-                               // neither are overridden, 
-                               // fall into default sorting below
-                       }
-               }
-       }
-
-       // magic section$end symbol always sorts to the end of its section
-       if ( left->contentType() == ld::Atom::typeSectionEnd )
-               return false;
-       if ( right->contentType() == ld::Atom::typeSectionEnd )
-               return true;
-
-       // the __common section can have real or tentative definitions
-       // we want the real ones to sort before tentative ones
-       bool leftIsTent  =  (left->definition() == ld::Atom::definitionTentative);
-       bool rightIsTent =  (right->definition() == ld::Atom::definitionTentative);
-       if ( leftIsTent != rightIsTent )
-               return rightIsTent; 
-
-#if 0  
-       // initializers are auto sorted to start of section
-       if ( !fInitializerSet.empty() ) {
-               bool leftFirst  = (fInitializerSet.count(left) != 0);
-               bool rightFirst = (fInitializerSet.count(right) != 0);
-               if ( leftFirst != rightFirst ) 
-                       return leftFirst;
-       }
-
-       // terminators are auto sorted to end of section
-       if ( !fTerminatorSet.empty() ) {
-               bool leftLast  = (fTerminatorSet.count(left) != 0);
-               bool rightLast = (fTerminatorSet.count(right) != 0);
-               if ( leftLast != rightLast ) 
-                       return rightLast;
-       }
-#endif
-       
-       // sort by .o order
-       uint32_t leftFileOrdinal = left->file()->ordinal();
-       uint32_t rightFileOrdinal = right->file()->ordinal();
-       if ( leftFileOrdinal != rightFileOrdinal )
-               return leftFileOrdinal< rightFileOrdinal;
-
-       // tentative defintions have no address in .o file, they are traditionally laid out by name
-       if ( leftIsTent && rightIsTent ) 
-               return (strcmp(left->name(), right->name()) < 0);
-
-       // lastly sort by atom address
-       int64_t addrDiff = left->objectAddress() - right->objectAddress();
-       if ( addrDiff == 0 ) {
-               // have same address so one might be an alias, and aliases need to sort before target
-               bool leftIsAlias = left->isAlias();
-               bool rightIsAlias = right->isAlias();
-               if ( leftIsAlias != rightIsAlias )
-                       return leftIsAlias;
-
-               // both at same address, sort by name 
-               return (strcmp(left->name(), right->name()) < 0);
-       }
-       return (addrDiff < 0);
-}
-
-bool Layout::matchesObjectFile(const ld::Atom* atom, const char* objectFileLeafName)
-{
-       if ( objectFileLeafName == NULL )
-               return true;
-       const char* atomFullPath = atom->file()->path();
-       const char* lastSlash = strrchr(atomFullPath, '/');
-       if ( lastSlash != NULL ) {
-               if ( strcmp(&lastSlash[1], objectFileLeafName) == 0 )
-                       return true;
-       }
-       else {
-               if ( strcmp(atomFullPath, objectFileLeafName) == 0 )
-                       return true;
-       }
-       return false;
-}
-
-
-bool Layout::orderableSection(const ld::Internal::FinalSection* sect)
-{
-       // atoms in only some sections are ordered 
-       switch ( sect->type() ) {
-               case ld::Section::typeUnclassified:
-               case ld::Section::typeCode:
-               case ld::Section::typeZeroFill:
-                       return true;
-               case ld::Section::typeImportProxies:
-                       return false;
-               default:
-                       // if section has command line aliases, then we must apply ordering so aliases layout before targets
-                       if ( _options.haveCmdLineAliases() ) {
-                               for (std::vector<const ld::Atom*>::const_iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
-                                       const ld::Atom* atom = *ait;
-                                       if ( atom->isAlias() )
-                                               return true;
-                               }
-                       }
-                       break;
-       }
-       return false;
-}
-
-void Layout::buildNameTable()
-{
-       for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
-               ld::Internal::FinalSection* sect = *sit;
-               // atoms in some special sections are never ordered 
-               if ( ! orderableSection(sect) )
-                       continue;
-               for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
-                       const ld::Atom* atom = *ait;
-                       if ( atom->symbolTableInclusion() == ld::Atom::symbolTableIn ) {
-                               const char* name = atom->name();
-                               if ( name != NULL) {
-                                       // static function or data
-                                       NameToAtom::iterator pos = _nameTable.find(name);
-                                       if ( pos == _nameTable.end() )
-                                               _nameTable[name] = atom;
-                                       else {
-                                               const ld::Atom* existing = _nameTable[name];
-                                               if ( existing != NULL ) {
-                                                       _nameCollisionAtoms.push_back(existing);
-                                                       _nameTable[name] = NULL;        // collision, denote with NULL
-                                               }
-                                               _nameCollisionAtoms.push_back(atom);
-                                       }
-                               }
-                       }
-               }
-       }
-       if ( _s_log ) {
-               fprintf(stderr, "buildNameTable() _nameTable:\n");
-               for(NameToAtom::iterator it=_nameTable.begin(); it != _nameTable.end(); ++it)
-                       fprintf(stderr, "  %p <- %s\n", it->second, it->first);
-               fprintf(stderr, "buildNameTable() _nameCollisionAtoms:\n");
-               for(std::vector<const ld::Atom*>::iterator it=_nameCollisionAtoms.begin(); it != _nameCollisionAtoms.end(); ++it)
-                       fprintf(stderr, "  %p, %s\n", *it, (*it)->name());
-       }
-}
-
-
-const ld::Atom* Layout::findAtom(const Options::OrderedSymbol& orderedSymbol)
-{
-       // look for name in _nameTable
-       NameToAtom::iterator pos = _nameTable.find(orderedSymbol.symbolName);
-       if ( pos != _nameTable.end() ) {
-               if ( (pos->second != NULL) && matchesObjectFile(pos->second, orderedSymbol.objectFileName) ) {
-                       //fprintf(stderr, "found %s in hash table\n", orderedSymbol.symbolName);
-                       return pos->second;
-               }
-               if ( pos->second == NULL ) {
-                       // name is in hash table, but atom is NULL, so that means there are duplicates, so we use super slow way
-                       if ( ( orderedSymbol.objectFileName == NULL) && _options.printOrderFileStatistics() ) {
-                               warning("%s specified in order_file but it exists in multiple .o files. "
-                                               "Prefix symbol with .o filename in order_file to disambiguate", orderedSymbol.symbolName);
-                       }
-                       for (std::vector<const ld::Atom*>::iterator it=_nameCollisionAtoms.begin(); it != _nameCollisionAtoms.end(); it++) {
-                               const ld::Atom* atom = *it;
-                               if ( strcmp(atom->name(), orderedSymbol.symbolName) == 0 ) {
-                                       if ( matchesObjectFile(atom, orderedSymbol.objectFileName) ) {
-                                               return atom;
-                                       }
-                               }
-                       }
-               }
-       }
-               
-       return NULL;
-}
-
-const ld::Atom* Layout::follower(const ld::Atom* atom)
-{
-       for (const ld::Atom* a = _followOnStarts[atom]; a != NULL; a = _followOnNexts[a]) {
-               assert(a != NULL);
-               if ( _followOnNexts[a] == atom ) {
-                       return a;
-               }
-       }
-       // no follower, first in chain
-       return NULL;
-}
-
-void Layout::buildFollowOnTables()
-{
-       // first make a pass to find all follow-on references and build start/next maps
-       // which are a way to represent clusters of atoms that must layout together
-       for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
-               ld::Internal::FinalSection* sect = *sit;
-               if ( !orderableSection(sect) ) 
-                       continue;
-               for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
-                       const ld::Atom* atom = *ait;
-                       for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
-                               if ( fit->kind == ld::Fixup::kindNoneFollowOn ) {
-                                       assert(fit->binding == ld::Fixup::bindingDirectlyBound);
-                                       const ld::Atom* followOnAtom = fit->u.target;
-                                       if ( _s_log ) fprintf(stderr, "ref %p %s -> %p %s\n", atom, atom->name(), followOnAtom, followOnAtom->name());
-                                       assert(_followOnNexts.count(atom) == 0);
-                                       _followOnNexts[atom] = followOnAtom;
-                                       if ( _followOnStarts.count(atom) == 0 ) {
-                                               // first time atom has been seen, make it start of chain
-                                               _followOnStarts[atom] = atom;
-                                               if ( _s_log ) fprintf(stderr, "  start %s -> %s\n", atom->name(), atom->name());
-                                       }
-                                       if ( _followOnStarts.count(followOnAtom) == 0 ) {
-                                               // first time followOnAtom has been seen, make atom start of chain
-                                               _followOnStarts[followOnAtom] = _followOnStarts[atom];
-                                               if ( _s_log ) fprintf(stderr, "  start %s -> %s\n", followOnAtom->name(), _followOnStarts[atom]->name());
-                                       }
-                                       else {
-                                               if ( _followOnStarts[followOnAtom] == followOnAtom ) {
-                                                       // followOnAtom atom already start of another chain, hook together 
-                                                       // and change all to use atom as start
-                                                       const ld::Atom* a = followOnAtom;
-                                                       while ( true ) {
-                                                               assert(_followOnStarts[a] == followOnAtom);
-                                                               _followOnStarts[a] = _followOnStarts[atom];
-                                                               if ( _s_log ) fprintf(stderr, "  adjust start for %s -> %s\n", a->name(), _followOnStarts[atom]->name());
-                                                               AtomToAtom::iterator pos = _followOnNexts.find(a);
-                                                               if ( pos != _followOnNexts.end() )
-                                                                       a = pos->second;
-                                                               else
-                                                                       break;
-                                                       }
-                                               }
-                                               else {
-                                                       // attempt to insert atom into existing followOn chain
-                                                       const ld::Atom* curPrevToFollowOnAtom = this->follower(followOnAtom);
-                                                       assert(curPrevToFollowOnAtom != NULL);
-                                                       assert((atom->size() == 0) || (curPrevToFollowOnAtom->size() == 0));
-                                                       if ( atom->size() == 0 ) {
-                                                               // insert alias into existing chain right before followOnAtom
-                                                               _followOnNexts[curPrevToFollowOnAtom] = atom;
-                                                               _followOnNexts[atom] = followOnAtom;
-                                                               _followOnStarts[atom] = _followOnStarts[followOnAtom];
-                                                       }
-                                                       else {
-                                                               // insert real atom into existing chain right before alias of followOnAtom
-                                                               const ld::Atom* curPrevPrevToFollowOn = this->follower(curPrevToFollowOnAtom);
-                                                               if ( curPrevPrevToFollowOn == NULL ) {
-                                                                       // nothing previous, so make this a start of a new chain
-                                                                       _followOnNexts[atom] = curPrevToFollowOnAtom;
-                                                                       for (const ld::Atom* a = atom; a != NULL; a = _followOnNexts[a]) {
-                                                                               if ( _s_log ) fprintf(stderr, "  adjust start for %s -> %s\n", a->name(), atom->name());
-                                                                               _followOnStarts[a] = atom;
-                                                                       }
-                                                               }
-                                                               else {
-                                                                       // is previous, insert into existing chain before previous
-                                                                       _followOnNexts[curPrevPrevToFollowOn] = atom;
-                                                                       _followOnNexts[atom] = curPrevToFollowOnAtom;
-                                                                       _followOnStarts[atom] = _followOnStarts[curPrevToFollowOnAtom];
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if ( _s_log ) {
-               for(AtomToAtom::iterator it = _followOnStarts.begin(); it != _followOnStarts.end(); ++it)
-                       fprintf(stderr, "start %s -> %s\n", it->first->name(), it->second->name());
-
-               for(AtomToAtom::iterator it = _followOnNexts.begin(); it != _followOnNexts.end(); ++it)
-                       fprintf(stderr, "next %s -> %s\n", it->first->name(), (it->second != NULL) ? it->second->name() : "null");
-       }
-}
-
-void Layout::buildOrdinalOverrideMap()
-{
-       // if no -order_file, then skip building override map
-       if ( ! _haveOrderFile )
-               return;
-
-       // build fast name->atom table
-       this->buildNameTable();
-
-       // handle .o files that cannot have their atoms rearranged
-       // with the start/next maps of follow-on atoms we can process the order file and produce override ordinals
-       uint32_t index = 0;
-       uint32_t matchCount = 0;
-       for(Options::OrderedSymbolsIterator it = _options.orderedSymbolsBegin(); it != _options.orderedSymbolsEnd(); ++it) {
-               const ld::Atom* atom = this->findAtom(*it);
-               if ( atom != NULL ) {
-                       AtomToAtom::iterator start = _followOnStarts.find(atom);
-                       if ( start != _followOnStarts.end() ) {
-                               // this symbol for the order file corresponds to an atom that is in a cluster that must lay out together
-                               for(const ld::Atom* nextAtom = start->second; nextAtom != NULL; nextAtom = _followOnNexts[nextAtom]) {
-                                       AtomToOrdinal::iterator pos = _ordinalOverrideMap.find(nextAtom);
-                                       if ( pos == _ordinalOverrideMap.end() ) {
-                                               _ordinalOverrideMap[nextAtom] = index++;
-                                               if (_s_log ) fprintf(stderr, "override ordinal %u assigned to %s in cluster from %s\n", index, nextAtom->name(), nextAtom->file()->path());
-                                       }
-                                       else {
-                                               if (_s_log ) fprintf(stderr, "could not order %s as %u because it was already laid out earlier by %s as %u\n",
-                                                                               atom->name(), index, _followOnStarts[atom]->name(), _ordinalOverrideMap[atom] );
-                                       }
-                               }
-                       }
-                       else {
-                               _ordinalOverrideMap[atom] = index;
-                               if (_s_log ) fprintf(stderr, "override ordinal %u assigned to %s from %s\n", index, atom->name(), atom->file()->path());
-                       }
-                       ++matchCount;
-               }
-               else {
-                       if ( _options.printOrderFileStatistics() ) {
-                               if ( it->objectFileName == NULL )
-                                       warning("can't find match for order_file entry: %s", it->symbolName);
-                               else
-                                       warning("can't find match for order_file entry: %s/%s", it->objectFileName, it->symbolName);
-                       }
-               }
-                ++index;
-       }
-       if ( _options.printOrderFileStatistics() && (_options.orderedSymbolsCount() != matchCount) ) {
-               warning("only %u out of %lu order_file symbols were applicable", matchCount, _options.orderedSymbolsCount() );
-       }
-
-
-}
-
-void Layout::doPass()
-{
-       // handle .o files that cannot have their atoms rearranged
-       this->buildFollowOnTables();
-
-       //
-       this->buildOrdinalOverrideMap();
-
-
-       // sort atoms in each section
-       for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
-               ld::Internal::FinalSection* sect = *sit;
-               if ( orderableSection(sect) ) {
-                       std::sort(sect->atoms.begin(), sect->atoms.end(), _comparer);
-               }
-               else {
-                       // bubble sort any typeSectionStart atom to the beginning
-                       bool moving = false;
-                       for (int i=sect->atoms.size()-1; i >= 0; --i) {
-                               if ( moving ) {
-                                       const ld::Atom* temp = sect->atoms[i];
-                                       sect->atoms[i] = sect->atoms[i+1];
-                                       sect->atoms[i+1] = temp;
-                               }
-                               if ( sect->atoms[i]->contentType() == ld::Atom::typeSectionStart ) 
-                                       moving = true;
-                       }
-                       // bubble sort any typeSectionEnd atom to the end
-                       moving = false;
-                       for (unsigned int i=sect->atoms.size(); i < sect->atoms.size(); ++i) {
-                               if ( moving ) {
-                                       const ld::Atom* temp = sect->atoms[i];
-                                       sect->atoms[i] = sect->atoms[i-1];
-                                       sect->atoms[i-1] = temp;
-                               }
-                               if ( sect->atoms[i]->contentType() == ld::Atom::typeSectionEnd ) 
-                                       moving = true;
-                       }
-               }
-       }
-       
-       //fprintf(stderr, "Sorted atoms:\n");
-       //for (std::vector<ld::Internal::FinalSection*>::iterator sit=_state.sections.begin(); sit != _state.sections.end(); ++sit) {
-       //      ld::Internal::FinalSection* sect = *sit;
-       //      for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
-       //              const ld::Atom* atom = *ait;
-       //              fprintf(stderr, "\t%s\t%s\n", sect->sectionName(), atom->name());
-       //      }
-       //}
-
-}
-
-
-void doPass(const Options& opts, ld::Internal& state)
-{
-       Layout layout(opts, state);
-       layout.doPass();
-}
-
-
-} // namespace order_file
-} // namespace passes 
-} // namespace ld 
diff --git a/src/ld/passes/order_file.h b/src/ld/passes/order_file.h
deleted file mode 100644 (file)
index 7a2aa87..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
- *
- * Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-#ifndef __ORDER_FILE_H__
-#define __ORDER_FILE_H__
-
-#include "Options.h"
-#include "ld.hpp"
-
-
-namespace ld {
-namespace passes {
-namespace order_file {
-
-// called by linker to re-arrange atoms to improve locality and performance
-extern void doPass(const Options& opts, ld::Internal& internal);
-
-
-} // namespace order_file
-} // namespace passes 
-} // namespace ld 
-
-#endif // __ORDER_FILE_H__
diff --git a/src/ld/passes/stubs/stub_ppc_classic.hpp b/src/ld/passes/stubs/stub_ppc_classic.hpp
deleted file mode 100644 (file)
index 6862b60..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
- *
- * Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// already in ld::passes::stubs namespace
-namespace ppc {
-namespace classic {
-
-
-
-class LazyPointerAtom : public ld::Atom {
-public:
-                                                                                       LazyPointerAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo, 
-                                                                                                                                               bool forLazyDylib, bool for64, bool weakImport)
-                               : ld::Atom( forLazyDylib ? _s_sectionLazy : _s_section, 
-                                                       ld::Atom::definitionRegular, ld::Atom::combineNever, 
-                                                       ld::Atom::scopeTranslationUnit,
-                                                       forLazyDylib ? ld::Atom::typeLazyDylibPointer : ld::Atom::typeLazyPointer,
-                                                       symbolTableNotIn, false, false, false, for64 ? ld::Atom::Alignment(3) : ld::Atom::Alignment(2)), 
-                               _stubTo(stubTo),
-                               _fixup1(0, ld::Fixup::k1of1, 
-                                               for64 ? ld::Fixup::kindStoreTargetAddressBigEndian64 : ld::Fixup::kindStoreTargetAddressBigEndian32, 
-                                               forLazyDylib ? pass.internal()->lazyBindingHelper : pass.internal()->classicBindingHelper),
-                               _fixup2(0, ld::Fixup::k1of1, ld::Fixup::kindLazyTarget, &stubTo),
-                               _for64(for64)
-                                       {  _fixup2.weakImport = weakImport; pass.addAtom(*this);  }
-
-       virtual const ld::File*                                 file() const                                    { return _stubTo.file(); }
-       virtual bool                                                    translationUnitSource(const char** dir, const char** ) const 
-                                                                                                                                                       { return false; }
-       virtual const char*                                             name() const                                    { return _stubTo.name(); }
-       virtual uint64_t                                                size() const                                    { return _for64 ? 8 : 4; }
-       virtual uint64_t                                                objectAddress() const                   { return 0; }
-       virtual void                                                    copyRawContent(uint8_t buffer[]) const { }
-       virtual void                                                    setScope(Scope)                                 { }
-       virtual ld::Fixup::iterator                             fixupsBegin() const                             { return &_fixup1; }
-       virtual ld::Fixup::iterator                             fixupsEnd()     const                           { return &((ld::Fixup*)&_fixup2)[1]; }
-
-private:
-       const ld::Atom&                                                 _stubTo;
-       mutable ld::Fixup                                               _fixup1;
-       mutable ld::Fixup                                               _fixup2;
-       const bool                                                              _for64;
-       
-       static ld::Section                                              _s_section;
-       static ld::Section                                              _s_sectionLazy;
-};
-
-ld::Section LazyPointerAtom::_s_section("__DATA", "__la_symbol_ptr", ld::Section::typeLazyPointer);
-ld::Section LazyPointerAtom::_s_sectionLazy("__DATA", "__ld_symbol_ptr", ld::Section::typeLazyDylibPointer);
-
-
-
-class StubPICAtom : public ld::Atom {
-public:
-                                                                                       StubPICAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo, 
-                                                                                                                                               bool forLazyDylib, bool for64, bool weakImport)
-                               : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
-                                                       ld::Atom::scopeLinkageUnit, ld::Atom::typeStub, 
-                                                       symbolTableNotIn, false, false, false, ld::Atom::Alignment(2)), 
-                               _stubTo(stubTo), 
-                               _lazyPointer(pass, stubTo, forLazyDylib, for64, weakImport),
-                               _fixup1(12, ld::Fixup::k1of4, ld::Fixup::kindSetTargetAddress, &_lazyPointer), 
-                               _fixup2(12, ld::Fixup::k2of4, ld::Fixup::kindSubtractTargetAddress, this), 
-                               _fixup3(12, ld::Fixup::k3of4, ld::Fixup::kindSubtractAddend, 8), 
-                               _fixup4(12, ld::Fixup::k4of4, ld::Fixup::kindStorePPCPicHigh16AddLow), 
-                               _fixup5(20, ld::Fixup::k1of4, ld::Fixup::kindSetTargetAddress, &_lazyPointer),
-                               _fixup6(20, ld::Fixup::k2of4, ld::Fixup::kindSubtractTargetAddress, this),
-                               _fixup7(20, ld::Fixup::k3of4, ld::Fixup::kindSubtractAddend, 8), 
-                               _fixup8(20, ld::Fixup::k4of4, for64 ? ld::Fixup::kindStorePPCPicLow14 : ld::Fixup::kindStorePPCPicLow16),
-                               _for64(for64)
-                               { pass.addAtom(*this); }
-
-       virtual const ld::File*                                 file() const                                    { return _stubTo.file(); }
-       virtual bool                                                    translationUnitSource(const char** dir, const char** ) const 
-                                                                                                                                                       { return false; }
-       virtual const char*                                             name() const                                    { return _stubTo.name(); }
-       virtual uint64_t                                                size() const                                    { return 32; }
-       virtual uint64_t                                                objectAddress() const                   { return 0; }
-       virtual void                                                    copyRawContent(uint8_t buffer[]) const {
-               OSWriteBigInt32(&buffer[ 0], 0, 0x7c0802a6);    //      mflr r0
-               OSWriteBigInt32(&buffer[ 4], 0, 0x429f0005);    //  bcl 20,31,Lpicbase
-               OSWriteBigInt32(&buffer[ 8], 0, 0x7d6802a6);    // Lpicbase: mflr r11
-               OSWriteBigInt32(&buffer[12], 0, 0x3d6b0000);    //      addis r11,r11,ha16(L_fwrite$lazy_ptr-Lpicbase)
-               OSWriteBigInt32(&buffer[16], 0, 0x7c0803a6);    //      mtlr r0
-               if ( _for64 )
-                       OSWriteBigInt32(&buffer[20], 0, 0xe98b0001);//  ldu r12,lo16(L_fwrite$lazy_ptr-Lpicbase)(r11)
-               else
-                       OSWriteBigInt32(&buffer[20], 0, 0x858b0000);//  lwzu r12,lo16(L_fwrite$lazy_ptr-Lpicbase)(r11)
-               OSWriteBigInt32(&buffer[24], 0, 0x7d8903a6);    //  mtctr r12
-               OSWriteBigInt32(&buffer[28], 0, 0x4e800420);    //  bctr
-       }
-       virtual void                                                    setScope(Scope)                                 { }
-       virtual ld::Fixup::iterator                             fixupsBegin() const                             { return &_fixup1; }
-       virtual ld::Fixup::iterator                             fixupsEnd()     const                           { return &((ld::Fixup*)&_fixup8)[1]; }
-
-private:
-       const ld::Atom&                                                 _stubTo;
-       LazyPointerAtom                                                 _lazyPointer;
-       mutable ld::Fixup                                               _fixup1;
-       mutable ld::Fixup                                               _fixup2;
-       mutable ld::Fixup                                               _fixup3;
-       mutable ld::Fixup                                               _fixup4;
-       mutable ld::Fixup                                               _fixup5;
-       mutable ld::Fixup                                               _fixup6;
-       mutable ld::Fixup                                               _fixup7;
-       mutable ld::Fixup                                               _fixup8;
-       const bool                                                              _for64;
-       
-       static ld::Section                                              _s_section;
-};
-
-ld::Section StubPICAtom::_s_section("__TEXT", "__picsymbolstub1", ld::Section::typeStub);
-
-
-
-class StubNoPICAtom : public ld::Atom {
-public:
-                                                                                       StubNoPICAtom(ld::passes::stubs::Pass& pass, const ld::Atom& stubTo, 
-                                                                                                                                               bool forLazyDylib, bool for64, bool weakImport)
-                               : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
-                                                       ld::Atom::scopeLinkageUnit, ld::Atom::typeStub, 
-                                                       symbolTableNotIn, false, false, false, ld::Atom::Alignment(2)), 
-                               _stubTo(stubTo), 
-                               _lazyPointer(pass, stubTo, forLazyDylib, for64, weakImport),
-                               _fixup1(0, ld::Fixup::k1of2, ld::Fixup::kindSetTargetAddress, &_lazyPointer), 
-                               _fixup2(0, ld::Fixup::k2of2, ld::Fixup::kindStorePPCAbsHigh16AddLow), 
-                               _fixup3(4, ld::Fixup::k1of2, ld::Fixup::kindSetTargetAddress, &_lazyPointer),
-                               _fixup4(4, ld::Fixup::k2of2, for64 ? ld::Fixup::kindStorePPCAbsLow14 : ld::Fixup::kindStorePPCAbsLow16),
-                               _for64(for64)
-                               { pass.addAtom(*this); }
-
-       virtual const ld::File*                                 file() const                                    { return _stubTo.file(); }
-       virtual bool                                                    translationUnitSource(const char** dir, const char** ) const 
-                                                                                                                                                       { return false; }
-       virtual const char*                                             name() const                                    { return _stubTo.name(); }
-       virtual uint64_t                                                size() const                                    { return 16; }
-       virtual uint64_t                                                objectAddress() const                   { return 0; }
-       virtual void                                                    copyRawContent(uint8_t buffer[]) const {
-               OSWriteBigInt32(&buffer[ 0], 0, 0x3d600000);    // lis r11,ha16(L_foo$lazy_ptr)
-               if ( _for64 )
-                       OSWriteBigInt32(&buffer[ 4], 0, 0xe98b0001);// ldu r12,lo16(L_foo$lazy_ptr)(r11)
-               else
-                       OSWriteBigInt32(&buffer[ 4], 0, 0x858b0000);// lwzu r12,lo16(L_foo$lazy_ptr)(r11)
-               OSWriteBigInt32(&buffer[ 8], 0, 0x7d8903a6);    // mtctr r12
-               OSWriteBigInt32(&buffer[12], 0, 0x4e800420);    // bctr
-       }
-       virtual void                                                    setScope(Scope)                                 { }
-       virtual ld::Fixup::iterator                             fixupsBegin() const                             { return &_fixup1; }
-       virtual ld::Fixup::iterator                             fixupsEnd()     const                           { return &((ld::Fixup*)&_fixup4)[1]; }
-
-private:
-       const ld::Atom&                                                 _stubTo;
-       LazyPointerAtom                                                 _lazyPointer;
-       mutable ld::Fixup                                               _fixup1;
-       mutable ld::Fixup                                               _fixup2;
-       mutable ld::Fixup                                               _fixup3;
-       mutable ld::Fixup                                               _fixup4;
-       const bool                                                              _for64;
-       
-       static ld::Section                                              _s_section;
-};
-
-ld::Section StubNoPICAtom::_s_section("__TEXT", "__symbol_stub1", ld::Section::typeStub);
-
-
-} // namespace classic
-} // namespace ppc 
-
index 274878bdc8ee9da4758c337c0726184da7b7b43b..aa4aaf12372eb50aa628fe16d5dd8e29bbbdb405 100644 (file)
@@ -89,7 +89,6 @@ private:
 #include "stub_x86_classic.hpp"
 #include "stub_arm.hpp"
 #include "stub_arm_classic.hpp"
-#include "stub_ppc_classic.hpp"
 
 
 
@@ -116,7 +115,6 @@ const ld::Atom* Pass::stubableFixup(const ld::Fixup* fixup, ld::Internal& state)
        if ( fixup->binding == ld::Fixup::bindingsIndirectlyBound ) {
                const ld::Atom* target = state.indirectBindingTable[fixup->u.bindingIndex];
                switch ( fixup->kind ) {
-                       case ld::Fixup::kindStoreTargetAddressPPCBranch24:
                        case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32:
                        case ld::Fixup::kindStoreTargetAddressARMBranch24:
                        case ld::Fixup::kindStoreTargetAddressThumbBranch22:
@@ -177,15 +175,6 @@ ld::Atom* Pass::makeStub(const ld::Atom& target, bool weakImport)
        }
 
        switch ( _architecture ) {
-               case CPU_TYPE_POWERPC: 
-                       if ( _pic )
-                               return new ld::passes::stubs::ppc::classic::StubPICAtom(*this, target, forLazyDylib, false, weakImport);
-                       else
-                               return new ld::passes::stubs::ppc::classic::StubNoPICAtom(*this, target, forLazyDylib, false, weakImport);
-                       break;
-               case CPU_TYPE_POWERPC64: 
-                       return new ld::passes::stubs::ppc::classic::StubPICAtom(*this, target, forLazyDylib, true, weakImport);
-                       break;
                case CPU_TYPE_I386:
                        if ( usingCompressedLINKEDIT() && !forLazyDylib )
                                return new ld::passes::stubs::x86::StubAtom(*this, target, stubToGlobalWeakDef, stubToResolver, weakImport);
@@ -304,9 +293,7 @@ void Pass::process(ld::Internal& state)
                                if ( _options.outputKind() != Options::kDynamicLibrary ) 
                                        throwf("resolver functions (%s) can only be used in dylibs", atom->name());
                                if ( !_options.makeCompressedDyldInfo() ) {
-                                       if ( _options.architecture() == CPU_TYPE_POWERPC )
-                                               throwf("resolver functions (%s) not supported for PowerPC", atom->name());
-                                       else if ( _options.architecture() == CPU_TYPE_ARM )
+                                       if ( _options.architecture() == CPU_TYPE_ARM )
                                                throwf("resolver functions (%s) can only be used when targeting iOS 4.2 or later", atom->name());
                                        else
                                                throwf("resolver functions (%s) can only be used when targeting Mac OS X 10.6 or later", atom->name());
index 3d7ac5eaa5c737f4714eaf697652a82484d97d82..44d8f53f7e2987fef7af162c309367328836ac59 100644 (file)
@@ -738,33 +738,6 @@ void dumper::dumpFixup(const ld::Fixup* ref)
                case ld::Fixup::kindStoreBigEndian64:
                        printf(", then store 64-bit big endian");
                        break;
-               case ld::Fixup::kindStorePPCBranch24:
-                       printf(", then store as PPC branch24");
-                       break;
-               case ld::Fixup::kindStorePPCBranch14:
-                       printf(", then store as PPC branch14");
-                       break;
-               case ld::Fixup::kindStorePPCPicLow14:
-                       printf(", then store as PPC low14 pic");
-                       break;
-               case ld::Fixup::kindStorePPCPicLow16:
-                       printf(", then store as PPC low14 pic");
-                       break;
-               case ld::Fixup::kindStorePPCPicHigh16AddLow:
-                       printf(", then store as PPC high16 pic");
-                       break;
-               case ld::Fixup::kindStorePPCAbsLow14:
-                       printf(", then store as PPC low14 abs");
-                       break;
-               case ld::Fixup::kindStorePPCAbsLow16:
-                       printf(", then store as PPC low14 abs");
-                       break;
-               case ld::Fixup::kindStorePPCAbsHigh16AddLow:
-                       printf(", then store as PPC high16 abs");
-                       break;
-               case ld::Fixup::kindStorePPCAbsHigh16:
-                       printf(", then store as PPC high16 abs, no carry");
-                       break;
                case ld::Fixup::kindStoreX86BranchPCRel8:
                        printf(", then store as x86 8-bit pcrel branch");
                        break;
@@ -840,12 +813,6 @@ void dumper::dumpFixup(const ld::Fixup* ref)
                case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear:
                        printf("x86 dtrace static is-enabled site");
                        break;
-               case ld::Fixup::kindStorePPCDtraceCallSiteNop:
-                       printf("ppc dtrace static probe site");
-                       break;
-               case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear:
-                       printf("ppc dtrace static is-enabled site");
-                       break;
                case ld::Fixup::kindStoreARMDtraceCallSiteNop:
                        printf("ARM dtrace static probe site");
                        break;
@@ -909,9 +876,6 @@ void dumper::dumpFixup(const ld::Fixup* ref)
                case ld::Fixup::kindStoreTargetAddressARMLoad12:
                        printf("ARM store 12-bit pc-rel branch to %s", referenceTargetAtomName(ref));
                        break;
-               case ld::Fixup::kindStoreTargetAddressPPCBranch24:
-                       printf("PowerPC store 24-bit pc-rel load of %s", referenceTargetAtomName(ref));
-                       break;
                case ld::Fixup::kindSetTargetTLVTemplateOffset:
                case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32:
                case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64:
@@ -1220,11 +1184,7 @@ int main(int argc, const char* argv[])
                                }
                                else if ( strcmp(arg, "-arch") == 0 ) {
                                        const char* arch = ++i<argc? argv[i]: "";
-                                       if ( strcmp(arch, "ppc64") == 0 )
-                                               sPreferredArch = CPU_TYPE_POWERPC64;
-                                       else if ( strcmp(arch, "ppc") == 0 )
-                                               sPreferredArch = CPU_TYPE_POWERPC;
-                                       else if ( strcmp(arch, "i386") == 0 )
+                                       if ( strcmp(arch, "i386") == 0 )
                                                sPreferredArch = CPU_TYPE_I386;
                                        else if ( strcmp(arch, "x86_64") == 0 )
                                                sPreferredArch = CPU_TYPE_X86_64;
index 2c86577133aaa4d0f3dab601eb9e4f261574433f..6a63ca18174aca63d27703aa5e81475aff1198ca 100644 (file)
@@ -1667,8 +1667,6 @@ const char*       DyldInfoPrinter<ppc>::relocTypeName(uint8_t r_type)
 {
        if ( r_type == GENERIC_RELOC_VANILLA )
                return "pointer";
-       else if ( r_type == PPC_RELOC_PB_LA_PTR )
-               return "pb pointer";
        else
                return "??";
 }
index 4841c7ca0c4ed47c7a4b812f0c566c63b8073f73..54dc560c1d21ea9d1020ef646e4da373181d1a76 100644 (file)
@@ -1066,9 +1066,6 @@ void MachOChecker<ppc>::checkLocalReloation(const macho_relocation_info<P>* relo
        
        }
        else {
-               // ignore pair relocs
-               if ( reloc->r_type() == PPC_RELOC_PAIR ) 
-                       return;
                // FIX
                if ( ! this->addressInWritableSegment(reloc->r_address() + this->relocBase()) )
                        throwf("local relocation address 0x%08X not in writable segment", reloc->r_address());
index d69fc3ca52ca06594972e751944ad3be67d8e102..2255789436f2303f6ea371a1a8fe0941219a6228 100644 (file)
@@ -650,13 +650,7 @@ void Rebaser<ppc>::doLocalRelocation(const macho_relocation_info<P>* reloc)
                }
        }
        else {
-               macho_scattered_relocation_info<P>* sreloc = (macho_scattered_relocation_info<P>*)reloc;
-               if ( sreloc->r_type() == PPC_RELOC_PB_LA_PTR ) {
-                       sreloc->set_r_value( sreloc->r_value() + fSlide );
-               }
-               else {
-                       throw "cannot rebase final linked image with scattered relocations";
-               }
+               throw "cannot rebase final linked image with scattered relocations";
        }
 }
 
index d24e62c57d471f3f19ecdb51184d74eea659a418..90605570149ca17895aebb3367b56823a9a73bb0 100644 (file)
@@ -104,8 +104,6 @@ private:
 };
 
 
-template <>     const char*    UnwindPrinter<ppc>::archName()          { return "ppc"; }
-template <>     const char*    UnwindPrinter<ppc64>::archName()        { return "ppc64"; }
 template <>     const char*    UnwindPrinter<x86>::archName()          { return "i386"; }
 template <>     const char*    UnwindPrinter<x86_64>::archName()       { return "x86_64"; }
 template <>     const char*    UnwindPrinter<arm>::archName()          { return "arm"; }
diff --git a/unit-tests/test-cases/archive-init-order/Makefile b/unit-tests/test-cases/archive-init-order/Makefile
new file mode 100644 (file)
index 0000000..83364e8
--- /dev/null
@@ -0,0 +1,48 @@
+##
+# Copyright (c) 2011 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+# 
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+# 
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+# 
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Check the order of functions from archives.
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.c -c -o foo.o 
+       ${CC} ${CCFLAGS} foo2.c -c -o foo2.o 
+       ${CC} ${CCFLAGS} foo3.c -c -o foo3.o 
+       ${CC} ${CCFLAGS} bar.c -c -o bar.o 
+       ${CC} ${CCFLAGS} bar2.c -c -o bar2.o 
+       ${CC} ${CCFLAGS} bar3.c -c -o bar3.o 
+       libtool -static foo.o foo2.o foo3.o -o libfoo.a
+       libtool -static bar3.o bar2.o bar.o -o libbar.a
+       ${CC} ${CCFLAGS} main.c -lbar -lfoo -L. -o main -Wl,-map,main.map
+       grep anon main.map | awk '{ print $$4}' > main-actual.txt
+       sort main-actual.txt > main-should.txt
+       diff main-actual.txt main-should.txt
+       ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+       rm -rf *.o *.a main main.map main*.txt
diff --git a/unit-tests/test-cases/archive-init-order/bar.c b/unit-tests/test-cases/archive-init-order/bar.c
new file mode 100644 (file)
index 0000000..850c211
--- /dev/null
@@ -0,0 +1,4 @@
+int bar() { return 0; }
+
+__attribute__((constructor))
+void bar_init() { }
diff --git a/unit-tests/test-cases/archive-init-order/bar2.c b/unit-tests/test-cases/archive-init-order/bar2.c
new file mode 100644 (file)
index 0000000..4c268ba
--- /dev/null
@@ -0,0 +1,4 @@
+int bar2() { return 0; }
+
+__attribute__((constructor))
+void bar2_init() { }
diff --git a/unit-tests/test-cases/archive-init-order/bar3.c b/unit-tests/test-cases/archive-init-order/bar3.c
new file mode 100644 (file)
index 0000000..a55167f
--- /dev/null
@@ -0,0 +1,4 @@
+int bar3() { return 0; }
+
+__attribute__((constructor))
+void bar3_init() { }
diff --git a/unit-tests/test-cases/archive-init-order/foo.c b/unit-tests/test-cases/archive-init-order/foo.c
new file mode 100644 (file)
index 0000000..6149aa1
--- /dev/null
@@ -0,0 +1,4 @@
+int foo() { return 1; }
+
+__attribute__((constructor))
+void foo_init() { }
diff --git a/unit-tests/test-cases/archive-init-order/foo2.c b/unit-tests/test-cases/archive-init-order/foo2.c
new file mode 100644 (file)
index 0000000..a429fe5
--- /dev/null
@@ -0,0 +1,4 @@
+int foo2() { return 1; }
+
+__attribute__((constructor))
+void foo2_init() { }
diff --git a/unit-tests/test-cases/archive-init-order/foo3.c b/unit-tests/test-cases/archive-init-order/foo3.c
new file mode 100644 (file)
index 0000000..b097ebf
--- /dev/null
@@ -0,0 +1,4 @@
+int foo3() { return 1; }
+
+__attribute__((constructor))
+void foo3_init() { }
diff --git a/unit-tests/test-cases/archive-init-order/main.c b/unit-tests/test-cases/archive-init-order/main.c
new file mode 100644 (file)
index 0000000..242b32a
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2011 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+extern int foo();
+extern int foo2();
+extern int foo3();
+extern int bar();
+extern int bar2();
+extern int bar3();
+
+int main()
+{
+    foo();
+    bar();
+    foo2();
+    bar2();
+    foo3();
+    bar3();
+       return 0;
+}
\ No newline at end of file
diff --git a/unit-tests/test-cases/dead_strip-initializers/Makefile b/unit-tests/test-cases/dead_strip-initializers/Makefile
new file mode 100644 (file)
index 0000000..4292550
--- /dev/null
@@ -0,0 +1,47 @@
+##
+# Copyright (c) 2011 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+# 
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+# 
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+# 
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Sanity check -dead_strip does not remove initializers and terminators
+#
+
+
+run: all
+
+all:
+       ${CXX} ${CCFLAGS} main.cxx other.cxx -dead_strip -o main
+       ${FAIL_IF_BAD_MACHO} main
+       nm main | grep dead_door_knob | ${FAIL_IF_STDIN}
+       nm main | grep ctr | ${FAIL_IF_EMPTY}
+       nm main | grep dtr | ${FAIL_IF_EMPTY}
+       ${CXX} ${CCFLAGS} -static main.cxx other.cxx -dead_strip -nostdlib -e _main -o main-static -Wl,-new_linker
+       ${FAIL_IF_BAD_MACHO} main-static
+       nm main-static | grep dead_door_knob | ${FAIL_IF_STDIN}
+       nm main-static | grep ctr | ${FAIL_IF_EMPTY}
+       nm main-static | grep dtr | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main-static
+
+clean:
+       rm -rf main main-static
diff --git a/unit-tests/test-cases/dead_strip-initializers/main.cxx b/unit-tests/test-cases/dead_strip-initializers/main.cxx
new file mode 100644 (file)
index 0000000..59af7c2
--- /dev/null
@@ -0,0 +1,24 @@
+
+int main()
+{
+       return 0;
+}
+
+
+
+void dead_door_knob() {  }
+
+
+extern "C" int ctr();
+extern "C" void dtr();
+
+
+int ctr() { return 10; }
+void dtr() { }
+
+
+#if __STATIC__
+extern "C" void __cxa_atexit();
+void __cxa_atexit() {}
+#endif
+
diff --git a/unit-tests/test-cases/dead_strip-initializers/other.cxx b/unit-tests/test-cases/dead_strip-initializers/other.cxx
new file mode 100644 (file)
index 0000000..1c6534c
--- /dev/null
@@ -0,0 +1,18 @@
+
+extern "C" int ctr();
+extern "C" void dtr();
+
+class Foo
+{
+public:
+       Foo() : field(ctr()) { }
+        ~Foo() { dtr(); }
+private:
+       int field;
+};
+
+
+Foo f1;
+Foo f2;
+
+
diff --git a/unit-tests/test-cases/dso_handle/Makefile b/unit-tests/test-cases/dso_handle/Makefile
new file mode 100644 (file)
index 0000000..f6c40e4
--- /dev/null
@@ -0,0 +1,23 @@
+
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+#
+# Verify the linker errors out nicely when __dso_handle is defined in source.
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} test.c -o test
+       ${FAIL_IF_BAD_MACHO} test
+       ${CC} ${CCFLAGS} test.c -DDSO_DEF=1 -o test-def 2>warnings.txt
+       ${FAIL_IF_BAD_MACHO} test-def
+       ${CC} ${CCFLAGS} test.c -DDSO_TENT=1 -o test-tent
+       ${PASS_IFF_GOOD_MACHO} test-tent
+
+
+clean:
+       rm -f test test-def test-tent warnings.txt
diff --git a/unit-tests/test-cases/dso_handle/test.c b/unit-tests/test-cases/dso_handle/test.c
new file mode 100644 (file)
index 0000000..0b984b0
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+#if DSO_DEF
+       void* __dso_handle = NULL;
+#elif DSO_TENT
+       void* __dso_handle;
+#else
+       extern void* __dso_handle;
+#endif
+
+int main()
+{
+       printf("dso_handle=%p\n", __dso_handle);
+       return 0;
+}
+
diff --git a/unit-tests/test-cases/fatal_warning/Makefile b/unit-tests/test-cases/fatal_warning/Makefile
new file mode 100644 (file)
index 0000000..6758bc0
--- /dev/null
@@ -0,0 +1,40 @@
+##
+# Copyright (c) 2011 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+# 
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+# 
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+# 
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+#
+# Check that warning under -fatal_warnings causes error
+#
+
+run: all
+
+all:
+       ${PASS_IFF_ERROR} ${CC} ${CCFLAGS} main.c -o main -pagezero_size 123 -Wl,-fatal_warnings  2>msgs.txt
+
+
+clean:
+       rm -f main msgs.txt
diff --git a/unit-tests/test-cases/fatal_warning/main.c b/unit-tests/test-cases/fatal_warning/main.c
new file mode 100644 (file)
index 0000000..fc047f7
--- /dev/null
@@ -0,0 +1,5 @@
+
+int main()
+{
+       return 0;
+}
index b27291a8236a5b09bff1cd90a43fe8d37d65d3f0..82192f8d4daa7a86960e3458e858db8cc4253234 100644 (file)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
+# Copyright (c) 2010-2011 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 # 
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
+
 #
 # <rdar://problem/7438246> LTO with 'dead code strip' can't ignore unused functions with undefined references
+# <rdar://problem/10052396> LTO many have eliminated need for some undefines
 #
 
 run: all
@@ -32,7 +34,8 @@ run: all
 all:
        ${CC} ${CCFLAGS} -flto bar.c  -c -o bar.o
        ${CC} ${CCFLAGS} -flto main.c -c -o main.o 
-       ${CC} ${CCFLAGS} -dead_strip main.o bar.o -o main
+       ${CC} ${CCFLAGS} main.o bar.o -o main
+       ${CC} ${CCFLAGS} main.o bar.o -o main -dead_strip 
        ${PASS_IFF_GOOD_MACHO} main
        
 clean:
diff --git a/unit-tests/test-cases/order_file-zero-fill/Makefile b/unit-tests/test-cases/order_file-zero-fill/Makefile
new file mode 100644 (file)
index 0000000..de2283e
--- /dev/null
@@ -0,0 +1,21 @@
+
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Check that -order_file will transform zero-fill (tentative def)
+# symbols to __data symbols to achieve ordering.
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} main.c foo.c -Wl,-order_file,main.order -o main
+       nm -nj main | grep _xyz_ > main.actual
+       diff main.expected main.actual
+       nm -nm main | grep _xyz_f4 | grep __data | ${FAIL_IF_EMPTY}
+       nm -nm main | grep _other | grep __common | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+       rm -f main  main.actual
diff --git a/unit-tests/test-cases/order_file-zero-fill/foo.c b/unit-tests/test-cases/order_file-zero-fill/foo.c
new file mode 100644 (file)
index 0000000..8bfc7d2
--- /dev/null
@@ -0,0 +1,4 @@
+
+int xyz_f2;
+int xyz_f4;
+int other;
diff --git a/unit-tests/test-cases/order_file-zero-fill/main.c b/unit-tests/test-cases/order_file-zero-fill/main.c
new file mode 100644 (file)
index 0000000..6c37d8e
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2011 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include <stdio.h>
+
+int xyz_m1;
+int xyz_m3;
+static int xyz_ms1;
+int xyz_mi3 = 4;
+int xyz_mi4 = 4;
+int main_common;
+
+
+int main()
+{
+       fprintf(stdout, "hello %p\n", &xyz_ms1);
+       return 0;
+}
diff --git a/unit-tests/test-cases/order_file-zero-fill/main.expected b/unit-tests/test-cases/order_file-zero-fill/main.expected
new file mode 100644 (file)
index 0000000..8b9edb4
--- /dev/null
@@ -0,0 +1,7 @@
+_xyz_f4
+_xyz_mi4
+_xyz_f2
+_xyz_m3
+_xyz_m1
+_xyz_ms1
+_xyz_mi3
diff --git a/unit-tests/test-cases/order_file-zero-fill/main.order b/unit-tests/test-cases/order_file-zero-fill/main.order
new file mode 100644 (file)
index 0000000..fa6c623
--- /dev/null
@@ -0,0 +1,7 @@
+_xyz_f4
+_xyz_mi4
+_xyz_f2
+_xyz_m3
+_xyz_m1
+_xyz_ms1
+
index 46e695c4b9fdb6200b8ea533ab57a51a150e0149..568ebc65b67f90c28072463307b5c72d304fd700 100644 (file)
@@ -32,7 +32,7 @@ run: all
 all:
        clang ${CCFLAGS} main.c -o main -dead_strip -mmacosx-version-min=10.7
        otool -lv main | grep S_THREAD_LOCAL_VARIABLES | ${FAIL_IF_EMPTY}
-       otool -lv main | grep S_THREAD_LOCAL_REGULAR | ${FAIL_IF_EMPTY}
+       otool -lv main | egrep 'S_THREAD_LOCAL_REGULAR|S_THREAD_LOCAL_ZEROFILL' | ${FAIL_IF_EMPTY}
        ${PASS_IFF_GOOD_MACHO} main
 
 clean: