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