ObjectFile.cpp revision 341825
138494Sobrien//===- ObjectFile.cpp - File format independent object file ---------------===// 238494Sobrien// 338494Sobrien// The LLVM Compiler Infrastructure 438494Sobrien// 538494Sobrien// This file is distributed under the University of Illinois Open Source 638494Sobrien// License. See LICENSE.TXT for details. 738494Sobrien// 838494Sobrien//===----------------------------------------------------------------------===// 938494Sobrien// 1038494Sobrien// This file defines a file format independent ObjectFile class. 1138494Sobrien// 1238494Sobrien//===----------------------------------------------------------------------===// 1338494Sobrien 1438494Sobrien#include "llvm/Object/ObjectFile.h" 1538494Sobrien#include "llvm/ADT/StringRef.h" 1638494Sobrien#include "llvm/BinaryFormat/Magic.h" 1738494Sobrien#include "llvm/Object/Binary.h" 1838494Sobrien#include "llvm/Object/COFF.h" 1938494Sobrien#include "llvm/Object/Error.h" 2042633Sobrien#include "llvm/Object/MachO.h" 2138494Sobrien#include "llvm/Object/Wasm.h" 2238494Sobrien#include "llvm/Support/Error.h" 2338494Sobrien#include "llvm/Support/ErrorHandling.h" 2438494Sobrien#include "llvm/Support/ErrorOr.h" 2538494Sobrien#include "llvm/Support/FileSystem.h" 2638494Sobrien#include "llvm/Support/MemoryBuffer.h" 2738494Sobrien#include "llvm/Support/raw_ostream.h" 2838494Sobrien#include <algorithm> 2938494Sobrien#include <cstdint> 3038494Sobrien#include <memory> 3138494Sobrien#include <system_error> 3238494Sobrien 3338494Sobrienusing namespace llvm; 3438494Sobrienusing namespace object; 3538494Sobrien 3638494Sobrienvoid ObjectFile::anchor() {} 3738494Sobrien 3838494SobrienObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source) 3938494Sobrien : SymbolicFile(Type, Source) {} 4038494Sobrien 4142659Sobrienbool SectionRef::containsSymbol(SymbolRef S) const { 4238494Sobrien Expected<section_iterator> SymSec = S.getSection(); 4338494Sobrien if (!SymSec) { 4438494Sobrien // TODO: Actually report errors helpfully. 4538494Sobrien consumeError(SymSec.takeError()); 4638494Sobrien return false; 4738494Sobrien } 4838578Sobrien return *this == **SymSec; 4938494Sobrien} 5038494Sobrien 5138494Sobrienuint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const { 5238578Sobrien uint32_t Flags = getSymbolFlags(Ref); 5339007Sobrien if (Flags & SymbolRef::SF_Undefined) 5439007Sobrien return 0; 5539007Sobrien if (Flags & SymbolRef::SF_Common) 5639007Sobrien return getCommonSymbolSize(Ref); 5739007Sobrien return getSymbolValueImpl(Ref); 5839007Sobrien} 5939007Sobrien 6038578Sobrienstd::error_code ObjectFile::printSymbolName(raw_ostream &OS, 6139007Sobrien DataRefImpl Symb) const { 6238578Sobrien Expected<StringRef> Name = getSymbolName(Symb); 6338494Sobrien if (!Name) 6438494Sobrien return errorToErrorCode(Name.takeError()); 6538494Sobrien OS << *Name; 6638494Sobrien return std::error_code(); 6738494Sobrien} 6838494Sobrien 6938494Sobrienuint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; } 7038494Sobrien 7138494Sobrienbool ObjectFile::isSectionBitcode(DataRefImpl Sec) const { 7238494Sobrien StringRef SectName; 7338494Sobrien if (!getSectionName(Sec, SectName)) 7438494Sobrien return SectName == ".llvmbc"; 7538494Sobrien return false; 7638494Sobrien} 7738494Sobrien 7838494Sobrienbool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; } 7938494Sobrien 8038494Sobriensection_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { 8138494Sobrien return section_iterator(SectionRef(Sec, this)); 8238494Sobrien} 8338494Sobrien 8438494SobrienTriple ObjectFile::makeTriple() const { 8538494Sobrien Triple TheTriple; 8638494Sobrien auto Arch = getArch(); 8738494Sobrien TheTriple.setArch(Triple::ArchType(Arch)); 8838494Sobrien 8938494Sobrien // For ARM targets, try to use the build attributes to build determine 9038494Sobrien // the build target. Target features are also added, but later during 9138494Sobrien // disassembly. 9238494Sobrien if (Arch == Triple::arm || Arch == Triple::armeb) 9338494Sobrien setARMSubArch(TheTriple); 9438494Sobrien 9538494Sobrien // TheTriple defaults to ELF, and COFF doesn't have an environment: 9638494Sobrien // the best we can do here is indicate that it is mach-o. 9738494Sobrien if (isMachO()) 9838494Sobrien TheTriple.setObjectFormat(Triple::MachO); 9938494Sobrien 10038494Sobrien if (isCOFF()) { 10138494Sobrien const auto COFFObj = dyn_cast<COFFObjectFile>(this); 10238494Sobrien if (COFFObj->getArch() == Triple::thumb) 10338494Sobrien TheTriple.setTriple("thumbv7-windows"); 10438494Sobrien } 10538494Sobrien 10638494Sobrien return TheTriple; 10738494Sobrien} 10838494Sobrien 10938494SobrienExpected<std::unique_ptr<ObjectFile>> 11038494SobrienObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type) { 11138494Sobrien StringRef Data = Object.getBuffer(); 11238494Sobrien if (Type == file_magic::unknown) 11338494Sobrien Type = identify_magic(Data); 11438494Sobrien 11538494Sobrien switch (Type) { 11638494Sobrien case file_magic::unknown: 11738494Sobrien case file_magic::bitcode: 11838494Sobrien case file_magic::coff_cl_gl_object: 11938494Sobrien case file_magic::archive: 12038494Sobrien case file_magic::macho_universal_binary: 12138494Sobrien case file_magic::windows_resource: 12238494Sobrien case file_magic::pdb: 12338494Sobrien return errorCodeToError(object_error::invalid_file_type); 12438494Sobrien case file_magic::elf: 12538494Sobrien case file_magic::elf_relocatable: 12638494Sobrien case file_magic::elf_executable: 12738494Sobrien case file_magic::elf_shared_object: 12838494Sobrien case file_magic::elf_core: 12938494Sobrien return createELFObjectFile(Object); 13038494Sobrien case file_magic::macho_object: 13138494Sobrien case file_magic::macho_executable: 13238494Sobrien case file_magic::macho_fixed_virtual_memory_shared_lib: 13338494Sobrien case file_magic::macho_core: 13438494Sobrien case file_magic::macho_preload_executable: 13538494Sobrien case file_magic::macho_dynamically_linked_shared_lib: 13638494Sobrien case file_magic::macho_dynamic_linker: 13738494Sobrien case file_magic::macho_bundle: 13838494Sobrien case file_magic::macho_dynamically_linked_shared_lib_stub: 13938494Sobrien case file_magic::macho_dsym_companion: 14038494Sobrien case file_magic::macho_kext_bundle: 14138494Sobrien return createMachOObjectFile(Object); 14238494Sobrien case file_magic::coff_object: 14338494Sobrien case file_magic::coff_import_library: 14438494Sobrien case file_magic::pecoff_executable: 14538494Sobrien return createCOFFObjectFile(Object); 14638494Sobrien case file_magic::wasm_object: 14738494Sobrien return createWasmObjectFile(Object); 14838494Sobrien } 14938494Sobrien llvm_unreachable("Unexpected Object File Type"); 15038494Sobrien} 15138494Sobrien 15238494SobrienExpected<OwningBinary<ObjectFile>> 15338494SobrienObjectFile::createObjectFile(StringRef ObjectPath) { 15438494Sobrien ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 15538494Sobrien MemoryBuffer::getFile(ObjectPath); 15642633Sobrien if (std::error_code EC = FileOrErr.getError()) 15742633Sobrien return errorCodeToError(EC); 15842633Sobrien std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get()); 15942633Sobrien 16042633Sobrien Expected<std::unique_ptr<ObjectFile>> ObjOrErr = 16142633Sobrien createObjectFile(Buffer->getMemBufferRef()); 16242633Sobrien if (Error Err = ObjOrErr.takeError()) 16342633Sobrien return std::move(Err); 16442633Sobrien std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); 16542633Sobrien 16638494Sobrien return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer)); 16738494Sobrien} 16838494Sobrien