diff options
author | Serban Constantinescu <serban.constantinescu@arm.com> | 2013-11-05 16:53:55 +0000 |
---|---|---|
committer | David Butcher <david.butcher@arm.com> | 2014-01-31 10:49:40 +0000 |
commit | f683e0163a84d93448b9388126902242367cd961 (patch) | |
tree | 9b1107fef6b054470d3edef320d22ecd36461568 | |
parent | 3a345f0df5f62d77e875a289e9aee89f0d1b526e (diff) | |
download | frameworks_native-f683e0163a84d93448b9388126902242367cd961.zip frameworks_native-f683e0163a84d93448b9388126902242367cd961.tar.gz frameworks_native-f683e0163a84d93448b9388126902242367cd961.tar.bz2 |
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>
-rw-r--r-- | include/binder/Parcel.h | 4 | ||||
-rw-r--r-- | libs/binder/Binder.cpp | 5 | ||||
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 40 | ||||
-rw-r--r-- | libs/binder/MemoryDealer.cpp | 4 | ||||
-rw-r--r-- | libs/binder/Parcel.cpp | 16 |
5 files changed, 47 insertions, 22 deletions
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 @@ class TextOutput; 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 @@ private: 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 @@ void BBinder::attachObject( 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 @@ status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* prox { 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 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy) { 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 @@ status_t IPCThreadState::executeCommand(int32_t cmd) 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 @@ status_t IPCThreadState::executeCommand(int32_t cmd) 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 @@ status_t IPCThreadState::executeCommand(int32_t cmd) 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 @@ status_t IPCThreadState::executeCommand(int32_t cmd) 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 @@ status_t IPCThreadState::executeCommand(int32_t cmd) 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 @@ void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t data 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 @@ void SimpleBestFitAllocator::dump_l(String8& result, 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 @@ status_t Parcel::writeInt64(int64_t val) 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 @@ int64_t Parcel::readInt64() const 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); |