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>
This commit is contained in:
Serban Constantinescu 2013-11-05 16:53:55 +00:00 committed by David Butcher
parent 3a345f0df5
commit f683e0163a
5 changed files with 47 additions and 22 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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]);

View File

@ -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);