"Fossies" - the Fresh Open Source Software Archive

Member "hashcat-6.2.6/deps/LZMA-SDK/C/Alloc.c" (2 Sep 2022, 10236 Bytes) of package /linux/privat/hashcat-6.2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "Alloc.c": 6.2.2_vs_6.2.3.

    1 /* Alloc.c -- Memory allocation functions
    2 2020-10-29 : Igor Pavlov : Public domain */
    3 
    4 #include "Precomp.h"
    5 
    6 #include <stdio.h>
    7 
    8 #ifdef _WIN32
    9 #include <windows.h>
   10 #endif
   11 #include <stdlib.h>
   12 
   13 #include "Alloc.h"
   14 
   15 /* #define _SZ_ALLOC_DEBUG */
   16 
   17 /* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
   18 #ifdef _SZ_ALLOC_DEBUG
   19 
   20 #include <stdio.h>
   21 int g_allocCount = 0;
   22 int g_allocCountMid = 0;
   23 int g_allocCountBig = 0;
   24 
   25 
   26 #define CONVERT_INT_TO_STR(charType, tempSize) \
   27   unsigned char temp[tempSize]; unsigned i = 0; \
   28   while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
   29   *s++ = (charType)('0' + (unsigned)val); \
   30   while (i != 0) { i--; *s++ = temp[i]; } \
   31   *s = 0;
   32 
   33 static void ConvertUInt64ToString(UInt64 val, char *s)
   34 {
   35   CONVERT_INT_TO_STR(char, 24);
   36 }
   37 
   38 #define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
   39 
   40 static void ConvertUInt64ToHex(UInt64 val, char *s)
   41 {
   42   UInt64 v = val;
   43   unsigned i;
   44   for (i = 1;; i++)
   45   {
   46     v >>= 4;
   47     if (v == 0)
   48       break;
   49   }
   50   s[i] = 0;
   51   do
   52   {
   53     unsigned t = (unsigned)(val & 0xF);
   54     val >>= 4;
   55     s[--i] = GET_HEX_CHAR(t);
   56   }
   57   while (i);
   58 }
   59 
   60 #define DEBUG_OUT_STREAM stderr
   61 
   62 static void Print(const char *s)
   63 {
   64   fputs(s, DEBUG_OUT_STREAM);
   65 }
   66 
   67 static void PrintAligned(const char *s, size_t align)
   68 {
   69   size_t len = strlen(s);
   70   for(;;)
   71   {
   72     fputc(' ', DEBUG_OUT_STREAM);
   73     if (len >= align)
   74       break;
   75     ++len;
   76   }
   77   Print(s);
   78 }
   79 
   80 static void PrintLn()
   81 {
   82   Print("\n");
   83 }
   84 
   85 static void PrintHex(UInt64 v, size_t align)
   86 {
   87   char s[32];
   88   ConvertUInt64ToHex(v, s);
   89   PrintAligned(s, align);
   90 }
   91 
   92 static void PrintDec(UInt64 v, size_t align)
   93 {
   94   char s[32];
   95   ConvertUInt64ToString(v, s);
   96   PrintAligned(s, align);
   97 }
   98 
   99 static void PrintAddr(void *p)
  100 {
  101   PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12);
  102 }
  103 
  104 
  105 #define PRINT_ALLOC(name, cnt, size, ptr) \
  106     Print(name " "); \
  107     PrintDec(cnt++, 10); \
  108     PrintHex(size, 10); \
  109     PrintAddr(ptr); \
  110     PrintLn();
  111  
  112 #define PRINT_FREE(name, cnt, ptr) if (ptr) { \
  113     Print(name " "); \
  114     PrintDec(--cnt, 10); \
  115     PrintAddr(ptr); \
  116     PrintLn(); }
  117  
  118 #else
  119 
  120 #define PRINT_ALLOC(name, cnt, size, ptr)
  121 #define PRINT_FREE(name, cnt, ptr)
  122 #define Print(s)
  123 #define PrintLn()
  124 #define PrintHex(v, align)
  125 #define PrintAddr(p)
  126 
  127 #endif
  128 
  129 
  130 
  131 void *MyAlloc(size_t size)
  132 {
  133   if (size == 0)
  134     return NULL;
  135   PRINT_ALLOC("Alloc    ", g_allocCount, size, NULL);
  136   #ifdef _SZ_ALLOC_DEBUG
  137   {
  138     void *p = malloc(size);
  139     // PRINT_ALLOC("Alloc    ", g_allocCount, size, p);
  140     return p;
  141   }
  142   #else
  143   return malloc(size);
  144   #endif
  145 }
  146 
  147 void MyFree(void *address)
  148 {
  149   PRINT_FREE("Free    ", g_allocCount, address);
  150   
  151   free(address);
  152 }
  153 
  154 #ifdef _WIN32
  155 
  156 void *MidAlloc(size_t size)
  157 {
  158   if (size == 0)
  159     return NULL;
  160   
  161   PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
  162   
  163   return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
  164 }
  165 
  166 void MidFree(void *address)
  167 {
  168   PRINT_FREE("Free-Mid", g_allocCountMid, address);
  169 
  170   if (!address)
  171     return;
  172   VirtualFree(address, 0, MEM_RELEASE);
  173 }
  174 
  175 #ifdef _7ZIP_LARGE_PAGES
  176 
  177 #ifdef MEM_LARGE_PAGES
  178   #define MY__MEM_LARGE_PAGES  MEM_LARGE_PAGES
  179 #else
  180   #define MY__MEM_LARGE_PAGES  0x20000000
  181 #endif
  182 
  183 extern
  184 SIZE_T g_LargePageSize;
  185 SIZE_T g_LargePageSize = 0;
  186 typedef SIZE_T (WINAPI *GetLargePageMinimumP)(VOID);
  187 
  188 #endif // _7ZIP_LARGE_PAGES
  189 
  190 void SetLargePageSize()
  191 {
  192   #ifdef _7ZIP_LARGE_PAGES
  193   SIZE_T size;
  194   GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
  195         GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
  196   if (!largePageMinimum)
  197     return;
  198   size = largePageMinimum();
  199   if (size == 0 || (size & (size - 1)) != 0)
  200     return;
  201   g_LargePageSize = size;
  202   #endif
  203 }
  204 
  205 
  206 void *BigAlloc(size_t size)
  207 {
  208   if (size == 0)
  209     return NULL;
  210 
  211   PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
  212   
  213   #ifdef _7ZIP_LARGE_PAGES
  214   {
  215     SIZE_T ps = g_LargePageSize;
  216     if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
  217     {
  218       size_t size2;
  219       ps--;
  220       size2 = (size + ps) & ~ps;
  221       if (size2 >= size)
  222       {
  223         void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MY__MEM_LARGE_PAGES, PAGE_READWRITE);
  224         if (res)
  225           return res;
  226       }
  227     }
  228   }
  229   #endif
  230 
  231   return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
  232 }
  233 
  234 void BigFree(void *address)
  235 {
  236   PRINT_FREE("Free-Big", g_allocCountBig, address);
  237   
  238   if (!address)
  239     return;
  240   VirtualFree(address, 0, MEM_RELEASE);
  241 }
  242 
  243 #endif
  244 
  245 
  246 static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
  247 static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
  248 const ISzAlloc g_Alloc = { SzAlloc, SzFree };
  249 
  250 static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); }
  251 static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); }
  252 const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
  253 
  254 static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
  255 static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
  256 const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
  257 
  258 
  259 /*
  260   uintptr_t : <stdint.h> C99 (optional)
  261             : unsupported in VS6
  262 */
  263 
  264 #ifdef _WIN32
  265   typedef UINT_PTR UIntPtr;
  266 #else
  267   /*
  268   typedef uintptr_t UIntPtr;
  269   */
  270   typedef ptrdiff_t UIntPtr;
  271 #endif
  272 
  273 
  274 #define ADJUST_ALLOC_SIZE 0
  275 /*
  276 #define ADJUST_ALLOC_SIZE (sizeof(void *) - 1)
  277 */
  278 /*
  279   Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if
  280      MyAlloc() can return address that is NOT multiple of sizeof(void *).
  281 */
  282 
  283 
  284 /*
  285 #define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
  286 */
  287 #define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
  288 
  289 
  290 #if !defined(_WIN32) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)
  291   #define USE_posix_memalign
  292 #endif
  293 
  294 #ifndef USE_posix_memalign
  295 #define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
  296 #endif
  297 
  298 /*
  299   This posix_memalign() is for test purposes only.
  300   We also need special Free() function instead of free(),
  301   if this posix_memalign() is used.
  302 */
  303 
  304 /*
  305 static int posix_memalign(void **ptr, size_t align, size_t size)
  306 {
  307   size_t newSize = size + align;
  308   void *p;
  309   void *pAligned;
  310   *ptr = NULL;
  311   if (newSize < size)
  312     return 12; // ENOMEM
  313   p = MyAlloc(newSize);
  314   if (!p)
  315     return 12; // ENOMEM
  316   pAligned = MY_ALIGN_PTR_UP_PLUS(p, align);
  317   ((void **)pAligned)[-1] = p;
  318   *ptr = pAligned;
  319   return 0;
  320 }
  321 */
  322 
  323 /*
  324   ALLOC_ALIGN_SIZE >= sizeof(void *)
  325   ALLOC_ALIGN_SIZE >= cache_line_size
  326 */
  327 
  328 #define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
  329 
  330 static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
  331 {
  332   #ifndef USE_posix_memalign
  333   
  334   void *p;
  335   void *pAligned;
  336   size_t newSize;
  337   UNUSED_VAR(pp);
  338 
  339   /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
  340      block to prevent cache line sharing with another allocated blocks */
  341 
  342   newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE;
  343   if (newSize < size)
  344     return NULL;
  345 
  346   p = MyAlloc(newSize);
  347   
  348   if (!p)
  349     return NULL;
  350   pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE);
  351 
  352   Print(" size="); PrintHex(size, 8);
  353   Print(" a_size="); PrintHex(newSize, 8);
  354   Print(" ptr="); PrintAddr(p);
  355   Print(" a_ptr="); PrintAddr(pAligned);
  356   PrintLn();
  357 
  358   ((void **)pAligned)[-1] = p;
  359 
  360   return pAligned;
  361 
  362   #else
  363 
  364   void *p;
  365   UNUSED_VAR(pp);
  366   if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
  367     return NULL;
  368 
  369   Print(" posix_memalign="); PrintAddr(p);
  370   PrintLn();
  371 
  372   return p;
  373 
  374   #endif
  375 }
  376 
  377 
  378 static void SzAlignedFree(ISzAllocPtr pp, void *address)
  379 {
  380   UNUSED_VAR(pp);
  381   #ifndef USE_posix_memalign
  382   if (address)
  383     MyFree(((void **)address)[-1]);
  384   #else
  385   free(address);
  386   #endif
  387 }
  388 
  389 
  390 const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
  391 
  392 
  393 
  394 #define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
  395 
  396 /* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
  397 #define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
  398 /*
  399 #define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
  400 */
  401 
  402 static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
  403 {
  404   CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
  405   void *adr;
  406   void *pAligned;
  407   size_t newSize;
  408   size_t extra;
  409   size_t alignSize = (size_t)1 << p->numAlignBits;
  410 
  411   if (alignSize < sizeof(void *))
  412     alignSize = sizeof(void *);
  413   
  414   if (p->offset >= alignSize)
  415     return NULL;
  416 
  417   /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
  418      block to prevent cache line sharing with another allocated blocks */
  419   extra = p->offset & (sizeof(void *) - 1);
  420   newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE;
  421   if (newSize < size)
  422     return NULL;
  423 
  424   adr = ISzAlloc_Alloc(p->baseAlloc, newSize);
  425   
  426   if (!adr)
  427     return NULL;
  428 
  429   pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
  430       alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
  431 
  432   PrintLn();
  433   Print("- Aligned: ");
  434   Print(" size="); PrintHex(size, 8);
  435   Print(" a_size="); PrintHex(newSize, 8);
  436   Print(" ptr="); PrintAddr(adr);
  437   Print(" a_ptr="); PrintAddr(pAligned);
  438   PrintLn();
  439 
  440   REAL_BLOCK_PTR_VAR(pAligned) = adr;
  441 
  442   return pAligned;
  443 }
  444 
  445 
  446 static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
  447 {
  448   if (address)
  449   {
  450     CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
  451     PrintLn();
  452     Print("- Aligned Free: ");
  453     PrintLn();
  454     ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
  455   }
  456 }
  457 
  458 
  459 void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p)
  460 {
  461   p->vt.Alloc = AlignOffsetAlloc_Alloc;
  462   p->vt.Free = AlignOffsetAlloc_Free;
  463 }