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 struct flat_binder_object; // defined in support_p/binder_module.h
class Parcel { class Parcel {
friend class IPCThreadState;
public: public:
class ReadableBlob; class ReadableBlob;
class WritableBlob; class WritableBlob;
@ -218,6 +219,9 @@ private:
status_t growData(size_t len); status_t growData(size_t len);
status_t restartWrite(size_t desired); status_t restartWrite(size_t desired);
status_t continueWrite(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 freeDataNoInit();
void initState(); void initState();
void scanForFds() const; void scanForFds() const;

View File

@ -142,8 +142,13 @@ void BBinder::attachObject(
if (!e) { if (!e) {
e = new Extras; 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), if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) { reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
#endif
delete e; delete e;
e = mExtras; 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(BC_REQUEST_DEATH_NOTIFICATION);
mOut.writeInt32((int32_t)handle); mOut.writeInt32((int32_t)handle);
mOut.writeInt32((int32_t)proxy); mOut.writePointer((uintptr_t)proxy);
return NO_ERROR; return NO_ERROR;
} }
@ -671,7 +671,7 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
{ {
mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION); mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
mOut.writeInt32((int32_t)handle); mOut.writeInt32((int32_t)handle);
mOut.writeInt32((int32_t)proxy); mOut.writePointer((uintptr_t)proxy);
return NO_ERROR; return NO_ERROR;
} }
@ -950,8 +950,8 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
break; break;
case BR_ACQUIRE: case BR_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readInt32(); refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readInt32(); obj = (BBinder*)mIn.readPointer();
ALOG_ASSERT(refs->refBase() == obj, ALOG_ASSERT(refs->refBase() == obj,
"BR_ACQUIRE: object %p does not match cookie %p (expected %p)", "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase()); refs, obj, refs->refBase());
@ -961,13 +961,13 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
obj->printRefs(); obj->printRefs();
} }
mOut.writeInt32(BC_ACQUIRE_DONE); mOut.writeInt32(BC_ACQUIRE_DONE);
mOut.writeInt32((int32_t)refs); mOut.writePointer((uintptr_t)refs);
mOut.writeInt32((int32_t)obj); mOut.writePointer((uintptr_t)obj);
break; break;
case BR_RELEASE: case BR_RELEASE:
refs = (RefBase::weakref_type*)mIn.readInt32(); refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readInt32(); obj = (BBinder*)mIn.readPointer();
ALOG_ASSERT(refs->refBase() == obj, ALOG_ASSERT(refs->refBase() == obj,
"BR_RELEASE: object %p does not match cookie %p (expected %p)", "BR_RELEASE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase()); refs, obj, refs->refBase());
@ -979,17 +979,17 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
break; break;
case BR_INCREFS: case BR_INCREFS:
refs = (RefBase::weakref_type*)mIn.readInt32(); refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readInt32(); obj = (BBinder*)mIn.readPointer();
refs->incWeak(mProcess.get()); refs->incWeak(mProcess.get());
mOut.writeInt32(BC_INCREFS_DONE); mOut.writeInt32(BC_INCREFS_DONE);
mOut.writeInt32((int32_t)refs); mOut.writePointer((uintptr_t)refs);
mOut.writeInt32((int32_t)obj); mOut.writePointer((uintptr_t)obj);
break; break;
case BR_DECREFS: case BR_DECREFS:
refs = (RefBase::weakref_type*)mIn.readInt32(); refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readInt32(); obj = (BBinder*)mIn.readPointer();
// NOTE: This assertion is not valid, because the object may no // NOTE: This assertion is not valid, because the object may no
// longer exist (thus the (BBinder*)cast above resulting in a different // longer exist (thus the (BBinder*)cast above resulting in a different
// memory address). // memory address).
@ -1000,8 +1000,8 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
break; break;
case BR_ATTEMPT_ACQUIRE: case BR_ATTEMPT_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readInt32(); refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readInt32(); obj = (BBinder*)mIn.readPointer();
{ {
const bool success = refs->attemptIncStrong(mProcess.get()); const bool success = refs->attemptIncStrong(mProcess.get());
@ -1103,15 +1103,15 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
case BR_DEAD_BINDER: case BR_DEAD_BINDER:
{ {
BpBinder *proxy = (BpBinder*)mIn.readInt32(); BpBinder *proxy = (BpBinder*)mIn.readPointer();
proxy->sendObituary(); proxy->sendObituary();
mOut.writeInt32(BC_DEAD_BINDER_DONE); mOut.writeInt32(BC_DEAD_BINDER_DONE);
mOut.writeInt32((int32_t)proxy); mOut.writePointer((uintptr_t)proxy);
} break; } break;
case BR_CLEAR_DEATH_NOTIFICATION_DONE: case BR_CLEAR_DEATH_NOTIFICATION_DONE:
{ {
BpBinder *proxy = (BpBinder*)mIn.readInt32(); BpBinder *proxy = (BpBinder*)mIn.readPointer();
proxy->getWeakRefs()->decWeak(proxy); proxy->getWeakRefs()->decWeak(proxy);
} break; } break;
@ -1166,7 +1166,7 @@ void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t data
if (parcel != NULL) parcel->closeFileDescriptors(); if (parcel != NULL) parcel->closeFileDescriptors();
IPCThreadState* state = self(); IPCThreadState* state = self();
state->mOut.writeInt32(BC_FREE_BUFFER); state->mOut.writeInt32(BC_FREE_BUFFER);
state->mOut.writeInt32((int32_t)data); state->mOut.writePointer((uintptr_t)data);
} }
}; // namespace android }; // 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 np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0; int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
snprintf(buffer, SIZE, " %3u: %08x | 0x%08X | 0x%08X | %s %s\n", snprintf(buffer, SIZE, " %3u: %p | 0x%08X | 0x%08X | %s %s\n",
i, int(cur), int(cur->start*kMemoryAlign), i, cur, int(cur->start*kMemoryAlign),
int(cur->size*kMemoryAlign), int(cur->size*kMemoryAlign),
int(cur->free) ? "F" : "A", int(cur->free) ? "F" : "A",
errs[np|pn]); errs[np|pn]);

View File

@ -633,6 +633,11 @@ status_t Parcel::writeInt64(int64_t val)
return writeAligned(val); return writeAligned(val);
} }
status_t Parcel::writePointer(uintptr_t val)
{
return writeAligned(val);
}
status_t Parcel::writeFloat(float val) status_t Parcel::writeFloat(float val)
{ {
return writeAligned(val); return writeAligned(val);
@ -978,6 +983,17 @@ int64_t Parcel::readInt64() const
return readAligned<int64_t>(); 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 status_t Parcel::readFloat(float *pArg) const
{ {
return readAligned(pArg); return readAligned(pArg);