1 /* 2 * Copyright 2012, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "bcc/Source.h" 18 19 #include <new> 20 21 #include <llvm/Bitcode/ReaderWriter.h> 22 #include <llvm/IR/LLVMContext.h> 23 #include <llvm/Linker.h> 24 #include <llvm/IR/Module.h> 25 #include <llvm/Support/MemoryBuffer.h> 26 #include <llvm/Support/system_error.h> 27 28 #include "bcc/BCCContext.h" 29 #include "bcc/Support/Log.h" 30 31 #include "BCCContextImpl.h" 32 33 namespace { 34 35 // Helper function to load the bitcode. This uses "bitcode lazy load" feature to 36 // reduce the startup time. On success, return the LLVM module object created 37 // and take the ownership of input memory buffer (i.e., pInput). On error, 38 // return NULL and will NOT take the ownership of pInput. 39 static inline llvm::Module *helper_load_bitcode(llvm::LLVMContext &pContext, 40 llvm::MemoryBuffer *pInput) { 41 std::string error; 42 llvm::Module *module = llvm::getLazyBitcodeModule(pInput, pContext, &error); 43 44 if (module == NULL) { 45 ALOGE("Unable to parse the given bitcode file `%s'! (%s)", 46 pInput->getBufferIdentifier(), error.c_str()); 47 } 48 49 return module; 50 } 51 52 } // end anonymous namespace 53 54 namespace bcc { 55 56 void Source::setModule(llvm::Module *pModule) { 57 if (!mNoDelete && (mModule != pModule)) delete mModule; 58 mModule = pModule; 59 } 60 61 Source *Source::CreateFromBuffer(BCCContext &pContext, 62 const char *pName, 63 const char *pBitcode, 64 size_t pBitcodeSize) { 65 llvm::StringRef input_data(pBitcode, pBitcodeSize); 66 llvm::MemoryBuffer *input_memory = 67 llvm::MemoryBuffer::getMemBuffer(input_data, "", false); 68 69 if (input_memory == NULL) { 70 ALOGE("Unable to load bitcode `%s' from buffer!", pName); 71 return NULL; 72 } 73 74 llvm::Module *module = helper_load_bitcode(pContext.mImpl->mLLVMContext, 75 input_memory); 76 if (module == NULL) { 77 delete input_memory; 78 return NULL; 79 } 80 81 Source *result = CreateFromModule(pContext, *module, /* pNoDelete */false); 82 if (result == NULL) { 83 delete module; 84 } 85 86 return result; 87 } 88 89 Source *Source::CreateFromFile(BCCContext &pContext, const std::string &pPath) { 90 llvm::OwningPtr<llvm::MemoryBuffer> input_data; 91 92 llvm::error_code ec = llvm::MemoryBuffer::getFile(pPath, input_data); 93 if (ec != llvm::error_code::success()) { 94 ALOGE("Failed to load bitcode from path %s! (%s)", pPath.c_str(), 95 ec.message().c_str()); 96 return NULL; 97 } 98 99 llvm::MemoryBuffer *input_memory = input_data.take(); 100 llvm::Module *module = helper_load_bitcode(pContext.mImpl->mLLVMContext, 101 input_memory); 102 if (module == NULL) { 103 delete input_memory; 104 return NULL; 105 } 106 107 Source *result = CreateFromModule(pContext, *module, /* pNoDelete */false); 108 if (result == NULL) { 109 delete module; 110 } 111 112 return result; 113 } 114 115 Source *Source::CreateFromFd(BCCContext &pContext, int pFd) { 116 llvm::OwningPtr<llvm::MemoryBuffer> input_data; 117 118 llvm::error_code ec = 119 llvm::MemoryBuffer::getOpenFile(pFd, /* Filename */"", input_data); 120 121 if (ec != llvm::error_code::success()) { 122 ALOGE("Failed to load bitcode from file descriptor %d! (%s)", 123 pFd, ec.message().c_str()); 124 return NULL; 125 } 126 127 llvm::MemoryBuffer *input_memory = input_data.take(); 128 llvm::Module *module = helper_load_bitcode(pContext.mImpl->mLLVMContext, 129 input_memory); 130 if (module == NULL) { 131 delete input_memory; 132 return NULL; 133 } 134 135 Source *result = CreateFromModule(pContext, *module, /* pNoDelete */false); 136 if (result == NULL) { 137 delete module; 138 } 139 140 return result; 141 } 142 143 Source *Source::CreateFromModule(BCCContext &pContext, llvm::Module &pModule, 144 bool pNoDelete) { 145 Source *result = new (std::nothrow) Source(pContext, pModule, pNoDelete); 146 if (result == NULL) { 147 ALOGE("Out of memory during Source object allocation for `%s'!", 148 pModule.getModuleIdentifier().c_str()); 149 } 150 return result; 151 } 152 153 Source::Source(BCCContext &pContext, llvm::Module &pModule, bool pNoDelete) 154 : mContext(pContext), mModule(&pModule), mNoDelete(pNoDelete) { 155 pContext.addSource(*this); 156 } 157 158 Source::~Source() { 159 mContext.removeSource(*this); 160 if (!mNoDelete) 161 delete mModule; 162 } 163 164 bool Source::merge(Source &pSource, bool pPreserveSource) { 165 std::string error; 166 llvm::Linker::LinkerMode mode = 167 ((pPreserveSource) ? llvm::Linker::PreserveSource : 168 llvm::Linker::DestroySource); 169 170 if (llvm::Linker::LinkModules(mModule, &pSource.getModule(), 171 mode, &error) != 0) { 172 ALOGE("Failed to link source `%s' with `%s' (%s)!", 173 getIdentifier().c_str(), 174 pSource.getIdentifier().c_str(), 175 error.c_str()); 176 return false; 177 } 178 179 if (!pPreserveSource) { 180 pSource.mNoDelete = true; 181 delete &pSource; 182 } 183 184 return true; 185 } 186 187 Source *Source::CreateEmpty(BCCContext &pContext, const std::string &pName) { 188 // Create an empty module 189 llvm::Module *module = 190 new (std::nothrow) llvm::Module(pName, pContext.mImpl->mLLVMContext); 191 192 if (module == NULL) { 193 ALOGE("Out of memory when creating empty LLVM module `%s'!", pName.c_str()); 194 return NULL; 195 } 196 197 Source *result = CreateFromModule(pContext, *module, /* pNoDelete */false); 198 if (result == NULL) { 199 delete module; 200 } 201 202 return result; 203 } 204 205 const std::string &Source::getIdentifier() const { 206 return mModule->getModuleIdentifier(); 207 } 208 209 } // namespace bcc 210