]> git.saurik.com Git - apple/ld64.git/commitdiff
ld64-302.3.tar.gz developer-tools-90 developer-tools-901 v302.3
authorApple <opensource@apple.com>
Tue, 18 Sep 2018 21:29:56 +0000 (21:29 +0000)
committerApple <opensource@apple.com>
Tue, 18 Sep 2018 21:29:56 +0000 (21:29 +0000)
19 files changed:
ld64.xcodeproj/project.pbxproj
src/abstraction/MachOFileAbstraction.hpp
src/create_configure
src/ld/HeaderAndLoadCommands.hpp
src/ld/InputFiles.cpp
src/ld/Options.cpp
src/ld/Options.h
src/ld/OutputFile.cpp
src/ld/Resolver.cpp
src/ld/ld.hpp
src/ld/parsers/generic_dylib_file.hpp
src/ld/parsers/lto_file.cpp
src/ld/parsers/lto_file.h
src/ld/parsers/macho_dylib_file.cpp
src/ld/parsers/macho_relocatable_file.cpp
src/ld/parsers/textstub_dylib_file.cpp
src/ld/passes/code_dedup.cpp
src/other/machochecker.cpp
src/other/unwinddump.cpp

index 600aeac98043e75b8bd9c8c3fcaa0f5452c0ff6b..7b7260e4730f0c391bbfd784d6d4b063f24a678c 100644 (file)
                F984A13B10B614CF009E9878 /* stub_arm_classic.hpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.h; path = stub_arm_classic.hpp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
                F984A38010BB4B0D009E9878 /* branch_island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = branch_island.cpp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
                F984A38110BB4B0D009E9878 /* branch_island.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = branch_island.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
+               F98565241E98090F00528B1C /* dwarf2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dwarf2.h; path = src/ld/dwarf2.h; sourceTree = "<group>"; };
                F989D0391062E6350014B60C /* stub_x86_64.hpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.h; path = stub_x86_64.hpp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
                F989D30B106826020014B60C /* OutputFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OutputFile.cpp; path = src/ld/OutputFile.cpp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
                F989D30C106826020014B60C /* OutputFile.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = OutputFile.h; path = src/ld/OutputFile.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
                                B091FB641ABA3AFB00CC8193 /* Bitcode.hpp */,
                                F9EA7582097882F3008B4F1D /* debugline.c */,
                                F9EA7583097882F3008B4F1D /* debugline.h */,
+                               F98565241E98090F00528B1C /* dwarf2.h */,
                                B3B672411406D42800A376BB /* Snapshot.cpp */,
                                B3B672441406D44300A376BB /* Snapshot.h */,
                        );
                F9023C3006D5A227001BBF46 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0600;
+                               LastUpgradeCheck = 0900;
                                ORGANIZATIONNAME = "Apple Inc.";
                        };
                        buildConfigurationList = F933D92309291AC90083EAC8 /* Build configuration list for PBXProject "ld64" */;
                83046A801C8FF23E00024A7E /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = NO;
                83046A811C8FF23E00024A7E /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = YES;
                83046A821C8FF23E00024A7E /* Release-assert */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = YES;
                F933D91C09291AC90083EAC8 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = NO;
                F933D91D09291AC90083EAC8 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = NO;
                F933D92009291AC90083EAC8 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = NO;
                F933D92109291AC90083EAC8 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = YES;
                F933D92409291AC90083EAC8 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = "$(inherited) build DerivedData";
                                GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_NO_COMMON_BLOCKS = YES;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
                                ONLY_ACTIVE_ARCH = YES;
                                SDKROOT = macosx.internal;
                        };
                F933D92509291AC90083EAC8 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = "$(inherited) build DerivedData";
                                GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_NO_COMMON_BLOCKS = YES;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
                                SDKROOT = macosx.internal;
                        };
                        name = Release;
                F9849FF810B5DE8E009E9878 /* Release-assert */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = "$(inherited) build DerivedData";
                                GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_NO_COMMON_BLOCKS = YES;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
                                SDKROOT = macosx.internal;
                        };
                        name = "Release-assert";
                F9849FFA10B5DE8E009E9878 /* Release-assert */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = NO;
                F9849FFD10B5DE8E009E9878 /* Release-assert */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_64_BIT)";
                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
                                CLANG_CXX_LIBRARY = "libc++";
                                COPY_PHASE_STRIP = YES;
index a417877b7e7c5745cbe421a8cd16c8c1ad5b37ba..252e41326bc0b6a28f44620a244f05c74214ad5c 100644 (file)
 #define DYLD_CACHE_ADJ_V2_IMAGE_OFF_32                 0x0C
 
 
+#ifndef LC_BUILD_VERSION
+       #define LC_BUILD_VERSION 0x32 /* build for platform min OS version */
+
+       /*
+        * The build_version_command contains the min OS version on which this 
+        * binary was built to run for its platform.  The list of known platforms and
+        * tool values following it.
+        */
+       struct build_version_command {
+               uint32_t        cmd;            /* LC_BUILD_VERSION */
+               uint32_t        cmdsize;        /* sizeof(struct build_version_command) plus */
+                                                               /* ntools * sizeof(struct build_tool_version) */
+               uint32_t        platform;       /* platform */
+               uint32_t        minos;          /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+               uint32_t        sdk;            /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+               uint32_t        ntools;         /* number of tool entries following this */
+       };
+
+       struct build_tool_version {
+               uint32_t        tool;           /* enum for the tool */
+               uint32_t        version;        /* version number of the tool */
+       };
+
+       /* Known values for the platform field above. */
+       #define PLATFORM_MACOS          1
+       #define PLATFORM_IOS            2
+       #define PLATFORM_TVOS           3
+       #define PLATFORM_WATCHOS        4
+       #define PLATFORM_BRIDGEOS       5
+
+       /* Known values for the tool field above. */
+       #define TOOL_CLANG      1
+       #define TOOL_SWIFT      2
+       #define TOOL_LD         3
+#endif
+
+#ifndef LC_NOTE
+       #define LC_NOTE 0x31
+       struct note_command {
+               uint32_t    cmd;        /* LC_NOTE */
+               uint32_t    cmdsize;    /* sizeof(struct note_command) */
+               char        data_owner[16];    /* owner name for this LC_NOTE */
+               uint64_t    offset;        /* file offset of this data */
+               uint64_t    size;        /* length of data region */
+       };
+#endif
+
 
 // kind target-address fixup-addr [adj] 
 
@@ -577,7 +624,7 @@ static const ArchInfo archInfoArray[] = {
        #define SUPPORT_ARCH_arm_any 1
 #endif
 #if SUPPORT_ARCH_arm64
-       { "arm64", CPU_TYPE_ARM64,   CPU_SUBTYPE_ARM64_ALL,  "arm64-",  "aarch64-",  false,  false },
+       { "arm64", CPU_TYPE_ARM64,   CPU_SUBTYPE_ARM64_ALL,  "arm64-",  "aarch64-",  true,  false },
 #endif
 #if SUPPORT_ARCH_arm64v8
        { "arm64v8", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8,   "arm64v8-",  "aarch64-",   true,  false },
@@ -1662,6 +1709,58 @@ private:
 };
 
 
+
+//
+// mach-o build version load command
+//
+template <typename P>
+class macho_build_version_command {
+public:
+       uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
+       void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
+
+       uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
+       void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
+
+       uint32_t                platform() const                                                INLINE { return fields.platform; }
+       void                    set_platform(uint32_t value)                    INLINE { E::set32(fields.platform, value); }
+
+       uint32_t                minos() const                                                   INLINE { return fields.minos; }
+       void                    set_minos(uint32_t value)                               INLINE { E::set32(fields.minos, value); }
+
+       uint32_t                sdk() const                                                             INLINE { return fields.sdk; }
+       void                    set_sdk(uint32_t value)                                 INLINE { E::set32(fields.sdk, value); }
+
+       uint32_t                ntools() const                                                  INLINE { return fields.ntools; }
+       void                    set_ntools(uint32_t value)                              INLINE { E::set32(fields.ntools, value); }
+
+
+       typedef typename P::E           E;
+private:
+       build_version_command   fields;
+};
+
+
+//
+// mach-o build version load command
+//
+template <typename P>
+class macho_build_tool_version {
+public:
+       uint32_t                tool() const                                                    INLINE { return E::get32(fields.tool); }
+       void                    set_tool(uint32_t value)                                INLINE { E::set32(fields.tool, value); }
+
+       uint32_t                version() const                                                 INLINE { return E::get32(fields.version); }
+       void                    set_version(uint32_t value)                             INLINE { E::set32(fields.version, value); }
+
+       typedef typename P::E           E;
+private:
+       build_tool_version      fields;
+};
+
+
+
+
 //
 // mach-o __LD, __compact_unwind section in object files
 //
index 3643079339cdac543b9d4f0ce18d42123f4e2a4c..a740779f57c69e8a36fd9da64d6613912dc4550e 100755 (executable)
@@ -46,3 +46,9 @@ else
 fi
 
 echo "#define BITCODE_XAR_VERSION \"1.0\"" >> ${DERIVED_FILE_DIR}/configure.h
+
+if [ -n "${RC_ProjectSourceVersion}" ]; then
+       echo "#define LD64_VERSION_NUM ${RC_ProjectSourceVersion}" >> ${DERIVED_FILE_DIR}/configure.h
+else
+       echo "#define LD64_VERSION_NUM 0" >> ${DERIVED_FILE_DIR}/configure.h
+fi
index a7d66207cf12e8d0c211a3eb5b57a22fd479eb1f..fbcc13fe7c4ceb35d34eed24896decce70671dfa 100644 (file)
@@ -106,6 +106,7 @@ private:
        uint8_t*                                        copyRoutinesLoadCommand(uint8_t* p) const;
        uint8_t*                                        copyUUIDLoadCommand(uint8_t* p) const;
        uint8_t*                                        copyVersionLoadCommand(uint8_t* p) const;
