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