[LLVM-C] Begin to Expose A More General Binary Interface

Summary:
Provides a new type, `LLVMBinaryRef`, and a binding to `llvm::object::createBinary` for more general interoperation with binary files than `LLVMObjectFileRef`.  It also provides the proper non-consuming API for input buffers and populates an out parameter for error handling if necessary - two things the previous API did not do.

In a follow-up, I'll define section and symbol iterators and begin to build upon the existing test infrastructure.

This patch is a first step towards deprecating that API and replacing it with something more robust.

Reviewers: deadalnix, whitequark

Reviewed By: whitequark

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60322

llvm-svn: 357822
This commit is contained in:
Robert Widmann 2019-04-05 21:36:50 +00:00
parent 40442658db
commit c76b621530
4 changed files with 76 additions and 0 deletions

View File

@ -39,6 +39,45 @@ typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef;
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);

View File

@ -163,6 +163,11 @@ typedef struct LLVMOpaqueModuleFlagEntry LLVMModuleFlagEntry;
*/
typedef struct LLVMOpaqueJITEventListener *LLVMJITEventListenerRef;
/**
* @see llvm::object::Binary
*/
typedef struct LLVMOpaqueBinary *LLVMBinaryRef;
/**
* @}
*/

View File

@ -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 @@ public:
}
};
// 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.

View File

@ -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 @@ wrap(const relocation_iterator *SI) {
(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);
}
// ObjectFile creation
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));