diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -155,6 +155,7 @@ uint64_t> callGraphProfile; bool allowMultipleDefinition; + bool fatLTOObjects; bool androidPackDynRelocs = false; bool armHasBlx = false; bool armHasMovtMovw = false; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1023,6 +1023,11 @@ args.hasFlag(OPT_allow_multiple_definition, OPT_no_allow_multiple_definition, false) || hasZOption(args, "muldefs"); + + config->fatLTOObjects = + args.hasFlag(OPT_fatlto_objects, + OPT_no_fatlto_objects, false); + config->androidMemtagHeap = args.hasFlag(OPT_android_memtag_heap, OPT_no_android_memtag_heap, false); config->androidMemtagStack = args.hasFlag(OPT_android_memtag_stack, @@ -2626,10 +2631,17 @@ // Now that we have a complete list of input files. // Beyond this point, no new files are added. // Aggregate all input sections into one place. - for (InputFile *f : ctx->objectFiles) - for (InputSectionBase *s : f->getSections()) - if (s && s != &InputSection::discarded) - inputSections.push_back(s); + for (InputFile *f : ctx->objectFiles) { + for (InputSectionBase *s : f->getSections()) { + if (s) { + // Do not aggregate the .fatlto section + if (s->name == ".fatlto") + continue; + if (s != &InputSection::discarded) + inputSections.push_back(s); + } + } + } for (BinaryFile *f : ctx->binaryFiles) for (InputSectionBase *s : f->getSections()) inputSections.push_back(cast(s)); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1715,6 +1715,13 @@ if (isBitcode(mb)) return make(mb, archiveName, offsetInArchive, /*lazy=*/false); + // If it is a fatLTO object file + if (config->fatLTOObjects) { + Expected fatLTOData = IRObjectFile::findBitcodeInMemBuffer(mb); + if (!errorToBool(fatLTOData.takeError())) + return make(*fatLTOData, archiveName, offsetInArchive, /*lazy=*/false); + } + switch (getELFKind(mb, archiveName)) { case ELF32LEKind: return make>(mb, archiveName); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -608,6 +608,10 @@ def thinlto_single_module_eq: JJ<"thinlto-single-module=">, HelpText<"Specific a single module to compile in ThinLTO mode, for debugging only">; +defm fatlto_objects: B<"fat-lto-objects", + "Use the embedded bitcode in the .fatlto section of the object file", + "Use the assembly in the object file (default)">; + def: J<"plugin-opt=O">, Alias, HelpText<"Alias for --lto-O">; def: F<"plugin-opt=debug-pass-manager">, Alias, HelpText<"Alias for --lto-debug-pass-manager">; diff --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp --- a/llvm/lib/Object/ObjectFile.cpp +++ b/llvm/lib/Object/ObjectFile.cpp @@ -79,7 +79,7 @@ bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const { Expected NameOrErr = getSectionName(Sec); if (NameOrErr) - return *NameOrErr == ".llvmbc"; + return *NameOrErr == ".llvmbc" || *NameOrErr == ".fatlto"; consumeError(NameOrErr.takeError()); return false; }