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 313dac3a9bSDimitry Andric bool SectionRef::containsSymbol(SymbolRef S) const { 323ca95b02SDimitry Andric Expected<section_iterator> SymSec = S.getSection(); 333ca95b02SDimitry Andric if (!SymSec) { 343ca95b02SDimitry Andric // TODO: Actually report errors helpfully. 353ca95b02SDimitry Andric consumeError(SymSec.takeError()); 363dac3a9bSDimitry Andric return false; 373ca95b02SDimitry Andric } 387d523365SDimitry Andric return *this == **SymSec; 393dac3a9bSDimitry Andric } 403dac3a9bSDimitry Andric 41875ed548SDimitry Andric uint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const { 42875ed548SDimitry Andric uint32_t Flags = getSymbolFlags(Ref); 43875ed548SDimitry Andric if (Flags & SymbolRef::SF_Undefined) 44875ed548SDimitry Andric return 0; 45875ed548SDimitry Andric if (Flags & SymbolRef::SF_Common) 46875ed548SDimitry Andric return getCommonSymbolSize(Ref); 47875ed548SDimitry Andric return getSymbolValueImpl(Ref); 48875ed548SDimitry Andric } 49875ed548SDimitry Andric 5091bc56edSDimitry Andric std::error_code ObjectFile::printSymbolName(raw_ostream &OS, 5191bc56edSDimitry Andric DataRefImpl Symb) const { 523ca95b02SDimitry Andric Expected<StringRef> Name = getSymbolName(Symb); 533ca95b02SDimitry Andric if (!Name) 543ca95b02SDimitry Andric return errorToErrorCode(Name.takeError()); 553dac3a9bSDimitry Andric OS << *Name; 5697bc6c73SDimitry Andric return std::error_code(); 572754fe60SDimitry Andric } 582754fe60SDimitry Andric 5997bc6c73SDimitry Andric uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; } 60284c1978SDimitry Andric 613ca95b02SDimitry Andric bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const { 623ca95b02SDimitry Andric StringRef SectName; 633ca95b02SDimitry Andric if (!getSectionName(Sec, SectName)) 643ca95b02SDimitry Andric return SectName == ".llvmbc"; 653ca95b02SDimitry Andric return false; 663ca95b02SDimitry Andric } 673ca95b02SDimitry Andric 68f785676fSDimitry Andric section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { 69f785676fSDimitry Andric return section_iterator(SectionRef(Sec, this)); 702754fe60SDimitry Andric } 71f785676fSDimitry Andric 723ca95b02SDimitry Andric Expected<std::unique_ptr<ObjectFile>> 7339d628a0SDimitry Andric ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) { 7439d628a0SDimitry Andric StringRef Data = Object.getBuffer(); 7591bc56edSDimitry Andric if (Type == sys::fs::file_magic::unknown) 7639d628a0SDimitry Andric Type = sys::fs::identify_magic(Data); 77f785676fSDimitry Andric 78f785676fSDimitry Andric switch (Type) { 79f785676fSDimitry Andric case sys::fs::file_magic::unknown: 80f785676fSDimitry Andric case sys::fs::file_magic::bitcode: 81f785676fSDimitry Andric case sys::fs::file_magic::archive: 82f785676fSDimitry Andric case sys::fs::file_magic::macho_universal_binary: 83f785676fSDimitry Andric case sys::fs::file_magic::windows_resource: 843ca95b02SDimitry Andric return errorCodeToError(object_error::invalid_file_type); 8539d628a0SDimitry Andric case sys::fs::file_magic::elf: 86f785676fSDimitry Andric case sys::fs::file_magic::elf_relocatable: 87f785676fSDimitry Andric case sys::fs::file_magic::elf_executable: 88f785676fSDimitry Andric case sys::fs::file_magic::elf_shared_object: 89f785676fSDimitry Andric case sys::fs::file_magic::elf_core: 903ca95b02SDimitry Andric return errorOrToExpected(createELFObjectFile(Object)); 91f785676fSDimitry Andric case sys::fs::file_magic::macho_object: 92f785676fSDimitry Andric case sys::fs::file_magic::macho_executable: 93f785676fSDimitry Andric case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: 94f785676fSDimitry Andric case sys::fs::file_magic::macho_core: 95f785676fSDimitry Andric case sys::fs::file_magic::macho_preload_executable: 96f785676fSDimitry Andric case sys::fs::file_magic::macho_dynamically_linked_shared_lib: 97f785676fSDimitry Andric case sys::fs::file_magic::macho_dynamic_linker: 98f785676fSDimitry Andric case sys::fs::file_magic::macho_bundle: 99f785676fSDimitry Andric case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: 100f785676fSDimitry Andric case sys::fs::file_magic::macho_dsym_companion: 101ff0cc061SDimitry Andric case sys::fs::file_magic::macho_kext_bundle: 102f785676fSDimitry Andric return createMachOObjectFile(Object); 103f785676fSDimitry Andric case sys::fs::file_magic::coff_object: 104f785676fSDimitry Andric case sys::fs::file_magic::coff_import_library: 105f785676fSDimitry Andric case sys::fs::file_magic::pecoff_executable: 1063ca95b02SDimitry Andric return errorOrToExpected(createCOFFObjectFile(Object)); 107f785676fSDimitry Andric } 108f785676fSDimitry Andric llvm_unreachable("Unexpected Object File Type"); 1092754fe60SDimitry Andric } 1102754fe60SDimitry Andric 1113ca95b02SDimitry Andric Expected<OwningBinary<ObjectFile>> 11239d628a0SDimitry Andric ObjectFile::createObjectFile(StringRef ObjectPath) { 11391bc56edSDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 11491bc56edSDimitry Andric MemoryBuffer::getFile(ObjectPath); 11591bc56edSDimitry Andric if (std::error_code EC = FileOrErr.getError()) 1163ca95b02SDimitry Andric return errorCodeToError(EC); 11739d628a0SDimitry Andric std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get()); 11839d628a0SDimitry Andric 1193ca95b02SDimitry Andric Expected<std::unique_ptr<ObjectFile>> ObjOrErr = 12039d628a0SDimitry Andric createObjectFile(Buffer->getMemBufferRef()); 1213ca95b02SDimitry Andric if (!ObjOrErr) 1223ca95b02SDimitry Andric ObjOrErr.takeError(); 12339d628a0SDimitry Andric std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); 12439d628a0SDimitry Andric 12539d628a0SDimitry Andric return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer)); 1262754fe60SDimitry Andric } 127