1218885Sdim//===- ObjectFile.cpp - File format independent object file -----*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file defines a file format independent ObjectFile class. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14280031Sdim#include "llvm/Object/COFF.h" 15280031Sdim#include "llvm/Object/MachO.h" 16218885Sdim#include "llvm/Object/ObjectFile.h" 17218885Sdim#include "llvm/Support/ErrorHandling.h" 18261991Sdim#include "llvm/Support/FileSystem.h" 19218885Sdim#include "llvm/Support/MemoryBuffer.h" 20276479Sdim#include "llvm/Support/raw_ostream.h" 21276479Sdim#include <system_error> 22218885Sdim 23218885Sdimusing namespace llvm; 24218885Sdimusing namespace object; 25218885Sdim 26234353Sdimvoid ObjectFile::anchor() { } 27234353Sdim 28280031SdimObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source) 29280031Sdim : SymbolicFile(Type, Source) {} 30276479Sdim 31288943Sdimbool SectionRef::containsSymbol(SymbolRef S) const { 32296417Sdim ErrorOr<section_iterator> SymSec = S.getSection(); 33296417Sdim if (!SymSec) 34288943Sdim return false; 35296417Sdim return *this == **SymSec; 36288943Sdim} 37288943Sdim 38288943Sdimuint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const { 39288943Sdim uint32_t Flags = getSymbolFlags(Ref); 40288943Sdim if (Flags & SymbolRef::SF_Undefined) 41288943Sdim return 0; 42288943Sdim if (Flags & SymbolRef::SF_Common) 43288943Sdim return getCommonSymbolSize(Ref); 44288943Sdim return getSymbolValueImpl(Ref); 45288943Sdim} 46288943Sdim 47276479Sdimstd::error_code ObjectFile::printSymbolName(raw_ostream &OS, 48276479Sdim DataRefImpl Symb) const { 49288943Sdim ErrorOr<StringRef> Name = getSymbolName(Symb); 50288943Sdim if (std::error_code EC = Name.getError()) 51276479Sdim return EC; 52288943Sdim OS << *Name; 53288943Sdim return std::error_code(); 54218885Sdim} 55218885Sdim 56288943Sdimuint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; } 57251662Sdim 58261991Sdimsection_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { 59261991Sdim return section_iterator(SectionRef(Sec, this)); 60261991Sdim} 61261991Sdim 62280031SdimErrorOr<std::unique_ptr<ObjectFile>> 63280031SdimObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) { 64280031Sdim StringRef Data = Object.getBuffer(); 65276479Sdim if (Type == sys::fs::file_magic::unknown) 66280031Sdim Type = sys::fs::identify_magic(Data); 67261991Sdim 68261991Sdim switch (Type) { 69261991Sdim case sys::fs::file_magic::unknown: 70261991Sdim case sys::fs::file_magic::bitcode: 71261991Sdim case sys::fs::file_magic::archive: 72261991Sdim case sys::fs::file_magic::macho_universal_binary: 73261991Sdim case sys::fs::file_magic::windows_resource: 74276479Sdim return object_error::invalid_file_type; 75280031Sdim case sys::fs::file_magic::elf: 76261991Sdim case sys::fs::file_magic::elf_relocatable: 77261991Sdim case sys::fs::file_magic::elf_executable: 78261991Sdim case sys::fs::file_magic::elf_shared_object: 79261991Sdim case sys::fs::file_magic::elf_core: 80261991Sdim return createELFObjectFile(Object); 81261991Sdim case sys::fs::file_magic::macho_object: 82261991Sdim case sys::fs::file_magic::macho_executable: 83261991Sdim case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: 84261991Sdim case sys::fs::file_magic::macho_core: 85261991Sdim case sys::fs::file_magic::macho_preload_executable: 86261991Sdim case sys::fs::file_magic::macho_dynamically_linked_shared_lib: 87261991Sdim case sys::fs::file_magic::macho_dynamic_linker: 88261991Sdim case sys::fs::file_magic::macho_bundle: 89261991Sdim case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: 90261991Sdim case sys::fs::file_magic::macho_dsym_companion: 91288943Sdim case sys::fs::file_magic::macho_kext_bundle: 92261991Sdim return createMachOObjectFile(Object); 93261991Sdim case sys::fs::file_magic::coff_object: 94261991Sdim case sys::fs::file_magic::coff_import_library: 95261991Sdim case sys::fs::file_magic::pecoff_executable: 96280031Sdim return createCOFFObjectFile(Object); 97261991Sdim } 98261991Sdim llvm_unreachable("Unexpected Object File Type"); 99218885Sdim} 100218885Sdim 101280031SdimErrorOr<OwningBinary<ObjectFile>> 102280031SdimObjectFile::createObjectFile(StringRef ObjectPath) { 103276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 104276479Sdim MemoryBuffer::getFile(ObjectPath); 105276479Sdim if (std::error_code EC = FileOrErr.getError()) 106276479Sdim return EC; 107280031Sdim std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get()); 108280031Sdim 109280031Sdim ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = 110280031Sdim createObjectFile(Buffer->getMemBufferRef()); 111280031Sdim if (std::error_code EC = ObjOrErr.getError()) 112280031Sdim return EC; 113280031Sdim std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); 114280031Sdim 115280031Sdim return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer)); 116218885Sdim} 117