Merge change 3537

* changes:
  Add tag for AggregationService.
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index a4351ac..4590626 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -50,6 +50,7 @@
 #define AID_DHCP          1014  /* dhcp client */
 #define AID_SDCARD_RW     1015  /* external storage write access */
 #define AID_VPN           1016  /* vpn system */
+#define AID_KEYSTORE      1017  /* keystore subsystem */
 
 #define AID_SHELL         2000  /* adb and debug shell user */
 #define AID_CACHE         2001  /* cache access */
@@ -97,7 +98,8 @@
     { "net_bt",    AID_NET_BT, },
     { "sdcard_rw", AID_SDCARD_RW, },
     { "vpn",       AID_VPN, },
-    { "inet",      AID_INET, }, 
+    { "keystore",  AID_KEYSTORE, },
+    { "inet",      AID_INET, },
     { "net_raw",   AID_NET_RAW, },
     { "misc",      AID_MISC, },
     { "nobody",    AID_NOBODY, },
diff --git a/libacc/Android.mk b/libacc/Android.mk
index 77c71c6..f3c2d35 100644
--- a/libacc/Android.mk
+++ b/libacc/Android.mk
@@ -1,9 +1,8 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-#
-# Shared library
-#
+# Shared library for target
+# ========================================================
 
 LOCAL_MODULE:= libacc
 LOCAL_SRC_FILES := acc.cpp
@@ -12,8 +11,27 @@
 LOCAL_SRC_FILES += disassem.cpp
 endif
 
-LOCAL_SHARED_LIBRARIES := libdl
+LOCAL_SHARED_LIBRARIES := libdl libcutils
 
 include $(BUILD_SHARED_LIBRARY)
 
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+# Shared library for host
+# ========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE:= libacc
+LOCAL_SRC_FILES := acc.cpp
+
+ifeq ($(TARGET_ARCH),arm)
+LOCAL_SRC_FILES += disassem.cpp
+endif
+
+LOCAL_STATIC_LIBRARIES := libcutils
+LOCAL_LDLIBS := -ldl
+
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+# Build children
+# ========================================================
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index de36ce5..e0043ef 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -10,12 +10,18 @@
 
 #include <ctype.h>
 #include <dlfcn.h>
+#include <errno.h>
 #include <setjmp.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <cutils/hashmap.h>
+
+#if defined(__i386__)
+#include <sys/mman.h>
+#endif
 
 #if defined(__arm__)
 #include <unistd.h>
@@ -988,7 +994,14 @@
         }
 
         virtual int finishCompile() {
-            return 0;
+            size_t pagesize = 4096;
+            size_t base = (size_t) getBase() & ~ (pagesize - 1);
+            size_t top =  ((size_t) getPC() + pagesize - 1) & ~ (pagesize - 1);
+            int err = mprotect((void*) base, top - base, PROT_READ | PROT_WRITE | PROT_EXEC);
+            if (err) {
+               error("mprotect() failed: %d", errno);
+            }
+            return err;
         }
 
     private:
@@ -1030,7 +1043,7 @@
 
         void gmov(int l, int t) {
             o(l + 0x83);
-            oad((t < LOCAL) << 7 | 5, t);
+            oad((t > -LOCAL && t < LOCAL) << 7 | 5, t);
         }
     };
 
@@ -1086,27 +1099,6 @@
         size_t mPosition;
     };
 
