mirror of
https://github.com/google/pebble.git
synced 2025-06-05 17:53:11 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
308
third_party/duma/duma_hlp.h
vendored
Normal file
308
third_party/duma/duma_hlp.h
vendored
Normal file
|
@ -0,0 +1,308 @@
|
|||
|
||||
/*
|
||||
* DUMA - Red-Zone memory allocator.
|
||||
* Copyright (C) 2002-2005 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
|
||||
* License: GNU LGPL (GNU Lesser General Public License, see COPYING-GPL)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* FILE CONTENTS:
|
||||
* internal implementation file
|
||||
* contains helper functions for DUMA
|
||||
*/
|
||||
|
||||
|
||||
/* Function: reduceProtectedMemory
|
||||
*
|
||||
* delete reductionSizekB amount of memory, which has already
|
||||
* been freed but got protected
|
||||
* return != 0 when more memory reducable
|
||||
*/
|
||||
static int
|
||||
reduceProtectedMemory( size_t reductionSizekB )
|
||||
{
|
||||
struct _DUMA_Slot * slot = _duma_g.allocList;
|
||||
size_t count = _duma_s.slotCount;
|
||||
size_t alreadyReducekB = 0;
|
||||
|
||||
#ifndef WIN32
|
||||
/* Windows VirtualFree(,,MEM_RELEASE) can only free whole allocations. not parts */
|
||||
|
||||
size_t delSize, newSize;
|
||||
|
||||
/* 1- try reducing memory to just keep page(s) with userAddress */
|
||||
for ( ; count > 0 && alreadyReducekB < reductionSizekB; --count, ++slot )
|
||||
if ( DUMAST_ALL_PROTECTED == slot->state )
|
||||
{
|
||||
/* free memory above userAddr; keep userAddr protected */
|
||||
newSize = (char*)slot->userAddress - (char*)slot->internalAddress;
|
||||
newSize = (newSize + DUMA_PAGE_SIZE) & ~(DUMA_PAGE_SIZE -1);
|
||||
delSize = slot->internalSize - newSize;
|
||||
Page_Delete( (char*)slot->internalAddress + newSize, delSize );
|
||||
alreadyReducekB += (delSize+1023) >>10;
|
||||
slot->state = DUMAST_BEGIN_PROTECTED;
|
||||
/* but keep the slot and userAddr */
|
||||
slot->internalSize = newSize;
|
||||
|
||||
if ( alreadyReducekB >= reductionSizekB )
|
||||
{
|
||||
_duma_s.sumProtectedMem -= alreadyReducekB;
|
||||
_duma_s.sumAllocatedMem -= alreadyReducekB;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* 2- deallocate all page(s) with userAddress, empty whole slot */
|
||||
slot = _duma_g.allocList;
|
||||
count = _duma_s.slotCount;
|
||||
for ( ; count > 0 && alreadyReducekB < reductionSizekB; --count, ++slot )
|
||||
if ( DUMAST_BEGIN_PROTECTED == slot->state
|
||||
#if defined(WIN32)
|
||||
|| DUMAST_ALL_PROTECTED == slot->state
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* free all the memory */
|
||||
Page_Delete(slot->internalAddress, slot->internalSize);
|
||||
alreadyReducekB += (slot->internalSize+1023) >>10;
|
||||
/* free slot and userAddr */
|
||||
slot->internalAddress = slot->userAddress = 0;
|
||||
slot->internalSize = slot->userSize = 0;
|
||||
slot->state = DUMAST_EMPTY;
|
||||
slot->allocator = EFA_INT_ALLOC;
|
||||
#ifndef DUMA_NO_LEAKDETECTION
|
||||
slot->fileSource = DUMAFS_EMPTY;
|
||||
slot->filename = 0;
|
||||
slot->lineno = 0;
|
||||
#endif
|
||||
|
||||
if ( alreadyReducekB >= reductionSizekB )
|
||||
{
|
||||
_duma_s.sumProtectedMem -= alreadyReducekB;
|
||||
_duma_s.sumAllocatedMem -= alreadyReducekB;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Function: slotForUserAddress
|
||||
*
|
||||
* Find the slot structure for a user address.
|
||||
*/
|
||||
static struct _DUMA_Slot *
|
||||
slotForUserAddress(void * address)
|
||||
{
|
||||
struct _DUMA_Slot * slot = _duma_g.allocList;
|
||||
size_t count = _duma_s.slotCount;
|
||||
|
||||
for ( ; count > 0; --count, ++slot )
|
||||
if ( slot->userAddress == address )
|
||||
return slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Function: nearestSlotForUserAddress
|
||||
*
|
||||
* Find the nearest slot structure for a user address.
|
||||
*/
|
||||
static struct _DUMA_Slot *
|
||||
nearestSlotForUserAddress(void * userAddress)
|
||||
{
|
||||
struct _DUMA_Slot * slot = _duma_g.allocList;
|
||||
size_t count = _duma_s.slotCount;
|
||||
|
||||
for ( ; count > 0; --count, ++slot )
|
||||
if ( (char*)slot->internalAddress <= (char*)userAddress
|
||||
&& (char*)userAddress <= (char*)slot->internalAddress + slot->internalSize
|
||||
)
|
||||
return slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* next to functions not needed so far .. */
|
||||
|
||||
/* Function: slotForInternalAddrNextTo
|
||||
*
|
||||
* Find the slot structure for an internal address.
|
||||
*/
|
||||
static struct _DUMA_Slot *
|
||||
slotForInternalAddrNextTo(void * address)
|
||||
{
|
||||
struct _DUMA_Slot * slot = _duma_g.allocList;
|
||||
size_t count = _duma_s.slotCount;
|
||||
|
||||
for ( ; count > 0; --count, ++slot )
|
||||
if ( slot->internalAddress == address )
|
||||
return slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Function: slotForInternalAddrPrevTo
|
||||
*
|
||||
* Given the internal address of a buffer, find the buffer immediately
|
||||
* before that buffer in the address space. This is used by free() to
|
||||
* coalesce two free buffers into one.
|
||||
*/
|
||||
static struct _DUMA_Slot *
|
||||
slotForInternalAddrPrevTo(void * address)
|
||||
{
|
||||
struct _DUMA_Slot * slot = _duma_g.allocList;
|
||||
size_t count = _duma_s.slotCount;
|
||||
|
||||
for ( ; count > 0; --count, ++slot )
|
||||
if ( (char*)slot->internalAddress + slot->internalSize == address )
|
||||
return slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Function: _duma_init_slack
|
||||
*
|
||||
* Initialise the no mans land, for a given slot
|
||||
*/
|
||||
static
|
||||
void _duma_init_slack( struct _DUMA_Slot * slot )
|
||||
{
|
||||
char * accBegAddr, * accEndAddr;
|
||||
char * tmpBegAddr, * tmpEndAddr;
|
||||
|
||||
#ifdef DUMA_EXPLICIT_INIT
|
||||
slot->slackfill = _duma_s.SLACKFILL;
|
||||
#endif
|
||||
|
||||
/* nothing to do for zero userSize */
|
||||
if ( !slot->userSize )
|
||||
return;
|
||||
|
||||
/* calculate accessible non-protectable address area */
|
||||
if ( (char*)slot->protAddress < (char*)slot->userAddress )
|
||||
{
|
||||
/* DUMA_PROTECT_BELOW was 1 when allocating this piece of memory */
|
||||
accBegAddr = (char*)slot->userAddress;
|
||||
accEndAddr = (char*)slot->internalAddress + slot->internalSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DUMA_PROTECT_BELOW was 0 when allocating this piece of memory */
|
||||
accBegAddr = (char*)slot->internalAddress;
|
||||
accEndAddr = (char*)slot->protAddress;
|
||||
}
|
||||
|
||||
tmpBegAddr = accBegAddr;
|
||||
tmpEndAddr = (char*)slot->userAddress;
|
||||
while (tmpBegAddr < tmpEndAddr)
|
||||
*tmpBegAddr++ = (char)_duma_s.SLACKFILL;
|
||||
|
||||
tmpBegAddr = (char*)slot->userAddress + slot->userSize;
|
||||
tmpEndAddr = accEndAddr;
|
||||
while (tmpBegAddr < tmpEndAddr)
|
||||
*tmpBegAddr++ = (char)_duma_s.SLACKFILL;
|
||||
}
|
||||
|
||||
|
||||
/* Function: _duma_check_slack
|
||||
*
|
||||
* Checks the integrity of no mans land, for a given slot
|
||||
*/
|
||||
static
|
||||
void _duma_check_slack( struct _DUMA_Slot * slot )
|
||||
{
|
||||
char * accBegAddr, * accEndAddr;
|
||||
char * tmpBegAddr, * tmpEndAddr;
|
||||
char slackfill;
|
||||
#ifdef DUMA_EXPLICIT_INIT
|
||||
slackfill = (char)slot->slackfill;
|
||||
#else
|
||||
slackfill = (char)_duma_s.SLACKFILL;
|
||||
#endif
|
||||
|
||||
/* nothing to do for zero userSize */
|
||||
if ( !slot->userSize )
|
||||
return;
|
||||
|
||||
/* calculate accessible non-protectable address area */
|
||||
if ( (char*)slot->protAddress < (char*)slot->userAddress )
|
||||
{
|
||||
/* DUMA_PROTECT_BELOW was 1 when allocating this piece of memory */
|
||||
accBegAddr = (char*)slot->userAddress;
|
||||
accEndAddr = (char*)slot->internalAddress + slot->internalSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DUMA_PROTECT_BELOW was 0 when allocating this piece of memory */
|
||||
accBegAddr = (char*)slot->internalAddress;
|
||||
accEndAddr = (char*)slot->protAddress;
|
||||
}
|
||||
|
||||
tmpBegAddr = accBegAddr;
|
||||
tmpEndAddr = (char*)slot->userAddress;
|
||||
while (tmpBegAddr < tmpEndAddr)
|
||||
{
|
||||
if ( (char)slackfill != *tmpBegAddr++ )
|
||||
{
|
||||
#ifndef DUMA_NO_LEAKDETECTION
|
||||
DUMA_Abort("ptr=%a: detected overwrite of ptrs no mans land below userSpace, size=%d alloced from %s(%i)",
|
||||
(DUMA_ADDR)slot->userAddress, (DUMA_SIZE)slot->userSize, slot->filename, slot->lineno);
|
||||
#else
|
||||
DUMA_Abort("ptr=%a: detected overwrite of ptrs no mans land below userSpace", (DUMA_ADDR)slot->userAddress);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
tmpBegAddr = (char*)slot->userAddress + slot->userSize;
|
||||
tmpEndAddr = accEndAddr;
|
||||
while (tmpBegAddr < tmpEndAddr)
|
||||
{
|
||||
if ( (char)slackfill != *tmpBegAddr++ )
|
||||
{
|
||||
#ifndef DUMA_NO_LEAKDETECTION
|
||||
DUMA_Abort("detected overwrite of no mans land above userSpace: ptr=%a, size=%d\nalloced from %s(%i)",
|
||||
(DUMA_ADDR)slot->userAddress, (DUMA_SIZE)slot->userSize, slot->filename, slot->lineno);
|
||||
#else
|
||||
DUMA_Abort("detected overwrite of no mans land above userSpace: ptr=%a", (DUMA_ADDR)slot->userAddress);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Function: _duma_check_all_slacks
|
||||
*
|
||||
* Checks the integrity of all no mans land
|
||||
*/
|
||||
static void
|
||||
_duma_check_all_slacks( void )
|
||||
{
|
||||
struct _DUMA_Slot * slot = _duma_g.allocList;
|
||||
size_t count = _duma_s.slotCount;
|
||||
|
||||
for ( ; count > 0; --count, ++slot )
|
||||
{
|
||||
/* CHECK INTEGRITY OF NO MANS LAND */
|
||||
if ( DUMAST_IN_USE == slot->state && slot->userSize )
|
||||
_duma_check_slack( slot );
|
||||
}
|
||||
}
|
||||
|
||||
// end
|
Loading…
Add table
Add a link
Reference in a new issue