amdgpu/addrlib: fix crash on allocation failure

This commit is contained in:
Sabre Shao 2016-02-25 05:30:33 -05:00 committed by Marek Olšák
parent 680f91e5d4
commit eb3036ed46
5 changed files with 31 additions and 36 deletions

View File

@ -110,7 +110,11 @@ ElemLib* ElemLib::Create(
if (pAddrLib) if (pAddrLib)
{ {
pElemLib = new(pAddrLib->GetClient()) ElemLib(const_cast<Lib* const>(pAddrLib)); VOID* pObj = Object::ClientAlloc(sizeof(ElemLib), pAddrLib->GetClient());
if (pObj)
{
pElemLib = new(pObj) ElemLib(const_cast<Lib* const>(pAddrLib));
}
} }
return pElemLib; return pElemLib;

View File

@ -87,7 +87,7 @@ Object::~Object()
**************************************************************************************************** ****************************************************************************************************
*/ */
VOID* Object::ClientAlloc( VOID* Object::ClientAlloc(
size_t objSize, ///< [in] Size to allocate size_t objSize, ///< [in] Size to allocate
const Client* pClient) ///< [in] Client pointer const Client* pClient) ///< [in] Client pointer
{ {
VOID* pObjMem = NULL; VOID* pObjMem = NULL;
@ -116,7 +116,8 @@ VOID* Object::ClientAlloc(
**************************************************************************************************** ****************************************************************************************************
*/ */
VOID* Object::Alloc( VOID* Object::Alloc(
size_t objSize) const ///< [in] Size to allocate size_t objSize ///< [in] Size to allocate
) const
{ {
return ClientAlloc(objSize, &m_client); return ClientAlloc(objSize, &m_client);
} }
@ -130,7 +131,7 @@ VOID* Object::Alloc(
**************************************************************************************************** ****************************************************************************************************
*/ */
VOID Object::ClientFree( 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 const Client* pClient) ///< [in] Client pointer
{ {
if (pClient->callbacks.freeSysMem != NULL) if (pClient->callbacks.freeSysMem != NULL)
@ -157,7 +158,8 @@ VOID Object::ClientFree(
**************************************************************************************************** ****************************************************************************************************
*/ */
VOID Object::Free( 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); ClientFree(pObjMem, &m_client);
} }
@ -167,33 +169,17 @@ VOID Object::Free(
* Object::operator new * Object::operator new
* *
* @brief * @brief
* Allocates memory needed for Object object. (with ADDR_CLIENT_HANDLE) * Placement new operator. (with pre-allocated memory pointer)
* *
* @return * @return
* Returns NULL if unsuccessful. * Returns pre-allocated memory pointer.
**************************************************************************************************** ****************************************************************************************************
*/ */
VOID* Object::operator new( VOID* Object::operator new(
size_t objSize, ///< [in] Size to allocate size_t objSize, ///< [in] Size to allocate
const Client* pClient) ///< [in] Client pointer VOID* pMem) ///< [in] Pre-allocated pointer
{ {
return ClientAlloc(objSize, pClient); return pMem;
}
/**
****************************************************************************************************
* 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
{
ClientFree(pObjMem, pClient);
} }
/** /**
@ -205,7 +191,7 @@ VOID Object::operator delete(
**************************************************************************************************** ****************************************************************************************************
*/ */
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<Object*>(pObjMem); Object* pObj = static_cast<Object*>(pObjMem);
ClientFree(pObjMem, &pObj->m_client); ClientFree(pObjMem, &pObj->m_client);
@ -224,7 +210,8 @@ VOID Object::operator delete(
*/ */
VOID Object::DebugPrint( VOID Object::DebugPrint(
const CHAR* pDebugString, ///< [in] Debug string const CHAR* pDebugString, ///< [in] Debug string
...) const ...
) const
{ {
#if DEBUG #if DEBUG
if (m_client.callbacks.debugPrint != NULL) if (m_client.callbacks.debugPrint != NULL)

View File

@ -62,25 +62,27 @@ public:
Object(const Client* pClient); Object(const Client* pClient);
virtual ~Object(); virtual ~Object();
VOID* operator new(size_t size, const Client* pClient); VOID* operator new(size_t size, VOID* pMem);
VOID operator delete(VOID* pObj, const Client* pClient);
VOID operator delete(VOID* pObj); 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* Alloc(size_t size) const;
VOID Free(VOID* pObj) const; VOID Free(VOID* pObj) const;
VOID DebugPrint( VOID DebugPrint(const CHAR* pDebugString, ...) const;
const CHAR* pDebugString,
...) const;
const Client* GetClient() const {return &m_client;} const Client* GetClient() const {return &m_client;}
protected: protected:
Client m_client; Client m_client;
private:
static VOID* ClientAlloc(size_t size, const Client* pClient); static VOID* ClientAlloc(size_t size, const Client* pClient);
static VOID ClientFree(VOID* pObj, const Client* pClient); static VOID ClientFree(VOID* pObj, const Client* pClient);
private:
// disallow the copy constructor // disallow the copy constructor
Object(const Object& a); Object(const Object& a);

View File

@ -85,7 +85,8 @@ public:
/// Creates CiLib object /// Creates CiLib object
static Addr::Lib* CreateObj(const Client* pClient) 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: private:

View File

@ -85,7 +85,8 @@ public:
/// Creates SiLib object /// Creates SiLib object
static Addr::Lib* CreateObj(const Client* pClient) 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: protected: