1 /* 2 * Copyright 2010-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 // Bitcode compiler (bcc) for Android: 18 // This is an eager-compilation JIT running on Android. 19 20 #include <bcc/bcc.h> 21 #include "bcc_internal.h" 22 23 #include "Config.h" 24 25 #include "Compiler.h" 26 #include "DebugHelper.h" 27 #include "Script.h" 28 29 #include <string> 30 31 #include <utils/StopWatch.h> 32 33 #include <llvm/Support/CodeGen.h> 34 35 using namespace bcc; 36 37 namespace llvm { 38 class Module; 39 } 40 41 static bool bccBuildStampPrinted = false; 42 43 static void bccPrintBuildStamp() { 44 if (!bccBuildStampPrinted) { 45 ALOGI("LIBBCC build time: %s", bccGetBuildTime()); 46 ALOGI("LIBBCC build revision: %s", bccGetBuildRev()); 47 bccBuildStampPrinted = true; 48 } 49 } 50 51 extern "C" BCCScriptRef bccCreateScript() { 52 BCC_FUNC_LOGGER(); 53 bccPrintBuildStamp(); 54 return wrap(new bcc::Script()); 55 } 56 57 58 extern "C" void bccDisposeScript(BCCScriptRef script) { 59 BCC_FUNC_LOGGER(); 60 delete unwrap(script); 61 } 62 63 64 extern "C" int bccRegisterSymbolCallback(BCCScriptRef script, 65 BCCSymbolLookupFn pFn, 66 void *pContext) { 67 BCC_FUNC_LOGGER(); 68 return unwrap(script)->registerSymbolCallback(pFn, pContext); 69 } 70 71 72 extern "C" int bccGetError(BCCScriptRef script) { 73 BCC_FUNC_LOGGER(); 74 return unwrap(script)->getError(); 75 } 76 77 extern "C" int bccReadBC(BCCScriptRef script, 78 char const *resName, 79 char const *bitcode, 80 size_t bitcodeSize, 81 unsigned long flags) { 82 BCC_FUNC_LOGGER(); 83 return unwrap(script)->addSourceBC(0, resName, bitcode, bitcodeSize, flags); 84 } 85 86 87 extern "C" int bccReadModule(BCCScriptRef script, 88 char const *resName /* deprecated */, 89 LLVMModuleRef module, 90 unsigned long flags) { 91 BCC_FUNC_LOGGER(); 92 return unwrap(script)->addSourceModule(0, unwrap(module), flags); 93 } 94 95 96 extern "C" int bccReadFile(BCCScriptRef script, 97 char const *path, 98 unsigned long flags) { 99 BCC_FUNC_LOGGER(); 100 return unwrap(script)->addSourceFile(0, path, flags); 101 } 102 103 104 extern "C" int bccLinkBC(BCCScriptRef script, 105 char const *resName, 106 char const *bitcode, 107 size_t bitcodeSize, 108 unsigned long flags) { 109 BCC_FUNC_LOGGER(); 110 return unwrap(script)->addSourceBC(1, resName, bitcode, bitcodeSize, flags); 111 } 112 113 114 extern "C" int bccLinkFile(BCCScriptRef script, 115 char const *path, 116 unsigned long flags) { 117 BCC_FUNC_LOGGER(); 118 return unwrap(script)->addSourceFile(1, path, flags); 119 } 120 121 122 extern "C" void bccMarkExternalSymbol(BCCScriptRef script, char const *name) { 123 BCC_FUNC_LOGGER(); 124 unwrap(script)->markExternalSymbol(name); 125 } 126 127 128 extern "C" int bccPrepareRelocatable(BCCScriptRef script, 129 char const *objPath, 130 bccRelocModelEnum RelocModel, 131 unsigned long flags) { 132 BCC_FUNC_LOGGER(); 133 llvm::Reloc::Model RM; 134 135 switch (RelocModel) { 136 case bccRelocDefault: { 137 RM = llvm::Reloc::Default; 138 break; 139 } 140 case bccRelocStatic: { 141 RM = llvm::Reloc::Static; 142 break; 143 } 144 case bccRelocPIC: { 145 RM = llvm::Reloc::PIC_; 146 break; 147 } 148 case bccRelocDynamicNoPIC: { 149 RM = llvm::Reloc::DynamicNoPIC; 150 break; 151 } 152 default: { 153 ALOGE("Unrecognized relocation model for bccPrepareObject!"); 154 return BCC_INVALID_VALUE; 155 } 156 } 157 158 return unwrap(script)->prepareRelocatable(objPath, RM, flags); 159 } 160 161 162 extern "C" int bccPrepareSharedObject(BCCScriptRef script, 163 char const *objPath, 164 char const *dsoPath, 165 unsigned long flags) { 166 BCC_FUNC_LOGGER(); 167 return unwrap(script)->prepareSharedObject(objPath, dsoPath, flags); 168 } 169 170 171 extern "C" int bccPrepareExecutable(BCCScriptRef script, 172 char const *cacheDir, 173 char const *cacheName, 174 unsigned long flags) { 175 BCC_FUNC_LOGGER(); 176 177 android::StopWatch compileTimer("bcc: PrepareExecutable time"); 178 179 return unwrap(script)->prepareExecutable(cacheDir, cacheName, flags); 180 } 181 182 183 extern "C" void *bccGetFuncAddr(BCCScriptRef script, char const *funcname) { 184 BCC_FUNC_LOGGER(); 185 186 void *addr = unwrap(script)->lookup(funcname); 187 188 #if DEBUG_BCC_REFLECT 189 ALOGD("Function Address: %s --> %p\n", funcname, addr); 190 #endif 191 192 return addr; 193 } 194 195 196 extern "C" void bccGetExportVarList(BCCScriptRef script, 197 size_t varListSize, 198 void **varList) { 199 BCC_FUNC_LOGGER(); 200 201 if (varList) { 202 unwrap(script)->getExportVarList(varListSize, varList); 203 204 #if DEBUG_BCC_REFLECT 205 size_t count = unwrap(script)->getExportVarCount(); 206 ALOGD("ExportVarCount = %lu\n", (unsigned long)count); 207 208 if (count > varListSize) { 209 count = varListSize; 210 } 211 212 for (size_t i = 0; i < count; ++i) { 213 ALOGD("ExportVarList[%lu] = %p\n", (unsigned long)i, varList[i]); 214 } 215 #endif 216 } 217 } 218 219 220 extern "C" void bccGetExportFuncList(BCCScriptRef script, 221 size_t funcListSize, 222 void **funcList) { 223 BCC_FUNC_LOGGER(); 224 225 if (funcList) { 226 unwrap(script)->getExportFuncList(funcListSize, funcList); 227 228 #if DEBUG_BCC_REFLECT 229 size_t count = unwrap(script)->getExportFuncCount(); 230 ALOGD("ExportFuncCount = %lu\n", (unsigned long)count); 231 232 if (count > funcListSize) { 233 count = funcListSize; 234 } 235 236 for (size_t i = 0; i < count; ++i) { 237 ALOGD("ExportFuncList[%lu] = %p\n", (unsigned long)i, funcList[i]); 238 } 239 #endif 240 } 241 } 242 243 244 extern "C" void bccGetExportForEachList(BCCScriptRef script, 245 size_t forEachListSize, 246 void **forEachList) { 247 BCC_FUNC_LOGGER(); 248 249 if (forEachList) { 250 unwrap(script)->getExportForEachList(forEachListSize, forEachList); 251 252 #if DEBUG_BCC_REFLECT 253 size_t count = unwrap(script)->getExportForEachCount(); 254 ALOGD("ExportForEachCount = %lu\n", (unsigned long)count); 255 256 if (count > forEachListSize) { 257 count = forEachListSize; 258 } 259 260 for (size_t i = 0; i < count; ++i) { 261 ALOGD("ExportForEachList[%lu] = %p\n", (unsigned long)i, forEachList[i]); 262 } 263 #endif 264 } 265 } 266