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:
parent
3a345f0df5
commit
f683e0163a
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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]);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user