12754fe60SDimitry Andric //===- ObjectFile.cpp - File format independent object file -----*- C++ -*-===// 22754fe60SDimitry Andric // 32754fe60SDimitry Andric // The LLVM Compiler Infrastructure 42754fe60SDimitry Andric // 52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source 62754fe60SDimitry Andric // License. See LICENSE.TXT for details. 72754fe60SDimitry Andric // 82754fe60SDimitry Andric //===----------------------------------------------------------------------===// 92754fe60SDimitry Andric // 102754fe60SDimitry Andric // This file defines a file format independent ObjectFile class. 112754fe60SDimitry Andric // 122754fe60SDimitry Andric //===----------------------------------------------------------------------===// 132754fe60SDimitry Andric 1439d628a0SDimitry Andric #include "llvm/Object/COFF.h" 1539d628a0SDimitry Andric #include "llvm/Object/MachO.h" 162754fe60SDimitry Andric #include "llvm/Object/ObjectFile.h" 172754fe60SDimitry Andric #include "llvm/Support/ErrorHandling.h" 18f785676fSDimitry Andric #include "llvm/Support/FileSystem.h" 192754fe60SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 2091bc56edSDimitry Andric #include "llvm/Support/raw_ostream.h" 2191bc56edSDimitry Andric #include <system_error> 222754fe60SDimitry Andric 232754fe60SDimitry Andric using namespace llvm; 242754fe60SDimitry Andric using namespace object; 252754fe60SDimitry Andric 26dff0c46cSDimitry Andric void ObjectFile::anchor() { } 27dff0c46cSDimitry Andric 2839d628a0SDimitry Andric ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source) 2939d628a0SDimitry Andric : SymbolicFile(Type, Source) {} 3091bc56edSDimitry Andric 3191bc56edSDimitry Andric std::error_code ObjectFile::printSymbolName(raw_ostream &OS, 3291bc56edSDimitry Andric DataRefImpl Symb) const { 3391bc56edSDimitry Andric StringRef Name; 3491bc56edSDimitry Andric if (std::error_code EC = getSymbolName(Symb, Name)) 3591bc56edSDimitry Andric return EC; 3691bc56edSDimitry Andric OS << Name; 3791bc56edSDimitry Andric return object_error::success; 382754fe60SDimitry Andric } 392754fe60SDimitry Andric 4091bc56edSDimitry Andric std::error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI, 41284c1978SDimitry Andric uint32_t &Result) const { 42284c1978SDimitry Andric Result = 0; 43284c1978SDimitry Andric return object_error::success; 44284c1978SDimitry Andric } 45284c1978SDimitry Andric 46f785676fSDimitry Andric section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { 47f785676fSDimitry Andric return section_iterator(SectionRef(Sec, this)); 482754fe60SDimitry Andric } 49f785676fSDimitry Andric 5039d628a0SDimitry Andric ErrorOr<std::unique_ptr<ObjectFile>> 5139d628a0SDimitry Andric ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) { 5239d628a0SDimitry Andric StringRef Data = Object.getBuffer(); 5391bc56edSDimitry Andric if (Type == sys::fs::file_magic::unknown) 5439d628a0SDimitry Andric Type = sys::fs::identify_magic(Data); 55f785676fSDimitry Andric 56f785676fSDimitry Andric switch (Type) { 57f785676fSDimitry Andric case sys::fs::file_magic::unknown: 58f785676fSDimitry Andric case sys::fs::file_magic::bitcode: 59f785676fSDimitry Andric case sys::fs::file_magic::archive: 60f785676fSDimitry Andric case sys::fs::file_magic::macho_universal_binary: 61f785676fSDimitry Andric case sys::fs::file_magic::windows_resource: 6291bc56edSDimitry Andric return object_error::invalid_file_type; 6339d628a0SDimitry Andric case sys::fs::file_magic::elf: 64f785676fSDimitry Andric case sys::fs::file_magic::elf_relocatable: 65f785676fSDimitry Andric case sys::fs::file_magic::elf_executable: 66f785676fSDimitry Andric case sys::fs::file_magic::elf_shared_object: 67f785676fSDimitry Andric case sys::fs::file_magic::elf_core: 68f785676fSDimitry Andric return createELFObjectFile(Object); 69f785676fSDimitry Andric case sys::fs::file_magic::macho_object: 70f785676fSDimitry Andric case sys::fs::file_magic::macho_executable: 71f785676fSDimitry Andric case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: 72f785676fSDimitry Andric case sys::fs::file_magic::macho_core: 73f785676fSDimitry Andric case sys::fs::file_magic::macho_preload_executable: 74f785676fSDimitry Andric case sys::fs::file_magic::macho_dynamically_linked_shared_lib: 75f785676fSDimitry Andric case sys::fs::file_magic::macho_dynamic_linker: 76f785676fSDimitry Andric case sys::fs::file_magic::macho_bundle: 77f785676fSDimitry Andric case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: 78f785676fSDimitry Andric case sys::fs::file_magic::macho_dsym_companion: 79ff0cc061SDimitry Andric case sys::fs::file_magic::macho_kext_bundle: 80f785676fSDimitry Andric return createMachOObjectFile(Object); 81f785676fSDimitry Andric case sys::fs::file_magic::coff_object: 82f785676fSDimitry Andric case sys::fs::file_magic::coff_import_library: 83f785676fSDimitry Andric case sys::fs::file_magic::pecoff_executable: 8439d628a0SDimitry Andric return createCOFFObjectFile(Object); 85f785676fSDimitry Andric } 86f785676fSDimitry Andric llvm_unreachable("Unexpected Object File Type"); 872754fe60SDimitry Andric } 882754fe60SDimitry Andric 8939d628a0SDimitry Andric ErrorOr<OwningBinary<ObjectFile>> 9039d628a0SDimitry Andric ObjectFile::createObjectFile(StringRef ObjectPath) { 9191bc56edSDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 9291bc56edSDimitry Andric MemoryBuffer::getFile(ObjectPath); 9391bc56edSDimitry Andric if (std::error_code EC = FileOrErr.getError()) 9491bc56edSDimitry Andric return EC; 9539d628a0SDimitry Andric std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get()); 9639d628a0SDimitry Andric 9739d628a0SDimitry Andric ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = 9839d628a0SDimitry Andric createObjectFile(Buffer->getMemBufferRef()); 9939d628a0SDimitry Andric if (std::error_code EC = ObjOrErr.getError()) 10039d628a0SDimitry Andric return EC; 10139d628a0SDimitry Andric std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); 10239d628a0SDimitry Andric 10339d628a0SDimitry Andric return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer)); 1042754fe60SDimitry Andric } 105