123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the C bindings to the file-format-independent object
- // library.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm-c/Object.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/Object/ObjectFile.h"
- #include "llvm/Object/MachOUniversal.h"
- #include "llvm/Support/MemAlloc.h"
- using namespace llvm;
- using namespace object;
- inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
- return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
- }
- inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
- return reinterpret_cast<LLVMObjectFileRef>(
- const_cast<OwningBinary<ObjectFile> *>(OF));
- }
- inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
- return reinterpret_cast<section_iterator*>(SI);
- }
- inline LLVMSectionIteratorRef
- wrap(const section_iterator *SI) {
- return reinterpret_cast<LLVMSectionIteratorRef>
- (const_cast<section_iterator*>(SI));
- }
- inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
- return reinterpret_cast<symbol_iterator*>(SI);
- }
- inline LLVMSymbolIteratorRef
- wrap(const symbol_iterator *SI) {
- return reinterpret_cast<LLVMSymbolIteratorRef>
- (const_cast<symbol_iterator*>(SI));
- }
- inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
- return reinterpret_cast<relocation_iterator*>(SI);
- }
- inline LLVMRelocationIteratorRef
- wrap(const relocation_iterator *SI) {
- return reinterpret_cast<LLVMRelocationIteratorRef>
- (const_cast<relocation_iterator*>(SI));
- }
- /*--.. Operations on binary files ..........................................--*/
- LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf,
- LLVMContextRef Context,
- char **ErrorMessage) {
- auto maybeContext = Context ? unwrap(Context) : nullptr;
- Expected<std::unique_ptr<Binary>> ObjOrErr(
- createBinary(unwrap(MemBuf)->getMemBufferRef(), maybeContext));
- if (!ObjOrErr) {
- *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
- return nullptr;
- }
- return wrap(ObjOrErr.get().release());
- }
- LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR) {
- auto Buf = unwrap(BR)->getMemoryBufferRef();
- return wrap(llvm::MemoryBuffer::getMemBuffer(
- Buf.getBuffer(), Buf.getBufferIdentifier(),
- /*RequiresNullTerminator*/false).release());
- }
- void LLVMDisposeBinary(LLVMBinaryRef BR) {
- delete unwrap(BR);
- }
- LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {
- class BinaryTypeMapper final : public Binary {
- public:
- static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) {
- switch (Kind) {
- case ID_Archive:
- return LLVMBinaryTypeArchive;
- case ID_MachOUniversalBinary:
- return LLVMBinaryTypeMachOUniversalBinary;
- case ID_COFFImportFile:
- return LLVMBinaryTypeCOFFImportFile;
- case ID_IR:
- return LLVMBinaryTypeIR;
- case ID_WinRes:
- return LLVMBinaryTypeWinRes;
- case ID_COFF:
- return LLVMBinaryTypeCOFF;
- case ID_ELF32L:
- return LLVMBinaryTypeELF32L;
- case ID_ELF32B:
- return LLVMBinaryTypeELF32B;
- case ID_ELF64L:
- return LLVMBinaryTypeELF64L;
- case ID_ELF64B:
- return LLVMBinaryTypeELF64B;
- case ID_MachO32L:
- return LLVMBinaryTypeMachO32L;
- case ID_MachO32B:
- return LLVMBinaryTypeMachO32B;
- case ID_MachO64L:
- return LLVMBinaryTypeMachO64L;
- case ID_MachO64B:
- return LLVMBinaryTypeMachO64B;
- case ID_Wasm:
- return LLVMBinaryTypeWasm;
- case ID_StartObjects:
- case ID_EndObjects:
- llvm_unreachable("Marker types are not valid binary kinds!");
- default:
- llvm_unreachable("Unknown binary kind!");
- }
- }
- };
- return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType());
- }
- LLVMBinaryRef LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR,
- const char *Arch,
- size_t ArchLen,
- char **ErrorMessage) {
- auto universal = cast<MachOUniversalBinary>(unwrap(BR));
- Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
- universal->getMachOObjectForArch({Arch, ArchLen}));
- if (!ObjOrErr) {
- *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
- return nullptr;
- }
- return wrap(ObjOrErr.get().release());
- }
- LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) {
- auto OF = cast<ObjectFile>(unwrap(BR));
- auto sections = OF->sections();
- if (sections.begin() == sections.end())
- return nullptr;
- return wrap(new section_iterator(sections.begin()));
- }
- LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR,
- LLVMSectionIteratorRef SI) {
- auto OF = cast<ObjectFile>(unwrap(BR));
- return (*unwrap(SI) == OF->section_end()) ? 1 : 0;
- }
- LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) {
- auto OF = cast<ObjectFile>(unwrap(BR));
- auto symbols = OF->symbols();
- if (symbols.begin() == symbols.end())
- return nullptr;
- return wrap(new symbol_iterator(symbols.begin()));
- }
- LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR,
- LLVMSymbolIteratorRef SI) {
- auto OF = cast<ObjectFile>(unwrap(BR));
- return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0;
- }
- // ObjectFile creation
- LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
- std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
- Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
- ObjectFile::createObjectFile(Buf->getMemBufferRef()));
- std::unique_ptr<ObjectFile> Obj;
- if (!ObjOrErr) {
- // TODO: Actually report errors helpfully.
- consumeError(ObjOrErr.takeError());
- return nullptr;
- }
- auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
- return wrap(Ret);
- }
- void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
- delete unwrap(ObjectFile);
- }
- // ObjectFile Section iterators
- LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
- OwningBinary<ObjectFile> *OB = unwrap(OF);
- section_iterator SI = OB->getBinary()->section_begin();
- return wrap(new section_iterator(SI));
- }
- void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
- delete unwrap(SI);
- }
- LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
- LLVMSectionIteratorRef SI) {
- OwningBinary<ObjectFile> *OB = unwrap(OF);
- return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
- }
- void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
- ++(*unwrap(SI));
- }
- void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
- LLVMSymbolIteratorRef Sym) {
- Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
- if (!SecOrErr) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(SecOrErr.takeError(), OS);
- report_fatal_error(Twine(OS.str()));
- }
- *unwrap(Sect) = *SecOrErr;
- }
- // ObjectFile Symbol iterators
- LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
- OwningBinary<ObjectFile> *OB = unwrap(OF);
- symbol_iterator SI = OB->getBinary()->symbol_begin();
- return wrap(new symbol_iterator(SI));
- }
- void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
- delete unwrap(SI);
- }
- LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
- LLVMSymbolIteratorRef SI) {
- OwningBinary<ObjectFile> *OB = unwrap(OF);
- return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
- }
- void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
- ++(*unwrap(SI));
- }
- // SectionRef accessors
- const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
- auto NameOrErr = (*unwrap(SI))->getName();
- if (!NameOrErr)
- report_fatal_error(NameOrErr.takeError());
- return NameOrErr->data();
- }
- uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
- return (*unwrap(SI))->getSize();
- }
- const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
- if (Expected<StringRef> E = (*unwrap(SI))->getContents())
- return E->data();
- else
- report_fatal_error(E.takeError());
- }
- uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
- return (*unwrap(SI))->getAddress();
- }
- LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
- LLVMSymbolIteratorRef Sym) {
- return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
- }
- // Section Relocation iterators
- LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
- relocation_iterator SI = (*unwrap(Section))->relocation_begin();
- return wrap(new relocation_iterator(SI));
- }
- void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
- delete unwrap(SI);
- }
- LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
- LLVMRelocationIteratorRef SI) {
- return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
- }
- void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
- ++(*unwrap(SI));
- }
- // SymbolRef accessors
- const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
- Expected<StringRef> Ret = (*unwrap(SI))->getName();
- if (!Ret) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(Ret.takeError(), OS);
- report_fatal_error(Twine(OS.str()));
- }
- return Ret->data();
- }
- uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
- Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
- if (!Ret) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(Ret.takeError(), OS);
- report_fatal_error(Twine(OS.str()));
- }
- return *Ret;
- }
- uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
- return (*unwrap(SI))->getCommonSize();
- }
- // RelocationRef accessors
- uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
- return (*unwrap(RI))->getOffset();
- }
- LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
- symbol_iterator ret = (*unwrap(RI))->getSymbol();
- return wrap(new symbol_iterator(ret));
- }
- uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
- return (*unwrap(RI))->getType();
- }
- // NOTE: Caller takes ownership of returned string.
- const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
- SmallVector<char, 0> ret;
- (*unwrap(RI))->getTypeName(ret);
- char *str = static_cast<char*>(safe_malloc(ret.size()));
- llvm::copy(ret, str);
- return str;
- }
- // NOTE: Caller takes ownership of returned string.
- const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
- return strdup("");
- }
|