+       uint8_t*                                        copyBuildVersionLoadCommand(uint8_t* p) const;
        uint8_t*                                        copySourceVersionLoadCommand(uint8_t* p) const;
        uint8_t*                                        copyThreadsLoadCommand(uint8_t* p) const;
        uint8_t*                                        copyEntryPointLoadCommand(uint8_t* p) const;
@@ -145,10 +146,12 @@ private:
        bool                                            _hasRPathLoadCommands;
        bool                                            _hasSubFrameworkLoadCommand;
        bool                                            _hasVersionLoadCommand;
+       bool                                            _hasBuildVersionLoadCommand;
        bool                                            _hasFunctionStartsLoadCommand;
        bool                                            _hasDataInCodeLoadCommand;
        bool                                            _hasSourceVersionLoadCommand;
        bool                                            _hasOptimizationHints;
+       Options::Platform                       _platform;
        uint32_t                                        _dylibLoadCommmandsCount;
        uint32_t                                        _allowableClientLoadCommmandsCount;
        uint32_t                                        _dyldEnvironExrasCount;
@@ -159,6 +162,7 @@ private:
        mutable uint32_t                        _linkeditCmdOffset;
        mutable uint32_t                        _symboltableCmdOffset;
        std::vector< std::vector<const char*> >  _linkerOptions;
+       std::unordered_set<uint64_t>&   _toolsVersions;
        
        static ld::Section                      _s_section;
        static ld::Section                      _s_preload_section;
@@ -177,7 +181,8 @@ HeaderAndLoadCommandsAtom<A>::HeaderAndLoadCommandsAtom(const Options& opts, ld:
                                ld::Atom::scopeTranslationUnit, ld::Atom::typeUnclassified, 
                                ld::Atom::symbolTableNotIn, false, false, false, 
                                (opts.outputKind() == Options::kPreload) ? ld::Atom::Alignment(0) : ld::Atom::Alignment(log2(opts.segmentAlignment())) ),
