blob: 01ef32f05a07c5094bf3808219584433a1ba3e37 [file] [log] [blame]
Stephen Hines7dfc4d82012-05-03 12:25:21 -07001/*
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
Stephen Hines2f6a4932012-05-03 12:27:13 -070020#include <bcc/bcc.h>
Stephen Hinesead5ccb2012-05-03 12:30:38 -070021#include "bcc_internal.h"
22
23#include "Config.h"
24
25#include "Compiler.h"
26#include "DebugHelper.h"
27#include "Script.h"
Stephen Hines7dfc4d82012-05-03 12:25:21 -070028
Stephen Hines4a68b1c2012-05-03 12:28:14 -070029#include <string>
Stephen Hines7dfc4d82012-05-03 12:25:21 -070030
31#include <utils/StopWatch.h>
32
Stephen Hinesead5ccb2012-05-03 12:30:38 -070033#include <llvm/Support/CodeGen.h>
Stephen Hines7dfc4d82012-05-03 12:25:21 -070034
Stephen Hines7dfc4d82012-05-03 12:25:21 -070035using namespace bcc;
36
37namespace llvm {
38 class Module;
39}
40
41static bool bccBuildStampPrinted = false;
42
43static 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
51extern "C" BCCScriptRef bccCreateScript() {
Stephen Hines5b948192012-05-03 12:26:56 -070052 BCC_FUNC_LOGGER();
Stephen Hines7dfc4d82012-05-03 12:25:21 -070053 bccPrintBuildStamp();
Stephen Hinesead5ccb2012-05-03 12:30:38 -070054 return wrap(new bcc::Script());
Stephen Hines7dfc4d82012-05-03 12:25:21 -070055}
56
57
58extern "C" void bccDisposeScript(BCCScriptRef script) {
Stephen Hines5b948192012-05-03 12:26:56 -070059 BCC_FUNC_LOGGER();
Stephen Hines4a68b1c2012-05-03 12:28:14 -070060 delete unwrap(script);
Stephen Hines7dfc4d82012-05-03 12:25:21 -070061}
62
63
64extern "C" int bccRegisterSymbolCallback(BCCScriptRef script,
65 BCCSymbolLookupFn pFn,
66 void *pContext) {
Stephen Hines5b948192012-05-03 12:26:56 -070067 BCC_FUNC_LOGGER();
Stephen Hines4a68b1c2012-05-03 12:28:14 -070068 return unwrap(script)->registerSymbolCallback(pFn, pContext);
Stephen Hines7dfc4d82012-05-03 12:25:21 -070069}
70
71
72extern "C" int bccGetError(BCCScriptRef script) {
Stephen Hines5b948192012-05-03 12:26:56 -070073 BCC_FUNC_LOGGER();
Stephen Hines4a68b1c2012-05-03 12:28:14 -070074 return unwrap(script)->getError();
Stephen Hines7dfc4d82012-05-03 12:25:21 -070075}
76
Stephen Hines7dfc4d82012-05-03 12:25:21 -070077extern "C" int bccReadBC(BCCScriptRef script,
78 char const *resName,
79 char const *bitcode,
80 size_t bitcodeSize,
81 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -070082 BCC_FUNC_LOGGER();
Stephen Hinesead5ccb2012-05-03 12:30:38 -070083 return unwrap(script)->addSourceBC(0, resName, bitcode, bitcodeSize, flags);
Stephen Hines7dfc4d82012-05-03 12:25:21 -070084}
85
86
87extern "C" int bccReadModule(BCCScriptRef script,
88 char const *resName /* deprecated */,
89 LLVMModuleRef module,
90 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -070091 BCC_FUNC_LOGGER();
Stephen Hinesead5ccb2012-05-03 12:30:38 -070092 return unwrap(script)->addSourceModule(0, unwrap(module), flags);
Stephen Hines7dfc4d82012-05-03 12:25:21 -070093}
94
95
96extern "C" int bccReadFile(BCCScriptRef script,
97 char const *path,
98 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -070099 BCC_FUNC_LOGGER();
Stephen Hinesead5ccb2012-05-03 12:30:38 -0700100 return unwrap(script)->addSourceFile(0, path, flags);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700101}
102
103
104extern "C" int bccLinkBC(BCCScriptRef script,
105 char const *resName,
106 char const *bitcode,
107 size_t bitcodeSize,
108 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -0700109 BCC_FUNC_LOGGER();
Stephen Hinesead5ccb2012-05-03 12:30:38 -0700110 return unwrap(script)->addSourceBC(1, resName, bitcode, bitcodeSize, flags);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700111}
112
113
114extern "C" int bccLinkFile(BCCScriptRef script,
115 char const *path,
116 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -0700117 BCC_FUNC_LOGGER();
Stephen Hinesead5ccb2012-05-03 12:30:38 -0700118 return unwrap(script)->addSourceFile(1, path, flags);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700119}
120
121
122extern "C" void bccMarkExternalSymbol(BCCScriptRef script, char const *name) {
Stephen Hines5b948192012-05-03 12:26:56 -0700123 BCC_FUNC_LOGGER();
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700124 unwrap(script)->markExternalSymbol(name);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700125}
126
127
128extern "C" int bccPrepareRelocatable(BCCScriptRef script,
129 char const *objPath,
130 bccRelocModelEnum RelocModel,
131 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -0700132 BCC_FUNC_LOGGER();
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700133 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);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700159}
160
161
162extern "C" int bccPrepareSharedObject(BCCScriptRef script,
163 char const *objPath,
164 char const *dsoPath,
165 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -0700166 BCC_FUNC_LOGGER();
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700167 return unwrap(script)->prepareSharedObject(objPath, dsoPath, flags);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700168}
169
170
171extern "C" int bccPrepareExecutable(BCCScriptRef script,
172 char const *cacheDir,
173 char const *cacheName,
174 unsigned long flags) {
Stephen Hines5b948192012-05-03 12:26:56 -0700175 BCC_FUNC_LOGGER();
176
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700177 android::StopWatch compileTimer("bcc: PrepareExecutable time");
178
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700179 return unwrap(script)->prepareExecutable(cacheDir, cacheName, flags);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700180}
181
182
183extern "C" void *bccGetFuncAddr(BCCScriptRef script, char const *funcname) {
Stephen Hines5b948192012-05-03 12:26:56 -0700184 BCC_FUNC_LOGGER();
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700185
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700186 void *addr = unwrap(script)->lookup(funcname);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700187
188#if DEBUG_BCC_REFLECT
189 ALOGD("Function Address: %s --> %p\n", funcname, addr);
190#endif
191
192 return addr;
193}
194
195
196extern "C" void bccGetExportVarList(BCCScriptRef script,
197 size_t varListSize,
198 void **varList) {
Stephen Hines5b948192012-05-03 12:26:56 -0700199 BCC_FUNC_LOGGER();
200
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700201 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);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700207
208 if (count > varListSize) {
209 count = varListSize;
210 }
211
212 for (size_t i = 0; i < count; ++i) {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700213 ALOGD("ExportVarList[%lu] = %p\n", (unsigned long)i, varList[i]);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700214 }
215#endif
216 }
217}
218
219
220extern "C" void bccGetExportFuncList(BCCScriptRef script,
221 size_t funcListSize,
222 void **funcList) {
Stephen Hines5b948192012-05-03 12:26:56 -0700223 BCC_FUNC_LOGGER();
224
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700225 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);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700231
232 if (count > funcListSize) {
233 count = funcListSize;
234 }
235
236 for (size_t i = 0; i < count; ++i) {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700237 ALOGD("ExportFuncList[%lu] = %p\n", (unsigned long)i, funcList[i]);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700238 }
239#endif
240 }
241}
242
243
244extern "C" void bccGetExportForEachList(BCCScriptRef script,
245 size_t forEachListSize,
246 void **forEachList) {
Stephen Hines5b948192012-05-03 12:26:56 -0700247 BCC_FUNC_LOGGER();
248
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700249 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);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700255
256 if (count > forEachListSize) {
257 count = forEachListSize;
258 }
259
260 for (size_t i = 0; i < count; ++i) {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700261 ALOGD("ExportForEachList[%lu] = %p\n", (unsigned long)i, forEachList[i]);
Stephen Hines7dfc4d82012-05-03 12:25:21 -0700262 }
263#endif
264 }
265}