[Mesa-dev] [PATCH 041/140] amdgpu/addrlib: fix crash on allocation failure
Marek Olšák
maraeo at gmail.com
Mon Mar 20 22:42:51 UTC 2017
From: Sabre Shao <sabre.shao at amd.com>
---
src/amd/addrlib/core/addrelemlib.cpp | 6 +++++-
src/amd/addrlib/core/addrobject.cpp | 41 ++++++++++++------------------------
src/amd/addrlib/core/addrobject.h | 14 ++++++------
src/amd/addrlib/r800/ciaddrlib.h | 3 ++-
src/amd/addrlib/r800/siaddrlib.h | 3 ++-
5 files changed, 31 insertions(+), 36 deletions(-)
diff --git a/src/amd/addrlib/core/addrelemlib.cpp b/src/amd/addrlib/core/addrelemlib.cpp
index c9d2074..770cee3 100644
--- a/src/amd/addrlib/core/addrelemlib.cpp
+++ b/src/amd/addrlib/core/addrelemlib.cpp
@@ -103,21 +103,25 @@ ElemLib::~ElemLib()
* Returns point to ADDR_CREATEINFO if successful.
****************************************************************************************************
*/
ElemLib* ElemLib::Create(
const Lib* pAddrLib) ///< [in] Pointer of parent AddrLib instance
{
ElemLib* pElemLib = NULL;
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;
}
/**************************************************************************************************
* ElemLib::Flt32sToInt32s
*
* @brief
* Convert a ADDR_FLT_32 value to Int32 value
diff --git a/src/amd/addrlib/core/addrobject.cpp b/src/amd/addrlib/core/addrobject.cpp
index cb62aa0..dcdb1bf 100644
--- a/src/amd/addrlib/core/addrobject.cpp
+++ b/src/amd/addrlib/core/addrobject.cpp
@@ -80,21 +80,21 @@ Object::~Object()
/**
****************************************************************************************************
* Object::ClientAlloc
*
* @brief
* Calls instanced allocSysMem inside Client
****************************************************************************************************
*/
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;
if (pClient->callbacks.allocSysMem != NULL)
{
ADDR_ALLOCSYSMEM_INPUT allocInput = {0};
allocInput.size = sizeof(ADDR_ALLOCSYSMEM_INPUT);
allocInput.flags.value = 0;
@@ -109,35 +109,36 @@ VOID* Object::ClientAlloc(
/**
****************************************************************************************************
* Object::Alloc
*
* @brief
* A wrapper of 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);
}
/**
****************************************************************************************************
* Object::ClientFree
*
* @brief
* Calls freeSysMem inside Client
****************************************************************************************************
*/
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)
{
if (pObjMem != NULL)
{
ADDR_FREESYSMEM_INPUT freeInput = {0};
freeInput.size = sizeof(ADDR_FREESYSMEM_INPUT);
freeInput.hClient = pClient->handle;
@@ -150,88 +151,74 @@ VOID Object::ClientFree(
/**
****************************************************************************************************
* Object::Free
*
* @brief
* A wrapper of 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);
}
/**
****************************************************************************************************
* 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;
}
/**
****************************************************************************************************
* Object::operator delete
*
* @brief
* Frees Object object memory.
****************************************************************************************************
*/
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);
}
/**
****************************************************************************************************
* Object::DebugPrint
*
* @brief
* Print debug message
*
* @return
* N/A
****************************************************************************************************
*/
VOID Object::DebugPrint(
const CHAR* pDebugString, ///< [in] Debug string
- ...) const
+ ...
+ ) const
{
#if DEBUG
if (m_client.callbacks.debugPrint != NULL)
{
va_list ap;
va_start(ap, pDebugString);
ADDR_DEBUGPRINT_INPUT debugPrintInput = {0};
diff --git a/src/amd/addrlib/core/addrobject.h b/src/amd/addrlib/core/addrobject.h
index 031103b..66886f6 100644
--- a/src/amd/addrlib/core/addrobject.h
+++ b/src/amd/addrlib/core/addrobject.h
@@ -55,39 +55,41 @@ struct Client
* @brief This class is the base class for all ADDR class objects.
****************************************************************************************************
*/
class Object
{
public:
Object();
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);
// disallow the assignment operator
Object& operator=(const Object& a);
};
} // Addr
#endif
diff --git a/src/amd/addrlib/r800/ciaddrlib.h b/src/amd/addrlib/r800/ciaddrlib.h
index c59a0b1..f6c8655 100644
--- a/src/amd/addrlib/r800/ciaddrlib.h
+++ b/src/amd/addrlib/r800/ciaddrlib.h
@@ -78,21 +78,22 @@ struct CIChipSettings
* @brief This class is the CI specific address library
* function set.
****************************************************************************************************
*/
class CiLib : public SiLib
{
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:
CiLib(const Client* pClient);
virtual ~CiLib();
protected:
// Hwl interface - defined in AddrLib1
virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(
diff --git a/src/amd/addrlib/r800/siaddrlib.h b/src/amd/addrlib/r800/siaddrlib.h
index 80c5cf4..86d2116 100644
--- a/src/amd/addrlib/r800/siaddrlib.h
+++ b/src/amd/addrlib/r800/siaddrlib.h
@@ -78,21 +78,22 @@ struct SIChipSettings
* @brief This class is the SI specific address library
* function set.
****************************************************************************************************
*/
class SiLib : public EgBasedLib
{
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:
SiLib(const Client* pClient);
virtual ~SiLib();
// Hwl interface - defined in AddrLib1
virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(
const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,
ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;
--
2.7.4
More information about the mesa-dev
mailing list