Skip to content

Instantly share code, notes, and snippets.

@mgeeky
Created December 5, 2016 01:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgeeky/eaa4220eba360135ce40a6dce690bf89 to your computer and use it in GitHub Desktop.
Save mgeeky/eaa4220eba360135ce40a6dce690bf89 to your computer and use it in GitHub Desktop.
Simple utility calculating some basic heap chunk's characteristics like chunk size, bin index and it's range - according to original Doug Lea's heap allocator implementation. Useful while grasping Heap Overflow binning conditions.
// vim: ai:si:ts=2:sw=2
#include <stdio.h>
#define INTERNAL_SIZE_T size_t
#define SIZE_SZ sizeof(INTERNAL_SIZE_T)
#define MINSIZE 2*SIZE_SZ
#define MALLOC_ALIGNMENT ( SIZE_SZ + SIZE_SZ )
#define MALLOC_ALIGN_MASK ( MALLOC_ALIGNMENT - 1 )
#define request2size(req, nb) \
((nb = (req) + (SIZE_SZ + MALLOC_ALIGN_MASK)),\
((long)nb <= 0 || nb < (INTERNAL_SIZE_T) (req) \
? (1) \
: ((nb < (MINSIZE + MALLOC_ALIGN_MASK) \
? (nb = MINSIZE) : (nb &= ~MALLOC_ALIGN_MASK)), 0)))
#define bin_index(sz) \
((((unsigned long)(sz) >> 9) == 0) ? ((unsigned long)(sz) >> 3):\
(((unsigned long)(sz) >> 9) <= 4) ? 56 + ((unsigned long)(sz) >> 6):\
(((unsigned long)(sz) >> 9) <= 20) ? 91 + ((unsigned long)(sz) >> 9):\
(((unsigned long)(sz) >> 9) <= 84) ? 110 + ((unsigned long)(sz) >> 12):\
(((unsigned long)(sz) >> 9) <= 340) ? 119 + ((unsigned long)(sz) >> 15):\
(((unsigned long)(sz) >> 9) <= 1364) ? 124 + ((unsigned long)(sz) >> 18):\
126)
void bin_range(unsigned long sz, unsigned long *bmin, unsigned long *bmax) {
unsigned long d = (unsigned long)(sz) >> 9;
if( d == 0 ) *bmin = ((unsigned long)(sz >> 3) * (1 << 3)), *bmax = (*bmin + (1 << 3));
else if( d <= 4 ) *bmin = ((unsigned long)(sz >> 6) * (1 << 6)), *bmax = (*bmin + (1 << 6));
else if( d <= 20 ) *bmin = ((unsigned long)(sz >> 9) * (1 << 9)), *bmax = (*bmin + (1 << 9));
else if( d <= 84 ) *bmin = ((unsigned long)(sz >> 12) * (1 << 12)), *bmax = (*bmin + (1 << 12));
else if( d <= 340 ) *bmin = ((unsigned long)(sz >> 15) * (1 << 15)), *bmax = (*bmin + (1 << 15));
else if( d <= 1364 ) *bmin = ((unsigned long)(sz >> 18) * (1 << 18)), *bmax = (*bmin + (1 << 18));
else *bmin = 0, *bmax = 0;
}
int main( int argc, char **argv) {
if (argc != 2) {
printf("Usage: %s <size>\n", argv[0]);
return 0;
}
unsigned long size = atoi(argv[1]);
unsigned long nb, min, max;
request2size(size, nb);
bin_range(size, &min, &max);
printf("Request:\t%d\n"
"Size:\t\t%d\n"
"Bin index:\t%d (%d-%d)\n",
size, nb, bin_index(nb), min, max);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment