Index: llvm/trunk/docs/BitCodeFormat.rst =================================================================== --- llvm/trunk/docs/BitCodeFormat.rst +++ llvm/trunk/docs/BitCodeFormat.rst @@ -467,10 +467,11 @@ ================================= Bitcode files for LLVM IR may also be wrapped in a native object file -(i.e. ELF, COFF, Mach-O). The bitcode must be stored in a section of the -object file named ``.llvmbc``. This wrapper format is useful for accommodating -LTO in compilation pipelines where intermediate objects must be native object -files which contain metadata in other sections. +(i.e. ELF, COFF, Mach-O). The bitcode must be stored in a section of the object +file named ``__LLVM,__bitcode`` for MachO and ``.llvmbc`` for the other object +formats. This wrapper format is useful for accommodating LTO in compilation +pipelines where intermediate objects must be native object files which contain +metadata in other sections. Not all tools support this format. Index: llvm/trunk/include/llvm/Object/MachO.h =================================================================== --- llvm/trunk/include/llvm/Object/MachO.h +++ llvm/trunk/include/llvm/Object/MachO.h @@ -226,6 +226,7 @@ bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; + bool isSectionBitcode(DataRefImpl Sec) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; Index: llvm/trunk/include/llvm/Object/ObjectFile.h =================================================================== --- llvm/trunk/include/llvm/Object/ObjectFile.h +++ llvm/trunk/include/llvm/Object/ObjectFile.h @@ -94,6 +94,7 @@ bool isData() const; bool isBSS() const; bool isVirtual() const; + bool isBitcode() const; bool containsSymbol(SymbolRef S) const; @@ -219,6 +220,7 @@ virtual bool isSectionBSS(DataRefImpl Sec) const = 0; // A section is 'virtual' if its contents aren't present in the object image. virtual bool isSectionVirtual(DataRefImpl Sec) const = 0; + virtual bool isSectionBitcode(DataRefImpl Sec) const; virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0; virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; @@ -296,6 +298,7 @@ static ErrorOr> createMachOObjectFile(MemoryBufferRef Object); + }; // Inline function definitions. @@ -394,6 +397,10 @@ return OwningObject->isSectionVirtual(SectionPimpl); } +inline bool SectionRef::isBitcode() const { + return OwningObject->isSectionBitcode(SectionPimpl); +} + inline relocation_iterator SectionRef::relocation_begin() const { return OwningObject->section_rel_begin(SectionPimpl); } Index: llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp +++ llvm/trunk/lib/Object/FunctionIndexObjectFile.cpp @@ -35,10 +35,7 @@ ErrorOr FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) { for (const SectionRef &Sec : Obj.sections()) { - StringRef SecName; - if (std::error_code EC = Sec.getName(SecName)) - return EC; - if (SecName == ".llvmbc") { + if (Sec.isBitcode()) { StringRef SecContents; if (std::error_code EC = Sec.getContents(SecContents)) return EC; Index: llvm/trunk/lib/Object/IRObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/IRObjectFile.cpp +++ llvm/trunk/lib/Object/IRObjectFile.cpp @@ -266,10 +266,7 @@ ErrorOr IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { for (const SectionRef &Sec : Obj.sections()) { - StringRef SecName; - if (std::error_code EC = Sec.getName(SecName)) - return EC; - if (SecName == ".llvmbc") { + if (Sec.isBitcode()) { StringRef SecContents; if (std::error_code EC = Sec.getContents(SecContents)) return EC; Index: llvm/trunk/lib/Object/MachOObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/MachOObjectFile.cpp +++ llvm/trunk/lib/Object/MachOObjectFile.cpp @@ -630,6 +630,14 @@ return false; } +bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const { + StringRef SegmentName = getSectionFinalSegmentName(Sec); + StringRef SectName; + if (!getSectionName(Sec, SectName)) + return (SegmentName == "__LLVM" && SectName == "__bitcode"); + return false; +} + relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { DataRefImpl Ret; Ret.d.a = Sec.d.a; Index: llvm/trunk/lib/Object/ObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/ObjectFile.cpp +++ llvm/trunk/lib/Object/ObjectFile.cpp @@ -55,6 +55,13 @@ uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; } +bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const { + StringRef SectName; + if (!getSectionName(Sec, SectName)) + return SectName == ".llvmbc"; + return false; +} + section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { return section_iterator(SectionRef(Sec, this)); } Index: llvm/trunk/test/LTO/X86/Inputs/bcsection.macho.s =================================================================== --- llvm/trunk/test/LTO/X86/Inputs/bcsection.macho.s +++ llvm/trunk/test/LTO/X86/Inputs/bcsection.macho.s @@ -1,2 +1,5 @@ -.section .llvmbc,.llvmbc +.section __FOO,__bitcode +.asciz "Wrong Section" + +.section __LLVM,__bitcode .incbin "bcsection.bc"