brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.0 KiB · 112927e Raw
358 lines · cpp
1//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//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 the C bindings to the file-format-independent object10// library.11//12//===----------------------------------------------------------------------===//13 14#include "llvm-c/Object.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/IR/LLVMContext.h"17#include "llvm/Object/ObjectFile.h"18#include "llvm/Object/MachOUniversal.h"19#include "llvm/Support/MemAlloc.h"20 21using namespace llvm;22using namespace object;23 24inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {25  return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);26}27 28inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {29  return reinterpret_cast<LLVMObjectFileRef>(30      const_cast<OwningBinary<ObjectFile> *>(OF));31}32 33inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {34  return reinterpret_cast<section_iterator*>(SI);35}36 37inline LLVMSectionIteratorRef38wrap(const section_iterator *SI) {39  return reinterpret_cast<LLVMSectionIteratorRef>40    (const_cast<section_iterator*>(SI));41}42 43inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {44  return reinterpret_cast<symbol_iterator*>(SI);45}46 47inline LLVMSymbolIteratorRef48wrap(const symbol_iterator *SI) {49  return reinterpret_cast<LLVMSymbolIteratorRef>50    (const_cast<symbol_iterator*>(SI));51}52 53inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {54  return reinterpret_cast<relocation_iterator*>(SI);55}56 57inline LLVMRelocationIteratorRef58wrap(const relocation_iterator *SI) {59  return reinterpret_cast<LLVMRelocationIteratorRef>60    (const_cast<relocation_iterator*>(SI));61}62 63/*--.. Operations on binary files ..........................................--*/64 65LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf,66                               LLVMContextRef Context,67                               char **ErrorMessage) {68  auto maybeContext = Context ? unwrap(Context) : nullptr;69  Expected<std::unique_ptr<Binary>> ObjOrErr(70      createBinary(unwrap(MemBuf)->getMemBufferRef(), maybeContext));71  if (!ObjOrErr) {72    *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());73    return nullptr;74  }75 76  return wrap(ObjOrErr.get().release());77}78 79LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR) {80  auto Buf = unwrap(BR)->getMemoryBufferRef();81  return wrap(llvm::MemoryBuffer::getMemBuffer(82                Buf.getBuffer(), Buf.getBufferIdentifier(),83                /*RequiresNullTerminator*/false).release());84}85 86void LLVMDisposeBinary(LLVMBinaryRef BR) {87  delete unwrap(BR);88}89 90LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {91  class BinaryTypeMapper final : public Binary {92  public:93    static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) {94      switch (Kind) {95      case ID_Archive:96        return LLVMBinaryTypeArchive;97      case ID_MachOUniversalBinary:98        return LLVMBinaryTypeMachOUniversalBinary;99      case ID_COFFImportFile:100        return LLVMBinaryTypeCOFFImportFile;101      case ID_IR:102        return LLVMBinaryTypeIR;103      case ID_WinRes:104        return LLVMBinaryTypeWinRes;105      case ID_COFF:106        return LLVMBinaryTypeCOFF;107      case ID_ELF32L:108        return LLVMBinaryTypeELF32L;109      case ID_ELF32B:110        return LLVMBinaryTypeELF32B;111      case ID_ELF64L:112        return LLVMBinaryTypeELF64L;113      case ID_ELF64B:114        return LLVMBinaryTypeELF64B;115      case ID_MachO32L:116        return LLVMBinaryTypeMachO32L;117      case ID_MachO32B:118        return LLVMBinaryTypeMachO32B;119      case ID_MachO64L:120        return LLVMBinaryTypeMachO64L;121      case ID_MachO64B:122        return LLVMBinaryTypeMachO64B;123      case ID_Offload:124        return LLVMBinaryTypeOffload;125      case ID_Wasm:126        return LLVMBinaryTypeWasm;127      case ID_DXContainer:128        return LLVMBinaryTypeDXcontainer;129      case ID_StartObjects:130      case ID_EndObjects:131        llvm_unreachable("Marker types are not valid binary kinds!");132      default:133        llvm_unreachable("Unknown binary kind!");134      }135    }136  };137  return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType());138}139 140LLVMBinaryRef LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR,141                                                        const char *Arch,142                                                        size_t ArchLen,143                                                        char **ErrorMessage) {144  auto universal = cast<MachOUniversalBinary>(unwrap(BR));145  Expected<std::unique_ptr<ObjectFile>> ObjOrErr(146      universal->getMachOObjectForArch({Arch, ArchLen}));147  if (!ObjOrErr) {148    *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());149    return nullptr;150  }151  return wrap(ObjOrErr.get().release());152}153 154LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) {155  auto OF = cast<ObjectFile>(unwrap(BR));156  auto sections = OF->sections();157  if (sections.begin() == sections.end())158    return nullptr;159  return wrap(new section_iterator(sections.begin()));160}161 162LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR,163                                              LLVMSectionIteratorRef SI) {164  auto OF = cast<ObjectFile>(unwrap(BR));165  return (*unwrap(SI) == OF->section_end()) ? 1 : 0;166}167 168LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) {169  auto OF = cast<ObjectFile>(unwrap(BR));170  auto symbols = OF->symbols();171  if (symbols.begin() == symbols.end())172    return nullptr;173  return wrap(new symbol_iterator(symbols.begin()));174}175 176LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR,177                                             LLVMSymbolIteratorRef SI) {178  auto OF = cast<ObjectFile>(unwrap(BR));179  return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0;180}181 182// ObjectFile creation183LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {184  std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));185  Expected<std::unique_ptr<ObjectFile>> ObjOrErr(186      ObjectFile::createObjectFile(Buf->getMemBufferRef()));187  if (!ObjOrErr) {188    // TODO: Actually report errors helpfully.189    consumeError(ObjOrErr.takeError());190    return nullptr;191  }192 193  auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));194  return wrap(Ret);195}196 197void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {198  delete unwrap(ObjectFile);199}200 201// ObjectFile Section iterators202LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {203  OwningBinary<ObjectFile> *OB = unwrap(OF);204  section_iterator SI = OB->getBinary()->section_begin();205  return wrap(new section_iterator(SI));206}207 208void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {209  delete unwrap(SI);210}211 212LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,213                                    LLVMSectionIteratorRef SI) {214  OwningBinary<ObjectFile> *OB = unwrap(OF);215  return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;216}217 218void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {219  ++(*unwrap(SI));220}221 222void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,223                                 LLVMSymbolIteratorRef Sym) {224  Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();225  if (!SecOrErr) {226   std::string Buf;227   raw_string_ostream OS(Buf);228   logAllUnhandledErrors(SecOrErr.takeError(), OS);229   report_fatal_error(Twine(OS.str()));230  }231  *unwrap(Sect) = *SecOrErr;232}233 234// ObjectFile Symbol iterators235LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {236  OwningBinary<ObjectFile> *OB = unwrap(OF);237  symbol_iterator SI = OB->getBinary()->symbol_begin();238  return wrap(new symbol_iterator(SI));239}240 241void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {242  delete unwrap(SI);243}244 245LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,246                                   LLVMSymbolIteratorRef SI) {247  OwningBinary<ObjectFile> *OB = unwrap(OF);248  return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;249}250 251void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {252  ++(*unwrap(SI));253}254 255// SectionRef accessors256const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {257  auto NameOrErr = (*unwrap(SI))->getName();258  if (!NameOrErr)259    report_fatal_error(NameOrErr.takeError());260  return NameOrErr->data();261}262 263uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {264  return (*unwrap(SI))->getSize();265}266 267const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {268  if (Expected<StringRef> E = (*unwrap(SI))->getContents())269    return E->data();270  else271    report_fatal_error(E.takeError());272}273 274uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {275  return (*unwrap(SI))->getAddress();276}277 278LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,279                                 LLVMSymbolIteratorRef Sym) {280  return (*unwrap(SI))->containsSymbol(**unwrap(Sym));281}282 283// Section Relocation iterators284LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {285  relocation_iterator SI = (*unwrap(Section))->relocation_begin();286  return wrap(new relocation_iterator(SI));287}288 289void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {290  delete unwrap(SI);291}292 293LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,294                                       LLVMRelocationIteratorRef SI) {295  return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;296}297 298void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {299  ++(*unwrap(SI));300}301 302 303// SymbolRef accessors304const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {305  Expected<StringRef> Ret = (*unwrap(SI))->getName();306  if (!Ret) {307    std::string Buf;308    raw_string_ostream OS(Buf);309    logAllUnhandledErrors(Ret.takeError(), OS);310    report_fatal_error(Twine(OS.str()));311  }312  return Ret->data();313}314 315uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {316  Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();317  if (!Ret) {318    std::string Buf;319    raw_string_ostream OS(Buf);320    logAllUnhandledErrors(Ret.takeError(), OS);321    report_fatal_error(Twine(OS.str()));322  }323  return *Ret;324}325 326uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {327  return (*unwrap(SI))->getCommonSize();328}329 330// RelocationRef accessors331uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {332  return (*unwrap(RI))->getOffset();333}334 335LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {336  symbol_iterator ret = (*unwrap(RI))->getSymbol();337  return wrap(new symbol_iterator(ret));338}339 340uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {341  return (*unwrap(RI))->getType();342}343 344// NOTE: Caller takes ownership of returned string.345const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {346  SmallVector<char, 0> ret;347  (*unwrap(RI))->getTypeName(ret);348  char *str = static_cast<char*>(safe_malloc(ret.size()));349  llvm::copy(ret, str);350  return str;351}352 353// NOTE: Caller takes ownership of returned string.354const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {355  return strdup("");356}357 358