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