]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/parsers/lto_file.cpp
ld64-236.3.tar.gz
[apple/ld64.git] / src / ld / parsers / lto_file.cpp
index 460dcf0b837da5d9751a7bcb76f0b06c91c073bd..3fe21f686cfb4458d1e74e718315d87c8c7e7587 100644 (file)
@@ -47,7 +47,6 @@
 #define __STDC_CONSTANT_MACROS 1
 #include "llvm-c/lto.h"
 
-
 namespace lto {
          
 
@@ -199,7 +198,8 @@ public:
        static bool                                             validFile(const uint8_t* fileContent, uint64_t fileLength, cpu_type_t architecture, cpu_subtype_t subarch);
        static const char*                              fileKind(const uint8_t* fileContent, uint64_t fileLength);
        static File*                                    parse(const uint8_t* fileContent, uint64_t fileLength, const char* path, 
-                                                                                       time_t modTime, ld::File::Ordinal ordinal, cpu_type_t architecture, cpu_subtype_t subarch, bool logAllFiles);
+                                                                                       time_t modTime, ld::File::Ordinal ordinal, cpu_type_t architecture, cpu_subtype_t subarch,
+                                                                                       bool logAllFiles, bool verboseOptimizationHints);
        static bool                                             libLTOisLoaded() { return (::lto_get_version() != NULL); }
        static bool                                             optimize(   const std::vector<const ld::Atom*>& allAtoms,
                                                                                                ld::Internal&                                           state,
@@ -213,6 +213,9 @@ public:
 private:
        static const char*                              tripletPrefixForArch(cpu_type_t arch);
        static ld::relocatable::File*   parseMachOFile(const uint8_t* p, size_t len, const OptimizeOptions& options);
+#if LTO_API_VERSION >= 7
+       static void ltoDiagnosticHandler(lto_codegen_diagnostic_severity_t, const char*, void*);
+#endif
 
        typedef std::unordered_set<const char*, ld::CStringHash, ld::CStringEquals>  CStringSet;
        typedef std::unordered_map<const char*, Atom*, ld::CStringHash, ld::CStringEquals> CStringToAtom;
@@ -276,7 +279,7 @@ const char* Parser::fileKind(const uint8_t* p, uint64_t fileLength)
 }
 
 File* Parser::parse(const uint8_t* fileContent, uint64_t fileLength, const char* path, time_t modTime, ld::File::Ordinal ordinal,
-                                                                                                       cpu_type_t architecture, cpu_subtype_t subarch, bool logAllFiles) 
+                                                                                                       cpu_type_t architecture, cpu_subtype_t subarch, bool logAllFiles, bool verboseOptimizationHints
 {
        File* f = new File(path, modTime, ordinal, fileContent, fileLength, architecture);
        _s_files.push_back(f);
@@ -295,6 +298,8 @@ ld::relocatable::File* Parser::parseMachOFile(const uint8_t* p, size_t len, cons
        objOpts.warnUnwindConversionProblems    = options.needsUnwindInfoSection;
        objOpts.keepDwarfUnwind         = options.keepDwarfUnwind;
        objOpts.forceDwarfConversion = false;
+       objOpts.neverConvertDwarf   = false;
+       objOpts.verboseOptimizationHints = options.verboseOptimizationHints;
        objOpts.subType                         = 0;
        
        // mach-o parsing is done in-memory, but need path for debug notes
@@ -461,6 +466,20 @@ struct CommandLineOrderFileSorter
 };
 
 
+#if LTO_API_VERSION >= 7
+void Parser::ltoDiagnosticHandler(lto_codegen_diagnostic_severity_t severity, const char* message, void*) 
+{
+       switch ( severity ) {
+               case LTO_DS_NOTE:
+               case LTO_DS_WARNING:
+                       warning("%s", message);
+                       break;
+               case LTO_DS_ERROR:
+                       throwf("%s", message);
+       }
+}
+#endif
+
 bool Parser::optimize(  const std::vector<const ld::Atom*>&    allAtoms,
                                                ld::Internal&                                           state,
                                                const OptimizeOptions&                          options,
@@ -483,6 +502,10 @@ bool Parser::optimize(  const std::vector<const ld::Atom*>&        allAtoms,
        
        // create optimizer and add each Reader
        lto_code_gen_t generator = ::lto_codegen_create();
+#if LTO_API_VERSION >= 7
+       lto_codegen_set_diagnostic_handler(generator, ltoDiagnosticHandler, NULL);
+#endif
+
        // <rdar://problem/12379604> The order that files are merged must match command line order
        std::sort(_s_files.begin(), _s_files.end(), CommandLineOrderFileSorter());
        ld::File::Ordinal lastOrdinal;
@@ -529,10 +552,7 @@ bool Parser::optimize(  const std::vector<const ld::Atom*>&        allAtoms,
                                                break;
                                        case ld::Fixup::bindingsIndirectlyBound:
                                                target = state.indirectBindingTable[fit->u.bindingIndex];
-                                               if ( target == NULL )
-                                                       throwf("'%s' in %s contains undefined reference", atom->name(), atom->file()->path());
-                                               assert(target != NULL);
-                                               if ( target->contentType() == ld::Atom::typeLTOtemporary )
+                                               if ( (target != NULL) && (target->contentType() == ld::Atom::typeLTOtemporary) )
                                                        nonLLVMRefs.insert(target->name());
                                        default:
                                                break;
@@ -742,6 +762,8 @@ bool Parser::optimize(  const std::vector<const ld::Atom*>& allAtoms,
 
 void Parser::AtomSyncer::doAtom(const ld::Atom& machoAtom)
 {
+       static const ld::Atom* lastProxiedAtom = NULL;
+       static const ld::File* lastProxiedFile = NULL;
        // update proxy atoms to point to real atoms and find new atoms
        const char* name = machoAtom.name();
        if ( machoAtom.scope() >= ld::Atom::scopeLinkageUnit ) {
@@ -749,6 +771,8 @@ void Parser::AtomSyncer::doAtom(const ld::Atom& machoAtom)
                if ( pos != _llvmAtoms.end() ) {
                        // turn Atom into a proxy for this mach-o atom
                        pos->second->setCompiledAtom(machoAtom);
+                       lastProxiedAtom = &machoAtom;
+                       lastProxiedFile = pos->second->file();
                }
                else {
                        // an atom of this name was not in the allAtoms list the linker gave us
@@ -774,6 +798,11 @@ void Parser::AtomSyncer::doAtom(const ld::Atom& machoAtom)
        else {
                // ld only knew about non-static atoms, so this one must be new
                _newAtoms.push_back(&machoAtom);
+               // <rdar://problem/15469363> if new static atom in same section as previous non-static atom, assign to same file as previous
+               if ( (lastProxiedAtom != NULL) && (lastProxiedAtom->section() == machoAtom.section()) ) {
+                       ld::Atom* ma = const_cast<ld::Atom*>(&machoAtom);
+                       ma->setFile(lastProxiedFile);
+               }
        }
        
        // adjust fixups to go through proxy atoms
@@ -844,11 +873,12 @@ bool isObjectFile(const uint8_t* fileContent, uint64_t fileLength, cpu_type_t ar
 //
 ld::relocatable::File* parse(const uint8_t* fileContent, uint64_t fileLength, 
                                                                const char* path, time_t modTime, ld::File::Ordinal ordinal,
-                                                               cpu_type_t architecture, cpu_subtype_t subarch, bool logAllFiles)
+                                                               cpu_type_t architecture, cpu_subtype_t subarch, bool logAllFiles,
+                                                               bool verboseOptimizationHints)
 {
        Mutex lock;
        if ( Parser::validFile(fileContent, fileLength, architecture, subarch) )
-               return Parser::parse(fileContent, fileLength, path, modTime, ordinal, architecture, subarch, logAllFiles);
+               return Parser::parse(fileContent, fileLength, path, modTime, ordinal, architecture, subarch, logAllFiles, verboseOptimizationHints);
        else
                return NULL;
 }