Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f683e016 authored by Serban Constantinescu's avatar Serban Constantinescu Committed by David Butcher
Browse files

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: default avatarMatthew Leach <matthew.leach@arm.com>
Signed-off-by: default avatarSerban Constantinescu <serban.constantinescu@arm.com>
parent 3a345f0d
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -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;
+5 −0
Original line number Original line Diff line number Diff line
@@ -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;
        }
        }
+20 −20
Original line number Original line Diff line number Diff line
@@ -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
+2 −2
Original line number Original line Diff line number Diff line
@@ -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]);
+16 −0
Original line number Original line Diff line number Diff line
@@ -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);