177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/*
2932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * Copyright 2010, The Android Open Source Project
377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao *
4932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * you may not use this file except in compliance with the License.
6932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * You may obtain a copy of the License at
7932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang *
8932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang *
10932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * Unless required by applicable law or agreed to in writing, software
11932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * See the License for the specific language governing permissions and
14932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang * limitations under the License.
1577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao */
1677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
17932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang// Bitcode compiler (bcc) for Android:
18932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang//    This is an eager-compilation JIT running on Android.
19932648d528f333d43defdf16b3f8e84afa865cc8Zonr Chang
20f340bf71ff377979d279132dcf5a801d76747d1fLogan#include <bcc/bcc.h>
21f340bf71ff377979d279132dcf5a801d76747d1fLogan#include "bcc_internal.h"
22f340bf71ff377979d279132dcf5a801d76747d1fLogan
23358490082d8435aa36feaff8107aa55c3cf363adLogan#include "Config.h"
24358490082d8435aa36feaff8107aa55c3cf363adLogan
25c4395235b212be7a626becb0c03020eab4859739Logan#include "Compiler.h"
264dcd6798f3db374a056ea6acc6b425f544c5207cLogan#include "DebugHelper.h"
27c4395235b212be7a626becb0c03020eab4859739Logan#include "Script.h"
2877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
29311c26faa483c639f03702a75220ca6f6509a01fLogan Chien#include <string>
30311c26faa483c639f03702a75220ca6f6509a01fLogan Chien
3139a2ca59c9021fe539c05b8c0520c56bd8b49a24Logan#include <utils/StopWatch.h>
327c5a5f755c5604950d8e31724ed02a532a47114bShih-wei Liao
33f340bf71ff377979d279132dcf5a801d76747d1fLoganusing namespace bcc;
34f340bf71ff377979d279132dcf5a801d76747d1fLogan
3539a2ca59c9021fe539c05b8c0520c56bd8b49a24Logannamespace llvm {
3639a2ca59c9021fe539c05b8c0520c56bd8b49a24Logan  class Module;
377c5a5f755c5604950d8e31724ed02a532a47114bShih-wei Liao}
387c5a5f755c5604950d8e31724ed02a532a47114bShih-wei Liao
393378a02729c2874b890e3939628a383ad0d1fe64Logan Chienstatic bool bccBuildStampPrinted = false;
403378a02729c2874b890e3939628a383ad0d1fe64Logan Chien
413378a02729c2874b890e3939628a383ad0d1fe64Logan Chienstatic void bccPrintBuildStamp() {
423378a02729c2874b890e3939628a383ad0d1fe64Logan Chien  if (!bccBuildStampPrinted) {
433378a02729c2874b890e3939628a383ad0d1fe64Logan Chien    LOGI("LIBBCC build time: %s", bccGetBuildTime());
443378a02729c2874b890e3939628a383ad0d1fe64Logan Chien    LOGI("LIBBCC build revision: %s", bccGetBuildRev());
453378a02729c2874b890e3939628a383ad0d1fe64Logan Chien    bccBuildStampPrinted = true;
463378a02729c2874b890e3939628a383ad0d1fe64Logan Chien  }
473378a02729c2874b890e3939628a383ad0d1fe64Logan Chien}
483378a02729c2874b890e3939628a383ad0d1fe64Logan Chien
49f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" BCCScriptRef bccCreateScript() {
503c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
513378a02729c2874b890e3939628a383ad0d1fe64Logan Chien  bccPrintBuildStamp();
52f340bf71ff377979d279132dcf5a801d76747d1fLogan  return wrap(new bcc::Script());
533f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
5477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
5539ebe2c22f8557752065465345bb3006d06e4497Shih-wei Liao
56f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" void bccDisposeScript(BCCScriptRef script) {
573c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
58f340bf71ff377979d279132dcf5a801d76747d1fLogan  delete unwrap(script);
593f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
6077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
6139ebe2c22f8557752065465345bb3006d06e4497Shih-wei Liao
62ce82d492bbcc4da2d5358275c27ec38eef060fbdShih-wei Liaoextern "C" int bccRegisterSymbolCallback(BCCScriptRef script,
63ce82d492bbcc4da2d5358275c27ec38eef060fbdShih-wei Liao                                         BCCSymbolLookupFn pFn,
64ce82d492bbcc4da2d5358275c27ec38eef060fbdShih-wei Liao                                         void *pContext) {
653c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
66f340bf71ff377979d279132dcf5a801d76747d1fLogan  return unwrap(script)->registerSymbolCallback(pFn, pContext);
673f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
6877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
6939ebe2c22f8557752065465345bb3006d06e4497Shih-wei Liao
70f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" int bccGetError(BCCScriptRef script) {
713c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
72f340bf71ff377979d279132dcf5a801d76747d1fLogan  return unwrap(script)->getError();
733f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
74abd1e3dd923239043a865a9eeaca69b24857e77eShih-wei Liao
75f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" int bccReadBC(BCCScriptRef script,
76f340bf71ff377979d279132dcf5a801d76747d1fLogan                         char const *resName,
77f340bf71ff377979d279132dcf5a801d76747d1fLogan                         char const *bitcode,
78f340bf71ff377979d279132dcf5a801d76747d1fLogan                         size_t bitcodeSize,
79f340bf71ff377979d279132dcf5a801d76747d1fLogan                         unsigned long flags) {
803c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
81474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return unwrap(script)->addSourceBC(0, resName, bitcode, bitcodeSize, flags);
823f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
836bfd542175fa5e0e15630b8c9e2982a8175073e8Shih-wei Liao
84f340bf71ff377979d279132dcf5a801d76747d1fLogan
85f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" int bccReadModule(BCCScriptRef script,
86474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                             char const *resName /* deprecated */,
87f340bf71ff377979d279132dcf5a801d76747d1fLogan                             LLVMModuleRef module,
88f340bf71ff377979d279132dcf5a801d76747d1fLogan                             unsigned long flags) {
893c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
90474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return unwrap(script)->addSourceModule(0, unwrap(module), flags);
91474cbd2fde362e63375f7a5099ca38b5c67835cfLogan}
92474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
93474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
94474cbd2fde362e63375f7a5099ca38b5c67835cfLoganextern "C" int bccReadFile(BCCScriptRef script,
95474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                           char const *path,
96474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                           unsigned long flags) {
97474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  BCC_FUNC_LOGGER();
98474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return unwrap(script)->addSourceFile(0, path, flags);
993f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
10077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
101f340bf71ff377979d279132dcf5a801d76747d1fLogan
102f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" int bccLinkBC(BCCScriptRef script,
103f340bf71ff377979d279132dcf5a801d76747d1fLogan                         char const *resName,
104f340bf71ff377979d279132dcf5a801d76747d1fLogan                         char const *bitcode,
105f340bf71ff377979d279132dcf5a801d76747d1fLogan                         size_t bitcodeSize,
106f340bf71ff377979d279132dcf5a801d76747d1fLogan                         unsigned long flags) {
1073c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
108474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return unwrap(script)->addSourceBC(1, resName, bitcode, bitcodeSize, flags);
109474cbd2fde362e63375f7a5099ca38b5c67835cfLogan}
110474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
111474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
112474cbd2fde362e63375f7a5099ca38b5c67835cfLoganextern "C" int bccLinkFile(BCCScriptRef script,
113474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                           char const *path,
114474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                           unsigned long flags) {
115474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  BCC_FUNC_LOGGER();
116474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return unwrap(script)->addSourceFile(1, path, flags);
1173f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
11877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
119f340bf71ff377979d279132dcf5a801d76747d1fLogan
1207890d437030c1594bc9c9f61fa1e80a57754b078Logan Chienextern "C" void bccMarkExternalSymbol(BCCScriptRef script, char const *name) {
1217890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien  BCC_FUNC_LOGGER();
1227890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien  unwrap(script)->markExternalSymbol(name);
1237890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien}
1247890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien
1257890d437030c1594bc9c9f61fa1e80a57754b078Logan Chien
12634c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wenextern "C" int bccPrepareSharedObject(BCCScriptRef script,
12734c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen                                      char const *cacheDir,
12834c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen                                      char const *cacheName,
12934c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen                                      unsigned long flags) {
13034c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen  return unwrap(script)->prepareSharedObject(cacheDir, cacheName, flags);
13134c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen}
13234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
13334c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen
134f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" int bccPrepareExecutable(BCCScriptRef script,
135c2be0a15b2dfcc6f471527a0112ac42d51a0bf2fLogan Chien                                    char const *cacheDir,
136c2be0a15b2dfcc6f471527a0112ac42d51a0bf2fLogan Chien                                    char const *cacheName,
137f340bf71ff377979d279132dcf5a801d76747d1fLogan                                    unsigned long flags) {
138311c26faa483c639f03702a75220ca6f6509a01fLogan Chien  BCC_FUNC_LOGGER();
139311c26faa483c639f03702a75220ca6f6509a01fLogan Chien
140f6267d1f0c65b10fa1d9b8aae08ad2c31df4a2e8Shih-wei Liao  android::StopWatch compileTimer("bcc: PrepareExecutable time");
141d80e65b0376b721220be0caaeccb2adf5866521cLogan
142311c26faa483c639f03702a75220ca6f6509a01fLogan Chien  return unwrap(script)->prepareExecutable(cacheDir, cacheName, flags);
1433f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
1447c5a5f755c5604950d8e31724ed02a532a47114bShih-wei Liao
14577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
146f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" void *bccGetFuncAddr(BCCScriptRef script, char const *funcname) {
1473c01aaae81208937b7a961f330b27f83eded9cbaLogan  BCC_FUNC_LOGGER();
148f340bf71ff377979d279132dcf5a801d76747d1fLogan
149f340bf71ff377979d279132dcf5a801d76747d1fLogan  void *addr = unwrap(script)->lookup(funcname);
150f340bf71ff377979d279132dcf5a801d76747d1fLogan
1519f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
1522d37d30d205d907125d3560834c9cd13f5c4eee2Logan Chien  LOGD("Function Address: %s --> %p\n", funcname, addr);
153d6d488c22238badd2a1e13c4bfc68f952e8cc43aShih-wei Liao#endif
154f340bf71ff377979d279132dcf5a801d76747d1fLogan
155f340bf71ff377979d279132dcf5a801d76747d1fLogan  return addr;
1563f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
15777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
158f340bf71ff377979d279132dcf5a801d76747d1fLogan
159f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" void bccGetExportVarList(BCCScriptRef script,
160f340bf71ff377979d279132dcf5a801d76747d1fLogan                                    size_t varListSize,
161f340bf71ff377979d279132dcf5a801d76747d1fLogan                                    void **varList) {
162f340bf71ff377979d279132dcf5a801d76747d1fLogan  BCC_FUNC_LOGGER();
163be79ada39b5e77b638940d2e157a45904ee09275Logan
164be79ada39b5e77b638940d2e157a45904ee09275Logan  if (varList) {
165f340bf71ff377979d279132dcf5a801d76747d1fLogan    unwrap(script)->getExportVarList(varListSize, varList);
166d6d488c22238badd2a1e13c4bfc68f952e8cc43aShih-wei Liao
1679f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
168f340bf71ff377979d279132dcf5a801d76747d1fLogan    size_t count = unwrap(script)->getExportVarCount();
169be79ada39b5e77b638940d2e157a45904ee09275Logan    LOGD("ExportVarCount = %lu\n", (unsigned long)count);
170be79ada39b5e77b638940d2e157a45904ee09275Logan
171be79ada39b5e77b638940d2e157a45904ee09275Logan    if (count > varListSize) {
172be79ada39b5e77b638940d2e157a45904ee09275Logan      count = varListSize;
173be79ada39b5e77b638940d2e157a45904ee09275Logan    }
174be79ada39b5e77b638940d2e157a45904ee09275Logan
175be79ada39b5e77b638940d2e157a45904ee09275Logan    for (size_t i = 0; i < count; ++i) {
1762d37d30d205d907125d3560834c9cd13f5c4eee2Logan Chien      LOGD("ExportVarList[%lu] = %p\n", (unsigned long)i, varList[i]);
177d6d488c22238badd2a1e13c4bfc68f952e8cc43aShih-wei Liao    }
178d6d488c22238badd2a1e13c4bfc68f952e8cc43aShih-wei Liao#endif
179be79ada39b5e77b638940d2e157a45904ee09275Logan  }
1803f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
18177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
182f340bf71ff377979d279132dcf5a801d76747d1fLogan
183f340bf71ff377979d279132dcf5a801d76747d1fLoganextern "C" void bccGetExportFuncList(BCCScriptRef script,
184f340bf71ff377979d279132dcf5a801d76747d1fLogan                                     size_t funcListSize,
185f340bf71ff377979d279132dcf5a801d76747d1fLogan                                     void **funcList) {
186f340bf71ff377979d279132dcf5a801d76747d1fLogan  BCC_FUNC_LOGGER();
187be79ada39b5e77b638940d2e157a45904ee09275Logan
188be79ada39b5e77b638940d2e157a45904ee09275Logan  if (funcList) {
189f340bf71ff377979d279132dcf5a801d76747d1fLogan    unwrap(script)->getExportFuncList(funcListSize, funcList);
190d6d488c22238badd2a1e13c4bfc68f952e8cc43aShih-wei Liao
1919f73de0deb296f6431523e2ebb2f888ee21c0bb4Shih-wei Liao#if DEBUG_BCC_REFLECT
192f340bf71ff377979d279132dcf5a801d76747d1fLogan    size_t count = unwrap(script)->getExportFuncCount();
193be79ada39b5e77b638940d2e157a45904ee09275Logan    LOGD("ExportFuncCount = %lu\n", (unsigned long)count);
194be79ada39b5e77b638940d2e157a45904ee09275Logan
195be79ada39b5e77b638940d2e157a45904ee09275Logan    if (count > funcListSize) {
196be79ada39b5e77b638940d2e157a45904ee09275Logan      count = funcListSize;
197be79ada39b5e77b638940d2e157a45904ee09275Logan    }
198be79ada39b5e77b638940d2e157a45904ee09275Logan
199be79ada39b5e77b638940d2e157a45904ee09275Logan    for (size_t i = 0; i < count; ++i) {
2002d37d30d205d907125d3560834c9cd13f5c4eee2Logan Chien      LOGD("ExportFuncList[%lu] = %p\n", (unsigned long)i, funcList[i]);
201d6d488c22238badd2a1e13c4bfc68f952e8cc43aShih-wei Liao    }
202d6d488c22238badd2a1e13c4bfc68f952e8cc43aShih-wei Liao#endif
203be79ada39b5e77b638940d2e157a45904ee09275Logan  }
2043f3d31fc9eac3d82ed9d04690aafb58f1715b8d8Logan}
20577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao
206