Binder: Make binder portable

Changes include
- Binder attempts to cast pointers to a int datatype
  which is not sufficient on a 64-bit platform.

- This patch introduces new read/write functions into
  Parcel that allow pointers to be written using the
  uintptr_t datatype for compile-time data type size
  selection.

-  Change access specifier for the methods above.

-  Binder uses the 64bit android_atomic_release_cas64
   (aka cmpxchg)

Change-Id: I595280541e0ba1d19c94b2ca2127bf9d96efabf1
Signed-off-by: Matthew Leach <matthew.leach@arm.com>
Signed-off-by: Serban Constantinescu <serban.constantinescu@arm.com>
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index c95f297..fa13ff5 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -38,6 +38,7 @@
 struct flat_binder_object;  // defined in support_p/binder_module.h
 
 class Parcel {
+    friend class IPCThreadState;
 public:
     class ReadableBlob;
     class WritableBlob;
@@ -218,6 +219,9 @@
     status_t            growData(size_t len);
     status_t            restartWrite(size_t desired);
     status_t            continueWrite(size_t desired);
+    status_t            writePointer(uintptr_t val);
+    status_t            readPointer(uintptr_t *pArg) const;
+    uintptr_t           readPointer() const;
     void                freeDataNoInit();
     void                initState();
     void                scanForFds() const;
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 1f21f9c..320bdea 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -142,8 +142,13 @@
 
     if (!e) {
         e = new Extras;
+#ifdef __LP64__
+        if (android_atomic_release_cas64(0, reinterpret_cast<int64_t>(e),
+                reinterpret_cast<volatile int64_t*>(&mExtras)) != 0) {
+#else
         if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
                 reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
+#endif
             delete e;
             e = mExtras;
         }
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 5951a3f..84bb94d 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -663,7 +663,7 @@
 {
     mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
     mOut.writeInt32((int32_t)handle);
-    mOut.writeInt32((int32_t)proxy);
+    mOut.writePointer((uintptr_t)proxy);
     return NO_ERROR;
 }
 
@@ -671,7 +671,7 @@
 {
     mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
     mOut.writeInt32((int32_t)handle);
-    mOut.writeInt32((int32_t)proxy);
+    mOut.writePointer((uintptr_t)proxy);
     return NO_ERROR;
 }
 
@@ -950,8 +950,8 @@
         break;
         
     case BR_ACQUIRE:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         ALOG_ASSERT(refs->refBase() == obj,
                    "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
                    refs, obj, refs->refBase());
@@ -961,13 +961,13 @@
             obj->printRefs();
         }
         mOut.writeInt32(BC_ACQUIRE_DONE);
-        mOut.writeInt32((int32_t)refs);
-        mOut.writeInt32((int32_t)obj);
+        mOut.writePointer((uintptr_t)refs);
+        mOut.writePointer((uintptr_t)obj);
         break;
         
     case BR_RELEASE:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         ALOG_ASSERT(refs->refBase() == obj,
                    "BR_RELEASE: object %p does not match cookie %p (expected %p)",
                    refs, obj, refs->refBase());
@@ -979,17 +979,17 @@
         break;
         
     case BR_INCREFS:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         refs->incWeak(mProcess.get());
         mOut.writeInt32(BC_INCREFS_DONE);
-        mOut.writeInt32((int32_t)refs);
-        mOut.writeInt32((int32_t)obj);
+        mOut.writePointer((uintptr_t)refs);
+        mOut.writePointer((uintptr_t)obj);
         break;
         
     case BR_DECREFS:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         // NOTE: This assertion is not valid, because the object may no
         // longer exist (thus the (BBinder*)cast above resulting in a different
         // memory address).
@@ -1000,8 +1000,8 @@
         break;
         
     case BR_ATTEMPT_ACQUIRE:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
          
         {
             const bool success = refs->attemptIncStrong(mProcess.get());
@@ -1103,15 +1103,15 @@
     
     case BR_DEAD_BINDER:
         {
-            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            BpBinder *proxy = (BpBinder*)mIn.readPointer();
             proxy->sendObituary();
             mOut.writeInt32(BC_DEAD_BINDER_DONE);
-            mOut.writeInt32((int32_t)proxy);
+            mOut.writePointer((uintptr_t)proxy);
         } break;
         
     case BR_CLEAR_DEATH_NOTIFICATION_DONE:
         {
-            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            BpBinder *proxy = (BpBinder*)mIn.readPointer();
             proxy->getWeakRefs()->decWeak(proxy);
         } break;
         
@@ -1166,7 +1166,7 @@
     if (parcel != NULL) parcel->closeFileDescriptors();
     IPCThreadState* state = self();
     state->mOut.writeInt32(BC_FREE_BUFFER);
-    state->mOut.writeInt32((int32_t)data);
+    state->mOut.writePointer((uintptr_t)data);
 }
 
 }; // namespace android
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index 8d0e0a7..2c9f244 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -445,8 +445,8 @@
         int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
         int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
 
-        snprintf(buffer, SIZE, "  %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
-            i, int(cur), int(cur->start*kMemoryAlign),
+        snprintf(buffer, SIZE, "  %3u: %p | 0x%08X | 0x%08X | %s %s\n",
+            i, cur, int(cur->start*kMemoryAlign),
             int(cur->size*kMemoryAlign),
                     int(cur->free) ? "F" : "A",
                     errs[np|pn]);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 38e019c..20cdb9a 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -633,6 +633,11 @@
     return writeAligned(val);
 }
 
+status_t Parcel::writePointer(uintptr_t val)
+{
+    return writeAligned(val);
+}
+
 status_t Parcel::writeFloat(float val)
 {
     return writeAligned(val);
@@ -978,6 +983,17 @@
     return readAligned<int64_t>();
 }
 
+status_t Parcel::readPointer(uintptr_t *pArg) const
+{
+    return readAligned(pArg);
+}
+
+uintptr_t Parcel::readPointer() const
+{
+    return readAligned<uintptr_t>();
+}
+
+
 status_t Parcel::readFloat(float *pArg) const
 {
     return readAligned(pArg);