blob: 65f7dfb5bbfd58184ae9a91805b27af07450b2b0 [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
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
20
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -070021#include "MCCacheReader.h"
22#include "MCCacheWriter.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080023#include "CompilerOption.h"
Logan Chiend2a5f302011-07-19 20:32:25 +080024
Logan4dcd6792011-02-28 05:12:00 +080025#include "DebugHelper.h"
Logan04329712011-01-06 06:10:57 +080026#include "FileHandle.h"
Daniel Malea094881f2011-12-14 17:39:16 -050027#include "GDBJITRegistrar.h"
Logancf3e5212010-12-29 01:44:55 +080028#include "ScriptCompiled.h"
Logan9a5f8682011-01-07 06:09:57 +080029#include "ScriptCached.h"
30#include "Sha1Helper.h"
Logan474cbd22011-01-31 01:47:44 +080031#include "SourceInfo.h"
Logancf3e5212010-12-29 01:44:55 +080032
Logan89eb47f2011-01-07 10:45:16 +080033#include <errno.h>
Logan474cbd22011-01-31 01:47:44 +080034#include <sys/stat.h>
35#include <sys/types.h>
Bhanu Chetlapallieb4509b2012-01-08 20:42:56 -080036#include <unistd.h>
Logancf3e5212010-12-29 01:44:55 +080037
Logan89eb47f2011-01-07 10:45:16 +080038#include <new>
39#include <string.h>
Logan033f46e2011-01-06 05:51:24 +080040#include <cutils/properties.h>
41
Loganecf4cbd2011-01-06 05:34:11 +080042namespace {
43
Logan033f46e2011-01-06 05:51:24 +080044bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080045 char buf[PROPERTY_VALUE_MAX];
46 property_get(str, buf, "0");
47 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080048}
49
Loganecf4cbd2011-01-06 05:34:11 +080050} // namespace anonymous
51
Logancf3e5212010-12-29 01:44:55 +080052namespace bcc {
53
54Script::~Script() {
Logan35849002011-01-15 07:30:43 +080055 switch (mStatus) {
56 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080057 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080058 break;
59
60#if USE_CACHE
61 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080062 delete mCached;
Logan35849002011-01-15 07:30:43 +080063 break;
64#endif
65
66 default:
67 break;
Logancf3e5212010-12-29 01:44:55 +080068 }
Logan474cbd22011-01-31 01:47:44 +080069
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -080070 for (size_t i = 0; i < 2; ++i) {
Logan474cbd22011-01-31 01:47:44 +080071 delete mSourceList[i];
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -080072 }
Logancf3e5212010-12-29 01:44:55 +080073}
74
75
Logan474cbd22011-01-31 01:47:44 +080076int Script::addSourceBC(size_t idx,
77 char const *resName,
78 const char *bitcode,
79 size_t bitcodeSize,
80 unsigned long flags) {
Shih-wei Liao898c5a92011-05-18 07:02:39 -070081
82 if (!resName) {
83 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +000084 ALOGE("Invalid argument: resName = NULL\n");
Shih-wei Liao898c5a92011-05-18 07:02:39 -070085 return 1;
86 }
87
Loganecf4cbd2011-01-06 05:34:11 +080088 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +080089 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +000090 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +080091 return 1;
92 }
93
Logan474cbd22011-01-31 01:47:44 +080094 if (!bitcode) {
95 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +000096 ALOGE("Invalid argument: bitcode = NULL\n");
Logan474cbd22011-01-31 01:47:44 +080097 return 1;
98 }
99
100 mSourceList[idx] = SourceInfo::createFromBuffer(resName,
101 bitcode, bitcodeSize,
102 flags);
103
104 if (!mSourceList[idx]) {
105 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000106 ALOGE("Out of memory while adding source bitcode\n");
Logan474cbd22011-01-31 01:47:44 +0800107 return 1;
108 }
109
Loganecf4cbd2011-01-06 05:34:11 +0800110 return 0;
Logancf3e5212010-12-29 01:44:55 +0800111}
112
113
Logan474cbd22011-01-31 01:47:44 +0800114int Script::addSourceModule(size_t idx,
115 llvm::Module *module,
116 unsigned long flags) {
Logancf3e5212010-12-29 01:44:55 +0800117 if (mStatus != ScriptStatus::Unknown) {
118 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000119 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800120 return 1;
121 }
122
Logan474cbd22011-01-31 01:47:44 +0800123 if (!module) {
124 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000125 ALOGE("Invalid argument: module = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800126 return 1;
127 }
128
129 mSourceList[idx] = SourceInfo::createFromModule(module, flags);
130
131 if (!mSourceList[idx]) {
132 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000133 ALOGE("Out of memory when add source module\n");
Logan474cbd22011-01-31 01:47:44 +0800134 return 1;
135 }
136
Loganecf4cbd2011-01-06 05:34:11 +0800137 return 0;
Logancf3e5212010-12-29 01:44:55 +0800138}
139
140
Logan474cbd22011-01-31 01:47:44 +0800141int Script::addSourceFile(size_t idx,
142 char const *path,
143 unsigned long flags) {
Logan3133c412011-01-06 06:15:40 +0800144 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800145 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000146 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800147 return 1;
148 }
149
Logan474cbd22011-01-31 01:47:44 +0800150 if (!path) {
151 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000152 ALOGE("Invalid argument: path = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800153 return 1;
154 }
155
156 struct stat sb;
157 if (stat(path, &sb) != 0) {
158 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000159 ALOGE("File not found: %s\n", path);
Logan474cbd22011-01-31 01:47:44 +0800160 return 1;
161 }
162
163 mSourceList[idx] = SourceInfo::createFromFile(path, flags);
164
165 if (!mSourceList[idx]) {
166 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000167 ALOGE("Out of memory while adding source file\n");
Logan474cbd22011-01-31 01:47:44 +0800168 return 1;
169 }
170
Logan3133c412011-01-06 06:15:40 +0800171 return 0;
Logancf3e5212010-12-29 01:44:55 +0800172}
173
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800174int Script::prepareRelocatable(char const *objPath,
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -0800175 llvm::Reloc::Model RelocModel,
176 unsigned long flags) {
Zonr Chang2fcbd022012-01-06 21:04:31 +0800177 CompilerOption option;
Shih-wei Liao8afed382012-01-10 15:57:24 +0800178 option.RelocModelOpt = RelocModel;
Zonr Chang2fcbd022012-01-06 21:04:31 +0800179 option.LoadAfterCompile = false;
Shih-wei Liao8454a3a2012-03-03 01:50:08 -0800180
Zonr Chang2fcbd022012-01-06 21:04:31 +0800181 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700182 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000183 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800184 return status;
185 }
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800186
187 FileHandle objFile;
188 if (objFile.open(objPath, OpenMode::Write) < 0) {
189 ALOGE("Failed to open %s for write.\n", objPath);
190 return 1;
Joseph Wen34c600a2011-07-25 17:59:17 -0700191 }
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800192
193 if (static_cast<size_t>(objFile.write(getELF(),
194 getELFSize())) != getELFSize()) {
195 objFile.close();
196 ::unlink(objPath);
197 ALOGE("Unable to write ELF to file %s.\n", objPath);
198 return false;
199 }
200
Shih-wei Liao8454a3a2012-03-03 01:50:08 -0800201 mObjectType = ScriptObject::Relocatable;
202
Shih-wei Liaod8ed6a92012-03-03 01:44:29 -0800203 return 0;
Joseph Wen34c600a2011-07-25 17:59:17 -0700204}
205
Logancf3e5212010-12-29 01:44:55 +0800206
Shih-wei Liao69341742012-03-03 01:45:36 -0800207int Script::prepareSharedObject(char const *objPath,
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -0800208 char const *dsoPath,
209 unsigned long flags) {
210 // TODO: Support cached shared object.
211 return 1;
212}
213
214
Logan Chien311c26f2011-07-11 14:30:34 +0800215int Script::prepareExecutable(char const *cacheDir,
216 char const *cacheName,
217 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800218 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800219 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000220 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800221 return 1;
222 }
223
Daniel Malea094881f2011-12-14 17:39:16 -0500224 int status = -1;
Logan35849002011-01-15 07:30:43 +0800225#if USE_CACHE
Shih-wei Liao8454a3a2012-03-03 01:50:08 -0800226 status = internalLoadCache(cacheDir, cacheName, /* checkOnly */ false);
Logan35849002011-01-15 07:30:43 +0800227#endif
Loganecf4cbd2011-01-06 05:34:11 +0800228
Stephen Hinese0918ac2012-03-01 23:28:09 -0800229 if (status != 0) {
230 CompilerOption option;
231 status = internalCompile(option);
Stephen Hinese0918ac2012-03-01 23:28:09 -0800232
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800233 if (status != 0) {
234 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
235 return status;
236 }
237
238 status = writeCache();
239 if (status != 0) {
240 ALOGE("Failed to write the cache for %s\n", cacheName);
241 return status;
242 }
Stephen Hines27b35102011-05-11 17:58:48 -0700243 }
Daniel Malea094881f2011-12-14 17:39:16 -0500244
245 // FIXME: Registration can be conditional on the presence of debug metadata
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800246 registerObjectWithGDB(getELF(), getELFSize()); // thread-safe registration
247
Shih-wei Liao8454a3a2012-03-03 01:50:08 -0800248 mObjectType = ScriptObject::Executable;
249
Stephen Hines27b35102011-05-11 17:58:48 -0700250 return status;
Logan033f46e2011-01-06 05:51:24 +0800251}
252
Logan35849002011-01-15 07:30:43 +0800253#if USE_CACHE
Zonr Chang743dd712012-01-19 10:13:52 +0800254int Script::internalLoadCache(char const *cacheDir, char const *cacheName,
Zonr Chang743dd712012-01-19 10:13:52 +0800255 bool checkOnly) {
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800256 if ((cacheDir == NULL) || (cacheName == NULL)) {
Zonr Chang743dd712012-01-19 10:13:52 +0800257 return 1;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800258 }
Zonr Chang743dd712012-01-19 10:13:52 +0800259
260 // Set cache file Name
261 mCacheName = cacheName;
262
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800263 // Santize mCacheDir. Ensure that mCacheDir ends with '/'.
Zonr Chang743dd712012-01-19 10:13:52 +0800264 mCacheDir = cacheDir;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800265 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
Zonr Chang743dd712012-01-19 10:13:52 +0800266 mCacheDir.push_back('/');
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800267 }
Zonr Chang743dd712012-01-19 10:13:52 +0800268
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800269 if (!isCacheable()) {
Logan033f46e2011-01-06 05:51:24 +0800270 return 1;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800271 }
Logan04329712011-01-06 06:10:57 +0800272
Zonr Chang4ea08862012-01-17 17:26:49 +0800273 std::string objPath = getCachedObjectPath();
274 std::string infoPath = getCacheInfoPath();
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700275
Logan Chien311c26f2011-07-11 14:30:34 +0800276 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700277 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800278 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800279 return 1;
280 }
281
Logan Chien311c26f2011-07-11 14:30:34 +0800282 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700283 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800284 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700285 return 1;
286 }
287
288 MCCacheReader reader;
289
290 // Register symbol lookup function
291 if (mpExtSymbolLookupFn) {
292 reader.registerSymbolCallback(mpExtSymbolLookupFn,
293 mpExtSymbolLookupFnContext);
294 }
Logan04329712011-01-06 06:10:57 +0800295
Logan9a5f8682011-01-07 06:09:57 +0800296 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700297 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700298 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800299
Logan474cbd22011-01-31 01:47:44 +0800300 for (size_t i = 0; i < 2; ++i) {
301 if (mSourceList[i]) {
302 mSourceList[i]->introDependency(reader);
303 }
Logan9a5f8682011-01-07 06:09:57 +0800304 }
305
Joseph Wen34c600a2011-07-25 17:59:17 -0700306 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700307 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700308
Logan9a5f8682011-01-07 06:09:57 +0800309 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700310 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700311
Logan04329712011-01-06 06:10:57 +0800312 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800313 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800314 return 1;
315 }
316
317 mCached = cached;
318 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800319
Loganf3c83ce2011-01-07 06:36:33 +0800320 // Dirty hack for libRS.
321 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800322 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800323 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
324 }
325
Loganf7f0ac52011-01-07 03:53:43 +0800326 return 0;
Logan033f46e2011-01-06 05:51:24 +0800327}
Logan35849002011-01-15 07:30:43 +0800328#endif
Logan033f46e2011-01-06 05:51:24 +0800329
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800330int Script::internalCompile(const CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800331 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800332 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800333
334 if (!mCompiled) {
335 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000336 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800337 return 1;
338 }
339
340 mStatus = ScriptStatus::Compiled;
341
Logan033f46e2011-01-06 05:51:24 +0800342 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800343 if (mpExtSymbolLookupFn) {
344 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
345 mpExtSymbolLookupFnContext);
346 }
347
Zonr Changdf3fee42012-01-10 15:58:36 +0800348 if (!mSourceList[0]) {
349 ALOGE("Source bitcode is not set.\n");
Logan474cbd22011-01-31 01:47:44 +0800350 return 1;
351 }
352
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800353 // Parse Source bitcode file (if necessary)
354 if (mSourceList[0]->prepareModule() != 0) {
355 ALOGE("Unable to setup source module\n");
Zonr Changdf3fee42012-01-10 15:58:36 +0800356 return 1;
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800357 }
358
359 // Parse Library bitcode file (if necessary)
360 if (mSourceList[1]) {
361 if (mSourceList[1]->prepareModule(mSourceList[0]->getContext()) != 0) {
362 ALOGE("Unable to setup library module\n");
363 return 1;
364 }
365 }
Zonr Changdf3fee42012-01-10 15:58:36 +0800366
367 // Set the main source module
368 if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000369 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800370 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800371 }
372
Logan3133c412011-01-06 06:15:40 +0800373 // Link the source module with the library module
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800374 if (mSourceList[1]) {
Zonr Changdf3fee42012-01-10 15:58:36 +0800375 if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000376 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800377 return 1;
378 }
379 }
Loganecf4cbd2011-01-06 05:34:11 +0800380
Logan3133c412011-01-06 06:15:40 +0800381 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800382 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000383 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800384 return 1;
385 }
386
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800387 return 0;
388}
389
390int Script::writeCache() {
Stephen Hines3e36c692012-03-05 12:39:45 -0800391 // Not compiled script or encountered error during the compilation.
Shih-wei Liaoa0ed34e2012-03-03 01:33:30 -0800392 if ((mStatus != ScriptStatus::Compiled) ||
393 (getCompilerErrorMessage() == NULL))
394 return 1;
395
Logan35849002011-01-15 07:30:43 +0800396#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800397 // Note: If we re-compile the script because the cached context slot not
398 // available, then we don't have to write the cache.
399
400 // Note: If the address of the context is not in the context slot, then
401 // we don't have to cache it.
402
Stephen Hines9ddeb6b2012-03-11 18:41:03 -0700403 if (isCacheable()) {
Logan42598052011-01-26 22:41:13 +0800404
Zonr Chang4ea08862012-01-17 17:26:49 +0800405 std::string objPath = getCachedObjectPath();
406 std::string infoPath = getCacheInfoPath();
Logan Chien311c26f2011-07-11 14:30:34 +0800407
Jeff Brown937a0bc2011-01-26 23:20:14 -0800408 // Remove the file if it already exists before writing the new file.
409 // The old file may still be mapped elsewhere in memory and we do not want
410 // to modify its contents. (The same script may be running concurrently in
411 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700412 ::unlink(objPath.c_str());
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700413 ::unlink(infoPath.c_str());
Jeff Brown937a0bc2011-01-26 23:20:14 -0800414
Logan Chien03a2e302011-07-13 21:46:32 +0800415 FileHandle objFile;
416 FileHandle infoFile;
417
418 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
419 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700420
Logan Chien311c26f2011-07-11 14:30:34 +0800421 MCCacheWriter writer;
Logana27a83f2011-01-07 10:25:48 +0800422
Joseph Wen2ca6e572011-06-24 14:12:23 -0700423#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800424 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700425 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700426 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800427#endif
Logana2e15af2011-01-07 11:46:08 +0800428
Logan474cbd22011-01-31 01:47:44 +0800429 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800430 if (mSourceList[i]) {
431 mSourceList[i]->introDependency(writer);
432 }
Logana2e15af2011-01-07 11:46:08 +0800433 }
434
Logana27a83f2011-01-07 10:25:48 +0800435 // libRS is threadable dirty hack
436 // TODO: This should be removed in the future
437 uint32_t libRS_threadable = 0;
438 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800439 libRS_threadable =
440 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
441 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800442 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700443
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700444 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700445 objFile.truncate();
446 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800447
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700448 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000449 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700450 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800451 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700452
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700453 infoFile.truncate();
454 infoFile.close();
455
456 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000457 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700458 infoPath.c_str(), strerror(errno));
459 }
Logan89eb47f2011-01-07 10:45:16 +0800460 }
461 }
Logan04329712011-01-06 06:10:57 +0800462 }
Logan35849002011-01-15 07:30:43 +0800463#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800464
465 return 0;
Logancf3e5212010-12-29 01:44:55 +0800466}
467
468
469char const *Script::getCompilerErrorMessage() {
470 if (mStatus != ScriptStatus::Compiled) {
471 mErrorCode = BCC_INVALID_OPERATION;
472 return NULL;
473 }
474
475 return mCompiled->getCompilerErrorMessage();
476}
477
478
479void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800480 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700481 case ScriptStatus::Compiled: {
482 return mCompiled->lookup(name);
483 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700484
Logan35849002011-01-15 07:30:43 +0800485#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700486 case ScriptStatus::Cached: {
487 return mCached->lookup(name);
488 }
Logan35849002011-01-15 07:30:43 +0800489#endif
Logan89eb47f2011-01-07 10:45:16 +0800490
Shih-wei Liaod50be322011-07-01 22:53:31 -0700491 default: {
492 mErrorCode = BCC_INVALID_OPERATION;
493 return NULL;
494 }
Logancf3e5212010-12-29 01:44:55 +0800495 }
Logancf3e5212010-12-29 01:44:55 +0800496}
497
498
Loganbe79ada2011-01-13 01:33:45 +0800499size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800500 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700501 case ScriptStatus::Compiled: {
502 return mCompiled->getExportVarCount();
503 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700504
Logan35849002011-01-15 07:30:43 +0800505#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700506 case ScriptStatus::Cached: {
507 return mCached->getExportVarCount();
508 }
Logan35849002011-01-15 07:30:43 +0800509#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700510
Shih-wei Liaod50be322011-07-01 22:53:31 -0700511 default: {
512 return 0;
513 }
Loganbe79ada2011-01-13 01:33:45 +0800514 }
515}
516
517
518size_t Script::getExportFuncCount() const {
519 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700520 case ScriptStatus::Compiled: {
521 return mCompiled->getExportFuncCount();
522 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700523
Logan35849002011-01-15 07:30:43 +0800524#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700525 case ScriptStatus::Cached: {
526 return mCached->getExportFuncCount();
527 }
Logan35849002011-01-15 07:30:43 +0800528#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700529
Shih-wei Liaod50be322011-07-01 22:53:31 -0700530 default: {
531 return 0;
532 }
Loganbe79ada2011-01-13 01:33:45 +0800533 }
534}
535
536
Stephen Hinescc366e52012-02-21 17:22:04 -0800537size_t Script::getExportForEachCount() const {
538 switch (mStatus) {
539 case ScriptStatus::Compiled: {
540 return mCompiled->getExportForEachCount();
541 }
542
543#if USE_CACHE
544 case ScriptStatus::Cached: {
545 return mCached->getExportForEachCount();
546 }
547#endif
548
549 default: {
550 return 0;
551 }
552 }
553}
554
555
Loganbe79ada2011-01-13 01:33:45 +0800556size_t Script::getPragmaCount() const {
557 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700558 case ScriptStatus::Compiled: {
559 return mCompiled->getPragmaCount();
560 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700561
Logan35849002011-01-15 07:30:43 +0800562#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700563 case ScriptStatus::Cached: {
564 return mCached->getPragmaCount();
565 }
Logan35849002011-01-15 07:30:43 +0800566#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700567
Shih-wei Liaod50be322011-07-01 22:53:31 -0700568 default: {
569 return 0;
570 }
Loganbe79ada2011-01-13 01:33:45 +0800571 }
572}
573
574
575size_t Script::getFuncCount() const {
576 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700577 case ScriptStatus::Compiled: {
578 return mCompiled->getFuncCount();
579 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700580
Logan35849002011-01-15 07:30:43 +0800581#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700582 case ScriptStatus::Cached: {
583 return mCached->getFuncCount();
584 }
Logan35849002011-01-15 07:30:43 +0800585#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700586
Shih-wei Liaod50be322011-07-01 22:53:31 -0700587 default: {
588 return 0;
589 }
Loganbe79ada2011-01-13 01:33:45 +0800590 }
591}
592
593
Stephen Hines071288a2011-01-27 14:38:26 -0800594size_t Script::getObjectSlotCount() const {
595 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700596 case ScriptStatus::Compiled: {
597 return mCompiled->getObjectSlotCount();
598 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700599
Stephen Hines071288a2011-01-27 14:38:26 -0800600#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700601 case ScriptStatus::Cached: {
602 return mCached->getObjectSlotCount();
603 }
Stephen Hines071288a2011-01-27 14:38:26 -0800604#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700605
Shih-wei Liaod50be322011-07-01 22:53:31 -0700606 default: {
607 return 0;
608 }
Stephen Hines071288a2011-01-27 14:38:26 -0800609 }
610}
611
612
Loganbe79ada2011-01-13 01:33:45 +0800613void Script::getExportVarList(size_t varListSize, void **varList) {
614 switch (mStatus) {
615#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700616 case ScriptStatus::STATUS: \
617 m##STATUS->getExportVarList(varListSize, varList); \
618 break;
Logancf3e5212010-12-29 01:44:55 +0800619
Logan35849002011-01-15 07:30:43 +0800620#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700621 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800622#endif
623
Shih-wei Liaod50be322011-07-01 22:53:31 -0700624 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800625#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800626
Shih-wei Liaod50be322011-07-01 22:53:31 -0700627 default: {
628 mErrorCode = BCC_INVALID_OPERATION;
629 }
Logan89eb47f2011-01-07 10:45:16 +0800630 }
Logancf3e5212010-12-29 01:44:55 +0800631}
632
Joseph Wenf36637f2011-07-06 18:27:12 -0700633void Script::getExportVarNameList(std::vector<std::string> &varList) {
634 switch (mStatus) {
635 case ScriptStatus::Compiled: {
636 return mCompiled->getExportVarNameList(varList);
637 }
638
639 default: {
640 mErrorCode = BCC_INVALID_OPERATION;
641 }
642 }
643}
644
Logancf3e5212010-12-29 01:44:55 +0800645
Loganbe79ada2011-01-13 01:33:45 +0800646void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800647 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800648#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700649 case ScriptStatus::STATUS: \
650 m##STATUS->getExportFuncList(funcListSize, funcList); \
651 break;
Logancf3e5212010-12-29 01:44:55 +0800652
Logan35849002011-01-15 07:30:43 +0800653#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700654 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800655#endif
656
Shih-wei Liaod50be322011-07-01 22:53:31 -0700657 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800658#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800659
Shih-wei Liaod50be322011-07-01 22:53:31 -0700660 default: {
661 mErrorCode = BCC_INVALID_OPERATION;
662 }
Logan89eb47f2011-01-07 10:45:16 +0800663 }
Logancf3e5212010-12-29 01:44:55 +0800664}
665
Joseph Wenf36637f2011-07-06 18:27:12 -0700666void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
667 switch (mStatus) {
668 case ScriptStatus::Compiled: {
669 return mCompiled->getExportFuncNameList(funcList);
670 }
671
672 default: {
673 mErrorCode = BCC_INVALID_OPERATION;
674 }
675 }
676}
677
Stephen Hinescc366e52012-02-21 17:22:04 -0800678void Script::getExportForEachList(size_t funcListSize, void **funcList) {
679 switch (mStatus) {
680#define DELEGATE(STATUS) \
681 case ScriptStatus::STATUS: \
682 m##STATUS->getExportForEachList(funcListSize, funcList); \
683 break;
684
685#if USE_CACHE
686 DELEGATE(Cached);
687#endif
688
689 DELEGATE(Compiled);
690#undef DELEGATE
691
692 default: {
693 mErrorCode = BCC_INVALID_OPERATION;
694 }
695 }
696}
697
698void Script::getExportForEachNameList(std::vector<std::string> &forEachList) {
699 switch (mStatus) {
700 case ScriptStatus::Compiled: {
701 return mCompiled->getExportForEachNameList(forEachList);
702 }
703
704 default: {
705 mErrorCode = BCC_INVALID_OPERATION;
706 }
707 }
708}
Logancf3e5212010-12-29 01:44:55 +0800709
Loganbe79ada2011-01-13 01:33:45 +0800710void Script::getPragmaList(size_t pragmaListSize,
711 char const **keyList,
712 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800713 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800714#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700715 case ScriptStatus::STATUS: \
716 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
717 break;
Logancf3e5212010-12-29 01:44:55 +0800718
Logan35849002011-01-15 07:30:43 +0800719#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700720 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800721#endif
722
Shih-wei Liaod50be322011-07-01 22:53:31 -0700723 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800724#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800725
Shih-wei Liaod50be322011-07-01 22:53:31 -0700726 default: {
727 mErrorCode = BCC_INVALID_OPERATION;
728 }
Logan89eb47f2011-01-07 10:45:16 +0800729 }
Logancf3e5212010-12-29 01:44:55 +0800730}
731
732
Loganf340bf72011-01-14 17:51:40 +0800733void Script::getFuncInfoList(size_t funcInfoListSize,
734 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800735 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800736#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700737 case ScriptStatus::STATUS: \
738 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
739 break;
Logancf3e5212010-12-29 01:44:55 +0800740
Logan35849002011-01-15 07:30:43 +0800741#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700742 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800743#endif
744
Shih-wei Liaod50be322011-07-01 22:53:31 -0700745 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800746#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800747
Shih-wei Liaod50be322011-07-01 22:53:31 -0700748 default: {
749 mErrorCode = BCC_INVALID_OPERATION;
750 }
Logan89eb47f2011-01-07 10:45:16 +0800751 }
Logancf3e5212010-12-29 01:44:55 +0800752}
753
Stephen Hines071288a2011-01-27 14:38:26 -0800754
755void Script::getObjectSlotList(size_t objectSlotListSize,
756 uint32_t *objectSlotList) {
757 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700758#define DELEGATE(STATUS) \
759 case ScriptStatus::STATUS: \
760 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
761 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800762
763#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700764 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800765#endif
766
Shih-wei Liaod50be322011-07-01 22:53:31 -0700767 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800768#undef DELEGATE
769
Shih-wei Liaod50be322011-07-01 22:53:31 -0700770 default: {
771 mErrorCode = BCC_INVALID_OPERATION;
772 }
Stephen Hines071288a2011-01-27 14:38:26 -0800773 }
774}
775
776
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800777int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800778 mpExtSymbolLookupFn = pFn;
779 mpExtSymbolLookupFnContext = pContext;
780
Logan7d2219f2011-01-06 06:19:25 +0800781 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800782 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000783 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800784 return 1;
Logancf3e5212010-12-29 01:44:55 +0800785 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800786 return 0;
Logancf3e5212010-12-29 01:44:55 +0800787}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700788
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800789bool Script::isCacheable() const {
790#if USE_CACHE
791 if (getBooleanProp("debug.bcc.nocache")) {
792 // Android system environment property: Disables the cache mechanism by
793 // setting "debug.bcc.nocache". So we will not load the cache file any
794 // way.
795 return false;
796 }
797
798 if (mCacheDir.empty() || mCacheName.empty()) {
799 // The application developer has not specified the cachePath, so
800 // we don't know where to open the cache file.
801 return false;
802 }
803
804 return true;
805#else
806 return false;
807#endif
808}
809
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700810size_t Script::getELFSize() const {
811 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700812 case ScriptStatus::Compiled: {
813 return mCompiled->getELFSize();
814 }
Daniel Malea094881f2011-12-14 17:39:16 -0500815#if USE_CACHE
816 case ScriptStatus::Cached: {
817 return mCached->getELFSize();
818 }
819#endif
Shih-wei Liaod50be322011-07-01 22:53:31 -0700820 default: {
821 return 0;
822 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700823 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700824}
825
826const char *Script::getELF() const {
827 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700828 case ScriptStatus::Compiled: {
829 return mCompiled->getELF();
830 }
Daniel Malea094881f2011-12-14 17:39:16 -0500831#if USE_CACHE
832 case ScriptStatus::Cached: {
833 return mCached->getELF();
834 }
835#endif
Shih-wei Liaod50be322011-07-01 22:53:31 -0700836 default: {
837 return NULL;
838 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700839 }
840}
Logancf3e5212010-12-29 01:44:55 +0800841
842} // namespace bcc