blob: 7c79254162b617b766338dadee2edbd2fbca4838 [file] [log] [blame]
Logancf3e5212010-12-29 01:44:55 +08001/*
Stephen Hinescc366e52012-02-21 17:22:04 -08002 * copyright 2010-2012, the android open source project
Logancf3e5212010-12-29 01:44:55 +08003 *
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
Logancf3e5212010-12-29 01:44:55 +080017#include "Script.h"
18
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070019#include <errno.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <unistd.h>
23
24#include <new>
25#include <cstring>
26
27#include <llvm/ADT/STLExtras.h>
28
29#include <cutils/properties.h>
30
Logan35849002011-01-15 07:30:43 +080031#include "Config.h"
32
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -070033#include "MCCacheReader.h"
34#include "MCCacheWriter.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080035#include "CompilerOption.h"
Logan Chiend2a5f302011-07-19 20:32:25 +080036
Zonr Changc09dee62012-04-12 17:15:30 +080037#include "BCCContextImpl.h"
Logan4dcd6792011-02-28 05:12:00 +080038#include "DebugHelper.h"
Logan04329712011-01-06 06:10:57 +080039#include "FileHandle.h"
Daniel Malea094881f2011-12-14 17:39:16 -050040#include "GDBJITRegistrar.h"
Logancf3e5212010-12-29 01:44:55 +080041#include "ScriptCompiled.h"
Logan9a5f8682011-01-07 06:09:57 +080042#include "ScriptCached.h"
43#include "Sha1Helper.h"
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070044#include "Source.h"
Logan033f46e2011-01-06 05:51:24 +080045
Loganecf4cbd2011-01-06 05:34:11 +080046namespace {
47
Logan033f46e2011-01-06 05:51:24 +080048bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080049 char buf[PROPERTY_VALUE_MAX];
50 property_get(str, buf, "0");
51 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080052}
53
Loganecf4cbd2011-01-06 05:34:11 +080054} // namespace anonymous
55
Logancf3e5212010-12-29 01:44:55 +080056namespace bcc {
57
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070058Script::Script(Source &pSource)
59 : mSource(&pSource),
60 mpExtSymbolLookupFn(NULL),
61 mpExtSymbolLookupFnContext(NULL) {
62 resetState();
63 return;
64}
65
Logancf3e5212010-12-29 01:44:55 +080066Script::~Script() {
Logan35849002011-01-15 07:30:43 +080067 switch (mStatus) {
68 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080069 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080070 break;
71
Logan35849002011-01-15 07:30:43 +080072 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080073 delete mCached;
Logan35849002011-01-15 07:30:43 +080074 break;
Logan35849002011-01-15 07:30:43 +080075
76 default:
77 break;
Logancf3e5212010-12-29 01:44:55 +080078 }
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070079 llvm::DeleteContainerPointers(mDependencyInfos);
80}
Logan474cbd22011-01-31 01:47:44 +080081
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070082void Script::resetState() {
83 mErrorCode = BCC_NO_ERROR;
84 mStatus = ScriptStatus::Unknown;
85 mObjectType = ScriptObject::Unknown;
86 mIsContextSlotNotAvail = false;
87 // FIXME: mpExtSymbolLookupFn and mpExtSymbolLookupFnContext should be assign
88 // to NULL during state resetting.
89 //mpExtSymbolLookupFn = NULL;
90 //mpExtSymbolLookupFnContext = NULL;
91 llvm::DeleteContainerPointers(mDependencyInfos);
92 return;
Logancf3e5212010-12-29 01:44:55 +080093}
94
95
Shih-wei Liao4ce024b2012-04-25 03:40:50 -070096Script::DependencyInfo::DependencyInfo(MCO_ResourceType pSourceType,
97 const std::string &pSourceName,
98 const uint8_t *pSHA1)
99 : mSourceType(pSourceType), mSourceName(pSourceName) {
100 ::memcpy(mSHA1, pSHA1, sizeof(mSHA1));
101 return;
Logancf3e5212010-12-29 01:44:55 +0800102}
103
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700104bool Script::reset(Source &pSource, bool pPreserveCurrent) {
105 if (mSource == &pSource) {
106 return false;
Logancf3e5212010-12-29 01:44:55 +0800107 }
108
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700109 if (!pPreserveCurrent) {
110 delete mSource;
Logan474cbd22011-01-31 01:47:44 +0800111 }
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700112 mSource = &pSource;
113 resetState();
114 return true;
Logancf3e5212010-12-29 01:44:55 +0800115}
116
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700117bool Script::mergeSource(Source &pSource, bool pPreserveSource) {
118 return mSource->merge(pSource, pPreserveSource);
119}
Logancf3e5212010-12-29 01:44:55 +0800120
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700121bool Script::addSourceDependencyInfo(MCO_ResourceType pSourceType,
122 const std::string &pSourceName,
123 const uint8_t *pSHA1) {
124 DependencyInfo *dep_info = new (std::nothrow) DependencyInfo(pSourceType,
125 pSourceName,
126 pSHA1);
127 if (dep_info == NULL) {
128 ALOGE("Out of memory when record dependency information of `%s'!",
129 pSourceName.c_str());
130 return false;
Logancf3e5212010-12-29 01:44:55 +0800131 }
132
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700133 mDependencyInfos.push_back(dep_info);
134 return true;
Logancf3e5212010-12-29 01:44:55 +0800135}
136
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800137int Script::prepareRelocatable(char const *objPath,
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -0800138 llvm::Reloc::Model RelocModel,
139 unsigned long flags) {
Zonr Chang2fcbd022012-01-06 21:04:31 +0800140 CompilerOption option;
Shih-wei Liao8afed382012-01-10 15:57:24 +0800141 option.RelocModelOpt = RelocModel;
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700142 option.RunLTO = false;
Zonr Chang2fcbd022012-01-06 21:04:31 +0800143 option.LoadAfterCompile = false;
Shih-wei Liao8454a3a2012-03-03 01:50:08 -0800144
Zonr Chang2fcbd022012-01-06 21:04:31 +0800145 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700146 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000147 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800148 return status;
149 }
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800150
151 FileHandle objFile;
152 if (objFile.open(objPath, OpenMode::Write) < 0) {
153 ALOGE("Failed to open %s for write.\n", objPath);
154 return 1;
Joseph Wen34c600a2011-07-25 17:59:17 -0700155 }
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800156
157 if (static_cast<size_t>(objFile.write(getELF(),
158 getELFSize())) != getELFSize()) {
159 objFile.close();
160 ::unlink(objPath);
161 ALOGE("Unable to write ELF to file %s.\n", objPath);
162 return false;
163 }
164
Shih-wei Liao8454a3a2012-03-03 01:50:08 -0800165 mObjectType = ScriptObject::Relocatable;
166
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800167 return 0;
Joseph Wen34c600a2011-07-25 17:59:17 -0700168}
169
Logancf3e5212010-12-29 01:44:55 +0800170
Shih-wei Liao69341742012-03-03 01:45:36 -0800171int Script::prepareSharedObject(char const *objPath,
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -0800172 char const *dsoPath,
173 unsigned long flags) {
174 // TODO: Support cached shared object.
175 return 1;
176}
177
178
Logan Chien311c26f2011-07-11 14:30:34 +0800179int Script::prepareExecutable(char const *cacheDir,
180 char const *cacheName,
181 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800182 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800183 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000184 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800185 return 1;
186 }
187
Stephen Hines0e567862012-03-11 20:26:40 -0700188 int status = internalLoadCache(cacheDir, cacheName, /* checkOnly */ false);
Loganecf4cbd2011-01-06 05:34:11 +0800189
Stephen Hinese0918ac2012-03-01 23:28:09 -0800190 if (status != 0) {
191 CompilerOption option;
192 status = internalCompile(option);
Stephen Hinese0918ac2012-03-01 23:28:09 -0800193
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800194 if (status != 0) {
195 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
196 return status;
197 }
198
199 status = writeCache();
200 if (status != 0) {
201 ALOGE("Failed to write the cache for %s\n", cacheName);
202 return status;
203 }
Stephen Hines27b35102011-05-11 17:58:48 -0700204 }
Daniel Malea094881f2011-12-14 17:39:16 -0500205
206 // FIXME: Registration can be conditional on the presence of debug metadata
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800207 registerObjectWithGDB(getELF(), getELFSize()); // thread-safe registration
208
Shih-wei Liao8454a3a2012-03-03 01:50:08 -0800209 mObjectType = ScriptObject::Executable;
210
Stephen Hines27b35102011-05-11 17:58:48 -0700211 return status;
Logan033f46e2011-01-06 05:51:24 +0800212}
213
Zonr Chang743dd712012-01-19 10:13:52 +0800214int Script::internalLoadCache(char const *cacheDir, char const *cacheName,
Zonr Chang743dd712012-01-19 10:13:52 +0800215 bool checkOnly) {
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800216 if ((cacheDir == NULL) || (cacheName == NULL)) {
Zonr Chang743dd712012-01-19 10:13:52 +0800217 return 1;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800218 }
Zonr Chang743dd712012-01-19 10:13:52 +0800219
220 // Set cache file Name
221 mCacheName = cacheName;
222
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800223 // Santize mCacheDir. Ensure that mCacheDir ends with '/'.
Zonr Chang743dd712012-01-19 10:13:52 +0800224 mCacheDir = cacheDir;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800225 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
Zonr Chang743dd712012-01-19 10:13:52 +0800226 mCacheDir.push_back('/');
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800227 }
Zonr Chang743dd712012-01-19 10:13:52 +0800228
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800229 if (!isCacheable()) {
Logan033f46e2011-01-06 05:51:24 +0800230 return 1;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800231 }
Logan04329712011-01-06 06:10:57 +0800232
Zonr Chang4ea08862012-01-17 17:26:49 +0800233 std::string objPath = getCachedObjectPath();
234 std::string infoPath = getCacheInfoPath();
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700235
Logan Chien311c26f2011-07-11 14:30:34 +0800236 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700237 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800238 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800239 return 1;
240 }
241
Logan Chien311c26f2011-07-11 14:30:34 +0800242 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700243 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800244 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700245 return 1;
246 }
247
248 MCCacheReader reader;
249
250 // Register symbol lookup function
251 if (mpExtSymbolLookupFn) {
252 reader.registerSymbolCallback(mpExtSymbolLookupFn,
253 mpExtSymbolLookupFnContext);
254 }
Logan04329712011-01-06 06:10:57 +0800255
Logan9a5f8682011-01-07 06:09:57 +0800256 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700257 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700258 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800259
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700260 for (unsigned i = 0; i < mDependencyInfos.size(); i++) {
261 const DependencyInfo *dep_info = mDependencyInfos[i];
262 reader.addDependency(dep_info->getSourceType(),
263 dep_info->getSourceName(),
264 dep_info->getSHA1Checksum());
Logan9a5f8682011-01-07 06:09:57 +0800265 }
266
Joseph Wen34c600a2011-07-25 17:59:17 -0700267 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700268 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700269
Logan9a5f8682011-01-07 06:09:57 +0800270 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700271 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700272
Logan04329712011-01-06 06:10:57 +0800273 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800274 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800275 return 1;
276 }
277
278 mCached = cached;
279 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800280
Loganf3c83ce2011-01-07 06:36:33 +0800281 // Dirty hack for libRS.
282 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800283 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800284 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
285 }
286
Loganf7f0ac52011-01-07 03:53:43 +0800287 return 0;
Logan033f46e2011-01-06 05:51:24 +0800288}
289
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800290int Script::internalCompile(const CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800291 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800292 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800293
294 if (!mCompiled) {
295 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000296 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800297 return 1;
298 }
299
300 mStatus = ScriptStatus::Compiled;
301
Logan033f46e2011-01-06 05:51:24 +0800302 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800303 if (mpExtSymbolLookupFn) {
304 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
305 mpExtSymbolLookupFnContext);
306 }
307
Zonr Changdf3fee42012-01-10 15:58:36 +0800308 // Set the main source module
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700309 if (mCompiled->readModule(mSource->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000310 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800311 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800312 }
313
Logan3133c412011-01-06 06:15:40 +0800314 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800315 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000316 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800317 return 1;
318 }
319
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800320 return 0;
321}
322
323int Script::writeCache() {
Stephen Hines3e36c692012-03-05 12:39:45 -0800324 // Not compiled script or encountered error during the compilation.
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800325 if ((mStatus != ScriptStatus::Compiled) ||
326 (getCompilerErrorMessage() == NULL))
327 return 1;
328
Logan42598052011-01-26 22:41:13 +0800329 // Note: If we re-compile the script because the cached context slot not
330 // available, then we don't have to write the cache.
331
332 // Note: If the address of the context is not in the context slot, then
333 // we don't have to cache it.
334
Stephen Hines9ddeb6b2012-03-11 18:41:03 -0700335 if (isCacheable()) {
Logan42598052011-01-26 22:41:13 +0800336
Zonr Chang4ea08862012-01-17 17:26:49 +0800337 std::string objPath = getCachedObjectPath();
338 std::string infoPath = getCacheInfoPath();
Logan Chien311c26f2011-07-11 14:30:34 +0800339
Jeff Brown937a0bc2011-01-26 23:20:14 -0800340 // Remove the file if it already exists before writing the new file.
341 // The old file may still be mapped elsewhere in memory and we do not want
342 // to modify its contents. (The same script may be running concurrently in
343 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700344 ::unlink(objPath.c_str());
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700345 ::unlink(infoPath.c_str());
Jeff Brown937a0bc2011-01-26 23:20:14 -0800346
Logan Chien03a2e302011-07-13 21:46:32 +0800347 FileHandle objFile;
348 FileHandle infoFile;
349
350 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
351 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700352
Logan Chien311c26f2011-07-11 14:30:34 +0800353 MCCacheWriter writer;
Logana27a83f2011-01-07 10:25:48 +0800354
Joseph Wen2ca6e572011-06-24 14:12:23 -0700355#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800356 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700357 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700358 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800359#endif
Logana2e15af2011-01-07 11:46:08 +0800360
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700361 for (unsigned i = 0; i < mDependencyInfos.size(); i++) {
362 const DependencyInfo *dep_info = mDependencyInfos[i];
363 writer.addDependency(dep_info->getSourceType(),
364 dep_info->getSourceName(),
365 dep_info->getSHA1Checksum());
Logana2e15af2011-01-07 11:46:08 +0800366 }
367
Shih-wei Liao4ce024b2012-04-25 03:40:50 -0700368
Logana27a83f2011-01-07 10:25:48 +0800369 // libRS is threadable dirty hack
370 // TODO: This should be removed in the future
371 uint32_t libRS_threadable = 0;
372 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800373 libRS_threadable =
374 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
375 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800376 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700377
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700378 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700379 objFile.truncate();
380 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800381
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700382 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000383 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700384 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800385 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700386
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700387 infoFile.truncate();
388 infoFile.close();
389
390 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000391 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700392 infoPath.c_str(), strerror(errno));
393 }
Logan89eb47f2011-01-07 10:45:16 +0800394 }
395 }
Logan04329712011-01-06 06:10:57 +0800396 }
Logan04329712011-01-06 06:10:57 +0800397
398 return 0;
Logancf3e5212010-12-29 01:44:55 +0800399}
400
401
402char const *Script::getCompilerErrorMessage() {
403 if (mStatus != ScriptStatus::Compiled) {
404 mErrorCode = BCC_INVALID_OPERATION;
405 return NULL;
406 }
407
408 return mCompiled->getCompilerErrorMessage();
409}
410
411
412void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800413 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700414 case ScriptStatus::Compiled: {
415 return mCompiled->lookup(name);
416 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700417
Shih-wei Liaod50be322011-07-01 22:53:31 -0700418 case ScriptStatus::Cached: {
419 return mCached->lookup(name);
420 }
Logan89eb47f2011-01-07 10:45:16 +0800421
Shih-wei Liaod50be322011-07-01 22:53:31 -0700422 default: {
423 mErrorCode = BCC_INVALID_OPERATION;
424 return NULL;
425 }
Logancf3e5212010-12-29 01:44:55 +0800426 }
Logancf3e5212010-12-29 01:44:55 +0800427}
428
429
Loganbe79ada2011-01-13 01:33:45 +0800430size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800431 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700432 case ScriptStatus::Compiled: {
433 return mCompiled->getExportVarCount();
434 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700435
Shih-wei Liaod50be322011-07-01 22:53:31 -0700436 case ScriptStatus::Cached: {
437 return mCached->getExportVarCount();
438 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700439
Shih-wei Liaod50be322011-07-01 22:53:31 -0700440 default: {
441 return 0;
442 }
Loganbe79ada2011-01-13 01:33:45 +0800443 }
444}
445
446
447size_t Script::getExportFuncCount() const {
448 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700449 case ScriptStatus::Compiled: {
450 return mCompiled->getExportFuncCount();
451 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700452
Shih-wei Liaod50be322011-07-01 22:53:31 -0700453 case ScriptStatus::Cached: {
454 return mCached->getExportFuncCount();
455 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700456
Shih-wei Liaod50be322011-07-01 22:53:31 -0700457 default: {
458 return 0;
459 }
Loganbe79ada2011-01-13 01:33:45 +0800460 }
461}
462
463
Stephen Hinescc366e52012-02-21 17:22:04 -0800464size_t Script::getExportForEachCount() const {
465 switch (mStatus) {
466 case ScriptStatus::Compiled: {
467 return mCompiled->getExportForEachCount();
468 }
469
Stephen Hinescc366e52012-02-21 17:22:04 -0800470 case ScriptStatus::Cached: {
471 return mCached->getExportForEachCount();
472 }
Stephen Hinescc366e52012-02-21 17:22:04 -0800473
474 default: {
475 return 0;
476 }
477 }
478}
479
480
Loganbe79ada2011-01-13 01:33:45 +0800481size_t Script::getPragmaCount() const {
482 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700483 case ScriptStatus::Compiled: {
484 return mCompiled->getPragmaCount();
485 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700486
Shih-wei Liaod50be322011-07-01 22:53:31 -0700487 case ScriptStatus::Cached: {
488 return mCached->getPragmaCount();
489 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700490
Shih-wei Liaod50be322011-07-01 22:53:31 -0700491 default: {
492 return 0;
493 }
Loganbe79ada2011-01-13 01:33:45 +0800494 }
495}
496
497
498size_t Script::getFuncCount() const {
499 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700500 case ScriptStatus::Compiled: {
501 return mCompiled->getFuncCount();
502 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700503
Shih-wei Liaod50be322011-07-01 22:53:31 -0700504 case ScriptStatus::Cached: {
505 return mCached->getFuncCount();
506 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700507
Shih-wei Liaod50be322011-07-01 22:53:31 -0700508 default: {
509 return 0;
510 }
Loganbe79ada2011-01-13 01:33:45 +0800511 }
512}
513
514
Stephen Hines071288a2011-01-27 14:38:26 -0800515size_t Script::getObjectSlotCount() const {
516 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700517 case ScriptStatus::Compiled: {
518 return mCompiled->getObjectSlotCount();
519 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700520
Shih-wei Liaod50be322011-07-01 22:53:31 -0700521 case ScriptStatus::Cached: {
522 return mCached->getObjectSlotCount();
523 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700524
Shih-wei Liaod50be322011-07-01 22:53:31 -0700525 default: {
526 return 0;
527 }
Stephen Hines071288a2011-01-27 14:38:26 -0800528 }
529}
530
531
Loganbe79ada2011-01-13 01:33:45 +0800532void Script::getExportVarList(size_t varListSize, void **varList) {
533 switch (mStatus) {
534#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700535 case ScriptStatus::STATUS: \
536 m##STATUS->getExportVarList(varListSize, varList); \
537 break;
Logancf3e5212010-12-29 01:44:55 +0800538
Shih-wei Liaod50be322011-07-01 22:53:31 -0700539 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800540
Shih-wei Liaod50be322011-07-01 22:53:31 -0700541 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800542#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800543
Shih-wei Liaod50be322011-07-01 22:53:31 -0700544 default: {
545 mErrorCode = BCC_INVALID_OPERATION;
546 }
Logan89eb47f2011-01-07 10:45:16 +0800547 }
Logancf3e5212010-12-29 01:44:55 +0800548}
549
Joseph Wenf36637f2011-07-06 18:27:12 -0700550void Script::getExportVarNameList(std::vector<std::string> &varList) {
551 switch (mStatus) {
552 case ScriptStatus::Compiled: {
553 return mCompiled->getExportVarNameList(varList);
554 }
555
556 default: {
557 mErrorCode = BCC_INVALID_OPERATION;
558 }
559 }
560}
561
Logancf3e5212010-12-29 01:44:55 +0800562
Loganbe79ada2011-01-13 01:33:45 +0800563void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800564 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800565#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700566 case ScriptStatus::STATUS: \
567 m##STATUS->getExportFuncList(funcListSize, funcList); \
568 break;
Logancf3e5212010-12-29 01:44:55 +0800569
Shih-wei Liaod50be322011-07-01 22:53:31 -0700570 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800571
Shih-wei Liaod50be322011-07-01 22:53:31 -0700572 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800573#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800574
Shih-wei Liaod50be322011-07-01 22:53:31 -0700575 default: {
576 mErrorCode = BCC_INVALID_OPERATION;
577 }
Logan89eb47f2011-01-07 10:45:16 +0800578 }
Logancf3e5212010-12-29 01:44:55 +0800579}
580
Joseph Wenf36637f2011-07-06 18:27:12 -0700581void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
582 switch (mStatus) {
583 case ScriptStatus::Compiled: {
584 return mCompiled->getExportFuncNameList(funcList);
585 }
586
587 default: {
588 mErrorCode = BCC_INVALID_OPERATION;
589 }
590 }
591}
592
Stephen Hinescc366e52012-02-21 17:22:04 -0800593void Script::getExportForEachList(size_t funcListSize, void **funcList) {
594 switch (mStatus) {
595#define DELEGATE(STATUS) \
596 case ScriptStatus::STATUS: \
597 m##STATUS->getExportForEachList(funcListSize, funcList); \
598 break;
599
Stephen Hinescc366e52012-02-21 17:22:04 -0800600 DELEGATE(Cached);
Stephen Hinescc366e52012-02-21 17:22:04 -0800601
602 DELEGATE(Compiled);
603#undef DELEGATE
604
605 default: {
606 mErrorCode = BCC_INVALID_OPERATION;
607 }
608 }
609}
610
611void Script::getExportForEachNameList(std::vector<std::string> &forEachList) {
612 switch (mStatus) {
613 case ScriptStatus::Compiled: {
614 return mCompiled->getExportForEachNameList(forEachList);
615 }
616
617 default: {
618 mErrorCode = BCC_INVALID_OPERATION;
619 }
620 }
621}
Logancf3e5212010-12-29 01:44:55 +0800622
Loganbe79ada2011-01-13 01:33:45 +0800623void Script::getPragmaList(size_t pragmaListSize,
624 char const **keyList,
625 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800626 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800627#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700628 case ScriptStatus::STATUS: \
629 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
630 break;
Logancf3e5212010-12-29 01:44:55 +0800631
Shih-wei Liaod50be322011-07-01 22:53:31 -0700632 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800633
Shih-wei Liaod50be322011-07-01 22:53:31 -0700634 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800635#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800636
Shih-wei Liaod50be322011-07-01 22:53:31 -0700637 default: {
638 mErrorCode = BCC_INVALID_OPERATION;
639 }
Logan89eb47f2011-01-07 10:45:16 +0800640 }
Logancf3e5212010-12-29 01:44:55 +0800641}
642
643
Loganf340bf72011-01-14 17:51:40 +0800644void Script::getFuncInfoList(size_t funcInfoListSize,
645 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800646 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800647#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700648 case ScriptStatus::STATUS: \
649 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
650 break;
Logancf3e5212010-12-29 01:44:55 +0800651
Shih-wei Liaod50be322011-07-01 22:53:31 -0700652 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800653
Shih-wei Liaod50be322011-07-01 22:53:31 -0700654 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800655#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800656
Shih-wei Liaod50be322011-07-01 22:53:31 -0700657 default: {
658 mErrorCode = BCC_INVALID_OPERATION;
659 }
Logan89eb47f2011-01-07 10:45:16 +0800660 }
Logancf3e5212010-12-29 01:44:55 +0800661}
662
Stephen Hines071288a2011-01-27 14:38:26 -0800663
664void Script::getObjectSlotList(size_t objectSlotListSize,
665 uint32_t *objectSlotList) {
666 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700667#define DELEGATE(STATUS) \
668 case ScriptStatus::STATUS: \
669 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
670 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800671
Shih-wei Liaod50be322011-07-01 22:53:31 -0700672 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800673
Shih-wei Liaod50be322011-07-01 22:53:31 -0700674 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800675#undef DELEGATE
676
Shih-wei Liaod50be322011-07-01 22:53:31 -0700677 default: {
678 mErrorCode = BCC_INVALID_OPERATION;
679 }
Stephen Hines071288a2011-01-27 14:38:26 -0800680 }
681}
682
683
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800684int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800685 mpExtSymbolLookupFn = pFn;
686 mpExtSymbolLookupFnContext = pContext;
687
Logan7d2219f2011-01-06 06:19:25 +0800688 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800689 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000690 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800691 return 1;
Logancf3e5212010-12-29 01:44:55 +0800692 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800693 return 0;
Logancf3e5212010-12-29 01:44:55 +0800694}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700695
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800696bool Script::isCacheable() const {
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800697 if (getBooleanProp("debug.bcc.nocache")) {
698 // Android system environment property: Disables the cache mechanism by
699 // setting "debug.bcc.nocache". So we will not load the cache file any
700 // way.
701 return false;
702 }
703
704 if (mCacheDir.empty() || mCacheName.empty()) {
705 // The application developer has not specified the cachePath, so
706 // we don't know where to open the cache file.
707 return false;
708 }
709
710 return true;
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800711}
712
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700713size_t Script::getELFSize() const {
714 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700715 case ScriptStatus::Compiled: {
716 return mCompiled->getELFSize();
717 }
Stephen Hines0e567862012-03-11 20:26:40 -0700718
Daniel Malea094881f2011-12-14 17:39:16 -0500719 case ScriptStatus::Cached: {
720 return mCached->getELFSize();
721 }
Stephen Hines0e567862012-03-11 20:26:40 -0700722
Shih-wei Liaod50be322011-07-01 22:53:31 -0700723 default: {
724 return 0;
725 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700726 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700727}
728
729const char *Script::getELF() const {
730 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700731 case ScriptStatus::Compiled: {
732 return mCompiled->getELF();
733 }
Stephen Hines0e567862012-03-11 20:26:40 -0700734
Daniel Malea094881f2011-12-14 17:39:16 -0500735 case ScriptStatus::Cached: {
736 return mCached->getELF();
737 }
Stephen Hines0e567862012-03-11 20:26:40 -0700738
Shih-wei Liaod50be322011-07-01 22:53:31 -0700739 default: {
740 return NULL;
741 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700742 }
743}
Logancf3e5212010-12-29 01:44:55 +0800744
745} // namespace bcc