diff --git a/llvm/include/llvm-c/Object.h b/llvm/include/llvm-c/Object.h --- a/llvm/include/llvm-c/Object.h +++ b/llvm/include/llvm-c/Object.h @@ -39,6 +39,45 @@ typedef struct LLVMOpaqueSymbolIterator *LLVMSymbolIteratorRef; typedef struct LLVMOpaqueRelocationIterator *LLVMRelocationIteratorRef; +/** + * Create a binary file from the given memory buffer. + * + * The exact type of the binary file will be inferred automatically, and the + * appropriate implementation selected. The context may be NULL except if + * the resulting file is an LLVM IR file. + * + * The memory buffer is not consumed by this function. It is the responsibilty + * of the caller to free it with \c LLVMDisposeMemoryBuffer. + * + * If NULL is returned, the \p ErrorMessage parameter is populated with the + * error's description. It is then the caller's responsibility to free this + * message by calling \c LLVMDisposeMessage. + * + * @see llvm::object::createBinary + */ +LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf, + LLVMContextRef Context, + char **ErrorMessage); + +/** + * Dispose of a binary file. + * + * The binary file does not own its backing buffer. It is the responsibilty + * of the caller to free it with \c LLVMDisposeMemoryBuffer. + */ +void LLVMDisposeBinary(LLVMBinaryRef BR); + +/** + * Retrieves a copy of the memory buffer associated with this object file. + * + * The returned buffer is merely a shallow copy and does not own the actual + * backing buffer of the binary. Nevertheless, it is the responsibility of the + * caller to free it with \c LLVMDisposeMemoryBuffer. + * + * @see llvm::object::getMemoryBufferRef + */ +LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR); + // ObjectFile creation LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf); void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile); diff --git a/llvm/include/llvm-c/Types.h b/llvm/include/llvm-c/Types.h --- a/llvm/include/llvm-c/Types.h +++ b/llvm/include/llvm-c/Types.h @@ -163,6 +163,11 @@ */ typedef struct LLVMOpaqueJITEventListener *LLVMJITEventListenerRef; +/** + * @see llvm::object::Binary + */ +typedef struct LLVMOpaqueBinary *LLVMBinaryRef; + /** * @} */ diff --git a/llvm/include/llvm/Object/Binary.h b/llvm/include/llvm/Object/Binary.h --- a/llvm/include/llvm/Object/Binary.h +++ b/llvm/include/llvm/Object/Binary.h @@ -13,6 +13,7 @@ #ifndef LLVM_OBJECT_BINARY_H #define LLVM_OBJECT_BINARY_H +#include "llvm-c/Types.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/Error.h" #include "llvm/Support/Error.h" @@ -162,6 +163,9 @@ } }; +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef) + /// Create a Binary from Source, autodetecting the file type. /// /// @param Source The data to create the Binary from. diff --git a/llvm/lib/Object/Object.cpp b/llvm/lib/Object/Object.cpp --- a/llvm/lib/Object/Object.cpp +++ b/llvm/lib/Object/Object.cpp @@ -13,6 +13,7 @@ #include "llvm-c/Object.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Object/ObjectFile.h" using namespace llvm; @@ -57,6 +58,33 @@ (const_cast(SI)); } +/*--.. Operations on binary files ..........................................--*/ + +LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf, + LLVMContextRef Context, + char **ErrorMessage) { + auto maybeContext = Context ? unwrap(Context) : nullptr; + Expected> 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); +} + // ObjectFile creation LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { std::unique_ptr Buf(unwrap(MemBuf));