blob: 7425d0a668379e4cfcbc5aca12bd356ebe694133 [file] [log] [blame]
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001/*
Stephen Hinescc366e52012-02-21 17:22:04 -08002 * Copyright 2010-2012, 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
Loganf340bf72011-01-14 17:51:40 +080020#include <bcc/bcc.h>
Shih-wei Liao77ed6142010-04-07 12:21:42 -070021
Logan Chien311c26f2011-07-11 14:30:34 +080022#include <string>
23
Shih-wei Liao7c5a5f72010-11-08 01:59:13 -080024#include <utils/StopWatch.h>
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -080025
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070026#include "Config.h"
27
28#include <bcc/bcc_mccache.h>
29#include "bcc_internal.h"
30
31#include "BCCContext.h"
32#include "Compiler.h"
33#include "DebugHelper.h"
Zonr Chang19218c02012-04-05 10:44:53 +080034#include "RSScript.h"
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070035#include "Sha1Helper.h"
36#include "Source.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -070037
Loganf340bf72011-01-14 17:51:40 +080038using namespace bcc;
39
Logan39a2ca52010-11-27 01:03:06 +080040namespace llvm {
41 class Module;
Shih-wei Liao7c5a5f72010-11-08 01:59:13 -080042}
43
Logan Chien3378a022011-07-13 19:44:37 +080044static bool bccBuildStampPrinted = false;
45
46static void bccPrintBuildStamp() {
47 if (!bccBuildStampPrinted) {
Steve Block440e0312012-01-04 20:06:16 +000048 ALOGI("LIBBCC build time: %s", bccGetBuildTime());
49 ALOGI("LIBBCC build revision: %s", bccGetBuildRev());
Logan Chien3378a022011-07-13 19:44:37 +080050 bccBuildStampPrinted = true;
51 }
52}
53
Loganf340bf72011-01-14 17:51:40 +080054extern "C" BCCScriptRef bccCreateScript() {
Logan3c01aaa2011-01-01 01:40:39 +080055 BCC_FUNC_LOGGER();
Logan Chien3378a022011-07-13 19:44:37 +080056 bccPrintBuildStamp();
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070057 // FIXME: This is a workaround for this API: use global BCC context and
58 // create an empty source to create a Script object.
59 BCCContext *context = BCCContext::GetOrCreateGlobalContext();
60 if (context == NULL) {
61 return NULL;
62 }
63
64 Source *source = Source::CreateEmpty(*context, "empty");
Zonr Chang19218c02012-04-05 10:44:53 +080065 return wrap(new RSScript(*source));
Logan3f3d31f2010-11-27 13:52:03 +080066}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070067
Shih-wei Liao39ebe2c2011-01-28 11:22:32 -080068
Loganf340bf72011-01-14 17:51:40 +080069extern "C" void bccDisposeScript(BCCScriptRef script) {
Logan3c01aaa2011-01-01 01:40:39 +080070 BCC_FUNC_LOGGER();
Loganf340bf72011-01-14 17:51:40 +080071 delete unwrap(script);
Logan3f3d31f2010-11-27 13:52:03 +080072}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070073
Shih-wei Liao39ebe2c2011-01-28 11:22:32 -080074
Shih-wei Liaoce82d492011-01-20 12:34:03 -080075extern "C" int bccRegisterSymbolCallback(BCCScriptRef script,
76 BCCSymbolLookupFn pFn,
77 void *pContext) {
Logan3c01aaa2011-01-01 01:40:39 +080078 BCC_FUNC_LOGGER();
Loganf340bf72011-01-14 17:51:40 +080079 return unwrap(script)->registerSymbolCallback(pFn, pContext);
Logan3f3d31f2010-11-27 13:52:03 +080080}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070081
Shih-wei Liao39ebe2c2011-01-28 11:22:32 -080082
Loganf340bf72011-01-14 17:51:40 +080083extern "C" int bccGetError(BCCScriptRef script) {
Logan3c01aaa2011-01-01 01:40:39 +080084 BCC_FUNC_LOGGER();
Loganf340bf72011-01-14 17:51:40 +080085 return unwrap(script)->getError();
Logan3f3d31f2010-11-27 13:52:03 +080086}
Shih-wei Liao77ed6142010-04-07 12:21:42 -070087
Zonr Chang19218c02012-04-05 10:44:53 +080088static bool helper_add_source(RSScript *pScript,
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070089 char const *pName,
90 char const *pBitcode,
91 size_t pBitcodeSize,
92 unsigned long pFlags,
93 bool pIsLink) {
94 bool need_dependency_check = !(pFlags & BCC_SKIP_DEP_SHA1);
95 if (!pName && need_dependency_check) {
96 pFlags |= BCC_SKIP_DEP_SHA1;
97
98 ALOGW("It is required to give resName for sha1 dependency check.\n");
99 ALOGW("Sha1sum dependency check will be skipped.\n");
100 ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
101 }
102
103 BCCContext *context = BCCContext::GetOrCreateGlobalContext();
104 if (context == NULL) {
105 return false;
106 }
107
108 Source *source = Source::CreateFromBuffer(*context, pName,
109 pBitcode, pBitcodeSize);
110 if (source == NULL) {
111 return false;
112 }
113
114 if (need_dependency_check) {
115 uint8_t sha1[20];
116 calcSHA1(sha1, pBitcode, pBitcodeSize);
Zonr Chang19218c02012-04-05 10:44:53 +0800117 if (!pScript->addSourceDependency(BCC_APK_RESOURCE, pName, sha1)) {
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700118 return false;
119 }
120 }
121
122 return ((pIsLink) ? pScript->mergeSource(*source) : pScript->reset(*source));
123}
124
Zonr Chang19218c02012-04-05 10:44:53 +0800125static bool helper_add_source(RSScript *pScript,
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700126 llvm::Module *pModule,
127 bool pIsLink) {
128 if (pModule == NULL)
129 return false;
130
131 BCCContext *context = BCCContext::GetOrCreateGlobalContext();
132 if (context == NULL) {
133 return false;
134 }
135
136 if (pModule == NULL) {
137 ALOGE("Cannot add null module to script!");
138 return false;
139 }
140
141 Source *source = Source::CreateFromModule(*context, *pModule, true);
142 if (source == NULL) {
143 return false;
144 }
145
146 return ((pIsLink) ? pScript->mergeSource(*source) : pScript->reset(*source));
147}
148
Zonr Chang19218c02012-04-05 10:44:53 +0800149static bool helper_add_source(RSScript *pScript,
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700150 char const *pPath,
151 unsigned long pFlags,
152 bool pIsLink) {
153 bool need_dependency_check = !(pFlags & BCC_SKIP_DEP_SHA1);
154 BCCContext *context = BCCContext::GetOrCreateGlobalContext();
155 if (context == NULL) {
156 return false;
157 }
158
159 Source *source = Source::CreateFromFile(*context, pPath);
160 if (source == NULL) {
161 return false;
162 }
163
164 if (need_dependency_check) {
165 uint8_t sha1[20];
166 calcFileSHA1(sha1, pPath);
Zonr Chang19218c02012-04-05 10:44:53 +0800167 if (!pScript->addSourceDependency(BCC_APK_RESOURCE, pPath, sha1)) {
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700168 return false;
169 }
170 }
171
172 return ((pIsLink) ? pScript->mergeSource(*source) : pScript->reset(*source));
173}
174
Loganf340bf72011-01-14 17:51:40 +0800175extern "C" int bccReadBC(BCCScriptRef script,
176 char const *resName,
177 char const *bitcode,
178 size_t bitcodeSize,
179 unsigned long flags) {
Logan3c01aaa2011-01-01 01:40:39 +0800180 BCC_FUNC_LOGGER();
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700181 return (helper_add_source(unwrap(script), resName,
182 bitcode, bitcodeSize,
183 flags, /* pIsLink */false) == false);
Logan3f3d31f2010-11-27 13:52:03 +0800184}
Zonr Chang932648d2010-10-13 22:23:56 +0800185
Loganf340bf72011-01-14 17:51:40 +0800186
187extern "C" int bccReadModule(BCCScriptRef script,
Logan474cbd22011-01-31 01:47:44 +0800188 char const *resName /* deprecated */,
Loganf340bf72011-01-14 17:51:40 +0800189 LLVMModuleRef module,
190 unsigned long flags) {
Logan3c01aaa2011-01-01 01:40:39 +0800191 BCC_FUNC_LOGGER();
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700192 return (helper_add_source(unwrap(script), unwrap(module),
193 /* pIsLink */false) == false);
Logan474cbd22011-01-31 01:47:44 +0800194}
195
196
197extern "C" int bccReadFile(BCCScriptRef script,
198 char const *path,
199 unsigned long flags) {
200 BCC_FUNC_LOGGER();
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700201 return (helper_add_source(unwrap(script), path,
202 flags, /* pIsLink */false) == false);
Logan3f3d31f2010-11-27 13:52:03 +0800203}
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700204
Loganf340bf72011-01-14 17:51:40 +0800205
206extern "C" int bccLinkBC(BCCScriptRef script,
207 char const *resName,
208 char const *bitcode,
209 size_t bitcodeSize,
210 unsigned long flags) {
Logan3c01aaa2011-01-01 01:40:39 +0800211 BCC_FUNC_LOGGER();
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700212 return (helper_add_source(unwrap(script), resName,
213 bitcode, bitcodeSize,
214 flags, /* pIsLink */true) == false);
Logan474cbd22011-01-31 01:47:44 +0800215}
216
217
218extern "C" int bccLinkFile(BCCScriptRef script,
219 char const *path,
220 unsigned long flags) {
221 BCC_FUNC_LOGGER();
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700222 return (helper_add_source(unwrap(script), path,
223 flags, /* pIsLink */true) == false);
Loganf340bf72011-01-14 17:51:40 +0800224}
225
226
Logan Chien7890d432011-08-03 14:55:17 +0800227extern "C" void bccMarkExternalSymbol(BCCScriptRef script, char const *name) {
228 BCC_FUNC_LOGGER();
229 unwrap(script)->markExternalSymbol(name);
230}
231
232
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -0800233extern "C" int bccPrepareRelocatable(BCCScriptRef script,
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800234 char const *objPath,
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -0800235 bccRelocModelEnum RelocModel,
236 unsigned long flags) {
Shih-wei Liao8afed382012-01-10 15:57:24 +0800237 BCC_FUNC_LOGGER();
238 llvm::Reloc::Model RM;
239
240 switch (RelocModel) {
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -0800241 case bccRelocDefault: {
242 RM = llvm::Reloc::Default;
243 break;
244 }
245 case bccRelocStatic: {
246 RM = llvm::Reloc::Static;
247 break;
248 }
249 case bccRelocPIC: {
250 RM = llvm::Reloc::PIC_;
251 break;
252 }
253 case bccRelocDynamicNoPIC: {
254 RM = llvm::Reloc::DynamicNoPIC;
255 break;
256 }
Shih-wei Liao8afed382012-01-10 15:57:24 +0800257 default: {
258 ALOGE("Unrecognized relocation model for bccPrepareObject!");
259 return BCC_INVALID_VALUE;
260 }
261 }
262
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800263 return unwrap(script)->prepareRelocatable(objPath, RM, flags);
Joseph Wen34c600a2011-07-25 17:59:17 -0700264}
265
266
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -0800267extern "C" int bccPrepareSharedObject(BCCScriptRef script,
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -0800268 char const *objPath,
269 char const *dsoPath,
270 unsigned long flags) {
271 BCC_FUNC_LOGGER();
Shih-wei Liao69341742012-03-03 01:45:36 -0800272 return unwrap(script)->prepareSharedObject(objPath, dsoPath, flags);
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -0800273}
274
275
Loganf340bf72011-01-14 17:51:40 +0800276extern "C" int bccPrepareExecutable(BCCScriptRef script,
Logan Chienc2be0a12011-07-19 23:10:48 +0800277 char const *cacheDir,
278 char const *cacheName,
Loganf340bf72011-01-14 17:51:40 +0800279 unsigned long flags) {
Logan Chien311c26f2011-07-11 14:30:34 +0800280 BCC_FUNC_LOGGER();
281
Shih-wei Liaof6267d12011-01-07 19:23:58 -0800282 android::StopWatch compileTimer("bcc: PrepareExecutable time");
Logand80e65b2010-12-03 21:28:04 +0800283
Logan Chien311c26f2011-07-11 14:30:34 +0800284 return unwrap(script)->prepareExecutable(cacheDir, cacheName, flags);
Logan3f3d31f2010-11-27 13:52:03 +0800285}
Shih-wei Liao7c5a5f72010-11-08 01:59:13 -0800286
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700287
Loganf340bf72011-01-14 17:51:40 +0800288extern "C" void *bccGetFuncAddr(BCCScriptRef script, char const *funcname) {
Logan3c01aaa2011-01-01 01:40:39 +0800289 BCC_FUNC_LOGGER();
Loganf340bf72011-01-14 17:51:40 +0800290
291 void *addr = unwrap(script)->lookup(funcname);
292
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700293#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000294 ALOGD("Function Address: %s --> %p\n", funcname, addr);
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800295#endif
Loganf340bf72011-01-14 17:51:40 +0800296
297 return addr;
Logan3f3d31f2010-11-27 13:52:03 +0800298}
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700299
Loganbe79ada2011-01-13 01:33:45 +0800300
Loganf340bf72011-01-14 17:51:40 +0800301extern "C" void bccGetExportVarList(BCCScriptRef script,
302 size_t varListSize,
303 void **varList) {
304 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800305
306 if (varList) {
Loganf340bf72011-01-14 17:51:40 +0800307 unwrap(script)->getExportVarList(varListSize, varList);
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800308
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700309#if DEBUG_BCC_REFLECT
Loganf340bf72011-01-14 17:51:40 +0800310 size_t count = unwrap(script)->getExportVarCount();
Steve Blockb20498e2011-12-20 16:24:20 +0000311 ALOGD("ExportVarCount = %lu\n", (unsigned long)count);
Loganbe79ada2011-01-13 01:33:45 +0800312
313 if (count > varListSize) {
314 count = varListSize;
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800315 }
Loganbe79ada2011-01-13 01:33:45 +0800316
317 for (size_t i = 0; i < count; ++i) {
Steve Blockb20498e2011-12-20 16:24:20 +0000318 ALOGD("ExportVarList[%lu] = %p\n", (unsigned long)i, varList[i]);
Loganbe79ada2011-01-13 01:33:45 +0800319 }
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800320#endif
Loganbe79ada2011-01-13 01:33:45 +0800321 }
Logan3f3d31f2010-11-27 13:52:03 +0800322}
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700323
Loganf340bf72011-01-14 17:51:40 +0800324
Loganf340bf72011-01-14 17:51:40 +0800325extern "C" void bccGetExportFuncList(BCCScriptRef script,
326 size_t funcListSize,
327 void **funcList) {
Logan3c01aaa2011-01-01 01:40:39 +0800328 BCC_FUNC_LOGGER();
Loganbe79ada2011-01-13 01:33:45 +0800329
Loganbe79ada2011-01-13 01:33:45 +0800330 if (funcList) {
Loganf340bf72011-01-14 17:51:40 +0800331 unwrap(script)->getExportFuncList(funcListSize, funcList);
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800332
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700333#if DEBUG_BCC_REFLECT
Loganf340bf72011-01-14 17:51:40 +0800334 size_t count = unwrap(script)->getExportFuncCount();
Steve Blockb20498e2011-12-20 16:24:20 +0000335 ALOGD("ExportFuncCount = %lu\n", (unsigned long)count);
Loganbe79ada2011-01-13 01:33:45 +0800336
337 if (count > funcListSize) {
338 count = funcListSize;
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800339 }
Loganbe79ada2011-01-13 01:33:45 +0800340
341 for (size_t i = 0; i < count; ++i) {
Steve Blockb20498e2011-12-20 16:24:20 +0000342 ALOGD("ExportFuncList[%lu] = %p\n", (unsigned long)i, funcList[i]);
Loganbe79ada2011-01-13 01:33:45 +0800343 }
Shih-wei Liaod6d488c2010-12-04 18:23:50 -0800344#endif
Loganbe79ada2011-01-13 01:33:45 +0800345 }
Logan3f3d31f2010-11-27 13:52:03 +0800346}
Stephen Hinescc366e52012-02-21 17:22:04 -0800347
348
349extern "C" void bccGetExportForEachList(BCCScriptRef script,
350 size_t forEachListSize,
351 void **forEachList) {
352 BCC_FUNC_LOGGER();
353
354 if (forEachList) {
355 unwrap(script)->getExportForEachList(forEachListSize, forEachList);
356
357#if DEBUG_BCC_REFLECT
358 size_t count = unwrap(script)->getExportForEachCount();
359 ALOGD("ExportForEachCount = %lu\n", (unsigned long)count);
360
361 if (count > forEachListSize) {
362 count = forEachListSize;
363 }
364
365 for (size_t i = 0; i < count; ++i) {
366 ALOGD("ExportForEachList[%lu] = %p\n", (unsigned long)i, forEachList[i]);
367 }
368#endif
369 }
370}