-    int ch; // Current input character, or EOF
-    intptr_t tok;     // token
-    intptr_t tokc;    // token extra info
-    int tokl;         // token operator level
-    intptr_t rsym; // return symbol
-    intptr_t loc; // local variable index
-    char* glo;  // global variable index
-    char* sym_stk;
-    char* dstk; // Define stack
-    char* dptr; // Macro state: Points to macro text during macro playback.
-    int dch;    // Macro state: Saves old value of ch during a macro playback.
-    char* last_id;
-    void* pSymbolBase;
-    char* pGlobalBase;
-    char* pVarsBase; // Value of variables
-
-    InputStream* file;
-
-    CodeBuf codeBuf;
-    CodeGenerator* pGen;
-
     class String {
     public:
         String() {
@@ -1115,18 +1107,34 @@
             mSize = 0;
         }
 
+        String(char* item, int len, bool adopt) {
+            if (adopt) {
+                mpBase = item;
+                mUsed = len;
+                mSize = len + 1;
+            } else {
+                mpBase = 0;
+                mUsed = 0;
+                mSize = 0;
+                appendBytes(item, len);
+            }
+        }
+
         ~String() {
             if (mpBase) {
                 free(mpBase);
             }
         }
 
-        char* getUnwrapped() {
+        inline char* getUnwrapped() {
             return mpBase;
         }
 
         void appendCStr(const char* s) {
-            int n = strlen(s);
+            appendBytes(s, strlen(s));
+        }
+
+        void appendBytes(const char* s, int n) {
             memcpy(ensure(n), s, n + 1);
         }
 
@@ -1134,6 +1142,14 @@
             * ensure(1) = c;
         }
 
+        char* orphan() {
+            char* result = mpBase;
+            mpBase = 0;
+            mUsed = 0;
+            mSize = 0;
+            return result;
+        }
+
         void printf(const char* fmt,...) {
             va_list ap;
             va_start(ap, fmt);
@@ -1148,7 +1164,7 @@
             free(temp);
         }
 
-        size_t len() {
+        inline size_t len() {
             return mUsed;
         }
 
@@ -1174,6 +1190,177 @@
         size_t mSize;
     };
 
+    /**
+     * Wrap an externally allocated string for use as a hash key.
+     */
+    class FakeString : public String {
+    public:
+        FakeString(char* string, size_t length) :
+            String(string, length, true) {}
+
+        ~FakeString() {
+            orphan();
+        }
+    };
+
+    template<class V> class StringTable {
+    public:
+        StringTable(size_t initialCapacity) {
+            mpMap = hashmapCreate(initialCapacity, hashFn, equalsFn);
+        }
+
+        ~StringTable() {
+            clear();
+        }
+
+        void clear() {
+            hashmapForEach(mpMap, freeKeyValue, this);
+        }
+
+        bool contains(String* pKey) {
+            bool result = hashmapContainsKey(mpMap, pKey);
+            return result;
+        }
+
+        V* get(String* pKey) {
+            V* result = (V*) hashmapGet(mpMap, pKey);
+            return result;
+        }
+
+        V* remove(String* pKey) {
+            V* result = (V*) hashmapRemove(mpMap, pKey);
+            return result;
+        }
+
+        V* put(String* pKey, V* value) {
+            V* result = (V*) hashmapPut(mpMap, pKey, value);
+            if (result) {
+                // The key was not adopted by the map, so delete it here.
+                delete pKey;
+            }
+            return result;
+        }
+
+    protected:
+        static int hashFn(void* pKey) {
+            String* pString = (String*) pKey;
+            return hashmapHash(pString->getUnwrapped(), pString->len());
+        }
+
+        static bool equalsFn(void* keyA, void* keyB) {
+            String* pStringA = (String*) keyA;
+            String* pStringB = (String*) keyB;
+            return pStringA->len() == pStringB->len()
+                && strcmp(pStringA->getUnwrapped(), pStringB->getUnwrapped())
+                    == 0;
+        }
+
+        static bool freeKeyValue(void* key, void* value, void* context) {
+            delete (String*) key;
+            delete (V*) value;
+            return true;
+        }
+
+        Hashmap* mpMap;
+    };
+
+    class MacroTable : public StringTable<String> {
+    public:
+        MacroTable() : StringTable<String>(10) {}
+    };
+
+    template<class E> class Array {
+        public:
+        Array() {
+            mpBase = 0;
+            mUsed = 0;
+            mSize = 0;
+        }
+
+        ~Array() {
+            if (mpBase) {
+                free(mpBase);
+            }
+        }
+
+        E get(int i) {
+            if (i < 0 || i > mUsed) {
+                error("internal error: Index out of range");
+                return E();
+            }
+            return mpBase[i];
+        }
+
+        void set(int i, E val) {
+            mpBase[i] =  val;
+        }
+
+        void pop() {
+            if (mUsed > 0) {
+                mUsed -= 1;
+            } else {
+                error("internal error: Popped empty stack.");
+            }
+        }
+
+        void push(E item) {
+            * ensure(1) = item;
+        }
+
+        size_t len() {
+            return mUsed;
+        }
+
+    private:
+        E* ensure(int n) {
+            size_t newUsed = mUsed + n;
+            if (newUsed > mSize) {
+                size_t newSize = mSize * 2 + 10;
+                if (newSize < newUsed) {
+                    newSize = newUsed;
+                }
+                mpBase = (E*) realloc(mpBase, sizeof(E) * newSize);
+                mSize = newSize;
+            }
+            E* result = mpBase + mUsed;
+            mUsed = newUsed;
+            return result;
+        }
+
+        E* mpBase;
+        size_t mUsed;
+        size_t mSize;
+    };
+
+    struct InputState {
+        InputStream* pStream;
+        int oldCh;
+    };
+
+
+    int ch; // Current input character, or EOF
+    intptr_t tok;     // token
+    intptr_t tokc;    // token extra info
+    int tokl;         // token operator level
+    intptr_t rsym; // return symbol
+    intptr_t loc; // local variable index
+    char* glo;  // global variable index
+    char* sym_stk;
+    char* dstk; // Define stack
+    char* dptr; // Macro state: Points to macro text during macro playback.
+    int dch;    // Macro state: Saves old value of ch during a macro playback.
+    char* last_id;
+    char* pGlobalBase;
+    char* pVarsBase; // Value of variables
+
+    InputStream* file;
+
+    CodeBuf codeBuf;
+    CodeGenerator* pGen;
+
+    MacroTable mMacros;
+    Array<InputState> mInputStateStack;
+
     String mErrorBuf;
 
     jmp_buf mErrorRecoveryJumpBuf;
@@ -1208,7 +1395,6 @@
 
     /* tokens in string heap */
     static const int TAG_TOK = ' ';
-    static const int TAG_MACRO = 2;
 
     static const int OP_INCREMENT = 0;
     static const int OP_DECREMENT = 1;
@@ -1251,7 +1437,7 @@
     void inp() {
         if (dptr) {
             ch = *dptr++;
-            if (ch == TAG_MACRO) {
+            if (ch == 0) {
                 dptr = 0;
                 ch = dch;
             }
@@ -1283,16 +1469,7 @@
                 inp();
                 next();
                 if (tok == TOK_DEFINE) {
-                    next();
-                    pdef(TAG_TOK); /* fill last ident tag */
-                    *(int *) tok = SYM_DEFINE;
-                    *(char* *) (tok + 4) = dstk; /* define stack */
-                    while (ch != '\n') {
-                        pdef(ch);
-                        inp();
-                    }
-                    pdef(ch);
-                    pdef(TAG_MACRO);
+                    doDefine();
                 } else if (tok == TOK_PRAGMA) {
                     doPragma();
                 } else {
@@ -1319,24 +1496,29 @@
                 if (dstk - sym_stk + 1 > ALLOC_SIZE) {
                     error("symbol stack overflow");
                 }
-                * dstk = TAG_TOK; /* no need to mark end of string (we
-                 suppose data is initialized to zero by calloc) */
-                tok = (intptr_t) (strstr(sym_stk, (last_id - 1))
-                        - sym_stk);
-                * dstk = 0; /* mark real end of ident for dlsym() */
-                tok = tok * 8 + TOK_IDENT;
-                if (tok > TOK_DEFINE) {
-                    if (tok + 8 > ALLOC_SIZE) {
-                        error("Variable Table overflow.");
-                    }
-                    tok = (intptr_t) (pVarsBase + tok);
-                    /*        printf("tok=%s %x\n", last_id, tok); */
-                    /* define handling */
-                    if (*(int *) tok == SYM_DEFINE) {
-                        dptr = *(char* *) (tok + 4);
-                        dch = ch;
-                        inp();
-                        next();
+                FakeString token(last_id, dstk-last_id);
+                // Is this a macro?
+                String* pValue = mMacros.get(&token);
+                if (pValue) {
+                    // Yes, it is a macro
+                    dstk = last_id-1;
+                    dptr = pValue->getUnwrapped();
+                    dch = ch;
+                    inp();
+                    next();
+                } else {
+                    * dstk = TAG_TOK; /* no need to mark end of string (we
+                     suppose data is initialized to zero by calloc) */
+                    tok = (intptr_t) (strstr(sym_stk, (last_id - 1))
+                            - sym_stk);
+                    * dstk = 0; /* mark real end of ident for dlsym() */
+                    tok = tok * 8 + TOK_IDENT;
+                    if (tok > TOK_DEFINE) {
+                        if (tok + 8 > ALLOC_SIZE) {
+                            error("Variable Table overflow.");
+                        }
+                        tok = (intptr_t) (pVarsBase + tok);
+                        /*        printf("tok=%s %x\n", last_id, tok); */
                     }
                 }
             }
@@ -1415,6 +1597,30 @@
 #endif
     }
 
+    void doDefine() {
+        String* pName = new String();
+        while (isspace(ch)) {
+            inp();
+        }
+        while (isid()) {
+            pName->append(ch);
+            inp();
+        }
+        if (ch == '(') {
+            delete pName;
+            error("Defines with arguments not supported");
+        }
+        while (isspace(ch)) {
+            inp();
+        }
+        String* pValue = new String();
+        while (ch != '\n' && ch != EOF) {
+            pValue->append(ch);
+            inp();
+        }
+        delete mMacros.put(pName, pValue);
+    }
+
     void doPragma() {
         // # pragma name(val)
         int state = 0;
@@ -1971,7 +2177,7 @@
             inp();
             next();
             globalDeclarations();
-            pGen->finishCompile();
+            result = pGen->finishCompile();
         }
         return result;
     }
diff --git a/libacc/tests/Android.mk b/libacc/tests/Android.mk
index 2cff9d3..1e4d328 100644
--- a/libacc/tests/Android.mk
+++ b/libacc/tests/Android.mk
@@ -1,5 +1,9 @@
 LOCAL_PATH:= $(call my-dir)
+
+# Executable for host
+# ========================================================
 include $(CLEAR_VARS)
+LOCAL_MODULE:= acc
 
 LOCAL_SRC_FILES:= \
 	main.cpp
@@ -7,9 +11,22 @@
 LOCAL_SHARED_LIBRARIES := \
     libacc
 
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_HOST_EXECUTABLE)
+
+# Executable for target
+# ========================================================
+include $(CLEAR_VARS)
 LOCAL_MODULE:= acc
 
+LOCAL_SRC_FILES:= \
+	main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libacc
+
+
 LOCAL_MODULE_TAGS := tests
 
-include $(BUILD_EXECUTABLE)
-
+include $(BUILD_EXECUTABLE)
\ No newline at end of file
diff --git a/libacc/tests/data/otcc-ansi.c b/libacc/tests/data/otcc-ansi.c
index 069514b..5b75879 100644
--- a/libacc/tests/data/otcc-ansi.c
+++ b/libacc/tests/data/otcc-ansi.c
@@ -50,7 +50,7 @@
         o();
     }
     C = 0;
-    d = h;
+    d = h;	
     if (X()) {
         E(32);
         M = D;
@@ -162,7 +162,7 @@
 
 void N(int j, int e) {
     ae(j + 131);
-    s((e < 512) << 7 | 5, e);
+    s((e > -512 && e < 512) << 7 | 5, e);
 }
 
 void T (int j) {
@@ -404,7 +404,7 @@
                     v=v +4;
                 }
                 ad();
-                if( d == 44)ad();
+                if( d == 44)ad()	;
             }
             ad();
         }
@@ -432,7 +432,12 @@
     }
 }
 
