summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSabre Shao <[email protected]>2016-02-25 05:30:33 -0500
committerMarek Olšák <[email protected]>2017-03-30 14:44:33 +0200
commiteb3036ed46d97d43728626207b423fdc9c09e3d7 (patch)
treed1a71fe647c8029efd9e23e03a71c52ba86e0caa
parent680f91e5d47e6147bac1c214e921bf655a4785a3 (diff)
amdgpu/addrlib: fix crash on allocation failure
-rw-r--r--src/amd/addrlib/core/addrelemlib.cpp6
-rw-r--r--src/amd/addrlib/core/addrobject.cpp41
-rw-r--r--src/amd/addrlib/core/addrobject.h14
-rw-r--r--src/amd/addrlib/r800/ciaddrlib.h3
-rw-r--r--src/amd/addrlib/r800/siaddrlib.h3
5 files changed, 31 insertions, 36 deletions
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<Lib* const>(pAddrLib));
+ VOID* pObj = Object::ClientAlloc(sizeof(ElemLib), pAddrLib->GetClient());
+ if (pObj)
+ {
+ pElemLib = new(pObj) ElemLib(const_cast<Lib* const>(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<Object*>(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: