Merge change 23852 into eclair

* changes:
  Fix a call to memset(3) with reversed arguments.
diff --git a/adb/commandline.c b/adb/commandline.c
index 6603452..411bb82 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -929,7 +929,7 @@
 
     if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
             || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
-            || !strcmp(argv[0], "root") || !strcmp(argv[0], "bugreport")) {
+            || !strcmp(argv[0], "root")) {
         char command[100];
         if (argc > 1)
             snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
@@ -945,6 +945,14 @@
         return 1;
     }
 
+    if(!strcmp(argv[0], "bugreport")) {
+        if (argc != 1) {
+            return 1;
+        }
+        do_cmd(ttype, serial, "shell", "dumpstate", "-", 0);
+        return 0;
+    }
+
     /* adb_command() wrapper commands */
 
     if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
diff --git a/adb/services.c b/adb/services.c
index 447c11b..cd02b36 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -32,8 +32,7 @@
 #    include <netdb.h>
 #  endif
 #else
-#include <sys/poll.h>
-#include <sys/reboot.h>
+#  include <sys/reboot.h>
 #endif
 
 typedef struct stinfo stinfo;
@@ -188,43 +187,6 @@
     adb_close(fd);
 }
 
-void bugreport_service(int fd, void *cookie)
-{
-    char    buffer[MAX_PAYLOAD];
-    int i, s;
-
-    /* start the dumpstate service */
-    property_set("ctl.start", "dumpstate");
-
-    /* socket will not be available until service starts */
-    for (i = 0; i < 10; i++) {
-        s = socket_local_client("dumpstate",
-                             ANDROID_SOCKET_NAMESPACE_RESERVED,
-                             SOCK_STREAM);
-        if (s >= 0)
-            break;
-        /* try again in 1 second */
-        sleep(1);
-    }
-
-    if (s < 0) {
-        const char* failed = "Failed to connect to dumpstate service\n";
-        writex(fd, failed, strlen(failed));
-        adb_close(fd);
-        return;
-    }
-
-    while (1) {
-        int length = adb_read(s, buffer, sizeof(buffer));
-        if (length <= 0)
-            break;
-        if (adb_write(fd, buffer, length) <= 0)
-            break;
-    }
-    adb_close(s);
-    adb_close(fd);
-}
-
 #endif
 
 #if 0
@@ -290,9 +252,12 @@
     return s[0];
 }
 
-#if !ADB_HOST
 static int create_subprocess(const char *cmd, const char *arg0, const char *arg1)
 {
+#ifdef HAVE_WIN32_PROC
+	fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
+	return -1;
+#else /* !HAVE_WIN32_PROC */
     char *devname;
     int ptm;
     pid_t pid;
@@ -335,6 +300,7 @@
                 cmd, strerror(errno), errno);
         exit(-1);
     } else {
+#if !ADB_HOST
         // set child's OOM adjustment to zero
         char text[64];
         snprintf(text, sizeof text, "/proc/%d/oom_adj", pid);
@@ -345,11 +311,11 @@
         } else {
            D("adb: unable to open %s\n", text);
         }
-
+#endif
         return ptm;
     }
+#endif /* !HAVE_WIN32_PROC */
 }
-#endif /* !ADB_HOST */
 
 #if ADB_HOST
 #define SHELL_COMMAND "/bin/sh"
@@ -357,76 +323,6 @@
 #define SHELL_COMMAND "/system/bin/sh"
 #endif
 
-#if !ADB_HOST
-static void shell_service(int s, void *command)
-{
-    char    buffer[MAX_PAYLOAD];
-    char    buffer2[MAX_PAYLOAD];
-    struct pollfd ufds[2];
-    int     fd, ret = 0;
-    unsigned count = 0;
-    char** args = (char **)command;
-    fd = create_subprocess(SHELL_COMMAND, args[0], args[1]);
-
-    while (1) {
-        while (count < sizeof(buffer)) {
-            ufds[0].fd = fd;
-            ufds[0].events = POLLIN | POLLHUP;
-            ufds[0].revents = 0;
-            ufds[1].fd = s;
-            ufds[1].events = POLLIN | POLLHUP;
-            ufds[1].revents = 0;
-            // use a 100ms timeout so we don't block indefinitely with our
-            // buffer partially filled.
-            ret = poll(ufds, 2, 100);
-            if (ret <= 0) {
-                D("poll returned %d\n", ret);
-                // file has closed or we timed out
-                // set ret to 1 so we don't exit the outer loop
-                ret = 1;
-                break;
-            }
-
-            if (ufds[0].revents & POLLIN) {
-                ret = adb_read(fd, buffer + count, sizeof(buffer) - count);
-                D("read fd ret: %d, count: %d\n", ret, count);
-                if (ret > 0)
-                    count += ret;
-                else
-                    break;
-            }
-            if (ufds[1].revents & POLLIN) {
-                ret = adb_read(s, buffer2, sizeof(buffer2));
-                D("read s ret: %d\n", ret);
-                if (ret > 0)
-                    adb_write(fd, buffer2, ret);
-                else
-                    break;
-            }
-
-            if ((ufds[0].revents & POLLHUP) || (ufds[1].revents & POLLHUP)) {
-                // set flag to exit after flushing the buffer
-                ret = -1;
-                break;
-            }
-        }
-
-        D("writing: %d\n", count);
-        if (count > 0) {
-            adb_write(s, buffer, count);
-            count = 0;
-        }
-        if (ret <= 0)
-            break;
-    }
-
-    D("shell_service done\n");
-
-    adb_close(fd);
-    adb_close(s);
-}
-#endif // !ADB_HOST
-
 int service_to_fd(const char *name)
 {
     int ret = -1;
@@ -477,16 +373,14 @@
         ret = create_jdwp_connection_fd(atoi(name+5));
     } else if (!strncmp(name, "log:", 4)) {
         ret = create_service_thread(log_service, get_log_file_path(name + 4));
+#endif
     } else if(!HOST && !strncmp(name, "shell:", 6)) {
-        const char* args[2];
         if(name[6]) {
-            args[0] = "-c";
-            args[1] = name + 6;
+            ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);
         } else {
-            args[0] = "-";
-            args[1] = 0;
+            ret = create_subprocess(SHELL_COMMAND, "-", 0);
         }
-        ret = create_service_thread(shell_service, (void *)args);
+#if !ADB_HOST
     } else if(!strncmp(name, "sync:", 5)) {
         ret = create_service_thread(file_sync_service, NULL);
     } else if(!strncmp(name, "remount:", 8)) {
@@ -506,8 +400,6 @@
         ret = create_service_thread(restart_tcp_service, (void *)port);
     } else if(!strncmp(name, "usb:", 4)) {
         ret = create_service_thread(restart_usb_service, NULL);
-    } else if(!strncmp(name, "bugreport:", 10)) {
-        ret = create_service_thread(bugreport_service, NULL);
 #endif
 #if 0
     } else if(!strncmp(name, "echo:", 5)){
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 535361c..b8ff29d 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
@@ -58,6 +58,17 @@
 #define ENABLE_ARM_DISASSEMBLY
 // #define PROVIDE_TRACE_CODEGEN
 
+// 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 {
@@ -1537,21 +1548,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);
                     }
                 }
             }
@@ -2021,6 +2038,10 @@
             return false;
         }
 
+        void incompatibleTypes(Type* pR0Type, Type* pType) {
+            error("Incompatible types old: %d new: %d", pR0Type->tag, pType->tag);
+        }
+
         size_t rotateRight(size_t n, size_t rotate) {
             return (n >> rotate) | (n << (32 - rotate));
         }
@@ -4450,10 +4471,8 @@
                 unary();
                 doPointer();
             } else if (t == '&') {
-                VariableInfo* pVI = VI(tok);
-                pGen->leaR0((int) pVI->pAddress, createPtrType(pVI->pType),
-                        ET_RVALUE);
-                next();
+                unary();
+                doAddressOf();
             } else if (t == EOF ) {
                 error("Unexpected EOF.");
             } else if (t == ';') {
@@ -4529,7 +4548,7 @@
                 pGen->forceR0RVal();
                 Type* pStruct = pGen->getR0Type();
                 if (pStruct->tag == TY_STRUCT) {
-                    doStructMember(pStruct);
+                    doStructMember(pStruct, true);
                 } else {
                     error("expected a struct value to the left of '.'");
                 }
@@ -4538,7 +4557,7 @@
                 Type* pPtr = pGen->getR0Type();
                 if (pPtr->tag == TY_POINTER && pPtr->pHead->tag == TY_STRUCT) {
                     pGen->loadR0FromR0();
-                    doStructMember(pPtr->pHead);
+                    doStructMember(pPtr->pHead, false);
                 } else {
                     error("Expected a pointer to a struct to the left of '->'");
                 }
@@ -4604,7 +4623,7 @@
         }
     }
 
-    void doStructMember(Type* pStruct) {
+    void doStructMember(Type* pStruct, bool isDot) {
         Type* pStructElement = lookupStructMember(pStruct, tok);
         if (pStructElement) {
             next();
@@ -4612,7 +4631,8 @@
         } else {
             String buf;
             decodeToken(buf, tok, true);
-            error("Expected a struct member to the right of '.', got %s", buf.getUnwrapped());
+            error("Expected a struct member to the right of '%s', got %s",
+                    isDot ? "." : "->", buf.getUnwrapped());
         }
     }
 
@@ -4656,6 +4676,16 @@
         }
     }
 
