1*0b57cec5SDimitry Andric //===-- BitReader.cpp -----------------------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "llvm-c/BitReader.h" 10*0b57cec5SDimitry Andric #include "llvm-c/Core.h" 11*0b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h" 12*0b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 13*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 14*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 15*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 16*0b57cec5SDimitry Andric #include <cstring> 17*0b57cec5SDimitry Andric #include <string> 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric using namespace llvm; 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric /* Builds a module from the bitcode in the specified memory buffer, returning a 22*0b57cec5SDimitry Andric reference to the module via the OutModule parameter. Returns 0 on success. 23*0b57cec5SDimitry Andric Optionally returns a human-readable error message via OutMessage. */ 24*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, 25*0b57cec5SDimitry Andric char **OutMessage) { 26*0b57cec5SDimitry Andric return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule, 27*0b57cec5SDimitry Andric OutMessage); 28*0b57cec5SDimitry Andric } 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf, 31*0b57cec5SDimitry Andric LLVMModuleRef *OutModule) { 32*0b57cec5SDimitry Andric return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule); 33*0b57cec5SDimitry Andric } 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 36*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf, 37*0b57cec5SDimitry Andric LLVMModuleRef *OutModule, 38*0b57cec5SDimitry Andric char **OutMessage) { 39*0b57cec5SDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 40*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 43*0b57cec5SDimitry Andric if (Error Err = ModuleOrErr.takeError()) { 44*0b57cec5SDimitry Andric std::string Message; 45*0b57cec5SDimitry Andric handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 46*0b57cec5SDimitry Andric Message = EIB.message(); 47*0b57cec5SDimitry Andric }); 48*0b57cec5SDimitry Andric if (OutMessage) 49*0b57cec5SDimitry Andric *OutMessage = strdup(Message.c_str()); 50*0b57cec5SDimitry Andric *OutModule = wrap((Module *)nullptr); 51*0b57cec5SDimitry Andric return 1; 52*0b57cec5SDimitry Andric } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release()); 55*0b57cec5SDimitry Andric return 0; 56*0b57cec5SDimitry Andric } 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 59*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf, 60*0b57cec5SDimitry Andric LLVMModuleRef *OutModule) { 61*0b57cec5SDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 62*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 63*0b57cec5SDimitry Andric 64*0b57cec5SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 65*0b57cec5SDimitry Andric expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx)); 66*0b57cec5SDimitry Andric if (ModuleOrErr.getError()) { 67*0b57cec5SDimitry Andric *OutModule = wrap((Module *)nullptr); 68*0b57cec5SDimitry Andric return 1; 69*0b57cec5SDimitry Andric } 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release()); 72*0b57cec5SDimitry Andric return 0; 73*0b57cec5SDimitry Andric } 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric /* Reads a module from the specified path, returning via the OutModule parameter 76*0b57cec5SDimitry Andric a module provider which performs lazy deserialization. Returns 0 on success. 77*0b57cec5SDimitry Andric Optionally returns a human-readable error message via OutMessage. */ 78*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 79*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf, 80*0b57cec5SDimitry Andric LLVMModuleRef *OutM, char **OutMessage) { 81*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 82*0b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 83*0b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> ModuleOrErr = 84*0b57cec5SDimitry Andric getOwningLazyBitcodeModule(std::move(Owner), Ctx); 85*0b57cec5SDimitry Andric // Release the buffer if we didn't take ownership of it since we never owned 86*0b57cec5SDimitry Andric // it anyway. 87*0b57cec5SDimitry Andric (void)Owner.release(); 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric if (Error Err = ModuleOrErr.takeError()) { 90*0b57cec5SDimitry Andric std::string Message; 91*0b57cec5SDimitry Andric handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 92*0b57cec5SDimitry Andric Message = EIB.message(); 93*0b57cec5SDimitry Andric }); 94*0b57cec5SDimitry Andric if (OutMessage) 95*0b57cec5SDimitry Andric *OutMessage = strdup(Message.c_str()); 96*0b57cec5SDimitry Andric *OutM = wrap((Module *)nullptr); 97*0b57cec5SDimitry Andric return 1; 98*0b57cec5SDimitry Andric } 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric *OutM = wrap(ModuleOrErr.get().release()); 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric return 0; 103*0b57cec5SDimitry Andric } 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 106*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf, 107*0b57cec5SDimitry Andric LLVMModuleRef *OutM) { 108*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 109*0b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors( 112*0b57cec5SDimitry Andric Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx)); 113*0b57cec5SDimitry Andric Owner.release(); 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric if (ModuleOrErr.getError()) { 116*0b57cec5SDimitry Andric *OutM = wrap((Module *)nullptr); 117*0b57cec5SDimitry Andric return 1; 118*0b57cec5SDimitry Andric } 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric *OutM = wrap(ModuleOrErr.get().release()); 121*0b57cec5SDimitry Andric return 0; 122*0b57cec5SDimitry Andric } 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 125*0b57cec5SDimitry Andric char **OutMessage) { 126*0b57cec5SDimitry Andric return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 127*0b57cec5SDimitry Andric OutMessage); 128*0b57cec5SDimitry Andric } 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 131*0b57cec5SDimitry Andric LLVMModuleRef *OutM) { 132*0b57cec5SDimitry Andric return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 133*0b57cec5SDimitry Andric } 134