Path: blob/main/contrib/llvm-project/llvm/lib/Object/Object.cpp
35232 views
//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//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 the C bindings to the file-format-independent object9// library.10//11//===----------------------------------------------------------------------===//1213#include "llvm-c/Object.h"14#include "llvm/ADT/SmallVector.h"15#include "llvm/IR/LLVMContext.h"16#include "llvm/Object/ObjectFile.h"17#include "llvm/Object/MachOUniversal.h"18#include "llvm/Support/MemAlloc.h"1920using namespace llvm;21using namespace object;2223inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {24return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);25}2627inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {28return reinterpret_cast<LLVMObjectFileRef>(29const_cast<OwningBinary<ObjectFile> *>(OF));30}3132inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {33return reinterpret_cast<section_iterator*>(SI);34}3536inline LLVMSectionIteratorRef37wrap(const section_iterator *SI) {38return reinterpret_cast<LLVMSectionIteratorRef>39(const_cast<section_iterator*>(SI));40}4142inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {43return reinterpret_cast<symbol_iterator*>(SI);44}4546inline LLVMSymbolIteratorRef47wrap(const symbol_iterator *SI) {48return reinterpret_cast<LLVMSymbolIteratorRef>49(const_cast<symbol_iterator*>(SI));50}5152inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {53return reinterpret_cast<relocation_iterator*>(SI);54}5556inline LLVMRelocationIteratorRef57wrap(const relocation_iterator *SI) {58return reinterpret_cast<LLVMRelocationIteratorRef>59(const_cast<relocation_iterator*>(SI));60}6162/*--.. Operations on binary files ..........................................--*/6364LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf,65LLVMContextRef Context,66char **ErrorMessage) {67auto maybeContext = Context ? unwrap(Context) : nullptr;68Expected<std::unique_ptr<Binary>> ObjOrErr(69createBinary(unwrap(MemBuf)->getMemBufferRef(), maybeContext));70if (!ObjOrErr) {71*ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());72return nullptr;73}7475return wrap(ObjOrErr.get().release());76}7778LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR) {79auto Buf = unwrap(BR)->getMemoryBufferRef();80return wrap(llvm::MemoryBuffer::getMemBuffer(81Buf.getBuffer(), Buf.getBufferIdentifier(),82/*RequiresNullTerminator*/false).release());83}8485void LLVMDisposeBinary(LLVMBinaryRef BR) {86delete unwrap(BR);87}8889LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {90class BinaryTypeMapper final : public Binary {91public:92static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) {93switch (Kind) {94case ID_Archive:95return LLVMBinaryTypeArchive;96case ID_MachOUniversalBinary:97return LLVMBinaryTypeMachOUniversalBinary;98case ID_COFFImportFile:99return LLVMBinaryTypeCOFFImportFile;100case ID_IR:101return LLVMBinaryTypeIR;102case ID_WinRes:103return LLVMBinaryTypeWinRes;104case ID_COFF:105return LLVMBinaryTypeCOFF;106case ID_ELF32L:107return LLVMBinaryTypeELF32L;108case ID_ELF32B:109return LLVMBinaryTypeELF32B;110case ID_ELF64L:111return LLVMBinaryTypeELF64L;112case ID_ELF64B:113return LLVMBinaryTypeELF64B;114case ID_MachO32L:115return LLVMBinaryTypeMachO32L;116case ID_MachO32B:117return LLVMBinaryTypeMachO32B;118case ID_MachO64L:119return LLVMBinaryTypeMachO64L;120case ID_MachO64B:121return LLVMBinaryTypeMachO64B;122case ID_Offload:123return LLVMBinaryTypeOffload;124case ID_Wasm:125return LLVMBinaryTypeWasm;126case ID_StartObjects:127case ID_EndObjects:128llvm_unreachable("Marker types are not valid binary kinds!");129default:130llvm_unreachable("Unknown binary kind!");131}132}133};134return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType());135}136137LLVMBinaryRef LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR,138const char *Arch,139size_t ArchLen,140char **ErrorMessage) {141auto universal = cast<MachOUniversalBinary>(unwrap(BR));142Expected<std::unique_ptr<ObjectFile>> ObjOrErr(143universal->getMachOObjectForArch({Arch, ArchLen}));144if (!ObjOrErr) {145*ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());146return nullptr;147}148return wrap(ObjOrErr.get().release());149}150151LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) {152auto OF = cast<ObjectFile>(unwrap(BR));153auto sections = OF->sections();154if (sections.begin() == sections.end())155return nullptr;156return wrap(new section_iterator(sections.begin()));157}158159LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR,160LLVMSectionIteratorRef SI) {161auto OF = cast<ObjectFile>(unwrap(BR));162return (*unwrap(SI) == OF->section_end()) ? 1 : 0;163}164165LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) {166auto OF = cast<ObjectFile>(unwrap(BR));167auto symbols = OF->symbols();168if (symbols.begin() == symbols.end())169return nullptr;170return wrap(new symbol_iterator(symbols.begin()));171}172173LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR,174LLVMSymbolIteratorRef SI) {175auto OF = cast<ObjectFile>(unwrap(BR));176return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0;177}178179// ObjectFile creation180LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {181std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));182Expected<std::unique_ptr<ObjectFile>> ObjOrErr(183ObjectFile::createObjectFile(Buf->getMemBufferRef()));184std::unique_ptr<ObjectFile> Obj;185if (!ObjOrErr) {186// TODO: Actually report errors helpfully.187consumeError(ObjOrErr.takeError());188return nullptr;189}190191auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));192return wrap(Ret);193}194195void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {196delete unwrap(ObjectFile);197}198199// ObjectFile Section iterators200LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {201OwningBinary<ObjectFile> *OB = unwrap(OF);202section_iterator SI = OB->getBinary()->section_begin();203return wrap(new section_iterator(SI));204}205206void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {207delete unwrap(SI);208}209210LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,211LLVMSectionIteratorRef SI) {212OwningBinary<ObjectFile> *OB = unwrap(OF);213return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;214}215216void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {217++(*unwrap(SI));218}219220void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,221LLVMSymbolIteratorRef Sym) {222Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();223if (!SecOrErr) {224std::string Buf;225raw_string_ostream OS(Buf);226logAllUnhandledErrors(SecOrErr.takeError(), OS);227report_fatal_error(Twine(OS.str()));228}229*unwrap(Sect) = *SecOrErr;230}231232// ObjectFile Symbol iterators233LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {234OwningBinary<ObjectFile> *OB = unwrap(OF);235symbol_iterator SI = OB->getBinary()->symbol_begin();236return wrap(new symbol_iterator(SI));237}238239void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {240delete unwrap(SI);241}242243LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,244LLVMSymbolIteratorRef SI) {245OwningBinary<ObjectFile> *OB = unwrap(OF);246return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;247}248249void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {250++(*unwrap(SI));251}252253// SectionRef accessors254const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {255auto NameOrErr = (*unwrap(SI))->getName();256if (!NameOrErr)257report_fatal_error(NameOrErr.takeError());258return NameOrErr->data();259}260261uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {262return (*unwrap(SI))->getSize();263}264265const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {266if (Expected<StringRef> E = (*unwrap(SI))->getContents())267return E->data();268else269report_fatal_error(E.takeError());270}271272uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {273return (*unwrap(SI))->getAddress();274}275276LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,277LLVMSymbolIteratorRef Sym) {278return (*unwrap(SI))->containsSymbol(**unwrap(Sym));279}280281// Section Relocation iterators282LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {283relocation_iterator SI = (*unwrap(Section))->relocation_begin();284return wrap(new relocation_iterator(SI));285}286287void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {288delete unwrap(SI);289}290291LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,292LLVMRelocationIteratorRef SI) {293return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;294}295296void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {297++(*unwrap(SI));298}299300301// SymbolRef accessors302const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {303Expected<StringRef> Ret = (*unwrap(SI))->getName();304if (!Ret) {305std::string Buf;306raw_string_ostream OS(Buf);307logAllUnhandledErrors(Ret.takeError(), OS);308report_fatal_error(Twine(OS.str()));309}310return Ret->data();311}312313uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {314Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();315if (!Ret) {316std::string Buf;317raw_string_ostream OS(Buf);318logAllUnhandledErrors(Ret.takeError(), OS);319report_fatal_error(Twine(OS.str()));320}321return *Ret;322}323324uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {325return (*unwrap(SI))->getCommonSize();326}327328// RelocationRef accessors329uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {330return (*unwrap(RI))->getOffset();331}332333LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {334symbol_iterator ret = (*unwrap(RI))->getSymbol();335return wrap(new symbol_iterator(ret));336}337338uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {339return (*unwrap(RI))->getType();340}341342// NOTE: Caller takes ownership of returned string.343const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {344SmallVector<char, 0> ret;345(*unwrap(RI))->getTypeName(ret);346char *str = static_cast<char*>(safe_malloc(ret.size()));347llvm::copy(ret, str);348return str;349}350351// NOTE: Caller takes ownership of returned string.352const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {353return strdup("");354}355356357358