brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · b0e4ea0 Raw
235 lines · cpp
1//===- ObjectFile.cpp - File format independent object file ---------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines a file format independent ObjectFile class.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Object/ObjectFile.h"14#include "llvm/ADT/StringRef.h"15#include "llvm/BinaryFormat/Magic.h"16#include "llvm/Object/Binary.h"17#include "llvm/Object/COFF.h"18#include "llvm/Object/DXContainer.h"19#include "llvm/Object/Error.h"20#include "llvm/Object/MachO.h"21#include "llvm/Object/Wasm.h"22#include "llvm/Support/Error.h"23#include "llvm/Support/ErrorHandling.h"24#include "llvm/Support/ErrorOr.h"25#include "llvm/Support/Format.h"26#include "llvm/Support/MemoryBuffer.h"27#include "llvm/Support/raw_ostream.h"28#include <cstdint>29#include <memory>30#include <system_error>31 32using namespace llvm;33using namespace object;34 35raw_ostream &object::operator<<(raw_ostream &OS, const SectionedAddress &Addr) {36  OS << "SectionedAddress{" << format_hex(Addr.Address, 10);37  if (Addr.SectionIndex != SectionedAddress::UndefSection)38    OS << ", " << Addr.SectionIndex;39  return OS << "}";40}41 42void ObjectFile::anchor() {}43 44ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source)45    : SymbolicFile(Type, Source) {}46 47bool SectionRef::containsSymbol(SymbolRef S) const {48  Expected<section_iterator> SymSec = S.getSection();49  if (!SymSec) {50    // TODO: Actually report errors helpfully.51    consumeError(SymSec.takeError());52    return false;53  }54  return *this == **SymSec;55}56 57Expected<uint64_t> ObjectFile::getSymbolValue(DataRefImpl Ref) const {58  uint32_t Flags;59  if (Error E = getSymbolFlags(Ref).moveInto(Flags))60    // TODO: Test this error.61    return std::move(E);62 63  if (Flags & SymbolRef::SF_Undefined)64    return 0;65  if (Flags & SymbolRef::SF_Common)66    return getCommonSymbolSize(Ref);67  return getSymbolValueImpl(Ref);68}69 70Error ObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const {71  Expected<StringRef> Name = getSymbolName(Symb);72  if (!Name)73    return Name.takeError();74  OS << *Name;75  return Error::success();76}77 78uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; }79 80bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {81  Expected<StringRef> NameOrErr = getSectionName(Sec);82  if (NameOrErr)83    return *NameOrErr == ".llvm.lto";84  consumeError(NameOrErr.takeError());85  return false;86}87 88bool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; }89 90bool ObjectFile::isBerkeleyText(DataRefImpl Sec) const {91  return isSectionText(Sec);92}93 94bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {95  return isSectionData(Sec);96}97 98bool ObjectFile::isDebugSection(DataRefImpl Sec) const { return false; }99 100bool ObjectFile::hasDebugInfo() const {101  return any_of(sections(),102                [](SectionRef Sec) { return Sec.isDebugSection(); });103}104 105Expected<section_iterator>106ObjectFile::getRelocatedSection(DataRefImpl Sec) const {107  return section_iterator(SectionRef(Sec, this));108}109 110Triple ObjectFile::makeTriple() const {111  Triple TheTriple;112  auto Arch = getArch();113  TheTriple.setArch(Triple::ArchType(Arch));114 115  auto OS = getOS();116  if (OS != Triple::UnknownOS)117    TheTriple.setOS(OS);118 119  // For ARM targets, try to use the build attributes to build determine120  // the build target. Target features are also added, but later during121  // disassembly.122  if (Arch == Triple::arm || Arch == Triple::armeb)123    setARMSubArch(TheTriple);124 125  // TheTriple defaults to ELF, and COFF doesn't have an environment:126  // something we can do here is indicate that it is mach-o.127  if (isMachO()) {128    TheTriple.setObjectFormat(Triple::MachO);129  } else if (isCOFF()) {130    const auto COFFObj = cast<COFFObjectFile>(this);131    if (COFFObj->getArch() == Triple::thumb)132      TheTriple.setTriple("thumbv7-windows");133  } else if (isXCOFF()) {134    // XCOFF implies AIX.135    TheTriple.setOS(Triple::AIX);136    TheTriple.setObjectFormat(Triple::XCOFF);137  } else if (isGOFF()) {138    TheTriple.setOS(Triple::ZOS);139    TheTriple.setObjectFormat(Triple::GOFF);140  } else if (TheTriple.isAMDGPU()) {141    TheTriple.setVendor(Triple::AMD);142  } else if (TheTriple.isNVPTX()) {143    TheTriple.setVendor(Triple::NVIDIA);144  }145 146  return TheTriple;147}148 149Expected<std::unique_ptr<ObjectFile>>150ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,151                             bool InitContent) {152  StringRef Data = Object.getBuffer();153  if (Type == file_magic::unknown)154    Type = identify_magic(Data);155 156  switch (Type) {157  case file_magic::unknown:158  case file_magic::bitcode:159  case file_magic::clang_ast:160  case file_magic::coff_cl_gl_object:161  case file_magic::archive:162  case file_magic::macho_universal_binary:163  case file_magic::windows_resource:164  case file_magic::pdb:165  case file_magic::minidump:166  case file_magic::goff_object:167  case file_magic::cuda_fatbinary:168  case file_magic::offload_binary:169  case file_magic::offload_bundle:170  case file_magic::offload_bundle_compressed:171  case file_magic::spirv_object:172    return errorCodeToError(object_error::invalid_file_type);173  case file_magic::tapi_file:174    return errorCodeToError(object_error::invalid_file_type);175  case file_magic::elf:176  case file_magic::elf_relocatable:177  case file_magic::elf_executable:178  case file_magic::elf_shared_object:179  case file_magic::elf_core:180    return createELFObjectFile(Object, InitContent);181  case file_magic::macho_object:182  case file_magic::macho_executable:183  case file_magic::macho_fixed_virtual_memory_shared_lib:184  case file_magic::macho_core:185  case file_magic::macho_preload_executable:186  case file_magic::macho_dynamically_linked_shared_lib:187  case file_magic::macho_dynamic_linker:188  case file_magic::macho_bundle:189  case file_magic::macho_dynamically_linked_shared_lib_stub:190  case file_magic::macho_dsym_companion:191  case file_magic::macho_kext_bundle:192  case file_magic::macho_file_set:193    return createMachOObjectFile(Object);194  case file_magic::coff_object:195  case file_magic::coff_import_library:196  case file_magic::pecoff_executable:197    return createCOFFObjectFile(Object);198  case file_magic::xcoff_object_32:199    return createXCOFFObjectFile(Object, Binary::ID_XCOFF32);200  case file_magic::xcoff_object_64:201    return createXCOFFObjectFile(Object, Binary::ID_XCOFF64);202  case file_magic::wasm_object:203    return createWasmObjectFile(Object);204  case file_magic::dxcontainer_object:205    return createDXContainerObjectFile(Object);206  }207  llvm_unreachable("Unexpected Object File Type");208}209 210Expected<OwningBinary<ObjectFile>>211ObjectFile::createObjectFile(StringRef ObjectPath) {212  ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =213      MemoryBuffer::getFile(ObjectPath);214  if (std::error_code EC = FileOrErr.getError())215    return errorCodeToError(EC);216  std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get());217 218  Expected<std::unique_ptr<ObjectFile>> ObjOrErr =219      createObjectFile(Buffer->getMemBufferRef());220  if (Error Err = ObjOrErr.takeError())221    return std::move(Err);222  std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());223 224  return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer));225}226 227bool ObjectFile::isReflectionSectionStrippable(228    llvm::binaryformat::Swift5ReflectionSectionKind ReflectionSectionKind)229    const {230  using llvm::binaryformat::Swift5ReflectionSectionKind;231  return ReflectionSectionKind == Swift5ReflectionSectionKind::fieldmd ||232         ReflectionSectionKind == Swift5ReflectionSectionKind::reflstr ||233         ReflectionSectionKind == Swift5ReflectionSectionKind::assocty;234}235