-               _options(opts), _state(state), _writer(writer), _address(0), _uuidCmdInOutputBuffer(NULL), _linkeditCmdOffset(0), _symboltableCmdOffset(0)
+               _options(opts), _state(state), _writer(writer), _address(0), _uuidCmdInOutputBuffer(NULL), _linkeditCmdOffset(0), _symboltableCmdOffset(0),
+               _toolsVersions(state.toolsVersions)
 {
        bzero(_uuid, 16);
        _hasDyldInfoLoadCommand = opts.makeCompressedDyldInfo();
@@ -233,9 +238,21 @@ HeaderAndLoadCommandsAtom<A>::HeaderAndLoadCommandsAtom(const Options& opts, ld:
        }
        _hasRPathLoadCommands = (_options.rpaths().size() != 0);
        _hasSubFrameworkLoadCommand = (_options.umbrellaName() != NULL);
-       _hasVersionLoadCommand = _options.addVersionLoadCommand() ||
-                                                        (!state.objectFileFoundWithNoVersion && (_options.outputKind() == Options::kObjectFile)
-                                                        && ((_options.platform() != Options::kPlatformUnknown) || (state.derivedPlatformLoadCommand != 0)) );
+       _platform = _options.platform();
+       if ( (_platform == Options::kPlatformUnknown) && (_state.derivedPlatform != 0) )
+               _platform = (Options::Platform)_state.derivedPlatform;
+       if ( _options.addVersionLoadCommand() ) {
+               _hasBuildVersionLoadCommand = _options.addBuildVersionLoadCommand();
+               _hasVersionLoadCommand = !_hasBuildVersionLoadCommand;
+       }
+       else if (((_options.outputKind() == Options::kObjectFile) && (_platform != Options::kPlatformUnknown) && !state.objectFileFoundWithNoVersion) ) {
+               _hasBuildVersionLoadCommand = (_platform == Options::kPlatform_bridgeOS);
+               _hasVersionLoadCommand = !_hasBuildVersionLoadCommand;
+       }
+       else {
+               _hasVersionLoadCommand = false;
+               _hasBuildVersionLoadCommand = false;
+       }
        _hasFunctionStartsLoadCommand = _options.addFunctionStarts();
        _hasDataInCodeLoadCommand = _options.addDataInCodeInfo();
        _hasSourceVersionLoadCommand = _options.needsSourceVersionLoadCommand();
@@ -410,6 +427,9 @@ uint64_t HeaderAndLoadCommandsAtom<A>::size() const
        if ( _hasVersionLoadCommand )
                sz += sizeof(macho_version_min_command<P>);
        
+       if ( _hasBuildVersionLoadCommand )
+               sz += alignedSize(sizeof(macho_build_version_command<P>) + sizeof(macho_build_tool_version<P>)*_toolsVersions.size());
+       
        if ( _hasSourceVersionLoadCommand )
                sz += sizeof(macho_source_version_command<P>);
                
@@ -513,6 +533,9 @@ uint32_t HeaderAndLoadCommandsAtom<A>::commandsCount() const
        if ( _hasVersionLoadCommand )
                ++count;
 
+       if ( _hasBuildVersionLoadCommand )
+               ++count;
+       
        if ( _hasSourceVersionLoadCommand )
                ++count;
                
@@ -680,7 +703,7 @@ uint32_t HeaderAndLoadCommandsAtom<arm>::cpuSubType() const
 template <>
 uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuSubType() const
 {
-       return CPU_SUBTYPE_ARM64_ALL;
+       return _state.cpuSubType;
 }
 
 
@@ -1159,14 +1182,7 @@ template <typename A>
 uint8_t* HeaderAndLoadCommandsAtom<A>::copyVersionLoadCommand(uint8_t* p) const
 {
        macho_version_min_command<P>* cmd = (macho_version_min_command<P>*)p;
-       switch (_options.platform()) {
-               case Options::kPlatformUnknown:
-                       assert(_state.derivedPlatformLoadCommand != 0 && "unknown platform");
-                       cmd->set_cmd(_state.derivedPlatformLoadCommand);
-                       cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
-                       cmd->set_version(_state.minOSVersion);
-                       cmd->set_sdk(0);
-                       break;
+       switch (_platform) {
                case Options::kPlatformOSX:
                        cmd->set_cmd(LC_VERSION_MIN_MACOSX);
                        cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
@@ -1193,10 +1209,40 @@ uint8_t* HeaderAndLoadCommandsAtom<A>::copyVersionLoadCommand(uint8_t* p) const
                        cmd->set_sdk(_options.sdkVersion());
                        break;
 #endif
+               case Options::kPlatformUnknown:
+                       assert(0 && "unknown platform");
+                       break;
+               case Options::kPlatform_bridgeOS:
+                       assert(0 && "bridgeOS uses LC_BUILD_VERSION");
+                       break;
        }
        return p + sizeof(macho_version_min_command<P>);
 }
 
+
+
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copyBuildVersionLoadCommand(uint8_t* p) const
+{
+       macho_build_version_command<P>* cmd = (macho_build_version_command<P>*)p;
+       
+       cmd->set_cmd(LC_BUILD_VERSION);
+       cmd->set_cmdsize(alignedSize(sizeof(macho_build_version_command<P>) + sizeof(macho_build_tool_version<P>)*_toolsVersions.size()));
+       cmd->set_platform(_options.platform());
+       cmd->set_minos(_state.minOSVersion);
+       cmd->set_sdk(_options.sdkVersion());
+       cmd->set_ntools(_toolsVersions.size());
+       macho_build_tool_version<P>* tools = (macho_build_tool_version<P>*)(p + sizeof(macho_build_version_command<P>));
+       for (uint64_t tool : _toolsVersions) {
+               tools->set_tool((uint64_t)tool >> 32);
+               tools->set_version(tool & 0xFFFFFFFF);
+               ++tools;
+       }
+
+       return p + cmd->cmdsize();
+}
+
+
 template <typename A>
 uint8_t* HeaderAndLoadCommandsAtom<A>::copySourceVersionLoadCommand(uint8_t* p) const
 {
@@ -1553,6 +1599,9 @@ void HeaderAndLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
        if ( _hasVersionLoadCommand )
                p = this->copyVersionLoadCommand(p);
 
+       if ( _hasBuildVersionLoadCommand )
+               p = this->copyBuildVersionLoadCommand(p);
+
        if ( _hasSourceVersionLoadCommand )
                p = this->copySourceVersionLoadCommand(p);
 
index 79401f2bf03013ea5d3dbc3137cae184755ac08e..1c69de62135e58464aca1c0174b4bfe09425485c 100644 (file)
@@ -1232,8 +1232,15 @@ void InputFiles::forEachInitialAtom(ld::File::AtomHandler& handler, ld::Internal
                        }
                                break;
                }
-               file->forEachAtom(handler);
+               try {
+                       file->forEachAtom(handler);
+               }
+               catch (const char* msg) {
+                       asprintf((char**)&_exception, "%s file '%s'", msg, file->path());
+               }
        }
+       if (_exception)
+               throw _exception;
 
        markExplicitlyLinkedDylibs();
        addLinkerOptionLibraries(state, handler);
index d36bc02cfc6b6835b331685cba79ff40904a996f..b7397863330fb3899f120aa552b128de6ceff6f5 100644 (file)
@@ -53,6 +53,8 @@ extern "C" size_t fnd_get_demangled_name(const char *mangledName, char *outputBu
 // upward dependency on lto::version()
 namespace lto {
        extern const char* version();
+       extern unsigned static_api_version();
+       extern unsigned runtime_api_version();
 }
 
 // magic to place command line in crash reports
@@ -171,7 +173,7 @@ Options::Options(int argc, const char* argv[])
          fObjcGcCompaction(false), fObjCGc(false), fObjCGcOnly(false), 
          fDemangle(false), fTLVSupport(false), 
          fVersionLoadCommand(false), fVersionLoadCommandForcedOn(false), 
-         fVersionLoadCommandForcedOff(false), fFunctionStartsLoadCommand(false),
+         fVersionLoadCommandForcedOff(false), fBuildVersionLoadCommand(false), fFunctionStartsLoadCommand(false),
          fFunctionStartsForcedOn(false), fFunctionStartsForcedOff(false),
          fDataInCodeInfoLoadCommand(false), fDataInCodeInfoLoadCommandForcedOn(false), fDataInCodeInfoLoadCommandForcedOff(false),
          fCanReExportSymbols(false), fObjcCategoryMerging(true), fPageAlignDataAtoms(false), 
@@ -190,11 +192,12 @@ Options::Options(int argc, const char* argv[])
          fBundleBitcode(false), fHideSymbols(false), fVerifyBitcode(false),
          fReverseMapUUIDRename(false), fDeDupe(true), fVerboseDeDupe(false),
          fReverseMapPath(NULL), fLTOCodegenOnly(false),
-         fIgnoreAutoLink(false), fAllowDeadDups(false), fAllowWeakImports(true), fBitcodeKind(kBitcodeProcess),
+         fIgnoreAutoLink(false), fAllowDeadDups(false), fAllowWeakImports(true), fNoInitializers(false), fBitcodeKind(kBitcodeProcess),
          fPlatform(kPlatformUnknown), fDebugInfoStripping(kDebugInfoMinimal), fTraceOutputFile(NULL),
          fMacVersionMin(ld::macVersionUnset), fIOSVersionMin(ld::iOSVersionUnset), fWatchOSVersionMin(ld::wOSVersionUnset),
          fSaveTempFiles(false), fSnapshotRequested(false), fPipelineFifo(NULL),
-         fDependencyInfoPath(NULL), fDependencyFileDescriptor(-1), fTraceFileDescriptor(-1), fMaxDefaultCommonAlign(0)
+         fDependencyInfoPath(NULL), fDependencyFileDescriptor(-1), fTraceFileDescriptor(-1), fMaxDefaultCommonAlign(0),
+         fUnalignedPointerTreatment(kUnalignedPointerIgnore)
 {
        this->checkForClassic(argc, argv);
        this->parsePreCommandLineEnvironmentSettings();
@@ -598,8 +601,10 @@ uint32_t Options::minOSversion() const
                case Options::kPlatform_tvOS:
                        return iOSVersionMin();
 #endif
-               default:
-                       break;
+               case kPlatform_bridgeOS:
+                       return iOSVersionMin();
+               case kPlatformUnknown:
+                       return 0;
        }
        return 0;
 }
@@ -613,7 +618,8 @@ void Options::setArchitecture(cpu_type_t type, cpu_subtype_t subtype, Options::P
                        fArchitectureName = t->archName;
                        fHasPreferredSubType = t->isSubType;
                        fArchSupportsThumb2 = t->supportsThumb2;
-                       fPlatform = platform;
+                       if ( fPlatform == kPlatformUnknown)
+                               fPlatform = platform;
                        switch ( type ) {
                                case CPU_TYPE_I386:
                                case CPU_TYPE_X86_64:
@@ -1501,12 +1507,8 @@ bool Options::minOS(ld::MacVersionMin requiredMacMin, ld::IOSVersionMin required
        if ( fMacVersionMin != ld::macVersionUnset ) {
                return ( fMacVersionMin >= requiredMacMin );
        }
-       else if ( fWatchOSVersionMin != ld::wOSVersionUnset ) {
-               // Hack until we fully track watch and ios versions seperately
-               return ( (fWatchOSVersionMin + 0x00070000) >= requirediPhoneOSMin);
-       }
        else {
-               return ( fIOSVersionMin >= requirediPhoneOSMin );
+               return min_iOS(requirediPhoneOSMin);
        }
 }
 
@@ -1516,6 +1518,10 @@ bool Options::min_iOS(ld::IOSVersionMin requirediOSMin)
                // Hack until we fully track watch and ios versions seperately
                return ( (fWatchOSVersionMin + 0x00070000) >= requirediOSMin);
        }
+       else if ( fPlatform == Options::kPlatform_bridgeOS ) {
+               // Hack until we fully track bridge and ios versions seperately
+               return ( (fIOSVersionMin + 0x00090000) >= requirediOSMin);
+       }
        else {
                return ( fIOSVersionMin >= requirediOSMin );
        }
@@ -2180,6 +2186,8 @@ std::string Options::getPlatformStr() const
                                return "AppleTVOS";
                        break;
 #endif
+               case Options::kPlatform_bridgeOS:
+                       return "bridgeOS";
                case Options::kPlatformUnknown:
                        return "Unknown";
        }
@@ -2247,6 +2255,10 @@ std::vector<std::string> Options::writeBitcodeLinkOptions() const
                        linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
                        break;
 #endif
+               case Options::kPlatform_bridgeOS:
+                       linkCommand.push_back("-bridgeos_version_min");
+                       linkCommand.push_back(getVersionString32((unsigned)fIOSVersionMin));
+                       break;
                case Options::kPlatformUnknown:
                        if ( fOutputKind != Options::kObjectFile ) {
                                throwf("platform is unknown for final bitcode bundle,"
@@ -2991,6 +3003,13 @@ void Options::parse(int argc, const char* argv[])
                                fTargetIOSSimulator = true;
                        }
        #endif
+                       else if ( strcmp(arg, "-bridgeos_version_min") == 0 ) {
+                               const char* vers = argv[++i];
+                               if ( vers == NULL )
+                                       throw "-bridgeos_version_min missing version argument";
+                               setIOSVersionMin(vers);
+                               fPlatform = kPlatform_bridgeOS;
+                       }
                        else if ( strcmp(arg, "-multiply_defined") == 0 ) {
                                //warnObsolete(arg);
                                ++i;
@@ -3252,8 +3271,8 @@ void Options::parse(int argc, const char* argv[])
                                if ( fReverseMapPath == NULL )
                                        throw "missing argument to -bitcode_symbol_map";
                                struct stat statbuf;
-                               ::stat(fReverseMapPath, &statbuf);
-                               if (S_ISDIR(statbuf.st_mode)) {
+                               int ret = ::stat(fReverseMapPath, &statbuf);
+                               if ( ret == 0 && S_ISDIR(statbuf.st_mode)) {
                                        char tempPath[PATH_MAX];
                                        sprintf(tempPath, "%s/XXXXXX", fReverseMapPath);
                                        int tempFile = ::mkstemp(tempPath);
@@ -3845,6 +3864,9 @@ void Options::parse(int argc, const char* argv[])
                        else if ( strcmp(argv[i], "-no_weak_imports") == 0 ) {
                                fAllowWeakImports = false;
                        }
+                       else if ( strcmp(argv[i], "-no_inits") == 0 ) {
+                               fNoInitializers = true;
+                       }
                        // put this last so that it does not interfer with other options starting with 'i'
                        else if ( strncmp(arg, "-i", 2) == 0 ) {
                                const char* colon = strchr(arg, ':');
@@ -3946,7 +3968,8 @@ void Options::buildSearchPaths(int argc, const char* argv[])
                         if ( argc == 2 ) {
                                const char* ltoVers = lto::version();
                                if ( ltoVers != NULL )
-                                       fprintf(stderr, "LTO support using: %s\n", ltoVers);
+                                       fprintf(stderr, "LTO support using: %s (static support for %d, runtime is %d)\n",
+                                                       ltoVers, lto::static_api_version(), lto::runtime_api_version());
                                fprintf(stderr, "TAPI support using: %s\n", tapi::Version::getFullVersionAsString().c_str());
                                exit(0);
                        }
@@ -4240,6 +4263,12 @@ void Options::parsePostCommandLineEnvironmentSettings()
                
 }
 
+
+static bool sharedCacheEligiblePath(const char* path)
+{
+       return ( (strncmp(path, "/usr/lib/", 9) == 0) || (strncmp(path, "/System/Library/", 16) == 0) );
+}
+
 void Options::reconfigureDefaults()
 {
        // sync reader options
@@ -4569,10 +4598,9 @@ void Options::reconfigureDefaults()
 
        // determine if info for shared region should be added
        if ( fOutputKind == Options::kDynamicLibrary ) {
-               if ( minOS(ld::mac10_5, ld::iOS_3_1) && !fTargetIOSSimulator )
+               if ( minOS(ld::mac10_5, ld::iOS_3_1) )
                        if ( !fPrebind && !fSharedRegionEligibleForceOff )
-                               if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
-                                       || (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
+                               if ( sharedCacheEligiblePath(this->installPath()) )
                                        fSharedRegionEligible = true;
        }
        else if ( fOutputKind == Options::kDyld ) {
@@ -4580,12 +4608,8 @@ void Options::reconfigureDefaults()
         fSharedRegionEligible = true;
        }
 
-       // <rdar://problem/18719327> warn if -rpath is used with OS dylibs
-       if ( fSharedRegionEligible && !fRPaths.empty() ) 
-               warning("-rpath cannot be used with dylibs that will be in the dyld shared cache");
-
        // automatically use __DATA_CONST in iOS dylibs
-       if ( fSharedRegionEligible && minOS(ld::mac10_Future, ld::iOS_9_0) && !fUseDataConstSegmentForceOff ) {
+       if ( fSharedRegionEligible && minOS(ld::mac10_Future, ld::iOS_9_0) && !fUseDataConstSegmentForceOff && !fTargetIOSSimulator) {
                fUseDataConstSegment = true;
        }
        if ( fUseDataConstSegmentForceOn ) {
@@ -4621,9 +4645,19 @@ void Options::reconfigureDefaults()
        // Use V2 shared cache info when targetting newer OSs
        if ( fSharedRegionEligible && minOS(ld::mac10_12, ld::iOS_9_0)) {
                fSharedRegionEncodingV2 = true;
-               // <rdar://problem/24772435> only use v2 for Swift dylibs on Mac OS X
-               if ( (fPlatform == kPlatformOSX) && (strncmp(this->installPath(), "/System/Library/PrivateFrameworks/Swift/", 40) != 0) )
+               if ( fPlatform == kPlatformOSX ) {
                        fSharedRegionEncodingV2 = false;
+                       // <rdar://problem/24772435> only use v2 for Swift dylibs on Mac OS X
+                       if ( strncmp(this->installPath(), "/System/Library/PrivateFrameworks/Swift/", 40) == 0 )
+                               fSharedRegionEncodingV2 = true;
+                       // <rdar://problem/31428120> an other OS frameworks that use swift need v2
+                       for (const char* searchPath  : fLibrarySearchPaths ) {
+                               if ( strstr(searchPath, "xctoolchain/usr/lib/swift/macos") != NULL ) {
+                                       fSharedRegionEncodingV2 = true;
+                                       break;
+                               }
+                       }
+               }
                fIgnoreOptimizationHints = true;
        }
 
@@ -5142,6 +5176,19 @@ void Options::reconfigureDefaults()
                }
        }
 
+
+       // <rdar://problem/32138080> Automatically use OrderFiles found in the AppleInternal SDK
+       if ( (fFinalName != NULL) && fOrderedSymbols.empty() && !fSDKPaths.empty() ) {
+               char path[PATH_MAX];
+               strlcpy(path , fSDKPaths.front(), sizeof(path));
+               strlcat(path , "/AppleInternal/OrderFiles/", sizeof(path));
+               strlcat(path , fFinalName, sizeof(path));
+               strlcat(path , ".order", sizeof(path));
+               FileInfo info;
+               if ( info.checkFileExists(*this, path) )
+                       parseOrderFile(path, false);
+       }
+
        // <rdar://problem/20503811> Reduce the default alignment of structures/arrays to save memory in embedded systems
        if ( fMaxDefaultCommonAlign == 0 ) {
                if ( fOutputKind == Options::kPreload )
@@ -5149,6 +5196,56 @@ void Options::reconfigureDefaults()
                else
                        fMaxDefaultCommonAlign = 15;
        }
+
+       // Add warnings for issues likely to cause OS verification issues
+       if ( fSharedRegionEligible && !fRPaths.empty() ) {
+               // <rdar://problem/18719327> warn if -rpath is used with OS dylibs
+               warning("OS dylibs should not add rpaths (linker option: -rpath) (Xcode build setting: LD_RUNPATH_SEARCH_PATHS)");
+       }
+       if ( (fOutputKind == Options::kDynamicLibrary) && (fDylibInstallName != NULL) && (fFinalName != NULL) && sharedCacheEligiblePath(fFinalName) ) {
+               if ( strncmp(fDylibInstallName, "@rpath", 6) == 0 )
+                       warning("OS dylibs should not use @rpath for -install_name.  Use absolute path instead");
+               if ( strcmp(fDylibInstallName, fFinalName) != 0 ) {
+                       bool different = true;
+                       // some projects end up with double slash in -final_output path
+                       if ( strstr(fFinalName, "//") != NULL ) {
+                               char fixedPath[strlen(fFinalName)+1];
+                               char* t = fixedPath;
+                               bool lastWasSlash = false;
+                               for (const char* s=fFinalName; *s != '\0'; ++s) {
+                                       if ( *s == '/' ) {
+                                               if ( !lastWasSlash )
+                                                       *t++ = *s;
+                                               lastWasSlash = true;
+                                       }
+                                       else {
+                                               *t++ = *s;
+                                               lastWasSlash = false;
+                                       }
+                               }
+                               *t = '\0';
+                               different = (strcmp(fDylibInstallName, fixedPath) != 0);
+                       }
+                       if ( different )
+                               warning("OS dylibs -install_name should match its real absolute path");
+               }
+       }
+
+       // set if unaligned pointers are warnings or errors
+       if ( fMacVersionMin >= ld::mac10_12 ) {
+               // ignore unaligned pointers when targeting older macOS versions
+               if ( fSharedRegionEligible )
+                       fUnalignedPointerTreatment = Options::kUnalignedPointerWarning;
+               else
+                       fUnalignedPointerTreatment = Options::kUnalignedPointerIgnore;
+       }
+       else if ( min_iOS(ld::iOS_10_0) ) {
+               fUnalignedPointerTreatment = Options::kUnalignedPointerWarning;
+       }
+       else {
+               fUnalignedPointerTreatment = Options::kUnalignedPointerIgnore;
+       }
+
 }
 
 void Options::checkIllegalOptionCombinations()
@@ -5164,6 +5261,7 @@ void Options::checkIllegalOptionCombinations()
                                        break;
                                case kPlatformiOS:
                                case kPlatformWatchOS:
+                               case kPlatform_bridgeOS:
                #if SUPPORT_APPLE_TV
                                case kPlatform_tvOS:
                #endif
@@ -5237,6 +5335,7 @@ void Options::checkIllegalOptionCombinations()
                                break;
                        case kPlatformiOS:
                        case kPlatformWatchOS:
+                       case kPlatform_bridgeOS:
        #if SUPPORT_APPLE_TV
                        case Options::kPlatform_tvOS:
        #endif
@@ -5666,6 +5765,10 @@ void Options::checkIllegalOptionCombinations()
                        warning("embedded dylibs/frameworks only run on iOS 8 or later");
        }
 
+       // bridgeOS always generates new load command
+       if ( fVersionLoadCommand && (fPlatform == kPlatform_bridgeOS) ) {
+               fBuildVersionLoadCommand = true;
+       }
 
        // produce nicer error when no input
        if ( fInputFiles.empty() ) {
index d489fd655a99a6f84a955fe3ece32b9c7215c507..4ff780ca35073dd75d7160ed568206e2039f405f 100644 (file)
@@ -88,8 +88,9 @@ public:
        enum LocalSymbolHandling { kLocalSymbolsAll, kLocalSymbolsNone, kLocalSymbolsSelectiveInclude, kLocalSymbolsSelectiveExclude };
        enum BitcodeMode { kBitcodeProcess, kBitcodeAsData, kBitcodeMarker, kBitcodeStrip };
        enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull };
+       enum UnalignedPointerTreatment { kUnalignedPointerError, kUnalignedPointerWarning, kUnalignedPointerIgnore };
 #if SUPPORT_APPLE_TV
-       enum Platform { kPlatformUnknown, kPlatformOSX, kPlatformiOS, kPlatformWatchOS, kPlatform_tvOS };
+       enum Platform { kPlatformUnknown, kPlatformOSX=1, kPlatformiOS=2, kPlatformWatchOS=3, kPlatform_tvOS=4, kPlatform_bridgeOS=5 };
 #else
        enum Platform { kPlatformUnknown, kPlatformOSX, kPlatformiOS, kPlatformWatchOS };
 #endif
@@ -123,6 +124,8 @@ public:
                        case kPlatform_tvOS:
                                return "tvOS";
                #endif
+                       case kPlatform_bridgeOS:
+                               return "bridgeOS";
                        case kPlatformUnknown:
                        default:
                                return "(unknown)";
@@ -144,6 +147,9 @@ public:
                        case 4:
                                strcpy(versionString, "3.0");
                                break;
+                       case 5:
+                               strcpy(versionString, "4.0");
+                               break;
                        default:
                                sprintf(versionString, "unknown ABI version 0x%02X", value);
                }
@@ -428,6 +434,7 @@ public:
        bool                                            objcGcOnly() const { return fObjCGcOnly; }
        bool                                            canUseThreadLocalVariables() const { return fTLVSupport; }
        bool                                            addVersionLoadCommand() const { return fVersionLoadCommand && (fPlatform != kPlatformUnknown); }
+       bool                                            addBuildVersionLoadCommand() const { return fBuildVersionLoadCommand; }
        bool                                            addFunctionStarts() const { return fFunctionStartsLoadCommand; }
        bool                                            addDataInCodeInfo() const { return fDataInCodeInfoLoadCommand; }
        bool                                            canReExportSymbols() const { return fCanReExportSymbols; }
@@ -461,6 +468,7 @@ public:
        bool                                            ignoreAutoLink() const { return fIgnoreAutoLink; }
        bool                                            allowDeadDuplicates() const { return fAllowDeadDups; }
        bool                                            allowWeakImports() const { return fAllowWeakImports; }
+       bool                                            noInitializers() const { return fNoInitializers; }
        BitcodeMode                                     bitcodeKind() const { return fBitcodeKind; }
        bool                                            sharedRegionEncodingV2() const { return fSharedRegionEncodingV2; }
        bool                                            useDataConstSegment() const { return fUseDataConstSegment; }
@@ -504,6 +512,7 @@ public:
        bool                                            hasDataSymbolMoves() const { return !fSymbolsMovesData.empty(); }
        bool                                            hasCodeSymbolMoves() const { return !fSymbolsMovesCode.empty(); }
        void                                            writeToTraceFile(const char* buffer, size_t len) const;
+       UnalignedPointerTreatment       unalignedPointerTreatment() const { return fUnalignedPointerTreatment; }
 
        static uint32_t                         parseVersionNumber32(const char*);
 
@@ -730,6 +739,7 @@ private:
        bool                                                            fVersionLoadCommand;
        bool                                                            fVersionLoadCommandForcedOn;
        bool                                                            fVersionLoadCommandForcedOff;
+       bool                                                            fBuildVersionLoadCommand;
        bool                                                            fFunctionStartsLoadCommand;
        bool                                                            fFunctionStartsForcedOn;
        bool                                                            fFunctionStartsForcedOff;
@@ -778,6 +788,7 @@ private:
        bool                                                            fIgnoreAutoLink;
        bool                                                            fAllowDeadDups;
        bool                                                            fAllowWeakImports;
+       bool                                                            fNoInitializers;
        BitcodeMode                                                     fBitcodeKind;
        Platform                                                        fPlatform;
        DebugInfoStripping                                      fDebugInfoStripping;
@@ -817,6 +828,7 @@ private:
        mutable int                                                     fDependencyFileDescriptor;
        mutable int                                                     fTraceFileDescriptor;
        uint8_t                                                         fMaxDefaultCommonAlign;
+       UnalignedPointerTreatment                       fUnalignedPointerTreatment;
 };
 
 
index 3b775c911c2ec8876501c96dceb229b324998c29..044f850cf7599ef9ebff147e07a4d6ae9192fe67 100644 (file)
@@ -684,7 +684,7 @@ void OutputFile::rangeCheckRIP32(int64_t displacement, ld::Internal& state, cons
                printSectionLayout(state);
                
                const ld::Atom* target; 
-               throwf("32-bit RIP relative reference out of range (%lld max is +/-4GB): from %s (0x%08llX) to %s (0x%08llX)", 
+               throwf("32-bit RIP relative reference out of range (%lld max is +/-2GB): from %s (0x%08llX) to %s (0x%08llX)",
                                displacement, atom->name(), atom->finalAddress(), referenceTargetAtomName(state, fixup), 
                                addressOf(state, fixup, &target));
        }
@@ -2948,7 +2948,7 @@ void OutputFile::buildSymbolTable(ld::Internal& state)
                        ++machoSectionIndex;
                for (std::vector<const ld::Atom*>::iterator ait = sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
                        const ld::Atom* atom = *ait;
-                       if ( setMachoSectionIndex ) 
+                       if ( setMachoSectionIndex )
                                (const_cast<ld::Atom*>(atom))->setMachoSection(machoSectionIndex);
                        else if ( sect->type() == ld::Section::typeMachHeader )
                                (const_cast<ld::Atom*>(atom))->setMachoSection(1); // __mh_execute_header is not in any section by needs n_sect==1
@@ -4275,12 +4275,18 @@ void OutputFile::addDyldInfo(ld::Internal& state,  ld::Internal::FinalSection* s
                        }
                }
                if ( ((address & (pointerSize-1)) != 0) && (rebaseType == REBASE_TYPE_POINTER) ) {
-                       if ( (pointerSize == 8) && ((address & 7) == 4) ) {
-                               // for now, don't warning about 8-byte pointers only 4-byte aligned
-                       }
-                       else {
-                               warning("pointer not aligned at address 0x%llX (%s + %lld from %s)",
-                                               address, atom->name(), (address - atom->finalAddress()), atom->safeFilePath());
+                       switch ( _options.unalignedPointerTreatment() ) {
+                               case Options::kUnalignedPointerError:
+                                       throwf("pointer not aligned at address 0x%llX (%s + %lld from %s)",
+                                                       address, atom->name(), (address - atom->finalAddress()), atom->safeFilePath());
+                                       break;
+                               case Options::kUnalignedPointerWarning:
+                                       warning("pointer not aligned at address 0x%llX (%s + %lld from %s)",
+                                                       address, atom->name(), (address - atom->finalAddress()), atom->safeFilePath());
+                                       break;
+                               case Options::kUnalignedPointerIgnore:
+                                       // do nothing
+                                       break;
                        }
                }
                _rebaseInfo.push_back(RebaseInfo(rebaseType, address));
@@ -4291,12 +4297,18 @@ void OutputFile::addDyldInfo(ld::Internal& state,  ld::Internal::FinalSection* s
                        sect->hasExternalRelocs = true; // so dyld knows to change permissions on __TEXT segment
                }
                if ( ((address & (pointerSize-1)) != 0) && (type == BIND_TYPE_POINTER) ) {
-                       if ( (pointerSize == 8) && ((address & 7) == 4) ) {
-                               // for now, don't warning about 8-byte pointers only 4-byte aligned
-                       }
-                       else {
-                               warning("pointer not aligned at address 0x%llX (%s + %lld from %s)",
-                                               address, atom->name(), (address - atom->finalAddress()), atom->safeFilePath());
+                       switch ( _options.unalignedPointerTreatment() ) {
+                               case Options::kUnalignedPointerError:
+                                       throwf("pointer not aligned at address 0x%llX (%s + %lld from %s)",
+                                                       address, atom->name(), (address - atom->finalAddress()), atom->safeFilePath());
+                                       break;
+                               case Options::kUnalignedPointerWarning:
+                                       warning("pointer not aligned at address 0x%llX (%s + %lld from %s)",
+                                                       address, atom->name(), (address - atom->finalAddress()), atom->safeFilePath());
+                                       break;
+                               case Options::kUnalignedPointerIgnore:
+                                       // do nothing
+                                       break;
                        }
                }
                _bindingInfo.push_back(BindingInfo(type, this->compressedOrdinalForAtom(target), target->name(), weak_import, address, addend));
@@ -5236,6 +5248,7 @@ void OutputFile::synthesizeDebugNotes(ld::Internal& state)
        // make a vector of atoms that come from files compiled with dwarf debug info
        std::vector<const ld::Atom*> atomsNeedingDebugNotes;
        std::set<const ld::Atom*> atomsWithStabs;
+       std::set<const ld::relocatable::File*> filesSeenWithStabs;
        atomsNeedingDebugNotes.reserve(1024);
        const ld::relocatable::File* objFile = NULL;
        bool objFileHasDwarf = false;
@@ -5285,8 +5298,11 @@ void OutputFile::synthesizeDebugNotes(ld::Internal& state)
                                }
                                if ( objFileHasDwarf )
                                        atomsNeedingDebugNotes.push_back(atom);
-                               if ( objFileHasStabs )
+                               if ( objFileHasStabs ) {
                                        atomsWithStabs.insert(atom);
+                                       if ( objFile != NULL )
+                                               filesSeenWithStabs.insert(objFile);
+                               }
                        }
                }
        }
@@ -5480,33 +5496,44 @@ void OutputFile::synthesizeDebugNotes(ld::Internal& state)
                endFileStab.string              = "";
                state.stabs.push_back(endFileStab);
        }
-       
-       // copy any stabs from .o file 
-       std::set<const ld::File*> filesSeenWithStabs;
-       for (std::set<const ld::Atom*>::iterator it=atomsWithStabs.begin(); it != atomsWithStabs.end(); it++) {
-               const ld::Atom* atom = *it;
-               objFile = dynamic_cast<const ld::relocatable::File*>(atom->file());
-               if ( objFile != NULL ) {
-                       if ( filesSeenWithStabs.count(objFile) == 0 ) {
-                               filesSeenWithStabs.insert(objFile);
-                               const std::vector<ld::relocatable::File::Stab>* stabs = objFile->stabs();
-                               if ( stabs != NULL ) {
-                                       for(std::vector<ld::relocatable::File::Stab>::const_iterator sit = stabs->begin(); sit != stabs->end(); ++sit) {
-                                               ld::relocatable::File::Stab stab = *sit;
-                                               // ignore stabs associated with atoms that were dead stripped or coalesced away
-                                               if ( (sit->atom != NULL) && (atomsWithStabs.count(sit->atom) == 0) )
+
+       // copy any stabs from .o files
+       bool deadStripping = _options.deadCodeStrip();
+       for (const ld::relocatable::File* obj : filesSeenWithStabs) {
+               const std::vector<ld::relocatable::File::Stab>* filesStabs = obj->stabs();
+               if ( filesStabs != NULL ) {
+                       for (const ld::relocatable::File::Stab& stab : *filesStabs ) {
+                               // ignore stabs associated with atoms that were dead stripped or coalesced away
+                               if ( (stab.atom != NULL) && (atomsWithStabs.count(stab.atom) == 0) )
+                                       continue;
+                               // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
+                               if ( (stab.type == N_SO) && (stab.string != NULL) && (stab.string[0] != '\0') ) {
+                                       uint64_t lowestAtomAddress = 0;
+                                       const ld::Atom* lowestAddressAtom = NULL;
+                                       for (const ld::relocatable::File::Stab& stab2 : *filesStabs ) {
+                                               if ( stab2.atom == NULL )
                                                        continue;
-                                               // <rdar://problem/8284718> Value of N_SO stabs should be address of first atom from translation unit
-                                               if ( (stab.type == N_SO) && (stab.string != NULL) && (stab.string[0] != '\0') ) {
-                                                       stab.atom = atom;
+                                               // skip over atoms that were dead stripped
+                                               if ( deadStripping && !stab2.atom->live() )
+                                                       continue;
+                                               if ( stab2.atom->coalescedAway() )
+                                                       continue;
+                                               uint64_t atomAddr = stab2.atom->objectAddress();
+                                               if ( (lowestAddressAtom == NULL) || (atomAddr < lowestAtomAddress) ) {
+                                                       lowestAddressAtom = stab2.atom;
+                                                       lowestAtomAddress = atomAddr;
                                                }
-                                               state.stabs.push_back(stab);
                                        }
+                                       ld::relocatable::File::Stab altStab = stab;
+                                       altStab.atom = lowestAddressAtom;
+                                       state.stabs.push_back(altStab);
+                               }
+                               else {
+                                       state.stabs.push_back(stab);
                                }
                        }
                }
        }
-
 }
 
 
index 24af5f8083186ab3e993b7c33832c17a6cbe0299..831fa7f0f051a5ca9ce6f6f0e74ffb9cd390610a 100644 (file)
@@ -51,7 +51,6 @@
 #include <AvailabilityMacros.h>
 
 #include "Options.h"
-
 #include "ld.hpp"
 #include "Bitcode.hpp"
 #include "InputFiles.h"
 #include "Resolver.h"
 #include "parsers/lto_file.h"
 
+#include "configure.h"
+
+#define VAL(x) #x
+#define STRINGIFY(x) VAL(x)
 
 namespace ld {
 namespace tool {
@@ -284,7 +287,7 @@ void Resolver::initializeState()
        
        _internal.cpuSubType = _options.subArchitecture();
        _internal.minOSVersion = _options.minOSversion();
-       _internal.derivedPlatformLoadCommand = 0;
+       _internal.derivedPlatform = 0;
        
        // In -r mode, look for -linker_option additions
        if ( _options.outputKind() == Options::kObjectFile ) {
@@ -293,6 +296,11 @@ void Resolver::initializeState()
                        doLinkerOption(*it, "command line");
                }
        }
+#ifdef LD64_VERSION_NUM
+       uint32_t packedNum = Options::parseVersionNumber32(STRINGIFY(LD64_VERSION_NUM));
+       uint64_t combined = (uint64_t)TOOL_LD << 32 | packedNum;
+       _internal.toolsVersions.insert(combined);
+#endif
 }
 
 void Resolver::buildAtomList()
@@ -366,6 +374,7 @@ void Resolver::doFile(const ld::File& file)
                                        // No bitcode section, figure out if the object file comes from LTO/compiler static library
                                        switch ( _options.platform() ) {
                                        case Options::kPlatformOSX:
+                                       case Options::kPlatform_bridgeOS:
                                        case Options::kPlatformUnknown:
                                                warning("all bitcode will be dropped because '%s' was built without bitcode. "
                                                                "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. ", file.path());
@@ -475,14 +484,19 @@ void Resolver::doFile(const ld::File& file)
                uint32_t objMinOS = objFile->minOSVersion();
                if ( !objMinOS )
                        _internal.objectFileFoundWithNoVersion = true;
-
-               uint32_t objPlatformLC = objFile->platformLoadCommand();
-               if ( (objPlatformLC != 0) && (_internal.derivedPlatformLoadCommand == 0) && (_options.outputKind() == Options::kObjectFile) )
-                       _internal.derivedPlatformLoadCommand = objPlatformLC;
-
                if ( (_options.outputKind() == Options::kObjectFile) && (objMinOS > _internal.minOSVersion) )
                        _internal.minOSVersion = objMinOS;
 
+               uint32_t objPlatform = objFile->platform();
+               if ( (objPlatform != 0) && (_options.outputKind() == Options::kObjectFile) && (_internal.derivedPlatform == 0)  )
+                       _internal.derivedPlatform = objPlatform;
+
+               // update set of known tools used
+               for (const std::pair<uint32_t,uint32_t>& entry : objFile->toolVersions()) {
+                       uint64_t combined = (uint64_t)entry.first << 32 | entry.second;
+                       _internal.toolsVersions.insert(combined);
+               }
+
                // update cpu-sub-type
                cpu_subtype_t nextObjectSubType = file.cpuSubType();
                switch ( _options.architecture() ) {
@@ -505,6 +519,19 @@ void Resolver::doFile(const ld::File& file)
                                }
                                break;
                        
+                       case CPU_TYPE_ARM64:
+                               if ( _options.subArchitecture() != nextObjectSubType ) {
+                                       if ( _options.allowSubArchitectureMismatches() ) {
+                                               warning("object file %s was built for different arm64 sub-type (%d) than link command line (%d)",
+                                                       file.path(), nextObjectSubType, _options.subArchitecture());
+                                       }
+                                       else {
+                                               throwf("object file %s was built for different arm64 sub-type (%d) than link command line (%d)",
+                                                       file.path(), nextObjectSubType, _options.subArchitecture());
+                                       }
+                               }
+                               break;
+
                        case CPU_TYPE_I386:
                                _internal.cpuSubType = CPU_SUBTYPE_I386_ALL;
                                break;
@@ -547,6 +574,7 @@ void Resolver::doFile(const ld::File& file)
                                         strncmp(tcLibPath, tempPath, strlen(tcLibPath)) != 0 ) {
                                        switch ( _options.platform() ) {
                                        case Options::kPlatformOSX:
+                                       case Options::kPlatform_bridgeOS:
                                        case Options::kPlatformUnknown:
                                                warning("all bitcode will be dropped because '%s' was built without bitcode. "
                                                                "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.", file.path());
@@ -766,6 +794,11 @@ void Resolver::doAtom(const ld::Atom& atom)
        if ( atom.section().type() == ld::Section::typeTempAlias )
                _haveAliases = true;
        
+       // prevent initializers if -no_inits used
+       if ( (atom.section().type() == ld::Section::typeInitializerPointers) && _options.noInitializers() ) {
+               throw "-no_inits specified, but initializer found";
+       }
+       
        if ( _options.deadCodeStrip() ) {
                // add to set of dead-strip-roots, all symbols that the compiler marks as don't strip
                if ( atom.dontDeadStrip() )
index 8351e3fa170666021957464b72df484c0a79c11f..5e9164f14953fcf3f6300c09b2aee7ed02957587 100644 (file)
@@ -157,7 +157,7 @@ public:
        virtual uint32_t                                        cpuSubType() const              { return 0; }
        virtual uint32_t                                        subFileCount() const    { return 1; }
        virtual uint32_t                                        minOSVersion() const    { return 0; }
-       virtual uint32_t                                        platformLoadCommand() const             { return 0; }
+       virtual uint32_t                                        platform() const                { return 0; }
     bool                                                               fileExists() const     { return _modTime != 0; }
        Type                                                            type() const { return _type; }
        virtual Bitcode*                                        getBitcode() const              { return NULL; }
@@ -213,6 +213,7 @@ namespace relocatable {
                        const char*                     string;
                };
                typedef const std::vector< std::vector<const char*> > LinkerOptionsList;
+               typedef std::vector<std::pair<uint32_t,uint32_t>> ToolVersionList;
 
                                                                                        File(const char* pth, time_t modTime, Ordinal ord)
                                                                                                : ld::File(pth, modTime, ord, Reloc) { }
@@ -224,6 +225,7 @@ namespace relocatable {
                virtual bool                                            canScatterAtoms() const = 0;
                virtual bool                                            hasLongBranchStubs()            { return false; }
                virtual LinkerOptionsList*                      linkerOptions() const = 0;
+               virtual const ToolVersionList&          toolVersions() const = 0;
                virtual SourceKind                                      sourceKind() const { return kSourceUnknown; }
                virtual const uint8_t*                          fileContent() const { return nullptr; }
        };
@@ -919,6 +921,7 @@ public:
        std::vector<const ld::relocatable::File*>       filesFromCompilerRT;
        std::vector<const ld::Atom*>                            deadAtoms;
        std::unordered_set<const char*>                         allUndefProxies;
+       std::unordered_set<uint64_t>                            toolsVersions;
        const ld::dylib::File*                                          bundleLoader;
        const Atom*                                                                     entryPoint;
        const Atom*                                                                     classicBindingHelper;
@@ -929,7 +932,7 @@ public:
        uint8_t                                                                         swiftVersion;
        uint32_t                                                                        cpuSubType;
        uint32_t                                                                        minOSVersion;
-       uint32_t                                                                        derivedPlatformLoadCommand;
+       uint32_t                                                                        derivedPlatform;
        bool                                                                            objectFileFoundWithNoVersion;
        bool                                                                            allObjectFilesScatterable;
        bool                                                                            someObjectFileHasDwarf;
index 529e4ab691cd025258779d9e4200ff7e5397d347..eb9d0ead94febe36918c820b048398e5ecd59c2b 100644 (file)
@@ -133,7 +133,7 @@ public:
        virtual ld::File::ObjcConstraint                objCConstraint() const override final { return _objcConstraint; }
        virtual uint8_t                                                 swiftVersion() const override final { return _swiftVersion; }
        virtual uint32_t                                                minOSVersion() const override final { return _minVersionInDylib; }
-       virtual uint32_t                                                platformLoadCommand() const     override final { return _platformInDylib; }
+       virtual uint32_t                                                platform() const        override final { return _platformInDylib; }
        virtual ld::Bitcode*                                    getBitcode() const override final { return _bitcode.get(); }
 
 
index 6915ae6ed19316d3b02b584ebe7afb030829803a..586516c8e8ea9802c20754765a289eb32c510cd2 100644 (file)
@@ -46,9 +46,6 @@
 #include "macho_relocatable_file.h"
 #include "lto_file.h"
 
-// #defines are a work around for <rdar://problem/8760268>
-#define __STDC_LIMIT_MACROS 1
-#define __STDC_CONSTANT_MACROS 1
 #include "llvm-c/lto.h"
 
 namespace lto {
@@ -109,6 +106,7 @@ public:
        const std::vector<ld::relocatable::File::Stab>* stabs() const override                  { return NULL; }
        bool                                                                            canScatterAtoms() const override                { return true; }
        LinkerOptionsList*                                                      linkerOptions() const override          { return NULL; }
+       const ToolVersionList&                                          toolVersions() const override           { return _toolVersions; }
        bool                                                                                            isThinLTO() const                       { return _isThinLTO; }
        void                                                                                            setIsThinLTO(bool ThinLTO)      { _isThinLTO = ThinLTO; }
        // fixme rdar://24734472 objCConstraint() and objcHasCategoryClassProperties()
@@ -148,6 +146,7 @@ private:
        ld::Fixup                                                               _fixupToInternal;
        ld::relocatable::File::DebugInfoKind    _debugInfo; 
        uint32_t                                                                _cpuSubType;
+       ToolVersionList                                                 _toolVersions;  // unused, may some day contain version of clang the created bitcode
 };
 
 //
@@ -550,7 +549,7 @@ void File::addToThinGenerator(thinlto_code_gen_t generator, int id) {
        assert(!_module && "Expected module to be disposed");
        std::string pathWithID = _path;
        pathWithID += std::to_string(id);
-       ::thinlto_codegen_add_module(generator, pathWithID.c_str(), (const char *)_content, _contentLength);
+       ::thinlto_codegen_add_module(generator, strdup(pathWithID.c_str()), (const char *)_content, _contentLength);
 }
 #endif
 
@@ -1146,7 +1145,7 @@ thinlto_code_gen_t Parser::init_thinlto_codegen(const std::vector<File*>&
                                const char* name = llvmAtom->name();
                                if ( deadllvmAtoms.find(name) == deadllvmAtoms.end() ) {
                                        if ( logMustPreserve )
-                                               fprintf(stderr, "lto_codegen_add_must_preserve_symbol(%s) because linker coalesce away and replace with a mach-o atom\n", name);
+                                               fprintf(stderr, "thinlto_codegen_add_must_preserve_symbol(%s) because linker coalesce away and replace with a mach-o atom\n", name);
                                        ::thinlto_codegen_add_must_preserve_symbol(thingenerator, name, strlen(name));
                                        deadllvmAtoms[name] = (Atom*)llvmAtom;
                                }
@@ -1167,15 +1166,15 @@ thinlto_code_gen_t Parser::init_thinlto_codegen(const std::vector<File*>&
                // 2 - included in nonLLVMRefs set.
                // If a symbol is not listed in exportList then LTO is free to optimize it away.
                if ( (atom->scope() == ld::Atom::scopeGlobal) && options.preserveAllGlobals ) {
-                       if ( logMustPreserve ) fprintf(stderr, "lto_codegen_add_must_preserve_symbol(%s) because global symbol\n", name);
+                       if ( logMustPreserve ) fprintf(stderr, "thinlto_codegen_add_must_preserve_symbol(%s) because global symbol\n", name);
                        ::thinlto_codegen_add_must_preserve_symbol(thingenerator, name, strlen(name));
                }
                else if ( nonLLVMRefs.find(name) != nonLLVMRefs.end() ) {
-                       if ( logMustPreserve ) fprintf(stderr, "lto_codegen_add_must_preserve_symbol(%s) because referenced from outside of ThinLTO\n", name);
+                       if ( logMustPreserve ) fprintf(stderr, "thinlto_codegen_add_must_preserve_symbol(%s) because referenced from outside of ThinLTO\n", name);
                        ::thinlto_codegen_add_must_preserve_symbol(thingenerator, name, strlen(name));
                }
                else if ( LLVMRefs.find(name) != LLVMRefs.end() ) {
-                       if ( logMustPreserve ) fprintf(stderr, "lto_codegen_add_must_preserve_symbol(%s) because referenced from another file\n", name);
+                       if ( logMustPreserve ) fprintf(stderr, "thinlto_codegen_add_cross_referenced_symbol(%s) because referenced from another file\n", name);
                        ::thinlto_codegen_add_cross_referenced_symbol(thingenerator, name, strlen(name));
                } else {
                        if ( logMustPreserve ) fprintf(stderr, "NOT preserving(%s)\n", name);
@@ -1264,7 +1263,7 @@ bool Parser::optimizeThinLTO(const std::vector<File*>&              files,
                        }
 
                        // Add the optimized bitcode to the codegen generator now.
-                       ::thinlto_codegen_add_module(thingenerator, tempMachoPath.c_str(), (const char *)machOFile.Buffer, machOFile.Size);
+                       ::thinlto_codegen_add_module(thingenerator, strdup(tempMachoPath.c_str()), (const char *)machOFile.Buffer, machOFile.Size);
                }
        }
 
@@ -1295,10 +1294,34 @@ bool Parser::optimizeThinLTO(const std::vector<File*>&              files,
        if ( numObjects == 0 )
                throwf("could not do ThinLTO codegen (thinlto_codegen_process didn't produce any object): '%s', using libLTO version '%s'", ::lto_get_error_message(), ::lto_get_version());
 
+       auto get_thinlto_buffer_or_load_file = [&] (unsigned ID) {
+#if LTO_API_VERSION >= 21
+               if ( useFileBasedAPI ) {
+                       const char* path = thinlto_module_get_object_file(thingenerator, ID);
+                       // map in whole file
+                       struct stat stat_buf;
+                       int fd = ::open(path, O_RDONLY, 0);
+                       if ( fd == -1 )
+                               throwf("can't open thinlto file '%s', errno=%d", path, errno);
+                       if ( ::fstat(fd, &stat_buf) != 0 )
+                               throwf("fstat thinlto file '%s' failed, errno=%d\n", path, errno);
+                       size_t len = stat_buf.st_size;
+                       if ( len < 20 )
+                               throwf("ThinLTO file '%s' too small (length=%zu)", path, len);
+                       const char* p = (const char*)::mmap(NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
+                       if ( p == (const char*)(-1) )
+                               throwf("can't map file, errno=%d", errno);
+                       ::close(fd);
+                       return LTOObjectBuffer{ p, len };
+               }
+#endif
+               return thinlto_module_get_object(thingenerator, ID);
+       };
+
        // if requested, save off objects files
        if ( options.saveTemps ) {
                for (unsigned bufID = 0; bufID < numObjects; ++bufID) {
-                       auto machOFile = thinlto_module_get_object(thingenerator, bufID);
+                       auto machOFile = get_thinlto_buffer_or_load_file(bufID);
                        std::string tempMachoPath = options.outputFilePath;
                        tempMachoPath += ".";
                        tempMachoPath += std::to_string(bufID);
@@ -1327,30 +1350,6 @@ bool Parser::optimizeThinLTO(const std::vector<File*>&              files,
                }
        }
 
-       auto get_thinlto_buffer_or_load_file = [&] (unsigned ID) {
-#if LTO_API_VERSION >= 21
-               if ( useFileBasedAPI ) {
-                       const char* path = thinlto_module_get_object_file(thingenerator, ID);
-                       // map in whole file
-                       struct stat stat_buf;
-                       int fd = ::open(path, O_RDONLY, 0);
-                       if ( fd == -1 )
-                               throwf("can't open thinlto file '%s', errno=%d", path, errno);
-                       if ( ::fstat(fd, &stat_buf) != 0 )
-                               throwf("fstat thinlto file '%s' failed, errno=%d\n", path, errno);
-                       size_t len = stat_buf.st_size;
-                       if ( len < 20 )
-                               throwf("ThinLTO file '%s' too small (length=%zu)", path, len);
-                       const char* p = (const char*)::mmap(NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
-                       if ( p == (const char*)(-1) )
-                               throwf("can't map file, errno=%d", errno);
-                       ::close(fd);
-                       return LTOObjectBuffer{ p, len };
-               }
-#endif
-               return thinlto_module_get_object(thingenerator, ID);
-       };
-
        auto ordinal = ld::File::Ordinal::LTOOrdinal().nextFileListOrdinal();
        for (unsigned bufID = 0; bufID < numObjects; ++bufID) {
                auto machOFile = get_thinlto_buffer_or_load_file(bufID);
@@ -1644,6 +1643,22 @@ const char* version()
        return ::lto_get_version();
 }
 
+//
+// used by "ld -v" to report static version of libLTO.dylib API being compiled
+//
+unsigned int static_api_version()
+{
+       return LTO_API_VERSION;
+}
+
+//
+// used by "ld -v" to report version of libLTO.dylib being used
+//
+unsigned int runtime_api_version()
+{
+       return ::lto_api_version();
+}
+
 
 //
 // used by ld for error reporting
index b582a8bb4733cfafdbaa71a3117779a83620f24c..a086548da109335baba59f284f30d3a951457cc6 100644 (file)
@@ -31,6 +31,10 @@ namespace lto {
 
 extern const char* version();
 
+extern unsigned int runtime_api_version();
+
+extern unsigned int static_api_version();
+
 extern bool libLTOisLoaded();
 
 extern const char* archName(const uint8_t* fileContent, uint64_t fileLength);
index 56b327ac097c595e803c963de111e75ae5209c85..b740c5540b111accd50110360e7fe8354320f2b9 100644 (file)
@@ -200,6 +200,14 @@ File<A>::File(const uint8_t* fileContent, uint64_t fileLength, const char* path,
                                this->_platformInDylib = cmd->cmd();
                                lcPlatform = Options::platformForLoadCommand(this->_platformInDylib);
                                break;
+                       case LC_BUILD_VERSION:
+                               {
+                                       const macho_build_version_command<P>* buildVersCmd = (macho_build_version_command<P>*)cmd;
+                                       this->_platformInDylib   = buildVersCmd->platform();
+                                       this->_minVersionInDylib = buildVersCmd->minos();
+                                       lcPlatform = (Options::Platform)this->_platformInDylib;
+                               }
+                               break;
                        case LC_CODE_SIGNATURE:
                                break;
                        case macho_segment_command<P>::CMD:
@@ -266,6 +274,7 @@ File<A>::File(const uint8_t* fileContent, uint64_t fileLength, const char* path,
                                if ( !this->_allowSimToMacOSXLinking ) {
                                        switch (platform) {
                                                case Options::kPlatformOSX:
+                                               case Options::kPlatform_bridgeOS:
                                                case Options::kPlatformiOS:
                                                        if ( lcPlatform == Options::kPlatformUnknown )
                                                                break;
@@ -305,6 +314,7 @@ File<A>::File(const uint8_t* fileContent, uint64_t fileLength, const char* path,
                        else {
                                switch (platform) {
                                        case Options::kPlatformOSX:
+                                       case Options::kPlatform_bridgeOS:
                                        case Options::kPlatformiOS:
                                                if ( lcPlatform == Options::kPlatformUnknown )
                                                        break;
@@ -557,7 +567,7 @@ void File<A>::addSymbol(const char* name, bool weakDef, bool tlv, pint_t address
                                                        this->_ignoreExports.insert(strdup(symName));
                                        }
                                        else if ( strncmp(symAction, "install_name$", 13) == 0 ) {
-                                               this->_dylibInstallPath = symName;
+                                               this->_dylibInstallPath = strdup(symName);
                                                this->_installPathOverride = true;
                                                // <rdar://problem/14448206> CoreGraphics redirects to ApplicationServices, but with wrong compat version
                                                if ( strcmp(this->_dylibInstallPath, "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices") == 0 )
@@ -764,7 +774,8 @@ bool isDylibFile(const uint8_t* fileContent, cpu_type_t* result, cpu_subtype_t*
        }
        if ( Parser<arm64>::validFile(fileContent, false) ) {
                *result = CPU_TYPE_ARM64;
-               *subResult = CPU_SUBTYPE_ARM64_ALL;
+               const auto* header = reinterpret_cast<const macho_header<Pointer32<LittleEndian>>*>(fileContent);
+               *subResult = header->cpusubtype();
                return true;
        }
        return false;
index c4ecd368dabcbc6a8f0b1b89667a4657ebd7f925..8a3e7922220a604fa0839a7b1b4a3ec7a7314470 100644 (file)
@@ -84,7 +84,7 @@ public:
                                                                                                _swiftVersion(0),
                                                                                                _cpuSubType(0),
                                                                                                _minOSVersion(0),
-                                                                                               _platform(0),
+                                                                                               _platform(Options::kPlatformUnknown),
                                                                                                _canScatterAtoms(false),
                                                                                                _objcHasCategoryClassPropertiesField(false),
                                                                                                _srcKind(kSourceUnknown) { }
@@ -95,7 +95,7 @@ public:
        virtual bool                                                                            justInTimeforEachAtom(const char* name, ld::File::AtomHandler&) const
                                                                                                                                                                        { return false; }
        virtual uint32_t                                                                        minOSVersion() const            { return _minOSVersion; }
-       virtual uint32_t                                                                        platformLoadCommand() const     { return _platform; }
+       virtual uint32_t                                                                        platform() const                        { return _platform; }
 
        // overrides of ld::relocatable::File 
        virtual ObjcConstraint                                                          objCConstraint() const                  { return _objConstraint; }
@@ -107,6 +107,7 @@ public:
        virtual bool                                                                            canScatterAtoms() const                 { return _canScatterAtoms; }
        virtual const char*                                                                     translationUnitSource() const;
        virtual LinkerOptionsList*                                                      linkerOptions() const                   { return &_linkerOptions; }
+       virtual const ToolVersionList&                                          toolVersions() const                    { return _toolVersions; }
        virtual uint8_t                                                                         swiftVersion() const                    { return _swiftVersion; }
        virtual ld::Bitcode*                                                            getBitcode() const                              { return _bitcode.get(); }
        virtual SourceKind                                                                      sourceKind() const                              { return _srcKind; }
@@ -141,12 +142,13 @@ private:
        uint8_t                                                                 _swiftVersion;
        uint32_t                                                                _cpuSubType;
        uint32_t                                                                _minOSVersion;
-       uint32_t                                                                _platform;
+       Options::Platform                                               _platform;
        bool                                                                    _canScatterAtoms;
        bool                                                                    _objcHasCategoryClassPropertiesField;
        std::vector<std::vector<const char*> >  _linkerOptions;
        std::unique_ptr<ld::Bitcode>                    _bitcode;
        SourceKind                                                              _srcKind;
+       ToolVersionList                                                 _toolVersions;
 };
 
 
@@ -2092,10 +2094,25 @@ bool Parser<A>::parseLoadCommands(Options::Platform platform, uint32_t linkMinOS
        #endif
                                if ( ignoreMismatchPlatform )
                                        break;
-                               _file->_platform = cmd->cmd();
                                lcPlatform = Options::platformForLoadCommand(cmd->cmd());
+                               _file->_platform = lcPlatform;
                                _file->_minOSVersion = ((macho_version_min_command<P>*)cmd)->version();
                                break;
+                       case LC_BUILD_VERSION:
+                               {
+                                       const macho_build_version_command<P>* buildVersCmd = (macho_build_version_command<P>*)cmd;
+                                       if ( ignoreMismatchPlatform )
+                                               break;
+                                       lcPlatform = (Options::Platform)buildVersCmd->platform();
+                                       _file->_platform = lcPlatform;
+                                       _file->_minOSVersion = buildVersCmd->minos();
+                                       const macho_build_tool_version<P>* entry = (macho_build_tool_version<P>*)((uint8_t*)cmd + sizeof(macho_build_version_command<P>));
+                                       for (uint32_t t=0; t < buildVersCmd->ntools(); ++t) {
+                                               _file->_toolVersions.push_back(std::make_pair(entry->tool(), entry->version()));
+                                               ++entry;
+                                       }
+                               }
+                               break;
                        case macho_segment_command<P>::CMD:
                                if ( segment != NULL )
                                        throw "more than one LC_SEGMENT found in object file";
@@ -2124,6 +2141,7 @@ bool Parser<A>::parseLoadCommands(Options::Platform platform, uint32_t linkMinOS
                                        if ( lcPlatform == Options::kPlatformUnknown )
                                                break;
                                        // fall through if the Platform is not Unknown
+                               case Options::kPlatform_bridgeOS:
                                case Options::kPlatformWatchOS:
                                        // Error when using bitcocde, warning otherwise.
                                        if (_usingBitcode)
@@ -2197,6 +2215,14 @@ Options::Platform Parser<A>::findPlatform(const macho_header<P>* header)
                                return Options::kPlatformOSX;
                        case LC_VERSION_MIN_IPHONEOS:
                                return Options::kPlatformiOS;
+                       case LC_VERSION_MIN_WATCHOS:
+                               return Options::kPlatformWatchOS;
+       #if SUPPORT_APPLE_TV
+                       case LC_VERSION_MIN_TVOS:
+                               return Options::kPlatform_tvOS;
+       #endif
+                       case LC_BUILD_VERSION:
+                               return (Options::Platform)((macho_build_version_command<P>*)cmd)->platform();
                }
                cmd = (const macho_load_command<P>*)(((char*)cmd)+cmd->cmdsize());
                if ( cmd > cmdsEnd )
@@ -7897,7 +7923,7 @@ bool isObjectFile(const uint8_t* fileContent, cpu_type_t* result, cpu_subtype_t*
        if ( mach_o::relocatable::Parser<arm64>::validFile(fileContent, false, 0) ) {
                const macho_header<Pointer64<LittleEndian> >* header = (const macho_header<Pointer64<LittleEndian> >*)fileContent;
                *result = CPU_TYPE_ARM64;
-               *subResult = CPU_SUBTYPE_ARM64_ALL;
+               *subResult = header->cpusubtype();
                *platform = Parser<arm64>::findPlatform(header);
                return true;
        }
index 0b83d410959e4e7a0b56c5a3e045f717438c8ec0..076736e714929eb6bafe0c297d3c7c382cb282d8 100644 (file)
@@ -92,6 +92,10 @@ static Options::Platform mapPlatform(tapi::Platform platform) {
                return Options::kPlatformWatchOS;
        case tapi::Platform::tvOS:
                return Options::kPlatform_tvOS;
+       #if ((TAPI_API_VERSION_MAJOR == 1 &&  TAPI_API_VERSION_MINOR >= 2) || (TAPI_API_VERSION_MAJOR > 1))
+       case tapi::Platform::bridgeOS:
+               return Options::kPlatform_bridgeOS;
+       #endif
        }
 
        return Options::kPlatformUnknown;
index c6bc8fb9701fbee26527336c491abe870a4d6a72..bba9b8e08e530ef8946f18068aff262a85c55994 100644 (file)
@@ -328,6 +328,7 @@ void doPass(const Options& opts, ld::Internal& state)
                 textAtoms.insert(pos, aliasAtom);
                 state.atomToSection[aliasAtom] = textSection;
                 replacementMap[dupAtom] = aliasAtom;
+                (const_cast<ld::Atom*>(dupAtom))->setCoalescedAway();
             }
         }
     }
index 0b08844d25ba4448e741ce7af1ced5ee575910f6..eddcbc96c26d0c655533f1130b13c8e40d178706 100644 (file)
@@ -462,6 +462,8 @@ void MachOChecker<A>::checkLoadCommands()
                        case LC_DATA_IN_CODE:
                        case LC_DYLIB_CODE_SIGN_DRS:
                        case LC_SOURCE_VERSION:
+                       case LC_NOTE:
+                       case LC_BUILD_VERSION:
                                break;
                        case LC_RPATH:
                                fHasLC_RPATH = true;
@@ -739,7 +741,7 @@ void MachOChecker<A>::checkLoadCommands()
                                        if ( fIndirectTableCount != 0  ) {
                                                if ( fDynamicSymbolTable->indirectsymoff() < linkEditSegment->fileoff() )
                                                        throw "indirect symbol table not in __LINKEDIT";
-                                               if ( (fDynamicSymbolTable->indirectsymoff()+fIndirectTableCount*8) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) )
+                                               if ( (fDynamicSymbolTable->indirectsymoff()+fIndirectTableCount*4) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) )
                                                        throw "indirect symbol table not in __LINKEDIT";
                                                if ( (fDynamicSymbolTable->indirectsymoff() % sizeof(pint_t)) != 0 )
                                                        throw "indirect symbol table not pointer aligned";
@@ -1544,13 +1546,11 @@ bool MachOChecker<A>::addressIsBindingSite(pint_t targetAddr)
                uint64_t segOffset = 0;
                uint32_t count;
                uint32_t skip;
-               uint8_t flags;
                const char* symbolName = NULL;
                int libraryOrdinal = 0;
                int segIndex;
                int64_t addend = 0;
                pint_t segStartAddr = 0;
-               pint_t addr;
                bool done = false;
                while ( !done && (p < end) ) {
                        uint8_t immediate = *p & BIND_IMMEDIATE_MASK;
index 5b264d1b3d0ba2b7246d8f51de6af1fd1794dcbb..70d4c9a6b37fe8a7663ab3aae763b232b926f29d 100644 (file)
@@ -215,7 +215,6 @@ void UnwindPrinter<A>::getSymbolTableInfo()
        const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)fHeader + sizeof(macho_header<P>));
        const macho_load_command<P>* cmd = cmds;
        for (uint32_t i = 0; i < cmd_count; ++i) {
-               uint32_t size = cmd->cmdsize();
                const uint8_t* endOfCmd = ((uint8_t*)cmd)+cmd->cmdsize();
                if ( endOfCmd > endOfLoadCommands )
                        throwf("load command #%d extends beyond the end of the load commands", i);
@@ -289,7 +288,6 @@ bool UnwindPrinter<A>::findUnwindSection()
        const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)fHeader + sizeof(macho_header<P>));
        const macho_load_command<P>* cmd = cmds;
        for (uint32_t i = 0; i < cmd_count; ++i) {
-               uint32_t size = cmd->cmdsize();
                const uint8_t* endOfCmd = ((uint8_t*)cmd)+cmd->cmdsize();
                if ( endOfCmd > endOfLoadCommands )
                        throwf("load command #%d extends beyond the end of the load commands", i);