amdgpu/addrlib: fix crash on allocation failure
authorSabre Shao <sabre.shao@amd.com>
Thu, 25 Feb 2016 10:30:33 +0000 (05:30 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 30 Mar 2017 12:44:33 +0000 (14:44 +0200)
src/amd/addrlib/core/addrelemlib.cpp
src/amd/addrlib/core/addrobject.cpp
src/amd/addrlib/core/addrobject.h
src/amd/addrlib/r800/ciaddrlib.h
src/amd/addrlib/r800/siaddrlib.h

index c9d20742ee1c1ccd2e5b1b6b17a4d5cedcbac31c..770cee3f947787bbdc1773fb4be5914058e35969 100644 (file)
@@ -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;
index cb62aa0fdec6ec323d4de5700d28b51bfb5a9660..dcdb1bffc2bde4771636165de9860115cab5ebac 100644 (file)
@@ -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)
index 031103b7374c8390ce80b4c2ca374e682592ba26..66886f6b52e4272df0bb7de13e5b06407df145ef 100644 (file)
@@ -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);
 
index c59a0b127a1b0857d7adfe87d14785384be00d7f..f6c865536ce17d3aba87fa8896bdcbefbf3fd77a 100644 (file)
@@ -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:
index 80c5cf4079f635c83179d1ce9d15e6c881e97cff..86d21167da74822153dd6457c1d4d42e3c2a93c4 100644 (file)
@@ -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: