blob: 01c513a289813e9d7b1fd4a463792ecf70f4f320 [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "bcc"
18#include <cutils/log.h>
19
Logan1f028c02010-11-27 01:02:48 +080020#if defined(__arm__)
21# define DEFAULT_ARM_CODEGEN
22# define PROVIDE_ARM_CODEGEN
23#elif defined(__i386__)
24# define DEFAULT_X86_CODEGEN
25# define PROVIDE_X86_CODEGEN
26#elif defined(__x86_64__)
27# define DEFAULT_X64_CODEGEN
28# define PROVIDE_X64_CODEGEN
29#endif
30
31#if defined(FORCE_ARM_CODEGEN)
32# define DEFAULT_ARM_CODEGEN
33# undef DEFAULT_X86_CODEGEN
34# undef DEFAULT_X64_CODEGEN
35# define PROVIDE_ARM_CODEGEN
36# undef PROVIDE_X86_CODEGEN
37# undef PROVIDE_X64_CODEGEN
38#elif defined(FORCE_X86_CODEGEN)
39# undef DEFAULT_ARM_CODEGEN
40# define DEFAULT_X86_CODEGEN
41# undef DEFAULT_X64_CODEGEN
42# undef PROVIDE_ARM_CODEGEN
43# define PROVIDE_X86_CODEGEN
44# undef PROVIDE_X64_CODEGEN
45#elif defined(FORCE_X64_CODEGEN)
46# undef DEFAULT_ARM_CODEGEN
47# undef DEFAULT_X86_CODEGEN
48# define DEFAULT_X64_CODEGEN
49# undef PROVIDE_ARM_CODEGEN
50# undef PROVIDE_X86_CODEGEN
51# define PROVIDE_X64_CODEGEN
52#endif
53
54#if defined(DEFAULT_ARM_CODEGEN)
Logandf23afa2010-11-27 11:04:54 +080055# define TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
Logan1f028c02010-11-27 01:02:48 +080056#elif defined(DEFAULT_X86_CODEGEN)
Logandf23afa2010-11-27 11:04:54 +080057# define TARGET_TRIPLE_STRING "i686-unknown-linux"
Logan1f028c02010-11-27 01:02:48 +080058#elif defined(DEFAULT_X64_CODEGEN)
Logandf23afa2010-11-27 11:04:54 +080059# define TARGET_TRIPLE_STRING "x86_64-unknown-linux"
Logan1f028c02010-11-27 01:02:48 +080060#endif
61
62#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
63# define ARM_USE_VFP
64#endif
65
Loganc4395232010-11-27 18:54:17 +080066#include "Compiler.h"
Logan1f028c02010-11-27 01:02:48 +080067
Logandf23afa2010-11-27 11:04:54 +080068#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080069
Logandf23afa2010-11-27 11:04:54 +080070#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080071
Logan1f028c02010-11-27 01:02:48 +080072#include "llvm/Bitcode/ReaderWriter.h"
73
Logan1f028c02010-11-27 01:02:48 +080074#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080075#include "llvm/CodeGen/RegAllocRegistry.h"
76#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080077
Logandf23afa2010-11-27 11:04:54 +080078#include "llvm/Transforms/IPO.h"
79#include "llvm/Transforms/Scalar.h"
80
81#include "llvm/Target/SubtargetFeature.h"
82#include "llvm/Target/TargetData.h"
83#include "llvm/Target/TargetMachine.h"
84#include "llvm/Target/TargetOptions.h"
85#include "llvm/Target/TargetRegistry.h"
86#include "llvm/Target/TargetSelect.h"
87
88#include "llvm/Support/ErrorHandling.h"
89#include "llvm/Support/MemoryBuffer.h"
90
91#include "llvm/GlobalValue.h"
92#include "llvm/Linker.h"
93#include "llvm/LLVMContext.h"
94#include "llvm/Metadata.h"
95#include "llvm/Module.h"
96#include "llvm/PassManager.h"
97#include "llvm/Value.h"
98
99#include <errno.h>
100#include <sys/file.h>
101#include <sys/mman.h>
102#include <sys/stat.h>
103#include <sys/types.h>
104#include <unistd.h>
105
106#include <string>
107#include <vector>
Logan1f028c02010-11-27 01:02:48 +0800108
Logandf23afa2010-11-27 11:04:54 +0800109namespace {
Logan1f028c02010-11-27 01:02:48 +0800110
111#define TEMP_FAILURE_RETRY1(exp) ({ \
112 typeof (exp) _rc; \
113 do { \
114 _rc = (exp); \
115 } while (_rc == -1 && errno == EINTR); \
116 _rc; })
117
118
Logandf23afa2010-11-27 11:04:54 +0800119int sysWriteFully(int fd, const void* buf, size_t count, const char* logMsg) {
Logan1f028c02010-11-27 01:02:48 +0800120 while (count != 0) {
121 ssize_t actual = TEMP_FAILURE_RETRY1(write(fd, buf, count));
122 if (actual < 0) {
123 int err = errno;
124 LOGE("%s: write failed: %s\n", logMsg, strerror(err));
125 return err;
126 } else if (actual != (ssize_t) count) {
127 LOGD("%s: partial write (will retry): (%d of %zd)\n",
128 logMsg, (int) actual, count);
129 buf = (const void*) (((const uint8_t*) buf) + actual);
130 }
131 count -= actual;
132 }
133
134 return 0;
135}
136
Logan9d94f162010-12-07 12:39:25 +0800137inline uint32_t statModifyTime(char const *filepath) {
138 struct stat st;
139
140 if (stat(filepath, &st) < 0) {
141 LOGE("Unable to stat \'%s\', with reason: %s\n", filepath, strerror(errno));
142 return 0;
143 }
144
145 return static_cast<uint32_t>(st.st_mtime);
146}
147
148static char const libRSPath[] = "/system/lib/libRS.so";
149
150static char const libBccPath[] = "/system/lib/libbcc.so";
151
Logandf23afa2010-11-27 11:04:54 +0800152} // namespace anonymous
153
Logan1f028c02010-11-27 01:02:48 +0800154
155namespace bcc {
156
157//////////////////////////////////////////////////////////////////////////////
158// BCC Compiler Static Variables
159//////////////////////////////////////////////////////////////////////////////
160
161bool Compiler::GlobalInitialized = false;
162
163bool Compiler::BccMmapImgAddrTaken[BCC_MMAP_IMG_COUNT];
164
165// Code generation optimization level for the compiler
166llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
167
168std::string Compiler::Triple;
169
170std::string Compiler::CPU;
171
172std::vector<std::string> Compiler::Features;
173
174// The named of metadata node that pragma resides (should be synced with
175// slang.cpp)
176const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
177
178// The named of metadata node that export variable name resides (should be
179// synced with slang_rs_metadata.h)
180const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
181
182// The named of metadata node that export function name resides (should be
183// synced with slang_rs_metadata.h)
184const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
185
186
187//////////////////////////////////////////////////////////////////////////////
188// Compiler
189//////////////////////////////////////////////////////////////////////////////
190
191void Compiler::GlobalInitialization() {
192 if (GlobalInitialized)
193 return;
194
195 // if (!llvm::llvm_is_multithreaded())
196 // llvm::llvm_start_multithreaded();
197
198 // Set Triple, CPU and Features here
199 Triple = TARGET_TRIPLE_STRING;
200
201 // TODO(sliao): NEON for JIT
202 // Features.push_back("+neon");
203 // Features.push_back("+vmlx");
204 // Features.push_back("+neonfp");
205 Features.push_back("+vfp3");
206 Features.push_back("+d16");
207
208#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
209 LLVMInitializeARMTargetInfo();
210 LLVMInitializeARMTarget();
211#if defined(USE_DISASSEMBLER)
212 LLVMInitializeARMDisassembler();
213 LLVMInitializeARMAsmPrinter();
214#endif
215#endif
216
217#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
218 LLVMInitializeX86TargetInfo();
219 LLVMInitializeX86Target();
220#if defined(USE_DISASSEMBLER)
221 LLVMInitializeX86Disassembler();
222 LLVMInitializeX86AsmPrinter();
223#endif
224#endif
225
226#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
227 LLVMInitializeX86TargetInfo();
228 LLVMInitializeX86Target();
229#if defined(USE_DISASSEMBLER)
230 LLVMInitializeX86Disassembler();
231 LLVMInitializeX86AsmPrinter();
232#endif
233#endif
234
235 // -O0: llvm::CodeGenOpt::None
236 // -O1: llvm::CodeGenOpt::Less
237 // -O2: llvm::CodeGenOpt::Default
238 // -O3: llvm::CodeGenOpt::Aggressive
239 CodeGenOptLevel = llvm::CodeGenOpt::None;
240
241 // Below are the global settings to LLVM
242
243 // Disable frame pointer elimination optimization
244 llvm::NoFramePointerElim = false;
245
246 // Use hardfloat ABI
247 //
248 // TODO(all): Need to detect the CPU capability and decide whether to use
249 // softfp. To use softfp, change following 2 lines to
250 //
251 // llvm::FloatABIType = llvm::FloatABI::Soft;
252 // llvm::UseSoftFloat = true;
253 //
254 llvm::FloatABIType = llvm::FloatABI::Soft;
255 llvm::UseSoftFloat = false;
256
257 // BCC needs all unknown symbols resolved at JIT/compilation time.
258 // So we don't need any dynamic relocation model.
259 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
260
261#if defined(DEFAULT_X64_CODEGEN)
262 // Data address in X86_64 architecture may reside in a far-away place
263 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
264#else
265 // This is set for the linker (specify how large of the virtual addresses
266 // we can access for all unknown symbols.)
267 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
268#endif
269
270 // Register the scheduler
271 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
272
273 // Register allocation policy:
274 // createFastRegisterAllocator: fast but bad quality
275 // createLinearScanRegisterAllocator: not so fast but good quality
276 llvm::RegisterRegAlloc::setDefault
277 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
278 llvm::createFastRegisterAllocator :
279 llvm::createLinearScanRegisterAllocator);
280
281 GlobalInitialized = true;
282}
283
284
285void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
286 std::string *Error = static_cast<std::string*>(UserData);
287 Error->assign(Message);
288 LOGE("%s", Message.c_str());
289 exit(1);
290}
291
292
293CodeMemoryManager *Compiler::createCodeMemoryManager() {
294 mCodeMemMgr.reset(new CodeMemoryManager());
295 return mCodeMemMgr.get();
296}
297
298
299CodeEmitter *Compiler::createCodeEmitter() {
300 mCodeEmitter.reset(new CodeEmitter(mCodeMemMgr.take()));
301 return mCodeEmitter.get();
302}
303
304
305Compiler::Compiler()
306 : mUseCache(false),
307 mCacheNew(false),
308 mCacheFd(-1),
309 mCacheMapAddr(NULL),
310 mCacheHdr(NULL),
311 mCacheSize(0),
312 mCacheDiff(0),
313 mCodeDataAddr(NULL),
314 mpSymbolLookupFn(NULL),
315 mpSymbolLookupContext(NULL),
316 mContext(NULL),
317 mModule(NULL),
318 mHasLinked(false) /* Turn off linker */ {
319 llvm::remove_fatal_error_handler();
320 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
321 mContext = new llvm::LLVMContext();
322 return;
323}
324
325
326int Compiler::readBC(const char *bitcode,
327 size_t bitcodeSize,
328 const BCCchar *resName) {
329 GlobalInitialization();
330
331 if (resName) {
332 // Turn on mUseCache mode iff
333 // 1. Has resName
334 // and, assuming USE_RELOCATE is false:
335 // 2. Later running code doesn't violate the following condition:
336 // mCodeDataAddr (set in loadCacheFile()) ==
337 // mCacheHdr->cachedCodeDataAddr
338 //
339 // BTW, this condition is achievable only when in the earlier
340 // cache-generating run,
341 // mpCodeMem == BccCodeAddr - MaxCodeSize - MaxGlobalVarSize,
342 // which means the mmap'ed is in the reserved area,
343 //
344 // Note: Upon violation, mUseCache will be set back to false.
345 mUseCache = true;
346
347 mCacheFd = openCacheFile(resName, true /* createIfMissing */);
348 if (mCacheFd >= 0 && !mCacheNew) { // Just use cache file
Logan139dc3c2010-12-03 01:32:05 +0800349 return -mCacheFd - 1;
Logan1f028c02010-11-27 01:02:48 +0800350 }
351 }
352
353 llvm::OwningPtr<llvm::MemoryBuffer> MEM;
354
355 if (bitcode == NULL || bitcodeSize <= 0)
356 return 0;
357
358 // Package input to object MemoryBuffer
359 MEM.reset(llvm::MemoryBuffer::getMemBuffer(
360 llvm::StringRef(bitcode, bitcodeSize)));
361
362 if (MEM.get() == NULL) {
363 setError("Error reading input program bitcode into memory");
364 return hasError();
365 }
366
367 // Read the input Bitcode as a Module
368 mModule = llvm::ParseBitcodeFile(MEM.get(), *mContext, &mError);
369 MEM.reset();
370 return hasError();
371}
372
373
374int Compiler::linkBC(const char *bitcode, size_t bitcodeSize) {
375 llvm::OwningPtr<llvm::MemoryBuffer> MEM;
376
377 if (bitcode == NULL || bitcodeSize <= 0)
378 return 0;
379
380 if (mModule == NULL) {
381 setError("No module presents for linking");
382 return hasError();
383 }
384
385 MEM.reset(llvm::MemoryBuffer::getMemBuffer(
386 llvm::StringRef(bitcode, bitcodeSize)));
387
388 if (MEM.get() == NULL) {
389 setError("Error reading input library bitcode into memory");
390 return hasError();
391 }
392
393 llvm::OwningPtr<llvm::Module> Lib(llvm::ParseBitcodeFile(MEM.get(),
394 *mContext,
395 &mError));
396 if (Lib.get() == NULL)
397 return hasError();
398
399 if (llvm::Linker::LinkModules(mModule, Lib.take(), &mError))
400 return hasError();
401
402 // Everything for linking should be settled down here with no error occurs
403 mHasLinked = true;
404 return hasError();
405}
406
407
408// interface for bccLoadBinary()
409int Compiler::loadCacheFile() {
410 // Check File Descriptor
411 if (mCacheFd < 0) {
412 LOGE("loading cache from invalid mCacheFd = %d\n", (int)mCacheFd);
413 goto giveup;
414 }
415
416 // Check File Size
417 struct stat statCacheFd;
418 if (fstat(mCacheFd, &statCacheFd) < 0) {
419 LOGE("unable to stat mCacheFd = %d\n", (int)mCacheFd);
420 goto giveup;
421 }
422
423 mCacheSize = statCacheFd.st_size;
424
425 if (mCacheSize < sizeof(oBCCHeader) ||
426 mCacheSize <= MaxCodeSize + MaxGlobalVarSize) {
427 LOGE("mCacheFd %d is too small to be correct\n", (int)mCacheFd);
428 goto giveup;
429 }
430
431 if (lseek(mCacheFd, 0, SEEK_SET) != 0) {
432 LOGE("Unable to seek to 0: %s\n", strerror(errno));
433 goto giveup;
434 }
435
436 // Part 1. Deal with the non-codedata section first
437 {
438 // Read cached file and perform quick integrity check
439
440 off_t heuristicCodeOffset = mCacheSize - MaxCodeSize - MaxGlobalVarSize;
441 LOGW("TODO(sliao)@loadCacheFile: mCacheSize=%x, heuristicCodeOffset=%llx",
442 (unsigned int)mCacheSize,
443 (unsigned long long int)heuristicCodeOffset);
444
445 mCacheMapAddr = (char *)malloc(heuristicCodeOffset);
446 if (!mCacheMapAddr) {
447 flock(mCacheFd, LOCK_UN);
448 LOGE("allocation failed.\n");
449 goto bail;
450 }
451
452 size_t nread = TEMP_FAILURE_RETRY1(read(mCacheFd, mCacheMapAddr,
453 heuristicCodeOffset));
454 if (nread != (size_t)heuristicCodeOffset) {
455 LOGE("read(mCacheFd) failed\n");
456 goto bail;
457 }
458
459 mCacheHdr = reinterpret_cast<oBCCHeader *>(mCacheMapAddr);
460 // Sanity check
461 if (mCacheHdr->codeOffset != (uint32_t)heuristicCodeOffset) {
462 LOGE("assertion failed: heuristic code offset is not correct.\n");
463 goto bail;
464 }
465 LOGW("TODO(sliao): mCacheHdr->cachedCodeDataAddr=%x", mCacheHdr->cachedCodeDataAddr);
466 LOGW("mCacheHdr->rootAddr=%x", mCacheHdr->rootAddr);
467 LOGW("mCacheHdr->initAddr=%x", mCacheHdr->initAddr);
468 LOGW("mCacheHdr->codeOffset=%x", mCacheHdr->codeOffset);
469 LOGW("mCacheHdr->codeSize=%x", mCacheHdr->codeSize);
470
471 // Verify the Cache File
472 if (memcmp(mCacheHdr->magic, OBCC_MAGIC, 4) != 0) {
473 LOGE("bad magic word\n");
474 goto bail;
475 }
476
477 if (memcmp(mCacheHdr->magicVersion, OBCC_MAGIC_VERS, 4) != 0) {
478 LOGE("bad oBCC version 0x%08x\n",
479 *reinterpret_cast<uint32_t *>(mCacheHdr->magicVersion));
480 goto bail;
481 }
482
483 if (mCacheSize < mCacheHdr->relocOffset +
Logan7cc1baf2010-11-28 23:46:11 +0800484 mCacheHdr->relocCount * sizeof(oBCCRelocEntry)) {
Logan1f028c02010-11-27 01:02:48 +0800485 LOGE("relocate table overflow\n");
486 goto bail;
487 }
488
489 if (mCacheSize < mCacheHdr->exportVarsOffset +
Logan7cc1baf2010-11-28 23:46:11 +0800490 mCacheHdr->exportVarsCount * sizeof(uint32_t)) {
Logan1f028c02010-11-27 01:02:48 +0800491 LOGE("export variables table overflow\n");
492 goto bail;
493 }
494
495 if (mCacheSize < mCacheHdr->exportFuncsOffset +
Logan7cc1baf2010-11-28 23:46:11 +0800496 mCacheHdr->exportFuncsCount * sizeof(uint32_t)) {
Logan1f028c02010-11-27 01:02:48 +0800497 LOGE("export functions table overflow\n");
498 goto bail;
499 }
500
501 if (mCacheSize < mCacheHdr->exportPragmasOffset +
Logan7cc1baf2010-11-28 23:46:11 +0800502 mCacheHdr->exportPragmasSize) {
Logan1f028c02010-11-27 01:02:48 +0800503 LOGE("export pragmas table overflow\n");
504 goto bail;
505 }
506
507 if (mCacheSize < mCacheHdr->codeOffset + mCacheHdr->codeSize) {
508 LOGE("code cache overflow\n");
509 goto bail;
510 }
511
512 if (mCacheSize < mCacheHdr->dataOffset + mCacheHdr->dataSize) {
513 LOGE("data (global variable) cache overflow\n");
514 goto bail;
515 }
516
517 long pagesize = sysconf(_SC_PAGESIZE);
518 if (mCacheHdr->codeOffset % pagesize != 0) {
519 LOGE("code offset must aligned to pagesize\n");
520 goto bail;
521 }
522 }
523
524 // Part 2. Deal with the codedata section
525 {
526 long pagesize = sysconf(_SC_PAGESIZE);
527
528 if (mCacheHdr->cachedCodeDataAddr % pagesize == 0) {
529 void *addr = reinterpret_cast<char *>(mCacheHdr->cachedCodeDataAddr);
530
531 // Try to mmap at cached address directly.
532 mCodeDataAddr = (char *) mmap(addr,
533 BCC_MMAP_IMG_SIZE,
534 PROT_READ | PROT_EXEC | PROT_WRITE,
535 MAP_PRIVATE | MAP_FIXED,
536 mCacheFd,
537 mCacheHdr->codeOffset);
538
539 if (mCodeDataAddr && mCodeDataAddr != MAP_FAILED) {
540 // Cheers! Mapped at the cached address successfully.
541
542 // Update the BccMmapImgAddrTaken table (if required)
543 if (mCacheHdr->cachedCodeDataAddr >= BCC_MMAP_IMG_BEGIN) {
544 size_t offset = mCacheHdr->cachedCodeDataAddr - BCC_MMAP_IMG_BEGIN;
545
546 if ((offset % BCC_MMAP_IMG_SIZE) == 0 &&
547 (offset / BCC_MMAP_IMG_SIZE) < BCC_MMAP_IMG_COUNT) {
548 Compiler::BccMmapImgAddrTaken[offset / BCC_MMAP_IMG_SIZE] = true;
549 }
550 }
551
552#if 1
553 // Check the checksum of code and data
554 {
555 uint32_t sum = mCacheHdr->checksum;
556 uint32_t *ptr = (uint32_t *)mCodeDataAddr;
557
558 for (size_t i = 0; i < BCC_MMAP_IMG_SIZE / sizeof(uint32_t); ++i) {
559 sum ^= *ptr++;
560 }
561
562 if (sum != 0) {
563 LOGE("Checksum check failed\n");
564 goto bail;
565 }
566
Shih-wei Liao9ea54b52010-12-01 17:57:07 -0800567 LOGI("Passed checksum even parity verification.\n");
Logan1f028c02010-11-27 01:02:48 +0800568 }
569#endif
570
571 flock(mCacheFd, LOCK_UN);
572 return 0; // loadCacheFile succeed!
573 }
574 }
575 }
576
577#if !USE_RELOCATE
578 // Note: Since this build does not support relocation, we have no
579 // choose but give up to load the cached file, and recompile the
580 // code.
581
582 flock(mCacheFd, LOCK_UN);
583 goto bail;
584#else
585
586 // Note: Currently, relocation code is not working. Give up now.
587 flock(mCacheFd, LOCK_UN);
588 goto bail;
589
590 // TODO(logan): Following code is not working. Don't use them.
591 // And rewrite them asap.
592#if 0
593 {
594 // Try to allocate at arbitary address. And perform relocation.
595 mCacheMapAddr = (char *) mmap(0,
596 mCacheSize,
597 PROT_READ | PROT_EXEC | PROT_WRITE,
598 MAP_PRIVATE,
599 mCacheFd,
600 0);
601
602 if (mCacheMapAddr == MAP_FAILED) {
603 LOGE("unable to mmap .oBBC cache: %s\n", strerror(errno));
604 flock(mCacheFd, LOCK_UN);
605 goto giveup;
606 }
607
608 flock(mCacheFd, LOCK_UN);
609 mCodeDataAddr = mCacheMapAddr + mCacheHdr->codeOffset;
610
611 // Relocate
612 mCacheDiff = mCodeDataAddr -
613 reinterpret_cast<char *>(mCacheHdr->cachedCodeDataAddr);
614
615 if (mCacheDiff) { // To relocate
616 if (mCacheHdr->rootAddr) {
617 mCacheHdr->rootAddr += mCacheDiff;
618 }
619
620 if (mCacheHdr->initAddr) {
621 mCacheHdr->initAddr += mCacheDiff;
622 }
623
624 oBCCRelocEntry *cachedRelocTable =
625 reinterpret_cast<oBCCRelocEntry *>(mCacheMapAddr +
626 mCacheHdr->relocOffset);
627
628 std::vector<llvm::MachineRelocation> relocations;
629
630 // Read in the relocs
631 for (size_t i = 0; i < mCacheHdr->relocCount; i++) {
632 oBCCRelocEntry *entry = &cachedRelocTable[i];
633
634 llvm::MachineRelocation reloc =
635 llvm::MachineRelocation::getGV((uintptr_t)entry->relocOffset,
636 (unsigned)entry->relocType, 0, 0);
637
638 reloc.setResultPointer(
639 reinterpret_cast<char *>(entry->cachedResultAddr) + mCacheDiff);
640
641 relocations.push_back(reloc);
642 }
643
644 // Rewrite machine code using llvm::TargetJITInfo relocate
645 {
646 llvm::TargetMachine *TM = NULL;
647 const llvm::Target *Target;
648 std::string FeaturesStr;
649
650 // Create TargetMachine
651 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
652 if (hasError())
653 goto bail;
654
655 if (!CPU.empty() || !Features.empty()) {
656 llvm::SubtargetFeatures F;
657 F.setCPU(CPU);
658 for (std::vector<std::string>::const_iterator I = Features.begin(),
659 E = Features.end(); I != E; I++)
660 F.AddFeature(*I);
661 FeaturesStr = F.getString();
662 }
663
664 TM = Target->createTargetMachine(Triple, FeaturesStr);
665 if (TM == NULL) {
666 setError("Failed to create target machine implementation for the"
667 " specified triple '" + Triple + "'");
668 goto bail;
669 }
670
671 TM->getJITInfo()->relocate(mCodeDataAddr,
672 &relocations[0], relocations.size(),
673 (unsigned char *)mCodeDataAddr+MaxCodeSize);
674
675 if (mCodeEmitter.get()) {
676 mCodeEmitter->Disassemble(llvm::StringRef("cache"),
677 reinterpret_cast<uint8_t*>(mCodeDataAddr),
678 2 * 1024 /*MaxCodeSize*/,
679 false);
680 }
681
682 delete TM;
683 }
684 } // End of if (mCacheDiff)
685
686 return 0; // Success!
687 }
688#endif
689#endif
690
691bail:
692 if (mCacheMapAddr) {
693 free(mCacheMapAddr);
694 }
695
696 if (mCodeDataAddr && mCodeDataAddr != MAP_FAILED) {
697 if (munmap(mCodeDataAddr, BCC_MMAP_IMG_SIZE) != 0) {
698 LOGE("munmap failed: %s\n", strerror(errno));
699 }
700 }
701
702 mCacheMapAddr = NULL;
703 mCacheHdr = NULL;
704 mCodeDataAddr = NULL;
705
706giveup:
707 return 1;
708}
709
710// interace for bccCompileBC()
711int Compiler::compile() {
712 llvm::TargetData *TD = NULL;
713
714 llvm::TargetMachine *TM = NULL;
715 const llvm::Target *Target;
716 std::string FeaturesStr;
717
718 llvm::FunctionPassManager *CodeGenPasses = NULL;
719
720 const llvm::NamedMDNode *PragmaMetadata;
721 const llvm::NamedMDNode *ExportVarMetadata;
722 const llvm::NamedMDNode *ExportFuncMetadata;
723
724 if (mModule == NULL) // No module was loaded
725 return 0;
726
727 // Create TargetMachine
728 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
729 if (hasError())
730 goto on_bcc_compile_error;
731
732 if (!CPU.empty() || !Features.empty()) {
733 llvm::SubtargetFeatures F;
734 F.setCPU(CPU);
Logana4994f52010-11-27 14:06:02 +0800735
736 for (std::vector<std::string>::const_iterator
737 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800738 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800739 }
740
Logan1f028c02010-11-27 01:02:48 +0800741 FeaturesStr = F.getString();
742 }
743
744 TM = Target->createTargetMachine(Triple, FeaturesStr);
745 if (TM == NULL) {
746 setError("Failed to create target machine implementation for the"
747 " specified triple '" + Triple + "'");
748 goto on_bcc_compile_error;
749 }
750
751 // Create memory manager for creation of code emitter later.
752 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
753 setError("Failed to startup memory management for further compilation");
754 goto on_bcc_compile_error;
755 }
756 mCodeDataAddr = (char *) (mCodeMemMgr.get()->getCodeMemBase());
757
758 // Create code emitter
759 if (!mCodeEmitter.get()) {
760 if (!createCodeEmitter()) {
761 setError("Failed to create machine code emitter to complete"
762 " the compilation");
763 goto on_bcc_compile_error;
764 }
765 } else {
766 // Reuse the code emitter
767 mCodeEmitter->reset();
768 }
769
770 mCodeEmitter->setTargetMachine(*TM);
771 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
772 mpSymbolLookupContext);
773
774 // Get target data from Module
775 TD = new llvm::TargetData(mModule);
776
777 // Load named metadata
778 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
779 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
780 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
781
782 // Create LTO passes and run them on the mModule
783 if (mHasLinked) {
784 llvm::TimePassesIsEnabled = true; // TODO(all)
785 llvm::PassManager LTOPasses;
786 LTOPasses.add(new llvm::TargetData(*TD));
787
788 std::vector<const char*> ExportSymbols;
789
790 // A workaround for getting export variable and function name. Will refine
791 // it soon.
792 if (ExportVarMetadata) {
793 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
794 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
795 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
796 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
797 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
798 llvm::StringRef ExportVarName =
799 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
800 ExportSymbols.push_back(ExportVarName.data());
801 }
802 }
803 }
804 }
805
806 if (ExportFuncMetadata) {
807 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
808 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
809 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
810 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
811 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
812 llvm::StringRef ExportFuncName =
813 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
814 ExportSymbols.push_back(ExportFuncName.data());
815 }
816 }
817 }
818 }
819 // root() and init() are born to be exported
820 ExportSymbols.push_back("root");
821 ExportSymbols.push_back("init");
822
823 // We now create passes list performing LTO. These are copied from
824 // (including comments) llvm::createStandardLTOPasses().
825
826 // Internalize all other symbols not listed in ExportSymbols
827 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
828
829 // Propagate constants at call sites into the functions they call. This
830 // opens opportunities for globalopt (and inlining) by substituting
831 // function pointers passed as arguments to direct uses of functions.
832 LTOPasses.add(llvm::createIPSCCPPass());
833
834 // Now that we internalized some globals, see if we can hack on them!
835 LTOPasses.add(llvm::createGlobalOptimizerPass());
836
837 // Linking modules together can lead to duplicated global constants, only
838 // keep one copy of each constant...
839 LTOPasses.add(llvm::createConstantMergePass());
840
841 // Remove unused arguments from functions...
842 LTOPasses.add(llvm::createDeadArgEliminationPass());
843
844 // Reduce the code after globalopt and ipsccp. Both can open up
845 // significant simplification opportunities, and both can propagate
846 // functions through function pointers. When this happens, we often have
847 // to resolve varargs calls, etc, so let instcombine do this.
848 LTOPasses.add(llvm::createInstructionCombiningPass());
849
850 // Inline small functions
851 LTOPasses.add(llvm::createFunctionInliningPass());
852
853 // Remove dead EH info.
854 LTOPasses.add(llvm::createPruneEHPass());
855
856 // Internalize the globals again after inlining
857 LTOPasses.add(llvm::createGlobalOptimizerPass());
858
859 // Remove dead functions.
860 LTOPasses.add(llvm::createGlobalDCEPass());
861
862 // If we didn't decide to inline a function, check to see if we can
863 // transform it to pass arguments by value instead of by reference.
864 LTOPasses.add(llvm::createArgumentPromotionPass());
865
866 // The IPO passes may leave cruft around. Clean up after them.
867 LTOPasses.add(llvm::createInstructionCombiningPass());
868 LTOPasses.add(llvm::createJumpThreadingPass());
869
870 // Break up allocas
871 LTOPasses.add(llvm::createScalarReplAggregatesPass());
872
873 // Run a few AA driven optimizations here and now, to cleanup the code.
874 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
875 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
876
877 // Hoist loop invariants.
878 LTOPasses.add(llvm::createLICMPass());
879
880 // Remove redundancies.
881 LTOPasses.add(llvm::createGVNPass());
882
883 // Remove dead memcpys.
884 LTOPasses.add(llvm::createMemCpyOptPass());
885
886 // Nuke dead stores.
887 LTOPasses.add(llvm::createDeadStoreEliminationPass());
888
889 // Cleanup and simplify the code after the scalar optimizations.
890 LTOPasses.add(llvm::createInstructionCombiningPass());
891
892 LTOPasses.add(llvm::createJumpThreadingPass());
893
894 // Delete basic blocks, which optimization passes may have killed.
895 LTOPasses.add(llvm::createCFGSimplificationPass());
896
897 // Now that we have optimized the program, discard unreachable functions.
898 LTOPasses.add(llvm::createGlobalDCEPass());
899
900 LTOPasses.run(*mModule);
901 }
902
903 // Create code-gen pass to run the code emitter
904 CodeGenPasses = new llvm::FunctionPassManager(mModule);
905 CodeGenPasses->add(TD); // Will take the ownership of TD
906
907 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
908 *mCodeEmitter,
909 CodeGenOptLevel)) {
910 setError("The machine code emission is not supported by BCC on target '"
911 + Triple + "'");
912 goto on_bcc_compile_error;
913 }
914
915 // Run the pass (the code emitter) on every non-declaration function in the
916 // module
917 CodeGenPasses->doInitialization();
918 for (llvm::Module::iterator I = mModule->begin(), E = mModule->end();
919 I != E; I++) {
920 if (!I->isDeclaration()) {
921 CodeGenPasses->run(*I);
922 }
923 }
924
925 CodeGenPasses->doFinalization();
926
927 // Copy the global address mapping from code emitter and remapping
928 if (ExportVarMetadata) {
929 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
930 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
931 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
932 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
933 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
934 llvm::StringRef ExportVarName =
935 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
936
937 CodeEmitter::global_addresses_const_iterator I, E;
938 for (I = mCodeEmitter->global_address_begin(),
939 E = mCodeEmitter->global_address_end();
940 I != E; I++) {
941 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
942 continue;
943 if (ExportVarName == I->first->getName()) {
944 mExportVars.push_back(I->second);
945 break;
946 }
947 }
948 if (I != mCodeEmitter->global_address_end())
949 continue; // found
950 }
951 }
952 // if reaching here, we know the global variable record in metadata is
953 // not found. So we make an empty slot
954 mExportVars.push_back(NULL);
955 }
956 assert((mExportVars.size() == ExportVarMetadata->getNumOperands()) &&
957 "Number of slots doesn't match the number of export variables!");
958 }
959
960 if (ExportFuncMetadata) {
961 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
962 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
963 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
964 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
965 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
966 llvm::StringRef ExportFuncName =
967 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
968 mExportFuncs.push_back(mCodeEmitter->lookup(ExportFuncName));
969 }
970 }
971 }
972 }
973
974 // Tell code emitter now can release the memory using during the JIT since
975 // we have done the code emission
976 mCodeEmitter->releaseUnnecessary();
977
978 // Finally, read pragma information from the metadata node of the @Module if
979 // any.
980 if (PragmaMetadata)
981 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
982 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
983 if (Pragma != NULL &&
984 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
985 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
986 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
987
988 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
989 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
990 llvm::StringRef PragmaName =
991 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
992 llvm::StringRef PragmaValue =
993 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
994
995 mPragmas.push_back(
996 std::make_pair(std::string(PragmaName.data(),
997 PragmaName.size()),
998 std::string(PragmaValue.data(),
999 PragmaValue.size())));
1000 }
1001 }
1002 }
1003
1004on_bcc_compile_error:
1005 // LOGE("on_bcc_compiler_error");
1006 if (CodeGenPasses) {
1007 delete CodeGenPasses;
1008 } else if (TD) {
1009 delete TD;
1010 }
1011 if (TM)
1012 delete TM;
1013
1014 if (mError.empty()) {
1015 if (mUseCache && mCacheFd >= 0 && mCacheNew) {
1016 genCacheFile();
1017 flock(mCacheFd, LOCK_UN);
1018 }
1019
1020 return false;
1021 }
1022
1023 // LOGE(getErrorMessage());
1024 return true;
1025}
1026
1027
1028// interface for bccGetScriptLabel()
1029void *Compiler::lookup(const char *name) {
1030 void *addr = NULL;
1031 if (mUseCache && mCacheFd >= 0 && !mCacheNew) {
1032 if (!strcmp(name, "root")) {
1033 addr = reinterpret_cast<void *>(mCacheHdr->rootAddr);
1034 } else if (!strcmp(name, "init")) {
1035 addr = reinterpret_cast<void *>(mCacheHdr->initAddr);
1036 }
1037 return addr;
1038 }
1039
1040 if (mCodeEmitter.get())
1041 // Find function pointer
1042 addr = mCodeEmitter->lookup(name);
1043 return addr;
1044}
1045
1046
1047// Interface for bccGetExportVars()
1048void Compiler::getExportVars(BCCsizei *actualVarCount,
1049 BCCsizei maxVarCount,
1050 BCCvoid **vars) {
1051 int varCount;
1052
1053 if (mUseCache && mCacheFd >= 0 && !mCacheNew) {
1054 varCount = static_cast<int>(mCacheHdr->exportVarsCount);
1055 if (actualVarCount)
1056 *actualVarCount = varCount;
1057 if (varCount > maxVarCount)
1058 varCount = maxVarCount;
1059 if (vars) {
1060 uint32_t *cachedVars = (uint32_t *)(mCacheMapAddr +
1061 mCacheHdr->exportVarsOffset);
1062
1063 for (int i = 0; i < varCount; i++) {
Logan7cc1baf2010-11-28 23:46:11 +08001064 *vars = (BCCvoid *)((char *)(*cachedVars) + mCacheDiff);
1065 vars++;
Logan1f028c02010-11-27 01:02:48 +08001066 cachedVars++;
1067 }
1068 }
1069 return;
1070 }
1071
1072 varCount = mExportVars.size();
1073 if (actualVarCount)
1074 *actualVarCount = varCount;
1075 if (varCount > maxVarCount)
1076 varCount = maxVarCount;
1077 if (vars) {
Logana4994f52010-11-27 14:06:02 +08001078 for (ExportVarList::const_iterator
1079 I = mExportVars.begin(), E = mExportVars.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +08001080 *vars++ = *I;
1081 }
1082 }
Logan1f028c02010-11-27 01:02:48 +08001083}
1084
1085
1086// Interface for bccGetExportFuncs()
1087void Compiler::getExportFuncs(BCCsizei *actualFuncCount,
1088 BCCsizei maxFuncCount,
1089 BCCvoid **funcs) {
1090 int funcCount;
1091
1092 if (mUseCache && mCacheFd >= 0 && !mCacheNew) {
1093 funcCount = static_cast<int>(mCacheHdr->exportFuncsCount);
1094 if (actualFuncCount)
1095 *actualFuncCount = funcCount;
1096 if (funcCount > maxFuncCount)
1097 funcCount = maxFuncCount;
1098 if (funcs) {
1099 uint32_t *cachedFuncs = (uint32_t *)(mCacheMapAddr +
1100 mCacheHdr->exportFuncsOffset);
1101
1102 for (int i = 0; i < funcCount; i++) {
Logan7cc1baf2010-11-28 23:46:11 +08001103 *funcs = (BCCvoid *)((char *)(*cachedFuncs) + mCacheDiff);
1104 funcs++;
Logan1f028c02010-11-27 01:02:48 +08001105 cachedFuncs++;
1106 }
1107 }
1108 return;
1109 }
1110
1111 funcCount = mExportFuncs.size();
1112 if (actualFuncCount)
1113 *actualFuncCount = funcCount;
1114 if (funcCount > maxFuncCount)
1115 funcCount = maxFuncCount;
1116 if (funcs) {
Logan7cc1baf2010-11-28 23:46:11 +08001117 for (ExportFuncList::const_iterator
1118 I = mExportFuncs.begin(), E = mExportFuncs.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +08001119 *funcs++ = *I;
1120 }
1121 }
Logan1f028c02010-11-27 01:02:48 +08001122}
1123
1124
1125// Interface for bccGetPragmas()
1126void Compiler::getPragmas(BCCsizei *actualStringCount,
1127 BCCsizei maxStringCount,
1128 BCCchar **strings) {
1129 int stringCount;
Logan7cc1baf2010-11-28 23:46:11 +08001130
Logan1f028c02010-11-27 01:02:48 +08001131 if (mUseCache && mCacheFd >= 0 && !mCacheNew) {
Logan7cc1baf2010-11-28 23:46:11 +08001132 stringCount = static_cast<int>(mCacheHdr->exportPragmasCount) * 2;
1133
Logan1f028c02010-11-27 01:02:48 +08001134 if (actualStringCount)
Logan7cc1baf2010-11-28 23:46:11 +08001135 *actualStringCount = stringCount;
1136
1137 if (stringCount > maxStringCount)
1138 stringCount = maxStringCount;
1139
1140 if (strings) {
1141 char *pragmaTab = mCacheMapAddr + mCacheHdr->exportPragmasOffset;
1142
1143 oBCCPragmaEntry *cachedPragmaEntries = (oBCCPragmaEntry *)pragmaTab;
1144
1145 for (int i = 0; stringCount >= 2; stringCount -= 2, i++) {
1146 *strings++ = pragmaTab + cachedPragmaEntries[i].pragmaNameOffset;
1147 *strings++ = pragmaTab + cachedPragmaEntries[i].pragmaValueOffset;
1148 }
1149 }
1150
Logan1f028c02010-11-27 01:02:48 +08001151 return;
1152 }
1153
1154 stringCount = mPragmas.size() * 2;
1155
1156 if (actualStringCount)
1157 *actualStringCount = stringCount;
1158 if (stringCount > maxStringCount)
1159 stringCount = maxStringCount;
1160 if (strings) {
Logan7cc1baf2010-11-28 23:46:11 +08001161 size_t i = 0;
Logan1f028c02010-11-27 01:02:48 +08001162 for (PragmaList::const_iterator it = mPragmas.begin();
Logan7cc1baf2010-11-28 23:46:11 +08001163 stringCount >= 2; stringCount -= 2, it++, ++i) {
Logan1f028c02010-11-27 01:02:48 +08001164 *strings++ = const_cast<BCCchar*>(it->first.c_str());
1165 *strings++ = const_cast<BCCchar*>(it->second.c_str());
1166 }
1167 }
1168
1169 return;
1170}
1171
1172
1173// Interface for bccGetFunctions()
1174void Compiler::getFunctions(BCCsizei *actualFunctionCount,
1175 BCCsizei maxFunctionCount,
1176 BCCchar **functions) {
1177 if (mCodeEmitter.get())
1178 mCodeEmitter->getFunctionNames(actualFunctionCount,
1179 maxFunctionCount,
1180 functions);
1181 else
1182 *actualFunctionCount = 0;
1183
1184 return;
1185}
1186
1187
1188// Interface for bccGetFunctionBinary()
1189void Compiler::getFunctionBinary(BCCchar *function,
1190 BCCvoid **base,
1191 BCCsizei *length) {
1192 if (mCodeEmitter.get()) {
1193 mCodeEmitter->getFunctionBinary(function, base, length);
1194 } else {
1195 *base = NULL;
1196 *length = 0;
1197 }
1198 return;
1199}
1200
1201
1202Compiler::~Compiler() {
1203 if (!mCodeMemMgr.get()) {
1204 // mCodeDataAddr and mCacheMapAddr are from loadCacheFile and not
1205 // managed by CodeMemoryManager.
1206
1207 if (mCodeDataAddr != 0 && mCodeDataAddr != MAP_FAILED) {
1208 if (munmap(mCodeDataAddr, BCC_MMAP_IMG_SIZE) < 0) {
1209 LOGE("munmap failed while releasing mCodeDataAddr\n");
1210 }
1211 }
1212
1213 if (mCacheMapAddr) {
1214 free(mCacheMapAddr);
1215 }
1216
1217 mCodeDataAddr = 0;
1218 mCacheMapAddr = 0;
1219 }
1220
1221 delete mModule;
Logan1f028c02010-11-27 01:02:48 +08001222 delete mContext;
Logana4994f52010-11-27 14:06:02 +08001223
1224 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +08001225}
1226
1227
1228// Design of caching EXE:
1229// ======================
1230// 1. Each process will have virtual address available starting at 0x7e00000.
1231// E.g., Books and Youtube all have its own 0x7e00000. Next, we should
1232// minimize the chance of needing to do relocation INSIDE an app too.
1233//
1234// 2. Each process will have ONE class static variable called BccCodeAddr.
1235// I.e., even though the Compiler class will have multiple Compiler objects,
1236// e.g, one object for carousel.rs and the other for pageturn.rs,
1237// both Compiler objects will share 1 static variable called BccCodeAddr.
1238//
1239// Key observation: Every app (process) initiates, say 3, scripts (which
1240// correspond to 3 Compiler objects) in the same order, usually.
1241//
1242// So, we should mmap to, e.g., 0x7e00000, 0x7e40000, 0x7e80000 for the 3
1243// scripts, respectively. Each time, BccCodeAddr should be updated after
1244// JITTing a script. BTW, in ~Compiler(), BccCodeAddr should NOT be
1245// decremented back by CodeDataSize. I.e., for 3 scripts: A, B, C,
1246// even if it's A -> B -> ~B -> C -> ~C -> B -> C ... no relocation will
1247// ever be needed.)
1248//
1249// If we are lucky, then we don't need relocation ever, since next time the
1250// application gets run, the 3 scripts are likely created in the SAME order.
1251//
1252//
1253// End-to-end algorithm on when to caching and when to JIT:
1254// ========================================================
1255// Prologue:
1256// ---------
1257// Assertion: bccReadBC() is always called and is before bccCompileBC(),
1258// bccLoadBinary(), ...
1259//
1260// Key variable definitions: Normally,
1261// Compiler::BccCodeAddr: non-zero if (USE_CACHE)
1262// | (Stricter, because currently relocation doesn't work. So mUseCache only
1263// | when BccCodeAddr is nonzero.)
1264// V
1265// mUseCache: In addition to (USE_CACHE), resName is non-zero
1266// Note: mUseCache will be set to false later on whenever we find that caching
1267// won't work. E.g., when mCodeDataAddr != mCacheHdr->cachedCodeDataAddr.
1268// This is because currently relocation doesn't work.
1269// | (Stricter, initially)
1270// V
1271// mCacheFd: In addition, >= 0 if openCacheFile() returns >= 0
1272// | (Stricter)
1273// V
1274// mCacheNew: In addition, mCacheFd's size is 0, so need to call genCacheFile()
1275// at the end of compile()
1276//
1277//
1278// Main algorithm:
1279// ---------------
1280// #if !USE_RELOCATE
1281// Case 1. ReadBC() doesn't detect a cache file:
1282// compile(), which calls genCacheFile() at the end.
1283// Note: mCacheNew will guard the invocation of genCacheFile()
1284// Case 2. ReadBC() find a cache file
1285// loadCacheFile(). But if loadCacheFile() failed, should go to Case 1.
1286// #endif
1287
1288// Note: loadCacheFile() and genCacheFile() go hand in hand
1289void Compiler::genCacheFile() {
1290 if (lseek(mCacheFd, 0, SEEK_SET) != 0) {
1291 LOGE("Unable to seek to 0: %s\n", strerror(errno));
1292 return;
1293 }
1294
1295 bool codeOffsetNeedPadding = false;
1296
1297 uint32_t offset = sizeof(oBCCHeader);
1298
1299 // BCC Cache File Header
1300 oBCCHeader *hdr = (oBCCHeader *)malloc(sizeof(oBCCHeader));
1301
1302 if (!hdr) {
1303 LOGE("Unable to allocate oBCCHeader.\n");
1304 return;
1305 }
1306
1307 // Magic Words
1308 memcpy(hdr->magic, OBCC_MAGIC, 4);
1309 memcpy(hdr->magicVersion, OBCC_MAGIC_VERS, 4);
1310
1311 // Timestamp
1312 hdr->sourceWhen = 0; // TODO(all)
1313 hdr->rslibWhen = 0; // TODO(all)
Logan9d94f162010-12-07 12:39:25 +08001314 hdr->libRSWhen = statModifyTime(libRSPath);
1315 hdr->libbccWhen = statModifyTime(libBccPath);
Logan1f028c02010-11-27 01:02:48 +08001316
1317 // Current Memory Address (Saved for Recalculation)
1318 hdr->cachedCodeDataAddr = reinterpret_cast<uint32_t>(mCodeDataAddr);
1319 hdr->rootAddr = reinterpret_cast<uint32_t>(lookup("root"));
1320 hdr->initAddr = reinterpret_cast<uint32_t>(lookup("init"));
1321
1322 // Relocation Table Offset and Entry Count
1323 hdr->relocOffset = sizeof(oBCCHeader);
1324 hdr->relocCount = mCodeEmitter->getCachingRelocations().size();
1325
Logan7cc1baf2010-11-28 23:46:11 +08001326 offset += hdr->relocCount * sizeof(oBCCRelocEntry);
Logan1f028c02010-11-27 01:02:48 +08001327
1328 // Export Variable Table Offset and Entry Count
1329 hdr->exportVarsOffset = offset;
1330 hdr->exportVarsCount = mExportVars.size();
1331
1332 offset += hdr->exportVarsCount * sizeof(uint32_t);
1333
1334 // Export Function Table Offset and Entry Count
1335 hdr->exportFuncsOffset = offset;
1336 hdr->exportFuncsCount = mExportFuncs.size();
1337
1338 offset += hdr->exportFuncsCount * sizeof(uint32_t);
1339
1340 // Export Pragmas Table Offset and Entry Count
1341 hdr->exportPragmasOffset = offset;
Logan7cc1baf2010-11-28 23:46:11 +08001342 hdr->exportPragmasCount = mPragmas.size();
1343 hdr->exportPragmasSize = hdr->exportPragmasCount * sizeof(oBCCPragmaEntry);
Logan1f028c02010-11-27 01:02:48 +08001344
Logan7cc1baf2010-11-28 23:46:11 +08001345 offset += hdr->exportPragmasCount * sizeof(oBCCPragmaEntry);
1346
1347 for (PragmaList::const_iterator
1348 I = mPragmas.begin(), E = mPragmas.end(); I != E; ++I) {
1349 offset += I->first.size() + 1;
1350 offset += I->second.size() + 1;
1351 hdr->exportPragmasSize += I->first.size() + I->second.size() + 2;
1352 }
Logan1f028c02010-11-27 01:02:48 +08001353
1354 // Code Offset and Size
1355
1356 { // Always pad to the page boundary for now
1357 long pagesize = sysconf(_SC_PAGESIZE);
1358
1359 if (offset % pagesize > 0) {
1360 codeOffsetNeedPadding = true;
1361 offset += pagesize - (offset % pagesize);
1362 }
1363 }
1364
1365 hdr->codeOffset = offset;
1366 hdr->codeSize = MaxCodeSize;
1367
1368 offset += hdr->codeSize;
1369
1370 // Data (Global Variable) Offset and Size
1371 hdr->dataOffset = offset;
1372 hdr->dataSize = MaxGlobalVarSize;
1373
1374 offset += hdr->dataSize;
1375
1376 // Checksum
1377#if 1
1378 {
1379 // Note: This is an simple checksum implementation that are using xor
1380 // to calculate even parity (for code and data only).
1381
1382 uint32_t sum = 0;
1383 uint32_t *ptr = (uint32_t *)mCodeDataAddr;
1384
1385 for (size_t i = 0; i < BCC_MMAP_IMG_SIZE / sizeof(uint32_t); ++i) {
1386 sum ^= *ptr++;
1387 }
1388
1389 hdr->checksum = sum;
1390 }
1391#else
1392 hdr->checksum = 0; // Set Field checksum. TODO(all)
1393#endif
1394
1395 // Write Header
1396 sysWriteFully(mCacheFd, reinterpret_cast<char const *>(hdr),
1397 sizeof(oBCCHeader), "Write oBCC header");
1398
1399 // Write Relocation Entry Table
1400 {
1401 size_t allocSize = hdr->relocCount * sizeof(oBCCRelocEntry);
1402
1403 oBCCRelocEntry const*records = &mCodeEmitter->getCachingRelocations()[0];
1404
1405 sysWriteFully(mCacheFd, reinterpret_cast<char const *>(records),
1406 allocSize, "Write Relocation Entries");
1407 }
1408
1409 // Write Export Variables Table
1410 {
1411 uint32_t *record, *ptr;
1412
1413 record = (uint32_t *)calloc(hdr->exportVarsCount, sizeof(uint32_t));
1414 ptr = record;
1415
1416 if (!record) {
1417 goto bail;
1418 }
1419
1420 for (ExportVarList::const_iterator I = mExportVars.begin(),
1421 E = mExportVars.end(); I != E; I++) {
1422 *ptr++ = reinterpret_cast<uint32_t>(*I);
1423 }
1424
1425 sysWriteFully(mCacheFd, reinterpret_cast<char const *>(record),
1426 hdr->exportVarsCount * sizeof(uint32_t),
1427 "Write ExportVars");
1428
1429 free(record);
1430 }
1431
1432 // Write Export Functions Table
1433 {
1434 uint32_t *record, *ptr;
1435
1436 record = (uint32_t *)calloc(hdr->exportFuncsCount, sizeof(uint32_t));
1437 ptr = record;
1438
1439 if (!record) {
1440 goto bail;
1441 }
1442
1443 for (ExportFuncList::const_iterator I = mExportFuncs.begin(),
1444 E = mExportFuncs.end(); I != E; I++) {
1445 *ptr++ = reinterpret_cast<uint32_t>(*I);
1446 }
1447
1448 sysWriteFully(mCacheFd, reinterpret_cast<char const *>(record),
1449 hdr->exportFuncsCount * sizeof(uint32_t),
1450 "Write ExportFuncs");
1451
1452 free(record);
1453 }
1454
1455
Logan7cc1baf2010-11-28 23:46:11 +08001456 // Write Export Pragmas Table
1457 {
1458 uint32_t pragmaEntryOffset =
1459 hdr->exportPragmasCount * sizeof(oBCCPragmaEntry);
Logan1f028c02010-11-27 01:02:48 +08001460
Logan7cc1baf2010-11-28 23:46:11 +08001461 for (PragmaList::const_iterator
1462 I = mPragmas.begin(), E = mPragmas.end(); I != E; ++I) {
1463 oBCCPragmaEntry entry;
1464
1465 entry.pragmaNameOffset = pragmaEntryOffset;
1466 entry.pragmaNameSize = I->first.size();
1467 pragmaEntryOffset += entry.pragmaNameSize + 1;
1468
1469 entry.pragmaValueOffset = pragmaEntryOffset;
1470 entry.pragmaValueSize = I->second.size();
1471 pragmaEntryOffset += entry.pragmaValueSize + 1;
1472
1473 sysWriteFully(mCacheFd, (char *)&entry, sizeof(oBCCPragmaEntry),
1474 "Write export pragma entry");
1475 }
1476
1477 for (PragmaList::const_iterator
1478 I = mPragmas.begin(), E = mPragmas.end(); I != E; ++I) {
1479 sysWriteFully(mCacheFd, I->first.c_str(), I->first.size() + 1,
1480 "Write export pragma name string");
1481 sysWriteFully(mCacheFd, I->second.c_str(), I->second.size() + 1,
1482 "Write export pragma value string");
1483 }
1484 }
Logan1f028c02010-11-27 01:02:48 +08001485
1486 if (codeOffsetNeedPadding) {
1487 // requires additional padding
1488 lseek(mCacheFd, hdr->codeOffset, SEEK_SET);
1489 }
1490
1491 // Write Generated Code and Global Variable
1492 sysWriteFully(mCacheFd, mCodeDataAddr, MaxCodeSize + MaxGlobalVarSize,
1493 "Write code and global variable");
1494
1495 goto close_return;
1496
1497bail:
1498 if (ftruncate(mCacheFd, 0) != 0) {
1499 LOGW("Warning: unable to truncate cache file: %s\n", strerror(errno));
1500 }
1501
1502close_return:
1503 free(hdr);
1504 close(mCacheFd);
1505 mCacheFd = -1;
1506}
1507
1508
1509// OpenCacheFile() returns fd of the cache file.
1510// Input:
1511// BCCchar *resName: Used to genCacheFileName()
1512// bool createIfMissing: If false, turn off caching
1513// Output:
1514// returns fd: If -1: Failed
1515// mCacheNew: If true, the returned fd is new. Otherwise, the fd is the
1516// cache file's file descriptor
1517// Note: openCacheFile() will check the cache file's validity,
1518// such as Magic number, sourceWhen... dependencies.
1519int Compiler::openCacheFile(const BCCchar *resName, bool createIfMissing) {
1520 int fd, cc;
1521 struct stat fdStat, fileStat;
1522 bool readOnly = false;
1523
1524 char *cacheFileName = genCacheFileName(resName, ".oBCC");
1525
1526 mCacheNew = false;
1527
1528retry:
1529 /*
1530 * Try to open the cache file. If we've been asked to,
1531 * create it if it doesn't exist.
1532 */
1533 fd = createIfMissing ? open(cacheFileName, O_CREAT|O_RDWR, 0644) : -1;
1534 if (fd < 0) {
1535 fd = open(cacheFileName, O_RDONLY, 0);
1536 if (fd < 0) {
1537 if (createIfMissing) {
1538 LOGW("Can't open bcc-cache '%s': %s\n",
1539 cacheFileName, strerror(errno));
1540 mUseCache = false;
1541 }
1542 return fd;
1543 }
1544 readOnly = true;
1545 }
1546
1547 /*
1548 * Grab an exclusive lock on the cache file. If somebody else is
1549 * working on it, we'll block here until they complete.
1550 */
1551 LOGV("bcc: locking cache file %s (fd=%d, boot=%d)\n",
1552 cacheFileName, fd);
1553
1554 cc = flock(fd, LOCK_EX | LOCK_NB);
1555 if (cc != 0) {
1556 LOGD("bcc: sleeping on flock(%s)\n", cacheFileName);
1557 cc = flock(fd, LOCK_EX);
1558 }
1559
1560 if (cc != 0) {
1561 LOGE("Can't lock bcc cache '%s': %d\n", cacheFileName, cc);
1562 close(fd);
1563 return -1;
1564 }
1565 LOGV("bcc: locked cache file\n");
1566
1567 /*
1568 * Check to see if the fd we opened and locked matches the file in
1569 * the filesystem. If they don't, then somebody else unlinked ours
1570 * and created a new file, and we need to use that one instead. (If
1571 * we caught them between the unlink and the create, we'll get an
1572 * ENOENT from the file stat.)
1573 */
1574 cc = fstat(fd, &fdStat);
1575 if (cc != 0) {
1576 LOGE("Can't stat open file '%s'\n", cacheFileName);
1577 LOGV("bcc: unlocking cache file %s\n", cacheFileName);
1578 goto close_fail;
1579 }
1580 cc = stat(cacheFileName, &fileStat);
1581 if (cc != 0 ||
1582 fdStat.st_dev != fileStat.st_dev || fdStat.st_ino != fileStat.st_ino) {
1583 LOGD("bcc: our open cache file is stale; sleeping and retrying\n");
1584 LOGV("bcc: unlocking cache file %s\n", cacheFileName);
1585 flock(fd, LOCK_UN);
1586 close(fd);
1587 usleep(250 * 1000); // if something is hosed, don't peg machine
1588 goto retry;
1589 }
1590
1591 /*
1592 * We have the correct file open and locked. If the file size is zero,
1593 * then it was just created by us, and we want to fill in some fields
1594 * in the "bcc" header and set "mCacheNew". Otherwise, we want to
1595 * verify that the fields in the header match our expectations, and
1596 * reset the file if they don't.
1597 */
1598 if (fdStat.st_size == 0) {
1599 if (readOnly) { // The device is readOnly --> close_fail
1600 LOGW("bcc: file has zero length and isn't writable\n");
1601 goto close_fail;
1602 }
1603 /*cc = createEmptyHeader(fd);
1604 if (cc != 0)
1605 goto close_fail;
1606 */
1607 mCacheNew = true;
1608 LOGV("bcc: successfully initialized new cache file\n");
1609 } else {
1610 // Calculate sourceWhen
1611 // XXX
1612 uint32_t sourceWhen = 0;
1613 uint32_t rslibWhen = 0;
Logan9d94f162010-12-07 12:39:25 +08001614 uint32_t libRSWhen = statModifyTime(libRSPath);
1615 uint32_t libbccWhen = statModifyTime(libBccPath);
Logan1f028c02010-11-27 01:02:48 +08001616 if (!checkHeaderAndDependencies(fd,
1617 sourceWhen,
1618 rslibWhen,
1619 libRSWhen,
1620 libbccWhen)) {
1621 // If checkHeaderAndDependencies returns 0: FAILED
1622 // Will truncate the file and retry to createIfMissing the file
1623
1624 if (readOnly) { // Shouldn't be readonly.
1625 /*
1626 * We could unlink and rewrite the file if we own it or
1627 * the "sticky" bit isn't set on the directory. However,
1628 * we're not able to truncate it, which spoils things. So,
1629 * give up now.
1630 */
1631 if (createIfMissing) {
1632 LOGW("Cached file %s is stale and not writable\n",
1633 cacheFileName);
1634 }
1635 goto close_fail;
1636 }
1637
1638 /*
1639 * If we truncate the existing file before unlinking it, any
1640 * process that has it mapped will fail when it tries to touch
1641 * the pages? Probably OK because we use MAP_PRIVATE.
1642 */
1643 LOGD("oBCC file is stale or bad; removing and retrying (%s)\n",
1644 cacheFileName);
1645 if (ftruncate(fd, 0) != 0) {
1646 LOGW("Warning: unable to truncate cache file '%s': %s\n",
1647 cacheFileName, strerror(errno));
1648 /* keep going */
1649 }
1650 if (unlink(cacheFileName) != 0) {
1651 LOGW("Warning: unable to remove cache file '%s': %d %s\n",
1652 cacheFileName, errno, strerror(errno));
1653 /* keep going; permission failure should probably be fatal */
1654 }
1655 LOGV("bcc: unlocking cache file %s\n", cacheFileName);
1656 flock(fd, LOCK_UN);
1657 close(fd);
1658 goto retry;
1659 } else {
1660 // Got cacheFile! Good to go.
1661 LOGV("Good cache file\n");
1662 }
1663 }
1664
1665 assert(fd >= 0);
1666 return fd;
1667
1668close_fail:
1669 flock(fd, LOCK_UN);
1670 close(fd);
1671 return -1;
1672} // End of openCacheFile()
1673
1674char *Compiler::genCacheFileName(const char *fileName,
1675 const char *subFileName) {
1676 char nameBuf[512];
1677 static const char kCachePath[] = "bcc-cache";
1678 char absoluteFile[sizeof(nameBuf)];
1679 const size_t kBufLen = sizeof(nameBuf) - 1;
1680 const char *dataRoot;
1681 char *cp;
1682
1683 // Get the absolute path of the raw/***.bc file.
1684 absoluteFile[0] = '\0';
1685 if (fileName[0] != '/') {
1686 /*
1687 * Generate the absolute path. This doesn't do everything it
1688 * should, e.g. if filename is "./out/whatever" it doesn't crunch
1689 * the leading "./" out, but it'll do.
1690 */
1691 if (getcwd(absoluteFile, kBufLen) == NULL) {
1692 LOGE("Can't get CWD while opening raw/***.bc file\n");
1693 return NULL;
1694 }
1695 // TODO(srhines): strncat() is a bit dangerous
1696 strncat(absoluteFile, "/", kBufLen);
1697 }
1698 strncat(absoluteFile, fileName, kBufLen);
1699
1700 if (subFileName != NULL) {
1701 strncat(absoluteFile, "/", kBufLen);
1702 strncat(absoluteFile, subFileName, kBufLen);
1703 }
1704
1705 /* Turn the path into a flat filename by replacing
1706 * any slashes after the first one with '@' characters.
1707 */
1708 cp = absoluteFile + 1;
1709 while (*cp != '\0') {
1710 if (*cp == '/') {
1711 *cp = '@';
1712 }
1713 cp++;
1714 }
1715
1716 /* Build the name of the cache directory.
1717 */
1718 dataRoot = getenv("ANDROID_DATA");
1719 if (dataRoot == NULL)
1720 dataRoot = "/data";
1721 snprintf(nameBuf, kBufLen, "%s/%s", dataRoot, kCachePath);
1722
1723 /* Tack on the file name for the actual cache file path.
1724 */
1725 strncat(nameBuf, absoluteFile, kBufLen);
1726
1727 LOGV("Cache file for '%s' '%s' is '%s'\n", fileName, subFileName, nameBuf);
1728 return strdup(nameBuf);
1729}
1730
1731/*
1732 * Read the oBCC header, verify it, then read the dependent section
1733 * and verify that data as well.
1734 *
1735 * On successful return, the file will be seeked immediately past the
1736 * oBCC header.
1737 */
1738bool Compiler::checkHeaderAndDependencies(int fd,
1739 uint32_t sourceWhen,
1740 uint32_t rslibWhen,
1741 uint32_t libRSWhen,
1742 uint32_t libbccWhen) {
1743 ssize_t actual;
1744 oBCCHeader optHdr;
1745 uint32_t val;
1746 uint8_t const *magic, *magicVer;
1747
1748 /*
1749 * Start at the start. The "bcc" header, when present, will always be
1750 * the first thing in the file.
1751 */
1752 if (lseek(fd, 0, SEEK_SET) != 0) {
1753 LOGE("bcc: failed to seek to start of file: %s\n", strerror(errno));
1754 goto bail;
1755 }
1756
1757 /*
1758 * Read and do trivial verification on the bcc header. The header is
1759 * always in host byte order.
1760 */
1761 actual = read(fd, &optHdr, sizeof(optHdr));
1762 if (actual < 0) {
1763 LOGE("bcc: failed reading bcc header: %s\n", strerror(errno));
1764 goto bail;
1765 } else if (actual != sizeof(optHdr)) {
1766 LOGE("bcc: failed reading bcc header (got %d of %zd)\n",
1767 (int) actual, sizeof(optHdr));
1768 goto bail;
1769 }
1770
1771 magic = optHdr.magic;
1772 if (memcmp(magic, OBCC_MAGIC, 4) != 0) {
1773 /* not an oBCC file, or previous attempt was interrupted */
1774 LOGD("bcc: incorrect opt magic number (0x%02x %02x %02x %02x)\n",
1775 magic[0], magic[1], magic[2], magic[3]);
1776 goto bail;
1777 }
1778
1779 magicVer = optHdr.magicVersion;
Logancd045f92010-12-06 19:04:53 +08001780 if (memcmp(magicVer, OBCC_MAGIC_VERS, 4) != 0) {
Logan1f028c02010-11-27 01:02:48 +08001781 LOGW("bcc: stale oBCC version (0x%02x %02x %02x %02x)\n",
1782 magicVer[0], magicVer[1], magicVer[2], magicVer[3]);
1783 goto bail;
1784 }
1785
1786 /*
1787 * Do the header flags match up with what we want?
1788 *
1789 * This is useful because it allows us to automatically regenerate
1790 * a file when settings change (e.g. verification is now mandatory),
1791 * but can cause difficulties if the thing we depend upon
1792 * were handled differently than the current options specify.
1793 *
1794 * So, for now, we essentially ignore "expectVerify" and "expectOpt"
1795 * by limiting the match mask.
1796 *
1797 * The only thing we really can't handle is incorrect byte-ordering.
1798 */
1799
1800 val = optHdr.sourceWhen;
1801 if (val && (val != sourceWhen)) {
1802 LOGI("bcc: source file mod time mismatch (%08x vs %08x)\n",
1803 val, sourceWhen);
1804 goto bail;
1805 }
1806 val = optHdr.rslibWhen;
1807 if (val && (val != rslibWhen)) {
1808 LOGI("bcc: rslib file mod time mismatch (%08x vs %08x)\n",
1809 val, rslibWhen);
1810 goto bail;
1811 }
1812 val = optHdr.libRSWhen;
1813 if (val && (val != libRSWhen)) {
1814 LOGI("bcc: libRS file mod time mismatch (%08x vs %08x)\n",
1815 val, libRSWhen);
1816 goto bail;
1817 }
1818 val = optHdr.libbccWhen;
1819 if (val && (val != libbccWhen)) {
1820 LOGI("bcc: libbcc file mod time mismatch (%08x vs %08x)\n",
1821 val, libbccWhen);
1822 goto bail;
1823 }
1824
1825 return true;
1826
1827bail:
1828 return false;
1829}
1830
1831} // namespace bcc