blob: a52c8f9c73aabdb0ebce27febe9e4c5802ec4f24 [file] [log] [blame]
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001/*
Zonr Chang932648d2010-10-13 22:23:56 +08002 * Copyright 2010, The Android Open Source Project
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003 *
Zonr Chang932648d2010-10-13 22:23:56 +08004 * 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.
Shih-wei Liao77ed6142010-04-07 12:21:42 -070015 */
16
Zonr Chang932648d2010-10-13 22:23:56 +080017// Bitcode compiler (bcc) for Android:
18// This is an eager-compilation JIT running on Android.
19
Shih-wei Liao77ed6142010-04-07 12:21:42 -070020#define LOG_TAG "bcc"
21#include <cutils/log.h>
22
Loganc4395232010-11-27 18:54:17 +080023#include "Compiler.h"
24#include "Script.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -070025
Loganc4395232010-11-27 18:54:17 +080026#include <bcc/bcc.h>
Logan39a2ca52010-11-27 01:03:06 +080027
Shih-wei Liao7c5a5f72010-11-08 01:59:13 -080028#include <utils/StopWatch.h>
Shih-wei Liao77ed6142010-04-07 12:21:42 -070029
Logane1323992011-01-12 04:47:13 +080030char const libbcc_build_time[24] = __DATE__ " " __TIME__;
31
Logan3c01aaa2011-01-01 01:40:39 +080032namespace bcc {
33 class FuncLogger {
34 private:
35 char const *mFuncName;
36
37 public:
38 FuncLogger(char const *name) : mFuncName(name) {
Shih-wei Liao707a2942011-01-03 23:08:20 +080039 // LOGI("---> BEGIN: libbcc [ %s ]\n", name);
Logan3c01aaa2011-01-01 01:40:39 +080040 }
41
42 ~FuncLogger() {
Shih-wei Liao707a2942011-01-03 23:08:20 +080043 // LOGI("---> END: libbcc [ %s ]\n", mFuncName);
Logan3c01aaa2011-01-01 01:40:39 +080044 }
45 };
46
47#define BCC_FUNC_LOGGER() bcc::FuncLogger XX__funcLogger(__FUNCTION__)
48} // namespace bcc
49
Shih-wei Liao77ed6142010-04-07 12:21:42 -070050
Logan39a2ca52010-11-27 01:03:06 +080051namespace llvm {
52 class Module;
Shih-wei Liao7c5a5f72010-11-08 01:59:13 -080053}
54
Logan39a2ca52010-11-27 01:03:06 +080055
Logan3f3d31f2010-11-27 13:52:03 +080056extern "C" BCCscript *bccCreateScript() {
Logan3c01aaa2011-01-01 01:40:39 +080057 BCC_FUNC_LOGGER();
Logan3f3d31f2010-11-27 13:52:03 +080058 return new BCCscript();
59}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070060
Logan3f3d31f2010-11-27 13:52:03 +080061extern "C" BCCenum bccGetError(BCCscript *script) {
Logan3c01aaa2011-01-01 01:40:39 +080062 BCC_FUNC_LOGGER();
Logan3f3d31f2010-11-27 13:52:03 +080063 return script->getError();
64}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070065
Logan3f3d31f2010-11-27 13:52:03 +080066extern "C" void bccDeleteScript(BCCscript *script) {
Logan3c01aaa2011-01-01 01:40:39 +080067 BCC_FUNC_LOGGER();
Logan3f3d31f2010-11-27 13:52:03 +080068 delete script;
69}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070070
Logan3f3d31f2010-11-27 13:52:03 +080071extern "C" void bccRegisterSymbolCallback(BCCscript *script,
72 BCCSymbolLookupFn pFn,
73 BCCvoid *pContext) {
Logan3c01aaa2011-01-01 01:40:39 +080074 BCC_FUNC_LOGGER();
Logan3f3d31f2010-11-27 13:52:03 +080075 script->registerSymbolCallback(pFn, pContext);
76}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070077
Logan3f3d31f2010-11-27 13:52:03 +080078extern "C" int bccReadModule(BCCscript *script, BCCvoid *module) {
Logan3c01aaa2011-01-01 01:40:39 +080079 BCC_FUNC_LOGGER();
Loganeaa0cc32010-12-29 01:04:20 +080080 return script->readModule(reinterpret_cast<llvm::Module*>(module));
Logan3f3d31f2010-11-27 13:52:03 +080081}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070082
Logan3f3d31f2010-11-27 13:52:03 +080083extern "C" int bccReadBC(BCCscript *script,
84 const BCCchar *bitcode,
Loganb9b04162010-12-20 16:36:57 +080085 BCCint bitcodeSize,
Logan9d547692011-01-06 05:26:34 +080086 long __DONT_USE_PARAM_1,
87 long __DONT_USE_PARAM_2,
Shih-wei Liaoe6a18512010-12-09 12:38:10 -080088 const BCCchar *resName,
89 const BCCchar *cacheDir) {
Logan3c01aaa2011-01-01 01:40:39 +080090 BCC_FUNC_LOGGER();
Loganf30a6712011-01-06 05:55:34 +080091 return script->readBC(bitcode, bitcodeSize, resName, cacheDir);
Logan3f3d31f2010-11-27 13:52:03 +080092}
Zonr Chang932648d2010-10-13 22:23:56 +080093
Shih-wei Liao4079b592011-01-11 04:54:13 -080094extern "C" int bccLinkBC(BCCscript *script,
95 const BCCchar *bitcode,
96 BCCint size) {
Logan3c01aaa2011-01-01 01:40:39 +080097 BCC_FUNC_LOGGER();
Shih-wei Liao4079b592011-01-11 04:54:13 -080098 return script->linkBC(bitcode, size);
Logan3f3d31f2010-11-27 13:52:03 +080099}
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700100
Shih-wei Liaof6267d12011-01-07 19:23:58 -0800101extern "C" int bccPrepareExecutable(BCCscript *script) {
Logan3c01aaa2011-01-01 01:40:39 +0800102 BCC_FUNC_LOGGER();
Logan3f3d31f2010-11-27 13:52:03 +0800103#if defined(__arm__)
Shih-wei Liaof6267d12011-01-07 19:23:58 -0800104 android::StopWatch compileTimer("bcc: PrepareExecutable time");
Logan3f3d31f2010-11-27 13:52:03 +0800105#endif
Logand80e65b2010-12-03 21:28:04 +0800106
Loganbe79ada2011-01-13 01:33:45 +0800107 int result = script->prepareExecutable();
Logand80e65b2010-12-03 21:28:04 +0800108 if (result)
109 script->setError(BCC_INVALID_OPERATION);
110
111 return result;
Logan3f3d31f2010-11-27 13:52:03 +0800112}
Shih-wei Liao7c5a5f72010-11-08 01:59:13 -0800113
Logan3f3d31f2010-11-27 13:52:03 +0800114extern "C" void bccGetScriptInfoLog(BCCscript *script,
115 BCCsizei maxLength,
116 BCCsizei *length,
117 BCCchar *infoLog) {
Logan3c01aaa2011-01-01 01:40:39 +0800118 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800119 LOGE("%s is deprecated. *********************************\n", __func__);
Logan3f3d31f2010-11-27 13:52:03 +0800120}
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700121
Logan3f3d31f2010-11-27 13:52:03 +0800122extern "C" void bccGetScriptLabel(BCCscript *script,
123 const BCCchar *name,
124 BCCvoid **address) {
Logan3c01aaa2011-01-01 01:40:39 +0800125 BCC_FUNC_LOGGER();
Loganeaa0cc32010-12-29 01:04:20 +0800126 void *value = script->lookup(name);
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800127 if (value) {
Logan3f3d31f2010-11-27 13:52:03 +0800128 *address = value;
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800129#if defined(USE_DISASSEMBLER_FILE)
130 LOGI("[GetScriptLabel] %s @ 0x%x", name, value);
131#endif
132 } else {
Logan3f3d31f2010-11-27 13:52:03 +0800133 script->setError(BCC_INVALID_VALUE);
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800134 }
Logan3f3d31f2010-11-27 13:52:03 +0800135}
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700136
Logan3f3d31f2010-11-27 13:52:03 +0800137extern "C" void bccGetExportVars(BCCscript *script,
Loganbe79ada2011-01-13 01:33:45 +0800138 BCCsizei *actualCount,
139 BCCsizei varListSize,
140 BCCvoid **varList) {
Logan3c01aaa2011-01-01 01:40:39 +0800141 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800142
143 if (actualCount) {
144 *actualCount = static_cast<BCCsizei>(script->getExportVarCount());
145 }
146
147 if (varList) {
148 script->getExportVarList(static_cast<size_t>(varListSize), varList);
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800149
150#if defined(USE_DISASSEMBLER_FILE)
Loganbe79ada2011-01-13 01:33:45 +0800151 size_t count = script->getExportVarCount();
152 LOGD("ExportVarCount = %lu\n", (unsigned long)count);
153
154 if (count > varListSize) {
155 count = varListSize;
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800156 }
Loganbe79ada2011-01-13 01:33:45 +0800157
158 for (size_t i = 0; i < count; ++i) {
159 LOGD("ExportVarList[%lu] = 0x%p\n", (unsigned long)i, varList[i]);
160 }
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800161#endif
Loganbe79ada2011-01-13 01:33:45 +0800162 }
Logan3f3d31f2010-11-27 13:52:03 +0800163}
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700164
Logan3f3d31f2010-11-27 13:52:03 +0800165extern "C" void bccGetExportFuncs(BCCscript *script,
Loganbe79ada2011-01-13 01:33:45 +0800166 BCCsizei *actualCount,
167 BCCsizei funcListSize,
168 BCCvoid **funcList) {
Logan3c01aaa2011-01-01 01:40:39 +0800169 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800170
171 if (actualCount) {
172 *actualCount = static_cast<BCCsizei>(script->getExportFuncCount());
173 }
174
175 if (funcList) {
176 script->getExportFuncList(static_cast<size_t>(funcListSize), funcList);
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800177
178#if defined(USE_DISASSEMBLER_FILE)
Loganbe79ada2011-01-13 01:33:45 +0800179 size_t count = script->getExportFuncCount();
180 LOGD("ExportFuncCount = %lu\n", (unsigned long)count);
181
182 if (count > funcListSize) {
183 count = funcListSize;
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800184 }
Loganbe79ada2011-01-13 01:33:45 +0800185
186 for (size_t i = 0; i < count; ++i) {
187 LOGD("ExportFuncList[%lu] = 0x%p\n", (unsigned long)i, funcList[i]);
188 }
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800189#endif
Loganbe79ada2011-01-13 01:33:45 +0800190 }
Logan3f3d31f2010-11-27 13:52:03 +0800191}
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700192
Logan3f3d31f2010-11-27 13:52:03 +0800193extern "C" void bccGetPragmas(BCCscript *script,
Loganbe79ada2011-01-13 01:33:45 +0800194 BCCsizei *actualCount,
195 BCCsizei stringListSize,
196 BCCchar **stringList) {
Logan3c01aaa2011-01-01 01:40:39 +0800197 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800198
199 if (actualCount) {
200 *actualCount = static_cast<BCCsizei>(script->getPragmaCount() * 2);
201 }
202
203 if (stringList) {
204 size_t pragmaListSize = static_cast<size_t>(stringListSize) / 2;
205
206 char const **buf = new (nothrow) char const *[pragmaListSize * 2];
207 if (!buf) {
208 return;
209 }
210
211 char const **keyList = buf;
212 char const **valueList = buf + pragmaListSize;
213
214 script->getPragmaList(pragmaListSize, keyList, valueList);
215
216 for (size_t i = 0; i < pragmaListSize; ++i) {
217 *stringList++ = const_cast<BCCchar *>(keyList[i]);
218 *stringList++ = const_cast<BCCchar *>(valueList[i]);
219 }
220
221 delete [] buf;
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800222
223#if defined(USE_DISASSEMBLER_FILE)
Loganbe79ada2011-01-13 01:33:45 +0800224 size_t count = script->getPragmaCount();
225 LOGD("PragmaCount = %lu\n", count);
226
227 if (count > pragmaListSize) {
228 count = pragmaListSize;
229 }
230
231 for (size_t i = 0; i < count; ++i) {
232 LOGD("Pragma[%lu] = (%s , %s)\n",
233 (unsigned long)i, stringList[2 * i], stringList[2 * i + 1]);
234 }
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800235#endif
Loganbe79ada2011-01-13 01:33:45 +0800236 }
Logan3f3d31f2010-11-27 13:52:03 +0800237}
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700238
Logan3f3d31f2010-11-27 13:52:03 +0800239extern "C" void bccGetFunctions(BCCscript *script,
Loganbe79ada2011-01-13 01:33:45 +0800240 BCCsizei *actualCount,
241 BCCsizei funcNameListSize,
242 BCCchar **funcNameList) {
Logan3c01aaa2011-01-01 01:40:39 +0800243 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800244
245 if (actualCount) {
246 *actualCount = static_cast<BCCsizei>(script->getFuncCount());
247 }
248
249 if (funcNameList) {
250 script->getFuncNameList(static_cast<size_t>(funcNameListSize),
251 const_cast<char const **>(funcNameList));
252 }
Logan3f3d31f2010-11-27 13:52:03 +0800253}
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700254
Logan3f3d31f2010-11-27 13:52:03 +0800255extern "C" void bccGetFunctionBinary(BCCscript *script,
Loganbe79ada2011-01-13 01:33:45 +0800256 BCCchar *funcname,
Logan3f3d31f2010-11-27 13:52:03 +0800257 BCCvoid **base,
258 BCCsizei *length) {
Logan3c01aaa2011-01-01 01:40:39 +0800259 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800260
261 size_t funcLength = 0;
262 script->getFuncBinary(funcname, base, &funcLength);
263
264 if (length) {
265 *length = static_cast<BCCsizei>(funcLength);
266 }
Logan3f3d31f2010-11-27 13:52:03 +0800267}