Merge change 24474 into eclair
* changes:
Fix an infinite loop in time2sub.
diff --git a/include/acc/acc.h b/include/acc/acc.h
index af21a46..1182355 100644
--- a/include/acc/acc.h
+++ b/include/acc/acc.h
@@ -77,6 +77,12 @@
void accGetPragmas(ACCscript* script, ACCsizei* actualStringCount,
ACCsizei maxStringCount, ACCchar** strings);
+/* Used to implement disassembly */
+
+void accGetProgramBinary(ACCscript* script,
+ ACCvoid** base,
+ ACCsizei* length);
+
#ifdef __cplusplus
};
#endif
diff --git a/libacc/Android.mk b/libacc/Android.mk
index f77e2b3..2b4998e 100644
--- a/libacc/Android.mk
+++ b/libacc/Android.mk
@@ -7,10 +7,6 @@
LOCAL_MODULE:= libacc
LOCAL_SRC_FILES := acc.cpp
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += disassem.cpp
-endif
-
LOCAL_SHARED_LIBRARIES := libdl libcutils
include $(BUILD_SHARED_LIBRARY)
@@ -24,10 +20,6 @@
LOCAL_CFLAGS := -O0 -g
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += disassem.cpp
-endif
-
LOCAL_STATIC_LIBRARIES := libcutils
LOCAL_LDLIBS := -ldl
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index c52b992..62dea4c 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -13,20 +13,20 @@
#include <ctype.h>
#include <errno.h>
+#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
#include <cutils/hashmap.h>
#if defined(__i386__)
#include <sys/mman.h>
#endif
-#if defined(__arm__)
-#include <unistd.h>
-#endif
#if defined(__arm__)
#define DEFAULT_ARM_CODEGEN
@@ -39,10 +39,6 @@
#define PROVIDE_X64_CODEGEN
#endif
-#ifdef PROVIDE_ARM_CODEGEN
-#include "disassem.h"
-#endif
-
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
#define ARM_USE_VFP
#endif
@@ -55,9 +51,22 @@
#define LOG_STACK(...) do {} while(0)
// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__)
-#define ENABLE_ARM_DISASSEMBLY
// #define PROVIDE_TRACE_CODEGEN
+// Uncomment to disable ARM peephole optimizations
+// #define DISABLE_ARM_PEEPHOLE
+
+// Uncomment to save input to a text file in DEBUG_DUMP_PATTERN
+// #define DEBUG_SAVE_INPUT_TO_FILE
+
+#ifdef DEBUG_SAVE_INPUT_TO_FILE
+#ifdef ARM_USE_VFP
+#define DEBUG_DUMP_PATTERN "/data/misc/acc_dump/%d.c"
+#else
+#define DEBUG_DUMP_PATTERN "/tmp/acc_dump/%d.c"
+#endif
+#endif
+
#define assert(b) assertImpl(b, __LINE__)
namespace acc {
@@ -179,7 +188,21 @@
Type* pType;
};
- class CodeBuf {
+ class ICodeBuf {
+ public:
+ virtual ~ICodeBuf() {}
+ virtual void init(int size) = 0;
+ virtual void setErrorSink(ErrorSink* pErrorSink) = 0;
+ virtual void o4(int n) = 0;
+ virtual void ob(int n) = 0;
+ virtual void* getBase() = 0;
+ virtual intptr_t getSize() = 0;
+ virtual intptr_t getPC() = 0;
+ // Call this before trying to modify code in the buffer.
+ virtual void flush() = 0;
+ };
+
+ class CodeBuf : public ICodeBuf {
char* ind; // Output code pointer
char* pProgramBase;
ErrorSink* mErrorSink;
@@ -214,52 +237,52 @@
mOverflowed = false;
}
- ~CodeBuf() {
+ virtual ~CodeBuf() {
release();
}
- void init(int size) {
+ virtual void init(int size) {
release();
mSize = size;
pProgramBase = (char*) calloc(1, size);
ind = pProgramBase;
}
- void setErrorSink(ErrorSink* pErrorSink) {
+ virtual void setErrorSink(ErrorSink* pErrorSink) {
mErrorSink = pErrorSink;
}
- int o4(int n) {
+ virtual void o4(int n) {
if(check(4)) {
- return 0;
+ return;
}
- intptr_t result = (intptr_t) ind;
* (int*) ind = n;
ind += 4;
- return result;
}
/*
* Output a byte. Handles all values, 0..ff.
*/
- void ob(int n) {
+ virtual void ob(int n) {
if(check(1)) {
return;
}
*ind++ = n;
}
- inline void* getBase() {
+ virtual void* getBase() {
return (void*) pProgramBase;
}
- intptr_t getSize() {
+ virtual intptr_t getSize() {
return ind - pProgramBase;
}
- intptr_t getPC() {
+ virtual intptr_t getPC() {
return (intptr_t) ind;
}
+
+ virtual void flush() {}
};
/**
@@ -291,7 +314,7 @@
}
virtual ~CodeGenerator() {}
- virtual void init(CodeBuf* pCodeBuf) {
+ virtual void init(ICodeBuf* pCodeBuf) {
this->pCodeBuf = pCodeBuf;
pCodeBuf->setErrorSink(mErrorSink);
}
@@ -473,11 +496,6 @@
*/
virtual void adjustStackAfterCall(Type* pDecl, int l, bool isIndirect) = 0;
- /* Print a disassembly of the assembled code to out. Return
- * non-zero if there is an error.
- */
- virtual int disassemble(FILE* out) = 0;
-
/* Generate a symbol at the current PC. t is the head of a
* linked list of addresses to patch.
*/
@@ -543,8 +561,8 @@
pCodeBuf->ob(n);
}
- intptr_t o4(int data) {
- return pCodeBuf->o4(data);
+ void o4(int data) {
+ pCodeBuf->o4(data);
}
intptr_t getBase() {
@@ -559,6 +577,10 @@
return pCodeBuf->getSize();
}
+ void flush() {
+ pCodeBuf->flush();
+ }
+
void error(const char* fmt,...) {
va_list ap;
va_start(ap, fmt);
@@ -674,19 +696,232 @@
private:
Vector<ExpressionValue> mExpressionStack;
- CodeBuf* pCodeBuf;
+ ICodeBuf* pCodeBuf;
ErrorSink* mErrorSink;
};
#ifdef PROVIDE_ARM_CODEGEN
+ static size_t rotateRight(size_t n, size_t rotate) {
+ return (n >> rotate) | (n << (32 - rotate));
+ }
+
+ static size_t rotateLeft(size_t n, size_t rotate) {
+ return (n << rotate) | (n >> (32 - rotate));
+ }
+
+ static bool encode12BitImmediate(size_t immediate, size_t* pResult) {
+ for(size_t i = 0; i < 16; i++) {
+ size_t rotate = i * 2;
+ size_t mask = rotateRight(0xff, rotate);
+ if ((immediate | mask) == mask) {
+ size_t bits8 = rotateLeft(immediate, rotate);
+ // assert(bits8 <= 0xff);
+ *pResult = (i << 8) | bits8;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static size_t decode12BitImmediate(size_t immediate) {
+ size_t data = immediate & 0xff;
+ size_t rotate = 2 * ((immediate >> 8) & 0xf);
+ return rotateRight(data, rotate);
+ }
+
+ class ARMCodeBuf : public ICodeBuf {
+ ICodeBuf* mpBase;
+ ErrorSink* mErrorSink;
+
+ class CircularQueue {
+ static const int SIZE = 16; // Must be power of 2
+ static const int MASK = SIZE-1;
+ unsigned int mBuf[SIZE];
+ int mHead;
+ int mCount;
+
+ public:
+ CircularQueue() {
+ mHead = 0;
+ mCount = 0;
+ }
+
+ void pushBack(unsigned int data) {
+ mBuf[(mHead + mCount) & MASK] = data;
+ mCount += 1;
+ }
+
+ unsigned int popFront() {
+ unsigned int result = mBuf[mHead];
+ mHead = (mHead + 1) & MASK;
+ mCount -= 1;
+ return result;
+ }
+
+ void popBack(int n) {
+ mCount -= n;
+ }
+
+ inline int count() {
+ return mCount;
+ }
+
+ bool empty() {
+ return mCount == 0;
+ }
+
+ bool full() {
+ return mCount == SIZE;
+ }
+
+ // The valid indexes are 1 - count() to 0
+ unsigned int operator[](int i) {
+ return mBuf[(mHead + mCount + i) & MASK];
+ }
+ };
+
+ CircularQueue mQ;
+
+ void error(const char* fmt,...) {
+ va_list ap;
+ va_start(ap, fmt);
+ mErrorSink->verror(fmt, ap);
+ va_end(ap);
+ }
+
+ void flush() {
+ while (!mQ.empty()) {
+ mpBase->o4(mQ.popFront());
+ }
+ mpBase->flush();
+ }
+
+ public:
+ ARMCodeBuf(ICodeBuf* pBase) {
+ mpBase = pBase;
+ }
+
+ virtual ~ARMCodeBuf() {
+ delete mpBase;
+ }
+
+ void init(int size) {
+ mpBase->init(size);
+ }
+
+ void setErrorSink(ErrorSink* pErrorSink) {
+ mErrorSink = pErrorSink;
+ mpBase->setErrorSink(pErrorSink);
+ }
+
+ void o4(int n) {
+ if (mQ.full()) {
+ mpBase->o4(mQ.popFront());
+ }
+ mQ.pushBack(n);
+
+#ifndef DISABLE_ARM_PEEPHOLE
+ // Peephole check
+ bool didPeep;
+ do {
+ const unsigned int opMask = 0x01e00000;
+ const unsigned int immediateMask = 0x00000fff;
+ didPeep = false;
+ if (mQ.count() >= 4) {
+
+ // Operand by a small constant
+ // push;mov #imm;pop;op ==> op #imm
+
+ if (mQ[-4] == 0xe92d0001 && // stmfd r13!, {r0}
+ (mQ[-3] & ~immediateMask) == 0xe3a00000 && // mov r0, #X
+ mQ[-2] == 0xe8bd0002 && // ldmea r13!, {r1}
+ (mQ[-1] & ~opMask) == (0xe0810000 & ~opMask)) { // OP r0, r1, r0
+ unsigned int movConst = mQ[-3];
+ unsigned int op = mQ[-1];
+ unsigned int combined = 0xe2000000 | (op & opMask) | (movConst & immediateMask);
+ // fprintf(stderr, "op %x movConst %x combined %x\n", op, movConst, combined);
+ if (! (combined == 0xe2800000 || combined == 0xe2400000)) { // add/sub #0
+ mQ.popBack(4);
+ mQ.pushBack(combined);
+ didPeep = true;
+ } else {
+ mQ.popBack(4);
+ didPeep = true;
+ }
+ }
+ }
+
+ // Load local variable
+ // sub r0,r11,#imm;ldr r0,[r0] ==> ldr r0, [r11,#-imm]
+ if (mQ.count() >= 2) {
+ if ((mQ[-2] & ~immediateMask) == 0xe24b0000 && // sub r0,r11,#imm
+ mQ[-1] == 0xe5900000) { // ldr r0, [r0]
+ unsigned int op = mQ[-2];
+ unsigned int ld = mQ[-1];
+ unsigned int combined = (op & immediateMask) | 0xE51B0000; // ldr r0, [r11, #-0]
+ mQ.popBack(2);
+ mQ.pushBack(combined);
+ didPeep = true;
+ }
+ }
+
+ // Constant array lookup
+
+ if (mQ.count() >= 6 &&
+ mQ[-6] == 0xe92d0001 && // stmfd r13!, {r0}
+ (mQ[-5] & ~immediateMask)== 0xe3a00000 && // mov r0, #0x00000001
+ mQ[-4] == 0xe8bd0002 && // ldmea r13!, {r1}
+ (mQ[-3] & ~immediateMask)== 0xe3a02000 && // mov r2, #0x00000004
+ mQ[-2] == 0xe0000092 && // mul r0, r2, r0
+ mQ[-1] == 0xe0810000) { // add r0, r1, r0
+ unsigned int mov1 = mQ[-5];
+ unsigned int mov2 = mQ[-3];
+ unsigned int const1 = decode12BitImmediate(mov1);
+ unsigned int const2 = decode12BitImmediate(mov2);
+ unsigned int comboConst = const1 * const2;
+ size_t immediate = 0;
+ if (encode12BitImmediate(comboConst, &immediate)) {
+ mQ.popBack(6);
+ unsigned int add = immediate | 0xE2800000; // add r0, r0, #n
+ if (comboConst) {
+ mQ.pushBack(add);
+ }
+ didPeep = true;
+ }
+ }
+
+ } while (didPeep);
+#endif
+ }
+
+ void ob(int n) {
+ error("ob() not supported.");
+ }
+
+ void* getBase() {
+ flush();
+ return mpBase->getBase();
+ }
+
+ intptr_t getSize() {
+ flush();
+ return mpBase->getSize();
+ }
+
+ intptr_t getPC() {
+ flush();
+ return mpBase->getPC();
+ }
+ };
+
class ARMCodeGenerator : public CodeGenerator {
public:
ARMCodeGenerator() {
#ifdef ARM_USE_VFP
- LOGD("Using ARM VFP hardware floating point.");
+ // LOGD("Using ARM VFP hardware floating point.");
#else
- LOGD("Using ARM soft floating point.");
+ // LOGD("Using ARM soft floating point.");
#endif
}
@@ -709,10 +944,12 @@
// sp, fp -> oldfp, retadr, arg0 arg1 ....
o4(0xE1A0B00D); // mov fp, sp
LOG_STACK("functionEntry: %d\n", mStackUse);
- return o4(0xE24DD000); // sub sp, sp, # <local variables>
+ int pc = getPC();
+ o4(0xE24DD000); // sub sp, sp, # <local variables>
// We don't know how many local variables we are going to use,
// but we will round the allocation up to a multiple of
// STACK_ALIGNMENT, so it won't affect the stack alignment.
+ return pc;
}
virtual void functionExit(Type* pDecl, int localVariableAddress, int localVariableSize) {
@@ -809,7 +1046,9 @@
}
virtual int gjmp(int t) {
- return o4(0xEA000000 | encodeAddress(t)); // b .L33
+ int pc = getPC();
+ o4(0xEA000000 | encodeAddress(t)); // b .L33
+ return pc;
}
/* l = 0: je, l == 1: jne */
@@ -840,7 +1079,9 @@
break;
}
int branch = l ? 0x1A000000 : 0x0A000000; // bne : beq
- return o4(branch | encodeAddress(t));
+ int pc = getPC();
+ o4(branch | encodeAddress(t));
+ return pc;
}
virtual void gcmp(int op) {
@@ -1475,7 +1716,8 @@
if (ea == 0) {
o4(0xEA000000); // b .L99
- result = o4(ea); // .L1: .word 0
+ result = getPC();
+ o4(ea); // .L1: .word 0
// .L99:
}
return result;
@@ -1537,21 +1779,27 @@
#endif
}
} else {
- assert (r0Tag == TY_DOUBLE);
- if (destTag == TY_INT) {
+ if (r0Tag == TY_DOUBLE) {
+ if (destTag == TY_INT) {
#ifdef ARM_USE_VFP
- o4(0xEEFD7BC7); // ftosizd s15, d7
- o4(0xEE170A90); // fmrs r0, s15
+ o4(0xEEFD7BC7); // ftosizd s15, d7
+ o4(0xEE170A90); // fmrs r0, s15
#else
- callRuntime((void*) runtime_double_to_int);
+ callRuntime((void*) runtime_double_to_int);
#endif
+ } else {
+ if(destTag == TY_FLOAT) {
+#ifdef ARM_USE_VFP
+ o4(0xEEF77BC7); // fcvtsd s15, d7
+#else
+ callRuntime((void*) runtime_double_to_float);
+#endif
+ } else {
+ incompatibleTypes(pR0Type, pType);
+ }
+ }
} else {
- assert(destTag == TY_FLOAT);
-#ifdef ARM_USE_VFP
- o4(0xEEF77BC7); // fcvtsd s15, d7
-#else
- callRuntime((void*) runtime_double_to_float);
-#endif
+ incompatibleTypes(pR0Type, pType);
}
}
}
@@ -1559,7 +1807,9 @@
}
virtual int beginFunctionCallArguments() {
- return o4(0xE24DDF00); // Placeholder
+ int pc = getPC();
+ o4(0xE24DDF00); // Placeholder sub sp, sp, #0
+ return pc;
}
virtual size_t storeR0ToArg(int l, Type* pArgType) {
@@ -1645,6 +1895,7 @@
if (l < 0 || l > 0x3FC) {
error("L out of range for stack adjustment: 0x%08x", l);
}
+ flush();
* (int*) a = 0xE24DDF00 | (l >> 2); // sub sp, sp, #0 << 2
mStackUse += mStackAlignmentAdjustment;
LOG_STACK("endFunctionCallArguments mStackUse: %d, mStackAlignmentAdjustment %d\n",
@@ -1654,7 +1905,9 @@
virtual int callForward(int symbol, Type* pFunc) {
setR0Type(pFunc->pHead);
// Forward calls are always short (local)
- return o4(0xEB000000 | encodeAddress(symbol));
+ int pc = getPC();
+ o4(0xEB000000 | encodeAddress(symbol));
+ return pc;
}
virtual void callIndirect(int l, Type* pFunc) {
@@ -1747,24 +2000,6 @@
#endif
}
- virtual int disassemble(FILE* out) {
-#ifdef ENABLE_ARM_DISASSEMBLY
- disasmOut = out;
- disasm_interface_t di;
- di.di_readword = disassemble_readword;
- di.di_printaddr = disassemble_printaddr;
- di.di_printf = disassemble_printf;
-
- int base = getBase();
- int pc = getPC();
- for(int i = base; i < pc; i += 4) {
- fprintf(out, "%08x: %08x ", i, *(int*) i);
- ::disasm(&di, i, 0);
- }
-#endif
- return 0;
- }
-
/**
* alignment (in bytes) for this type of data
*/
@@ -1816,27 +2051,6 @@
}
private:
- static FILE* disasmOut;
-
- static u_int
- disassemble_readword(u_int address)
- {
- return(*((u_int *)address));
- }
-
- static void
- disassemble_printaddr(u_int address)
- {
- fprintf(disasmOut, "0x%08x", address);
- }
-
- static void
- disassemble_printf(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- vfprintf(disasmOut, fmt, ap);
- va_end(ap);
- }
static const int BRANCH_REL_ADDRESS_MASK = 0x00ffffff;
@@ -2007,26 +2221,8 @@
}
}
- bool encode12BitImmediate(size_t immediate, size_t* pResult) {
- for(size_t i = 0; i < 16; i++) {
- size_t rotate = i * 2;
- size_t mask = rotateRight(0xff, rotate);
- if ((immediate | mask) == mask) {
- size_t bits8 = rotateLeft(immediate, rotate);
- assert(bits8 <= 0xff);
- *pResult = (i << 8) | bits8;
- return true;
- }
- }
- return false;
- }
-
- size_t rotateRight(size_t n, size_t rotate) {
- return (n >> rotate) | (n << (32 - rotate));
- }
-
- size_t rotateLeft(size_t n, size_t rotate) {
- return (n << rotate) | (n >> (32 - rotate));
+ void incompatibleTypes(Type* pR0Type, Type* pType) {
+ error("Incompatible types old: %d new: %d", pR0Type->tag, pType->tag);
}
void callRuntime(void* fn) {
@@ -2762,10 +2958,6 @@
return 5;
}
- virtual int disassemble(FILE* out) {
- return 0;
- }
-
/* output a symbol and patch all calls to it */
virtual void gsym(int t) {
int n;
@@ -2942,7 +3134,7 @@
delete mpBase;
}
- virtual void init(CodeBuf* pCodeBuf) {
+ virtual void init(ICodeBuf* pCodeBuf) {
mpBase->init(pCodeBuf);
}
@@ -3093,10 +3285,6 @@
return mpBase->jumpOffset();
}
- virtual int disassemble(FILE* out) {
- return mpBase->disassemble(out);
- }
-
/* output a symbol and patch all calls to it */
virtual void gsym(int t) {
fprintf(stderr, "gsym(%d)\n", t);
@@ -3719,7 +3907,7 @@
int mLineNumber;
bool mbBumpLine;
- CodeBuf codeBuf;
+ ICodeBuf* pCodeBuf;
CodeGenerator* pGen;
String mErrorBuf;
@@ -4758,13 +4946,13 @@
next();
skip('(');
if (t == TOK_WHILE) {
- n = codeBuf.getPC(); // top of loop, target of "next" iteration
+ n = pCodeBuf->getPC(); // top of loop, target of "next" iteration
a = test_expr();
} else {
if (tok != ';')
commaExpr();
skip(';');
- n = codeBuf.getPC();
+ n = pCodeBuf->getPC();
a = 0;
if (tok != ';')
a = test_expr();
@@ -4772,14 +4960,14 @@
if (tok != ')') {
t = pGen->gjmp(0);
commaExpr();
- pGen->gjmp(n - codeBuf.getPC() - pGen->jumpOffset());
+ pGen->gjmp(n - pCodeBuf->getPC() - pGen->jumpOffset());
pGen->gsym(t);
n = t + 4;
}
}
skip(')');
block((intptr_t) &a, false);
- pGen->gjmp(n - codeBuf.getPC() - pGen->jumpOffset()); /* jmp */
+ pGen->gjmp(n - pCodeBuf->getPC() - pGen->jumpOffset()); /* jmp */
pGen->gsym(a);
} else if (tok == '{') {
if (! outermostFunctionBlock) {
@@ -5327,6 +5515,16 @@
mLocals.add(pDecl);
}
+ bool checkUndeclaredStruct(Type* pBaseType) {
+ if (pBaseType->tag == TY_STRUCT && pBaseType->length < 0) {
+ String temp;
+ decodeToken(temp, pBaseType->structTag, false);
+ error("Undeclared struct %s", temp.getUnwrapped());
+ return true;
+ }
+ return false;
+ }
+
void localDeclarations(Type* pBaseType) {
intptr_t a;
@@ -5339,6 +5537,9 @@
if (!pDecl->id) {
break;
}
+ if (checkUndeclaredStruct(pDecl)) {
+ break;
+ }
int variableAddress = 0;
addLocalSymbol(pDecl);
size_t alignment = pGen->alignmentOf(pDecl);
@@ -5436,6 +5637,11 @@
continue;
}
+ if (checkUndeclaredStruct(pDecl)) {
+ skip(';');
+ continue;
+ }
+
if (! isDefined(pDecl->id)) {
addGlobalSymbol(pDecl);
}
@@ -5487,7 +5693,7 @@
/* patch forward references */
pGen->resolveForward((int) name->pForward);
/* put function address */
- name->pAddress = (void*) codeBuf.getPC();
+ name->pAddress = (void*) pCodeBuf->getPC();
}
// Calculate stack offsets for parameters
mLocals.pushLevel();
@@ -5554,6 +5760,10 @@
delete pGen;
pGen = 0;
}
+ if (pCodeBuf) {
+ delete pCodeBuf;
+ pCodeBuf = 0;
+ }
if (file) {
delete file;
file = 0;
@@ -5578,6 +5788,7 @@
dch = 0;
file = 0;
pGlobalBase = 0;
+ pCodeBuf = 0;
pGen = 0;
mPragmaStringCount = 0;
mCompileResult = 0;
@@ -5590,10 +5801,14 @@
delete pGen;
pGen = 0;
+ delete pCodeBuf;
+ pCodeBuf = new CodeBuf();
+
if (architecture != NULL) {
#ifdef PROVIDE_ARM_CODEGEN
if (! pGen && strcmp(architecture, "arm") == 0) {
pGen = new ARMCodeGenerator();
+ pCodeBuf = new ARMCodeBuf(pCodeBuf);
}
#endif
#ifdef PROVIDE_X86_CODEGEN
@@ -5609,6 +5824,7 @@
if (pGen == NULL) {
#if defined(DEFAULT_ARM_CODEGEN)
pGen = new ARMCodeGenerator();
+ pCodeBuf = new ARMCodeBuf(pCodeBuf);
#elif defined(DEFAULT_X86_CODEGEN)
pGen = new X86CodeGenerator();
#endif
@@ -5657,7 +5873,6 @@
mLocals.setTokenTable(&mTokenTable);
internKeywords();
- codeBuf.init(ALLOC_SIZE);
setArchitecture(NULL);
if (!pGen) {
return -1;
@@ -5665,8 +5880,12 @@
#ifdef PROVIDE_TRACE_CODEGEN
pGen = new TraceCodeGenerator(pGen);
#endif
- pGen->setErrorSink(this);
- pGen->init(&codeBuf);
+ pGen->setErrorSink(this);
+
+ if (pCodeBuf) {
+ pCodeBuf->init(ALLOC_SIZE);
+ }
+ pGen->init(pCodeBuf);
file = new TextInputStream(text, textLength);
pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
glo = pGlobalBase;
@@ -5716,15 +5935,6 @@
return true;
}
- int dump(FILE* out) {
- fwrite(codeBuf.getBase(), 1, codeBuf.getSize(), out);
- return 0;
- }
-
- int disassemble(FILE* out) {
- return pGen->disassemble(out);
- }
-
/* Look through the symbol table to find a symbol.
* If found, return its value.
*/
@@ -5757,10 +5967,14 @@
}
}
+ void getProgramBinary(ACCvoid** base, ACCsizei* length) {
+ *base = pCodeBuf->getBase();
+ *length = (ACCsizei) pCodeBuf->getSize();
+ }
+
char* getErrorMessage() {
return mErrorBuf.getUnwrapped();
}
-
};
const char* Compiler::operatorChars =
@@ -5774,10 +5988,6 @@
2, 2 /* ~ ! */
};
-#ifdef PROVIDE_ARM_CODEGEN
-FILE* Compiler::ARMCodeGenerator::disasmOut;
-#endif
-
#ifdef PROVIDE_X86_CODEGEN
const int Compiler::X86CodeGenerator::operatorHelper[] = {
0x1, // ++
@@ -5895,6 +6105,29 @@
dest += len;
}
text[totalLength] = '\0';
+
+#ifdef DEBUG_SAVE_INPUT_TO_FILE
+ LOGD("Saving input to file...");
+ int counter;
+ char path[PATH_MAX];
+ for (counter = 0; counter < 4096; counter++) {
+ sprintf(path, DEBUG_DUMP_PATTERN, counter);
+ if(access(path, F_OK) != 0) {
+ break;
+ }
+ }
+ if (counter < 4096) {
+ LOGD("Saving input to file %s", path);
+ FILE* fd = fopen(path, "w");
+ if (fd) {
+ fwrite(text, totalLength, 1, fd);
+ fclose(fd);
+ LOGD("Saved input to file %s", path);
+ } else {
+ LOGD("Could not save. errno: %d", errno);
+ }
+ }
+#endif
}
extern "C"
@@ -5952,8 +6185,9 @@
}
extern "C"
-void accDisassemble(ACCscript* script) {
- script->compiler.disassemble(stderr);
+void accGetProgramBinary(ACCscript* script,
+ ACCvoid** base, ACCsizei* length) {
+ script->compiler.getProgramBinary(base, length);
}
diff --git a/libacc/tests/Android.mk b/libacc/tests/Android.mk
index 77e48be..e9fbe03 100644
--- a/libacc/tests/Android.mk
+++ b/libacc/tests/Android.mk
@@ -21,7 +21,8 @@
LOCAL_MODULE:= acc
LOCAL_SRC_FILES:= \
- main.cpp
+ main.cpp \
+ disassem.cpp
LOCAL_SHARED_LIBRARIES := \
libacc
diff --git a/libacc/armreg.h b/libacc/tests/armreg.h
similarity index 100%
rename from libacc/armreg.h
rename to libacc/tests/armreg.h
diff --git a/libacc/disassem.cpp b/libacc/tests/disassem.cpp
similarity index 100%
rename from libacc/disassem.cpp
rename to libacc/tests/disassem.cpp
diff --git a/libacc/disassem.h b/libacc/tests/disassem.h
similarity index 100%
rename from libacc/disassem.h
rename to libacc/tests/disassem.h
diff --git a/libacc/tests/main.cpp b/libacc/tests/main.cpp
index 5e9e816..311fec0 100644
--- a/libacc/tests/main.cpp
+++ b/libacc/tests/main.cpp
@@ -20,6 +20,14 @@
#include <unistd.h>
#endif
+#if defined(__arm__)
+#define PROVIDE_ARM_DISASSEMBLY
+#endif
+
+#ifdef PROVIDE_ARM_DISASSEMBLY
+#include "disassem.h"
+#endif
+
#include <acc/acc.h>
@@ -29,15 +37,57 @@
return mainFunc(argc, argv);
}
-// Private API for development:
-
-extern "C"
-void accDisassemble(ACCscript* script);
-
ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
}
+#ifdef PROVIDE_ARM_DISASSEMBLY
+
+static FILE* disasmOut;
+
+static u_int
+disassemble_readword(u_int address)
+{
+ return(*((u_int *)address));
+}
+
+static void
+disassemble_printaddr(u_int address)
+{
+ fprintf(disasmOut, "0x%08x", address);
+}
+
+static void
+disassemble_printf(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(disasmOut, fmt, ap);
+ va_end(ap);
+}
+
+static int disassemble(ACCscript* script, FILE* out) {
+ disasmOut = out;
+ disasm_interface_t di;
+ di.di_readword = disassemble_readword;
+ di.di_printaddr = disassemble_printaddr;
+ di.di_printf = disassemble_printf;
+
+ ACCvoid* base;
+ ACCsizei length;
+
+ accGetProgramBinary(script, &base, &length);
+ unsigned long* pBase = (unsigned long*) base;
+ unsigned long* pEnd = (unsigned long*) (((unsigned char*) base) + length);
+
+ for(unsigned long* pInstruction = pBase; pInstruction < pEnd; pInstruction++) {
+ fprintf(out, "%08x: %08x ", (int) pInstruction, *pInstruction);
+ ::disasm(&di, (uint) pInstruction, 0);
+ }
+ return 0;
+}
+
+#endif // PROVIDE_ARM_DISASSEMBLY
+
int main(int argc, char** argv) {
const char* inFile = NULL;
bool printListing;
@@ -121,7 +171,9 @@
}
if (printListing) {
- accDisassemble(script);
+#ifdef PROVIDE_ARM_DISASSEMBLY
+ disassemble(script, stderr);
+#endif
}
if (runResults) {
diff --git a/libzipfile/centraldir.c b/libzipfile/centraldir.c
index 0391c09..0e264a3 100644
--- a/libzipfile/centraldir.c
+++ b/libzipfile/centraldir.c
@@ -233,7 +233,7 @@
len = (buf+bufsize)-p;
for (i=0; i < file->totalEntryCount; i++) {
Zipentry* entry = malloc(sizeof(Zipentry));
- memset(entry, sizeof(Zipentry), 0);
+ memset(entry, 0, sizeof(Zipentry));
err = read_central_directory_entry(file, entry, &p, &len);
if (err != 0) {
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 779f2a9..e28dd30 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -5,11 +5,15 @@
copy_from := \
etc/dbus.conf \
- etc/init.goldfish.sh \
etc/hosts
ifeq ($(TARGET_PRODUCT),generic)
-copy_from := etc/vold.conf
+copy_from += etc/vold.conf
+endif
+
+# for non -user build, also copy emulator-support script into /system/etc
+ifneq ($(TARGET_BUILD_VARIANT),user)
+copy_from += etc/init.goldfish.sh
endif
copy_to := $(addprefix $(TARGET_OUT)/,$(copy_from))
@@ -32,11 +36,13 @@
ALL_PREBUILT += $(file)
endif
+# for non -user build, also copy emulator-specific init script into /
+ifneq ($(TARGET_BUILD_VARIANT),user)
file := $(TARGET_ROOT_OUT)/init.goldfish.rc
$(file) : $(LOCAL_PATH)/etc/init.goldfish.rc | $(ACP)
$(transform-prebuilt-to-target)
ALL_PREBUILT += $(file)
-
+endif
# create some directories (some are mount points)
DIRS := $(addprefix $(TARGET_ROOT_OUT)/, \
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 8365fd8..5d0c8b5 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -70,27 +70,24 @@
# storing dumps on platforms which do not have a dedicated dump partition.
mkdir /data/dontpanic
- # STOPSHIP!
- chmod 0777 /data/dontpanic
+ chown root system /data/dontpanic
+ chmod 0750 /data/dontpanic
# Collect apanic data, free resources and re-arm trigger
copy /proc/apanic_console /data/dontpanic/apanic_console
chown root system /data/dontpanic/apanic_console
- # STOPSHIP!
- chmod 0664 /data/dontpanic/apanic_console
+ chmod 0640 /data/dontpanic/apanic_console
copy /proc/apanic_threads /data/dontpanic/apanic_threads
chown root system /data/dontpanic/apanic_threads
- # STOPSHIP!
- chmod 0664 /data/dontpanic/apanic_threads
+ chmod 0640 /data/dontpanic/apanic_threads
write /proc/apanic_console 1
# Collect ramconsole data
copy /proc/last_kmsg /data/dontpanic/last_kmsg
chown root system /data/dontpanic/last_kmsg
- # STOPSHIP!
- chmod 0664 /data/dontpanic/last_kmsg
+ chmod 0640 /data/dontpanic/last_kmsg
# Same reason as /data above
mount yaffs2 mtd@cache /cache nosuid nodev
diff --git a/vold/volmgr_vfat.c b/vold/volmgr_vfat.c
index 22e2dcf..4c695e4 100644
--- a/vold/volmgr_vfat.c
+++ b/vold/volmgr_vfat.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <sys/mount.h>
+#include <cutils/properties.h>
#include "vold.h"
#include "volmgr.h"
@@ -108,14 +109,29 @@
}
/*
- * The mount masks restrict access so that:
- * 1. The 'system' user cannot access the SD card at all -
- * (protects system_server from grabbing file references)
- * 2. Group users can RWX
- * 3. Others can only RX
+ * Note: This is a temporary hack. If the sampling profiler is enabled,
+ * we make the SD card world-writable so any process can write snapshots.
+ *
+ * TODO: Remove this code once we have a drop box in system_server.
*/
- rc = mount(devpath, vol->mount_point, "vfat", flags,
- "utf8,uid=1000,gid=1015,fmask=702,dmask=702,shortname=mixed");
+ char value[PROPERTY_VALUE_MAX];
+ property_get("persist.sampling_profiler", value, "");
+ if (value[0] == '1') {
+ LOGW("The SD card is world-writable because the"
+ " 'persist.sampling_profiler' system property is set to '1'.");
+ rc = mount(devpath, vol->mount_point, "vfat", flags,
+ "utf8,uid=1000,gid=1015,fmask=000,dmask=000,shortname=mixed");
+ } else {
+ /*
+ * The mount masks restrict access so that:
+ * 1. The 'system' user cannot access the SD card at all -
+ * (protects system_server from grabbing file references)
+ * 2. Group users can RWX
+ * 3. Others can only RX
+ */
+ rc = mount(devpath, vol->mount_point, "vfat", flags,
+ "utf8,uid=1000,gid=1015,fmask=702,dmask=702,shortname=mixed");
+ }
if (rc && errno == EROFS) {
LOGE("vfat_mount(%d:%d, %s): Read only filesystem - retrying mount RO",