| //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // 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/Object/ObjectFile.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)); |
| } |
| |
| // 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, ""); |
| OS.flush(); |
| report_fatal_error(Buf); |
| } |
| *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) { |
| StringRef ret; |
| if (std::error_code ec = (*unwrap(SI))->getName(ret)) |
| report_fatal_error(ec.message()); |
| return ret.data(); |
| } |
| |
| uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { |
| return (*unwrap(SI))->getSize(); |
| } |
| |
| const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { |
| StringRef ret; |
| if (std::error_code ec = (*unwrap(SI))->getContents(ret)) |
| report_fatal_error(ec.message()); |
| return ret.data(); |
| } |
| |
| 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, ""); |
| OS.flush(); |
| report_fatal_error(Buf); |
| } |
| 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, ""); |
| OS.flush(); |
| report_fatal_error(Buf); |
| } |
| 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())); |
| std::copy(ret.begin(), ret.end(), str); |
| return str; |
| } |
| |
| // NOTE: Caller takes ownership of returned string. |
| const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { |
| return strdup(""); |
| } |
| |