+    void doAddressOf() {
+        Type* pR0 = pGen->getR0Type();
+        bool isFuncPtr = pR0->tag == TY_POINTER && pR0->pHead->tag == TY_FUNC;
+        if ((! isFuncPtr) && pGen->getR0ExpressionType() != ET_LVALUE) {
+            error("Expected an lvalue");
+        }
+        Type* pR0Type = pGen->getR0Type();
+        pGen->setR0ExpressionType(ET_RVALUE);
+    }
+
     /* Recursive descent parser for binary operations.
      */
     void binaryOp(int level) {
@@ -5293,7 +5323,7 @@
 
     void checkLVal() {
         if (pGen->getR0ExpressionType() != ET_LVALUE) {
-            error("Expected an lval");
+            error("Expected an lvalue");
         }
     }
 
@@ -5318,6 +5348,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;
 
@@ -5330,6 +5370,9 @@
                 if (!pDecl->id) {
                     break;
                 }
+                if (checkUndeclaredStruct(pDecl)) {
+                    break;
+                }
                 int variableAddress = 0;
                 addLocalSymbol(pDecl);
                 size_t alignment = pGen->alignmentOf(pDecl);
@@ -5427,6 +5470,11 @@
                 continue;
             }
 
+            if (checkUndeclaredStruct(pDecl)) {
+                skip(';');
+                continue;
+            }
+
             if (! isDefined(pDecl->id)) {
                 addGlobalSymbol(pDecl);
             }
@@ -5886,6 +5934,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"
diff --git a/libacc/tests/data/addressOf.c b/libacc/tests/data/addressOf.c
new file mode 100644
index 0000000..e7acde5
--- /dev/null
+++ b/libacc/tests/data/addressOf.c
@@ -0,0 +1,31 @@
+void testStruct() {
+    struct str {
+        float x;
+        float y;
+    };
+
+    struct str base;
+    int index = 0;
+
+    base.x = 10.0;
+    struct str *s = &base;
+
+    float *v = &(*s).x;
+    float *v2 = &s[index].x;
+    printf("testStruct: %g %g %g\n",base.x, *v, *v2);
+}
+
+void testArray() {
+    int a[2];
+    a[0] = 1;
+    a[1] = 2;
+    int* p = &a[0];
+    int* p2 = a;
+    printf("testArray: %d %d %d\n", a[0], *p, *p2);
+}
+
+int main() {
+    testStruct();
+    testArray();
+    return 0;
+}
diff --git a/libacc/tests/test.py b/libacc/tests/test.py
index a8575b1..c982d16 100644
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -471,6 +471,13 @@
 result: 6
 ""","""""")
 
+    def testAddressOf(self):
+        self.compileCheck(["-R", "data/addressOf.c"], """Executing compiled code:
+testStruct: 10 10 10
+testArray: 1 1 1
+result: 0
+""","""""")
+
 def main():
     checkEnvironment()
     parseArgv()
diff --git a/libcutils/atomic-android-arm.S b/libcutils/atomic-android-arm.S
index c56ec5d..f4299fd 100644
--- a/libcutils/atomic-android-arm.S
+++ b/libcutils/atomic-android-arm.S
@@ -55,23 +55,8 @@
  */
  
 android_atomic_write:
-    stmdb   sp!, {r4, lr}
-    mov     r2, r1
-    mov     r1, r0
-1: @ android_atomic_write
-    ldr     r0, [r2]
-    mov     r3, #kernel_atomic_base
-#ifdef __ARM_HAVE_PC_INTERWORK
-    add     lr, pc, #4
-    add     pc, r3, #(kernel_cmpxchg - kernel_atomic_base)
-#else
-    add     r3, r3, #(kernel_cmpxchg - kernel_atomic_base)
-    mov     lr, pc
-    bx      r3
-#endif
-    bcc     1b
-    ldmia   sp!, {r4, lr}
-    bx      lr
+    str     r0, [r1]
+    bx      lr;
 
 /*
  * ----------------------------------------------------------------------------
diff --git a/libcutils/atomic-android-armv6.S b/libcutils/atomic-android-armv6.S
index 64146c1..a713089 100644
--- a/libcutils/atomic-android-armv6.S
+++ b/libcutils/atomic-android-armv6.S
@@ -45,11 +45,8 @@
  */
 
 android_atomic_write:
-1:  ldrex   r12, [r1]
-    strex   r12, r0, [r1]
-    cmp     r12, #0
-    bne     1b
-    bx      lr
+    str     r0, [r1]
+    bx      lr;
 
 /*
  * ----------------------------------------------------------------------------
diff --git a/logcat/event-log-tags b/logcat/event-log-tags
index b5386d3..4db86cb 100644
--- a/logcat/event-log-tags
+++ b/logcat/event-log-tags
@@ -82,6 +82,10 @@
 # disk space free on the /data partition in bytes
 2746 free_storage_left (data|2|2)
 
+# contacts aggregation: time and number of contacts.
+# count is negative for query phase, positive for merge phase
+2747 contacts_aggregation (aggregation time|2|3), (count|1|1)
+
 # when a NotificationManager.notify is called
 2750 notification_enqueue (pkg|3),(id|1|5),(notification|3)
 # when someone tries to cancel a notification, the notification manager sometimes
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 7d9869f..5d0c8b5 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -70,26 +70,24 @@
     # storing dumps on platforms which do not have a dedicated dump partition.
    
     mkdir /data/dontpanic
-    chmod 0770 /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",