+int run(int g, int e) {
+    return (*(int(*)()) *(int*) (P + 592))(g, e);
+}
+
 int main(int g, int e) {
+    int result;
     Q = stdin;
     if (g-- > 1) {
         e = e + 4;
@@ -445,5 +450,13 @@
     o();
     ad();
     ab(0);
-    return (*(int(*)()) *(int*) (P + 592))(g, e);
+    if (mprotect((ac + 592) & (~ 4095), (99999 + 4095) & (~ 4095), 7)) {
+        printf("Mprotect failed. %d\n", errno);
+        return -1;
+    }
+    fprintf(stderr, "otcc-ansi.c: About to execute compiled code:\n");
+    result = run(g, e);
+    fprintf(stderr, "atcc-ansi.c: result: %d\n", result);
+    return result;
 }
+
diff --git a/libacc/tests/data/otcc.c b/libacc/tests/data/otcc.c
index 577fcf3..433ae2e 100644
--- a/libacc/tests/data/otcc.c
+++ b/libacc/tests/data/otcc.c
@@ -441,6 +441,8 @@
 o f;
 c;
 ab(0);
+mprotect(ac & (~ 4095), (99999 + 4095) & (~ 4095), 7);
+fprintf(stderr, "otcc.c: about to execute compiled code.\n");
 J(*(int(*)f)k(P+592))(g,n;
 }
 
diff --git a/libacc/tests/data/returnval-ansi.c b/libacc/tests/data/returnval-ansi.c
index 42802c5..6b53fd5 100644
--- a/libacc/tests/data/returnval-ansi.c
+++ b/libacc/tests/data/returnval-ansi.c
@@ -1,7 +1,8 @@
+
 int main(int argc, char** argv) {
   return f();
 }
 
 int f() {
-    return 10;
+    return 42;
 }
diff --git a/libacc/tests/data/returnval.c b/libacc/tests/data/returnval.c
index 1b9dd81..1cf5bae 100644
--- a/libacc/tests/data/returnval.c
+++ b/libacc/tests/data/returnval.c
@@ -1,6 +1,3 @@
-#pragma foo3(bar) //sdfsfd
-#pragma a(b)
-
 main() {
   return 42;
 }
diff --git a/libacc/tests/main.cpp b/libacc/tests/main.cpp
index acee09d..d624cbb 100644
--- a/libacc/tests/main.cpp
+++ b/libacc/tests/main.cpp
@@ -32,6 +32,7 @@
 int main(int argc, char** argv) {
     const char* inFile = NULL;
     bool printListing;
+    bool runResults = false;
     FILE* in = stdin;
     int i;
     for (i = 1; i < argc; i++) {
@@ -41,6 +42,9 @@
                 case 'S':
                     printListing = true;
                     break;
+                case 'R':
+                    runResults = true;
+                    break;
             default:
                 fprintf(stderr, "Unrecognized flag %s\n", arg);
                 return 3;
@@ -108,7 +112,7 @@
     accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
 
     result = accGetError(script);
-    if (result == ACC_NO_ERROR) {
+    if (result == ACC_NO_ERROR && runResults) {
         fprintf(stderr, "Executing compiled code:\n");
         int codeArgc = argc - i + 1;
         char** codeArgv = argv + i - 1;
diff --git a/libacc/tests/testarm b/libacc/tests/testarm
index 24fbc42..1d4b866 100755
--- a/libacc/tests/testarm
+++ b/libacc/tests/testarm
@@ -6,4 +6,4 @@
 mm -j8
 cd tests
 adb sync
-adb shell /system/bin/acc -S /system/bin/returnval-ansi.c
+adb shell /system/bin/acc -R -S /system/bin/returnval-ansi.c
diff --git a/libacc/tests/testlocal b/libacc/tests/testlocal
index ccabf7d..1650bf9 100755
--- a/libacc/tests/testlocal
+++ b/libacc/tests/testlocal
@@ -1,17 +1,21 @@
-#!/bin/sh
-rm -f test-acc
-cd ..
-g++ -I../include acc.cpp disassem.cpp tests/main.cpp -g -ldl -o tests/test-acc
-cd tests
-if [ -x "test-acc" ]; then
-  ./test-acc -S data/returnval-ansi.c
+#!/bin/bash
 
-  if [ "$(uname)" = "Linux" ]; then
-    if [ "$(uname -m)" = "i686" ]; then
-      echo "Linux i686. Testing otcc-ansi.c"
-      ./test-acc data/otcc-ansi.c data/returnval.c
-      echo "Linux i686. Testing otcc-ansi.c data/otcc.c"
-      ./test-acc data/otcc-ansi.c data/otcc.c data/returnval.c
-    fi
-  fi
+SCRIPT_DIR=`dirname $BASH_SOURCE`
+DATA=$SCRIPT_DIR/data
+ACC=`which acc`
+
+echo "Compiling returnval-ansi.c"
+$ACC -S $DATA/returnval-ansi.c
+
+echo "Compiling whole compiler."
+$ACC -S "$DATA/otcc-ansi.c"
+
+if file $ACC | grep -q "ELF 32-bit LSB executable, Intel 80386"; then
+	echo "Linux 32bit Intel."
+        $ACC -R $DATA/returnval-ansi.c
+        echo Testing otcc-ansi.c
+	$ACC -R "$DATA/otcc-ansi.c" "$DATA/returnval.c"
+	$ACC -R $DATA/otcc-ansi.c $DATA/otcc.c $DATA/returnval.c
 fi
+
+echo "Done with tests."
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e16a3f0..25463a8 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -23,6 +23,7 @@
     mkdir /system
     mkdir /data 0771 system system
     mkdir /cache 0770 system cache
+    mkdir /config 0500 root root
     mkdir /sqlite_stmt_journals 01777 root root
     mount tmpfs tmpfs /sqlite_stmt_journals size=4m
 
@@ -54,7 +55,7 @@
 
 # mount mtd partitions
     # Mount /system rw first to give the filesystem a chance to save a checkpoint
-    mount yaffs2 mtd@system /system 
+    mount yaffs2 mtd@system /system
     mount yaffs2 mtd@system /system ro remount
 
     # We chown/chmod /data again so because mount is run as root + defaults
@@ -74,6 +75,9 @@
 # create basic filesystem structure
     mkdir /data/misc 01771 system misc
     mkdir /data/misc/hcid 0770 bluetooth bluetooth
+    mkdir /data/misc/keystore 0770 keystore keystore
+    mkdir /data/misc/vpn 0770 system system
+    mkdir /data/misc/vpn/profiles 0770 system system
     mkdir /data/local 0771 shell shell
     mkdir /data/local/tmp 0771 shell shell
     mkdir /data/data 0771 system system
@@ -284,3 +288,19 @@
 
 service flash_recovery /system/bin/flash_image recovery /system/recovery.img
     oneshot
+
+service racoon /system/bin/racoon -F -f /etc/racoon/racoon.conf
+    socket racoon stream 600 system system
+    disabled
+    oneshot
+
+service mtpd /system/bin/mtpd
+    socket mtpd stream 600 system system
+    disabled
+    oneshot
+
+service keystore /system/bin/keystore
+    user keystore
+    group keystore
+    socket keystore stream 666
+