From 10039c02ea1d34d39fb3b66f522c53bb50751da5 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 18 Sep 2014 21:28:49 +0000 Subject: LTO: introduce object file-based on-disk module format. This format is simply a regular object file with the bitcode stored in a section named ".llvmbc", plus any number of other (non-allocated) sections. One immediate use case for this is to accommodate compilation processes which expect the object file to contain metadata in non-allocated sections, such as the ".go_export" section used by some Go compilers [1], although I imagine that in the future we could consider compiling parts of the module (such as large non-inlinable functions) directly into the object file to improve LTO efficiency. [1] http://golang.org/doc/install/gccgo#Imports Differential Revision: http://reviews.llvm.org/D4371 llvm-svn: 218078 --- llvm/lib/Object/IRObjectFile.cpp | 42 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'llvm/lib/Object/IRObjectFile.cpp') diff --git a/llvm/lib/Object/IRObjectFile.cpp b/llvm/lib/Object/IRObjectFile.cpp index 856f4c6..f3bea51 100644 --- a/llvm/lib/Object/IRObjectFile.cpp +++ b/llvm/lib/Object/IRObjectFile.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" @@ -264,11 +265,50 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const { return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } +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") { + StringRef SecContents; + if (std::error_code EC = Sec.getContents(SecContents)) + return EC; + return MemoryBufferRef(SecContents, Obj.getFileName()); + } + } + + return object_error::bitcode_section_not_found; +} + +ErrorOr IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { + sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); + switch (Type) { + case sys::fs::file_magic::bitcode: + return Object; + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::coff_object: { + ErrorOr> ObjFile = + ObjectFile::createObjectFile(Object, Type); + if (!ObjFile) + return ObjFile.getError(); + return findBitcodeInObject(*ObjFile->get()); + } + default: + return object_error::invalid_file_type; + } +} + ErrorOr> llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object, LLVMContext &Context) { + ErrorOr BCOrErr = findBitcodeInMemBuffer(Object); + if (!BCOrErr) + return BCOrErr.getError(); - std::unique_ptr Buff(MemoryBuffer::getMemBuffer(Object, false)); + std::unique_ptr Buff( + MemoryBuffer::getMemBuffer(BCOrErr.get(), false)); ErrorOr MOrErr = getLazyBitcodeModule(std::move(Buff), Context); if (std::error_code EC = MOrErr.getError()) -- cgit v1.1