From: Sabre Shao Date: Thu, 25 Feb 2016 10:30:33 +0000 (-0500) Subject: amdgpu/addrlib: fix crash on allocation failure X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eb3036ed46d97d43728626207b423fdc9c09e3d7;p=mesa.git amdgpu/addrlib: fix crash on allocation failure --- diff --git a/src/amd/addrlib/core/addrelemlib.cpp b/src/amd/addrlib/core/addrelemlib.cpp index c9d20742ee1..770cee3f947 100644 --- a/src/amd/addrlib/core/addrelemlib.cpp +++ b/src/amd/addrlib/core/addrelemlib.cpp @@ -110,7 +110,11 @@ ElemLib* ElemLib::Create( if (pAddrLib) { - pElemLib = new(pAddrLib->GetClient()) ElemLib(const_cast(pAddrLib)); + VOID* pObj = Object::ClientAlloc(sizeof(ElemLib), pAddrLib->GetClient()); + if (pObj) + { + pElemLib = new(pObj) ElemLib(const_cast(pAddrLib)); + } } return pElemLib; diff --git a/src/amd/addrlib/core/addrobject.cpp b/src/amd/addrlib/core/addrobject.cpp index cb62aa0fdec..dcdb1bffc2b 100644 --- a/src/amd/addrlib/core/addrobject.cpp +++ b/src/amd/addrlib/core/addrobject.cpp @@ -87,7 +87,7 @@ Object::~Object() **************************************************************************************************** */ VOID* Object::ClientAlloc( - size_t objSize, ///< [in] Size to allocate + size_t objSize, ///< [in] Size to allocate const Client* pClient) ///< [in] Client pointer { VOID* pObjMem = NULL; @@ -116,7 +116,8 @@ VOID* Object::ClientAlloc( **************************************************************************************************** */ VOID* Object::Alloc( - size_t objSize) const ///< [in] Size to allocate + size_t objSize ///< [in] Size to allocate + ) const { return ClientAlloc(objSize, &m_client); } @@ -130,7 +131,7 @@ VOID* Object::Alloc( **************************************************************************************************** */ VOID Object::ClientFree( - VOID* pObjMem, ///< [in] User virtual address to free. + VOID* pObjMem, ///< [in] User virtual address to free. const Client* pClient) ///< [in] Client pointer { if (pClient->callbacks.freeSysMem != NULL) @@ -157,7 +158,8 @@ VOID Object::ClientFree( **************************************************************************************************** */ VOID Object::Free( - VOID* pObjMem) const ///< [in] User virtual address to free. + VOID* pObjMem ///< [in] User virtual address to free. + ) const { ClientFree(pObjMem, &m_client); } @@ -167,33 +169,17 @@ VOID Object::Free( * Object::operator new * * @brief -* Allocates memory needed for Object object. (with ADDR_CLIENT_HANDLE) +* Placement new operator. (with pre-allocated memory pointer) * * @return -* Returns NULL if unsuccessful. +* Returns pre-allocated memory pointer. **************************************************************************************************** */ VOID* Object::operator new( - size_t objSize, ///< [in] Size to allocate - const Client* pClient) ///< [in] Client pointer -{ - return ClientAlloc(objSize, pClient); -} - - -/** -**************************************************************************************************** -* Object::operator delete -* -* @brief -* Frees Object object memory. -**************************************************************************************************** -*/ -VOID Object::operator delete( - VOID* pObjMem, ///< [in] User virtual address to free. - const Client* pClient) ///< [in] Client handle + size_t objSize, ///< [in] Size to allocate + VOID* pMem) ///< [in] Pre-allocated pointer { - ClientFree(pObjMem, pClient); + return pMem; } /** @@ -205,7 +191,7 @@ VOID Object::operator delete( **************************************************************************************************** */ VOID Object::operator delete( - VOID* pObjMem) ///< [in] User virtual address to free. + VOID* pObjMem) ///< [in] User virtual address to free. { Object* pObj = static_cast(pObjMem); ClientFree(pObjMem, &pObj->m_client); @@ -224,7 +210,8 @@ VOID Object::operator delete( */ VOID Object::DebugPrint( const CHAR* pDebugString, ///< [in] Debug string - ...) const + ... + ) const { #if DEBUG if (m_client.callbacks.debugPrint != NULL) diff --git a/src/amd/addrlib/core/addrobject.h b/src/amd/addrlib/core/addrobject.h index 031103b7374..66886f6b52e 100644 --- a/src/amd/addrlib/core/addrobject.h +++ b/src/amd/addrlib/core/addrobject.h @@ -62,25 +62,27 @@ public: Object(const Client* pClient); virtual ~Object(); - VOID* operator new(size_t size, const Client* pClient); - VOID operator delete(VOID* pObj, const Client* pClient); + VOID* operator new(size_t size, VOID* pMem); VOID operator delete(VOID* pObj); + /// Microsoft compiler requires a matching delete implementation, which seems to be called when + /// bad_alloc is thrown. But currently C++ exception isn't allowed so a dummy implementation is + /// added to eliminate the warning. + VOID operator delete(VOID* pObj, VOID* pMem) { ADDR_ASSERT_ALWAYS(); } + VOID* Alloc(size_t size) const; VOID Free(VOID* pObj) const; - VOID DebugPrint( - const CHAR* pDebugString, - ...) const; + VOID DebugPrint(const CHAR* pDebugString, ...) const; const Client* GetClient() const {return &m_client;} protected: Client m_client; -private: static VOID* ClientAlloc(size_t size, const Client* pClient); static VOID ClientFree(VOID* pObj, const Client* pClient); +private: // disallow the copy constructor Object(const Object& a); diff --git a/src/amd/addrlib/r800/ciaddrlib.h b/src/amd/addrlib/r800/ciaddrlib.h index c59a0b127a1..f6c865536ce 100644 --- a/src/amd/addrlib/r800/ciaddrlib.h +++ b/src/amd/addrlib/r800/ciaddrlib.h @@ -85,7 +85,8 @@ public: /// Creates CiLib object static Addr::Lib* CreateObj(const Client* pClient) { - return new(pClient) CiLib(pClient); + VOID* pMem = Object::ClientAlloc(sizeof(CiLib), pClient); + return (pMem != NULL) ? new (pMem) CiLib(pClient) : NULL; } private: diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h index 80c5cf4079f..86d21167da7 100644 --- a/src/amd/addrlib/r800/siaddrlib.h +++ b/src/amd/addrlib/r800/siaddrlib.h @@ -85,7 +85,8 @@ public: /// Creates SiLib object static Addr::Lib* CreateObj(const Client* pClient) { - return new(pClient) SiLib(pClient); + VOID* pMem = Object::ClientAlloc(sizeof(SiLib), pClient); + return (pMem != NULL) ? new (pMem) SiLib(pClient) : NULL; } protected: