Example #1
0
void *cmsMem_realloc(void *origBuf, UINT32 size)
{
   void *buf;
   UINT32 origSize, origAllocSize, origAllocFlags;
   UINT32 allocSize;
   UINT32 *intBuf;

   if (origBuf == NULL)
   {
      cmsLog_error("cannot take a NULL buffer");
      return NULL;
   }

   if (size == 0)
   {
      cmsMem_free(origBuf);
      return NULL;
   }

   allocSize = REAL_ALLOC_SIZE(size);


   intBuf = (UINT32 *) (((UINT32) origBuf) - CMS_MEM_HEADER_LENGTH);

   origAllocFlags = intBuf[0];
   origSize = intBuf[1];

   /* sanity check the original length */
   if (intBuf[1] != (intBuf[2] ^ 0xffffffff))
   {
      cmsLog_error("memory underflow detected, %d %d", intBuf[1], intBuf[2]);
      cmsAst_assert(0);
      return NULL;
   }

   origAllocSize = REAL_ALLOC_SIZE(origSize);

   if (allocSize <= origAllocSize)
   {
      /* currently, I don't shrink buffers, but could in the future. */
      return origBuf;
   }

   buf = cmsMem_alloc(allocSize, origAllocFlags);
   if (buf != NULL)
   {
      /* got new buffer, copy orig buffer to new buffer */
      memcpy(buf, origBuf, origSize);
      cmsMem_free(origBuf);
   }
   else
   {
      /*
       * We could not allocate a bigger buffer.
       * Return NULL but leave the original buffer untouched.
       */
   }

   return buf;
}
Example #2
0
/** Free previously allocated memory
 * @param buf Previously allocated buffer.
 */
void cmsMem_free(void *buf)
{
   UINT32 size;

   if (buf != NULL)
   {
      UINT32 *intBuf = (UINT32 *) (((UINT32) buf) - CMS_MEM_HEADER_LENGTH);

#ifdef CMS_MEM_LEAK_TRACING
      {
         AllocRecord *allocRec;
         dlist_for_each_entry(allocRec, &glbAllocRec, dlist)
            if (allocRec->bufAddr == buf)
               break;

         if ((DlistNode *) allocRec != &glbAllocRec)
         {
            dlist_unlink((struct dlist_node *) allocRec);
            free(allocRec);
         }
         else
         {
            /*
             * Buffers allocated from shared mem could have been freed by 
             * another app, so if we have an alloc record but cannot find
             * it in shared mem, ignore it.  But if the alloc record is in
             * private heap, that is an error.
             */
            if (!IS_IN_SHARED_MEM(buf))
            {
               cmsLog_error("possible double free, could not find allocRec for buf %p", buf);
            }
         }
      }
#endif

      size = intBuf[1];

      if (intBuf[1] != (intBuf[2] ^ 0xffffffff))
      {
         cmsLog_error("memory underflow detected, %d %d", intBuf[1], intBuf[2]);
         cmsAst_assert(0);
         return;
      }

#ifdef CMS_MEM_DEBUG
      {
         UINT32 allocSize, intSize, roundup4Size, i;
         UINT8 *charBuf = (UINT8 *) buf;

         allocSize = REAL_ALLOC_SIZE(intBuf[1]);
         intSize = allocSize / sizeof(UINT32);
         roundup4Size = ROUNDUP4(intBuf[1]);

         for (i=intBuf[1]; i < roundup4Size; i++)
         {
            if (charBuf[i] != (UINT8) (CMS_MEM_FOOTER_PATTERN & 0xff))
            {
               cmsLog_error("memory overflow detected at idx=%d 0x%x 0x%x 0x%x",
                            i, charBuf[i], intBuf[intSize-1], intBuf[intSize-2]);
               cmsAst_assert(0);
               return;
            }
         }
               
         if ((intBuf[intSize - 1] != CMS_MEM_FOOTER_PATTERN) ||
             (intBuf[intSize - 2] != CMS_MEM_FOOTER_PATTERN))
         {
            cmsLog_error("memory overflow detected, 0x%x 0x%x",
                         intBuf[intSize - 1], intBuf[intSize - 2]);
            cmsAst_assert(0);
            return;
         }

#ifdef CMS_MEM_POISON_ALLOC_FREE
         /*
          * write garbage into buffer which is about to be freed to detect
          * users of freed buffers.
          */
         memset(intBuf, CMS_MEM_FREE_PATTERN, allocSize);
#endif
      }

#endif  /* CMS_MEM_DEBUG */


      buf = intBuf;  /* buf points to real start of buffer */


#ifdef MDM_SHARED_MEM
      if (IS_IN_SHARED_MEM(buf))
      {
         brel(buf);
      }
      else
#endif
      {
         oal_free(buf);
         mStats.bytesAllocd -= size;
         mStats.numFrees++;
      }
   }
Example #3
0
void *cmsMem_alloc(UINT32 size, UINT32 allocFlags)
{
   void *buf;
   UINT32 allocSize;

#ifdef CMS_MEM_LEAK_TRACING
   initAllocSeq();
#endif

   allocSize = REAL_ALLOC_SIZE(size);

#ifdef MDM_SHARED_MEM
   if (allocFlags & ALLOC_SHARED_MEM)
   {
#ifdef CMS_MEM_LEAK_TRACING
      buf = bget(allocSize, allocSeq);
#else
      buf = bget(allocSize);
#endif
   }
   else
#endif
   {
      buf = oal_malloc(allocSize);
      if (buf)
      {
         mStats.bytesAllocd += size;
         mStats.numAllocs++;
      }
   }


   if (buf != NULL)
   {
      UINT32 *intBuf = (UINT32 *) buf;
      UINT32 intSize = allocSize / sizeof(UINT32);


      if (allocFlags & ALLOC_ZEROIZE)
      {
         memset(buf, 0, allocSize);
      }
#ifdef CMS_MEM_POISON_ALLOC_FREE
      else
      {
         /*
          * Set alloc'ed buffer to garbage to catch use-before-init.
          * But we also allocate huge buffers for storing image downloads.
          * Don't bother writing garbage to those huge buffers.
          */
         if (allocSize < 64 * 1024)
         {
            memset(buf, CMS_MEM_ALLOC_PATTERN, allocSize);
         }
      }
#endif
         
      /*
       * Record the allocFlags in the first word, and the 
       * size of user buffer in the next 2 words of the buffer.
       * Make 2 copies of the size in case one of the copies gets corrupted by
       * an underflow.  Make one copy the XOR of the other so that there are
       * not so many 0's in size fields.
       */
      intBuf[0] = allocFlags;
      intBuf[1] = size;
      intBuf[2] = intBuf[1] ^ 0xffffffff;

      buf = &(intBuf[3]); /* this gets returned to user */

#ifdef CMS_MEM_DEBUG
      {
         UINT8 *charBuf = (UINT8 *) buf;
         UINT32 i, roundup4Size = ROUNDUP4(size);

         for (i=size; i < roundup4Size; i++)
         {
            charBuf[i] = CMS_MEM_FOOTER_PATTERN & 0xff;
         }

         intBuf[intSize - 1] = CMS_MEM_FOOTER_PATTERN;
         intBuf[intSize - 2] = CMS_MEM_FOOTER_PATTERN;
      }
#endif

#ifdef CMS_MEM_LEAK_TRACING
      {
         AllocRecord *allocRec;
         if (!(allocRec = calloc(1, sizeof(AllocRecord))))
         {
            cmsLog_error("could not malloc a record to track alloc");
         }
         else
         {
            allocRec->bufAddr = buf;
            allocRec->userSize = size;
            allocRec->seq = allocSeq++;
            backtrace(allocRec->stackAddr, NUM_STACK_ENTRIES);
            /*
             * new allocs are placed at the beginning of the list, right after
             * the head.
             */
            dlist_append((struct dlist_node *)allocRec, &glbAllocRec);
         }

         /*
          * do periodic garbage collection on the allocRecs which point
          * to shmBuf's that has been freed by another app.
          */
         if ((allocSeq % 2000) == 0)
         {
            cmsLog_debug("Starting allocRec garbage collection");
            garbageCollectAllocRec();
            cmsLog_debug("garbage collection done");
         }
      }
#endif

   }

   return buf;
}
Example #4
0
void utlMem_free(void *buf)
{
    UINT32 size;

    if (buf != NULL)
    {
        UINTPTR *intBuf = (UINTPTR *) (((UINTPTR) buf) - UTL_MEM_HEADER_LENGTH);

#ifdef UTL_MEM_LEAK_TRACING
        {
            AllocRecord *allocRec;
            dlist_for_each_entry(allocRec, &glbAllocRec, dlist)
                if (allocRec->bufAddr == buf)
                    break;

            if ((DlistNode *) allocRec != &glbAllocRec)
            {
                dlist_del((struct dlist_node *) allocRec);
                free(allocRec);
            }
        }
#endif

        size = intBuf[1];

        if (intBuf[1] != (intBuf[2] ^ UTL_MEM_HEADER_MASK))
        {
            utlLog_error("memory underflow detected, %d %d", intBuf[1], intBuf[2]);
            utlAst_assert(0);
            return;
        }

#ifdef UTL_MEM_DEBUG
        {
            UINT32 allocSize, intSize, roundupSize, i;
            UINT8 *charBuf = (UINT8 *) buf;

            allocSize = REAL_ALLOC_SIZE(intBuf[1]);
            intSize = allocSize / sizeof(UINTPTR);
            roundupSize = ROUNDUP(intBuf[1]);

            for (i=intBuf[1]; i < roundupSize; i++)
            {
                if (charBuf[i] != (UINT8) (UTL_MEM_FOOTER_PATTERN & 0xff))
                {
                    utlLog_error("memory overflow detected at idx=%d 0x%x 0x%x 0x%x",
                            i, charBuf[i], intBuf[intSize-1], intBuf[intSize-2]);
                    utlAst_assert(0);
                    return;
                }
            }

            if ((intBuf[intSize - 1] != UTL_MEM_FOOTER_PATTERN) ||
                    (intBuf[intSize - 2] != UTL_MEM_FOOTER_PATTERN))
            {
                utlLog_error("memory overflow detected, 0x%x 0x%x",
                        intBuf[intSize - 1], intBuf[intSize - 2]);
                utlAst_assert(0);
                return;
            }

#ifdef UTL_MEM_POISON_ALLOC_FREE
            /*
             * write garbage into buffer which is about to be freed to detect
             * users of freed buffers.
             */
            memset(intBuf, UTL_MEM_FREE_PATTERN, allocSize);
#endif
        }

#endif  /* UTL_MEM_DEBUG */

        buf = intBuf;  /* buf points to real start of buffer */

        osl_free(buf);
        mStats.bytesAllocd -= size;
        mStats.numFrees++;
    }