1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28: static Void_t*
29: #if __STD_C
30: malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
31: #else
32: malloc_hook_ini(sz, caller)
33: size_t sz; const __malloc_ptr_t caller;
34: #endif
35: {
36: __malloc_hook = NULL;
37: ptmalloc_init();
38: return public_mALLOc(sz);
39: }
40:
41: static Void_t*
42: #if __STD_C
43: realloc_hook_ini(Void_t* ptr, size_t sz, const __malloc_ptr_t caller)
44: #else
45: realloc_hook_ini(ptr, sz, caller)
46: Void_t* ptr; size_t sz; const __malloc_ptr_t caller;
47: #endif
48: {
49: __malloc_hook = NULL;
50: __realloc_hook = NULL;
51: ptmalloc_init();
52: return public_rEALLOc(ptr, sz);
53: }
54:
55: static Void_t*
56: #if __STD_C
57: memalign_hook_ini(size_t alignment, size_t sz, const __malloc_ptr_t caller)
58: #else
59: memalign_hook_ini(alignment, sz, caller)
60: size_t alignment; size_t sz; const __malloc_ptr_t caller;
61: #endif
62: {
63: __memalign_hook = NULL;
64: ptmalloc_init();
65: return public_mEMALIGn(alignment, sz);
66: }
67:
68:
69: static int using_malloc_checking;
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84: static int disallow_malloc_check;
85:
86:
87: void
88: __malloc_check_init()
89: {
90: if (disallow_malloc_check) {
91: disallow_malloc_check = 0;
92: return;
93: }
94: using_malloc_checking = 1;
95: __malloc_hook = malloc_check;
96: __free_hook = free_check;
97: __realloc_hook = realloc_check;
98: __memalign_hook = memalign_check;
99: if(check_action & 1)
100: malloc_printerr (5, "malloc: using debugging hooks", NULL);
101: }
102:
103:
104:
105:
106:
107:
108: #define MAGICBYTE(p) ( ( ((size_t)p >> 3) ^ ((size_t)p >> 11)) & 0xFF )
109:
110:
111:
112:
113: static Void_t*
114: internal_function
115: #if __STD_C
116: mem2mem_check(Void_t *ptr, size_t sz)
117: #else
118: mem2mem_check(ptr, sz) Void_t *ptr; size_t sz;
119: #endif
120: {
121: mchunkptr p;
122: unsigned char* m_ptr = (unsigned char*)BOUNDED_N(ptr, sz);
123: size_t i;
124:
125: if (!ptr)
126: return ptr;
127: p = mem2chunk(ptr);
128: for(i = chunksize(p) - (chunk_is_mmapped(p) ? 2*SIZE_SZ+1 : SIZE_SZ+1);
129: i > sz;
130: i -= 0xFF) {
131: if(i-sz < 0x100) {
132: m_ptr[i] = (unsigned char)(i-sz);
133: break;
134: }
135: m_ptr[i] = 0xFF;
136: }
137: m_ptr[sz] = MAGICBYTE(p);
138: return (Void_t*)m_ptr;
139: }
140:
141:
142:
143:
144: static mchunkptr
145: internal_function
146: #if __STD_C
147: mem2chunk_check(Void_t* mem, unsigned char **magic_p)
148: #else
149: mem2chunk_check(mem, magic_p) Void_t* mem; unsigned char **magic_p;
150: #endif
151: {
152: mchunkptr p;
153: INTERNAL_SIZE_T sz, c;
154: unsigned char magic;
155:
156: if(!aligned_OK(mem)) return NULL;
157: p = mem2chunk(mem);
158: if (!chunk_is_mmapped(p)) {
159:
160: int contig = contiguous(&main_arena);
161: sz = chunksize(p);
162: if((contig &&
163: ((char*)p<mp_.sbrk_base ||
164: ((char*)p + sz)>=(mp_.sbrk_base+main_arena.system_mem) )) ||
165: sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) ||
166: ( !prev_inuse(p) && (p->prev_size&MALLOC_ALIGN_MASK ||
167: (contig && (char*)prev_chunk(p)<mp_.sbrk_base) ||
168: next_chunk(prev_chunk(p))!=p) ))
169: return NULL;
170: magic = MAGICBYTE(p);
171: for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
172: if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
173: }
174: } else {
175: unsigned long offset, page_mask = malloc_getpagesize-1;
176:
177:
178:
179:
180: offset = (unsigned long)mem & page_mask;
181: if((offset!=MALLOC_ALIGNMENT && offset!=0 && offset!=0x10 &&
182: offset!=0x20 && offset!=0x40 && offset!=0x80 && offset!=0x100 &&
183: offset!=0x200 && offset!=0x400 && offset!=0x800 && offset!=0x1000 &&
184: offset<0x2000) ||
185: !chunk_is_mmapped(p) || (p->size & PREV_INUSE) ||
186: ( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) ||
187: ( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) )
188: return NULL;
189: magic = MAGICBYTE(p);
190: for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
191: if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
192: }
193: }
194: ((unsigned char*)p)[sz] ^= 0xFF;
195: if (magic_p)
196: *magic_p = (unsigned char *)p + sz;
197: return p;
198: }
199:
200:
201:
202:
203: static int
204: internal_function
205: #if __STD_C
206: top_check(void)
207: #else
208: top_check()
209: #endif
210: {
211: mchunkptr t = top(&main_arena);
212: char* brk, * new_brk;
213: INTERNAL_SIZE_T front_misalign, sbrk_size;
214: unsigned long pagesz = malloc_getpagesize;
215:
216: if (t == initial_top(&main_arena) ||
217: (!chunk_is_mmapped(t) &&
218: chunksize(t)>=MINSIZE &&
219: prev_inuse(t) &&
220: (!contiguous(&main_arena) ||
221: (char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem)))
222: return 0;
223:
224: malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
225:
226:
227: brk = MORECORE(0);
228: front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK;
229: if (front_misalign > 0)
230: front_misalign = MALLOC_ALIGNMENT - front_misalign;
231: sbrk_size = front_misalign + mp_.top_pad + MINSIZE;
232: sbrk_size += pagesz - ((unsigned long)(brk + sbrk_size) & (pagesz - 1));
233: new_brk = (char*)(MORECORE (sbrk_size));
234: if (new_brk == (char*)(MORECORE_FAILURE))
235: {
236: MALLOC_FAILURE_ACTION;
237: return -1;
238: }
239:
240: if (__after_morecore_hook)
241: (*__after_morecore_hook) ();
242: main_arena.system_mem = (new_brk - mp_.sbrk_base) + sbrk_size;
243:
244: top(&main_arena) = (mchunkptr)(brk + front_misalign);
245: set_head(top(&main_arena), (sbrk_size - front_misalign) | PREV_INUSE);
246:
247: return 0;
248: }
249:
250: static Void_t*
251: #if __STD_C
252: malloc_check(size_t sz, const Void_t *caller)
253: #else
254: malloc_check(sz, caller) size_t sz; const Void_t *caller;
255: #endif
256: {
257: Void_t *victim;
258:
259: if (sz+1 == 0) {
260: MALLOC_FAILURE_ACTION;
261: return NULL;
262: }
263:
264: (void)mutex_lock(&main_arena.mutex);
265: victim = (top_check() >= 0) ? _int_malloc(&main_arena, sz+1) : NULL;
266: (void)mutex_unlock(&main_arena.mutex);
267: return mem2mem_check(victim, sz);
268: }
269:
270: static void
271: #if __STD_C
272: free_check(Void_t* mem, const Void_t *caller)
273: #else
274: free_check(mem, caller) Void_t* mem; const Void_t *caller;
275: #endif
276: {
277: mchunkptr p;
278:
279: if(!mem) return;
280: (void)mutex_lock(&main_arena.mutex);
281: p = mem2chunk_check(mem, NULL);
282: if(!p) {
283: (void)mutex_unlock(&main_arena.mutex);
284:
285: malloc_printerr(check_action, "free(): invalid pointer", mem);
286: return;
287: }
288: #if HAVE_MMAP
289: if (chunk_is_mmapped(p)) {
290: (void)mutex_unlock(&main_arena.mutex);
291: munmap_chunk(p);
292: return;
293: }
294: #endif
295: #if 0
296: memset(mem, 0, chunksize(p) - (SIZE_SZ+1));
297: #endif
298: _int_free(&main_arena, mem);
299: (void)mutex_unlock(&main_arena.mutex);
300: }
301:
302: static Void_t*
303: #if __STD_C
304: realloc_check(Void_t* oldmem, size_t bytes, const Void_t *caller)
305: #else
306: realloc_check(oldmem, bytes, caller)
307: Void_t* oldmem; size_t bytes; const Void_t *caller;
308: #endif
309: {
310: mchunkptr oldp;
311: INTERNAL_SIZE_T nb, oldsize;
312: Void_t* newmem = 0;
313: unsigned char *magic_p;
314:
315: if (bytes+1 == 0) {
316: MALLOC_FAILURE_ACTION;
317: return NULL;
318: }
319: if (oldmem == 0) return malloc_check(bytes, NULL);
320: if (bytes == 0) {
321: free_check (oldmem, NULL);
322: return NULL;
323: }
324: (void)mutex_lock(&main_arena.mutex);
325: oldp = mem2chunk_check(oldmem, &magic_p);
326: (void)mutex_unlock(&main_arena.mutex);
327: if(!oldp) {
328: malloc_printerr(check_action, "realloc(): invalid pointer", oldmem);
329: return malloc_check(bytes, NULL);
330: }
331: oldsize = chunksize(oldp);
332:
333: checked_request2size(bytes+1, nb);
334: (void)mutex_lock(&main_arena.mutex);
335:
336: #if HAVE_MMAP
337: if (chunk_is_mmapped(oldp)) {
338: #if HAVE_MREMAP
339: mchunkptr newp = mremap_chunk(oldp, nb);
340: if(newp)
341: newmem = chunk2mem(newp);
342: else
343: #endif
344: {
345:
346: if(oldsize - SIZE_SZ >= nb)
347: newmem = oldmem;
348: else {
349:
350: if (top_check() >= 0)
351: newmem = _int_malloc(&main_arena, bytes+1);
352: if (newmem) {
353: MALLOC_COPY(BOUNDED_N(newmem, bytes+1), oldmem, oldsize - 2*SIZE_SZ);
354: munmap_chunk(oldp);
355: }
356: }
357: }
358: } else {
359: #endif
360: if (top_check() >= 0)
361: newmem = _int_realloc(&main_arena, oldmem, bytes+1);
362: #if 0
363: if(newmem)
364: newp = mem2chunk(newmem);
365: nb = chunksize(newp);
366: if(oldp<newp || oldp>=chunk_at_offset(newp, nb)) {
367: memset((char*)oldmem + 2*sizeof(mbinptr), 0,
368: oldsize - (2*sizeof(mbinptr)+2*SIZE_SZ+1));
369: } else if(nb > oldsize+SIZE_SZ) {
370: memset((char*)BOUNDED_N(chunk2mem(newp), bytes) + oldsize,
371: 0, nb - (oldsize+SIZE_SZ));
372: }
373: #endif
374: #if HAVE_MMAP
375: }
376: #endif
377:
378:
379:
380:
381: if (newmem == NULL) *magic_p ^= 0xFF;
382:
383: (void)mutex_unlock(&main_arena.mutex);
384:
385: return mem2mem_check(newmem, bytes);
386: }
387:
388: static Void_t*
389: #if __STD_C
390: memalign_check(size_t alignment, size_t bytes, const Void_t *caller)
391: #else
392: memalign_check(alignment, bytes, caller)
393: size_t alignment; size_t bytes; const Void_t *caller;
394: #endif
395: {
396: INTERNAL_SIZE_T nb;
397: Void_t* mem;
398:
399: if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL);
400: if (alignment < MINSIZE) alignment = MINSIZE;
401:
402: if (bytes+1 == 0) {
403: MALLOC_FAILURE_ACTION;
404: return NULL;
405: }
406: checked_request2size(bytes+1, nb);
407: (void)mutex_lock(&main_arena.mutex);
408: mem = (top_check() >= 0) ? _int_memalign(&main_arena, alignment, bytes+1) :
409: NULL;
410: (void)mutex_unlock(&main_arena.mutex);
411: return mem2mem_check(mem, bytes);
412: }
413:
414: #ifndef NO_THREADS
415:
416: # ifdef _LIBC
417: # if USE___THREAD || !defined SHARED
418:
419: # define NO_STARTER
420: # endif
421: # endif
422:
423: # ifdef NO_STARTER
424: # undef NO_STARTER
425: # else
426:
427:
428:
429:
430: static Void_t*
431: #if __STD_C
432: malloc_starter(size_t sz, const Void_t *caller)
433: #else
434: malloc_starter(sz, caller) size_t sz; const Void_t *caller;
435: #endif
436: {
437: Void_t* victim;
438:
439: victim = _int_malloc(&main_arena, sz);
440:
441: return victim ? BOUNDED_N(victim, sz) : 0;
442: }
443:
444: static Void_t*
445: #if __STD_C
446: memalign_starter(size_t align, size_t sz, const Void_t *caller)
447: #else
448: memalign_starter(align, sz, caller) size_t align, sz; const Void_t *caller;
449: #endif
450: {
451: Void_t* victim;
452:
453: victim = _int_memalign(&main_arena, align, sz);
454:
455: return victim ? BOUNDED_N(victim, sz) : 0;
456: }
457:
458: static void
459: #if __STD_C
460: free_starter(Void_t* mem, const Void_t *caller)
461: #else
462: free_starter(mem, caller) Void_t* mem; const Void_t *caller;
463: #endif
464: {
465: mchunkptr p;
466:
467: if(!mem) return;
468: p = mem2chunk(mem);
469: #if HAVE_MMAP
470: if (chunk_is_mmapped(p)) {
471: munmap_chunk(p);
472: return;
473: }
474: #endif
475: _int_free(&main_arena, mem);
476: }
477:
478: # endif
479: #endif
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498: #define MALLOC_STATE_MAGIC 0x444c4541l
499: #define MALLOC_STATE_VERSION (0*0x100l + 3l)
500:
501: struct malloc_save_state {
502: long magic;
503: long version;
504: mbinptr av[NBINS * 2 + 2];
505: char* sbrk_base;
506: int sbrked_mem_bytes;
507: unsigned long trim_threshold;
508: unsigned long top_pad;
509: unsigned int n_mmaps_max;
510: unsigned long mmap_threshold;
511: int check_action;
512: unsigned long max_sbrked_mem;
513: unsigned long max_total_mem;
514: unsigned int n_mmaps;
515: unsigned int max_n_mmaps;
516: unsigned long mmapped_mem;
517: unsigned long max_mmapped_mem;
518: int using_malloc_checking;
519: };
520:
521: Void_t*
522: public_gET_STATe(void)
523: {
524: struct malloc_save_state* ms;
525: int i;
526: mbinptr b;
527:
528: ms = (struct malloc_save_state*)public_mALLOc(sizeof(*ms));
529: if (!ms)
530: return 0;
531: (void)mutex_lock(&main_arena.mutex);
532: malloc_consolidate(&main_arena);
533: ms->magic = MALLOC_STATE_MAGIC;
534: ms->version = MALLOC_STATE_VERSION;
535: ms->av[0] = 0;
536: ms->av[1] = 0;
537: ms->av[2] = top(&main_arena);
538: ms->av[3] = 0;
539: for(i=1; i<NBINS; i++) {
540: b = bin_at(&main_arena, i);
541: if(first(b) == b)
542: ms->av[2*i+2] = ms->av[2*i+3] = 0;
543: else {
544: ms->av[2*i+2] = first(b);
545: ms->av[2*i+3] = last(b);
546: }
547: }
548: ms->sbrk_base = mp_.sbrk_base;
549: ms->sbrked_mem_bytes = main_arena.system_mem;
550: ms->trim_threshold = mp_.trim_threshold;
551: ms->top_pad = mp_.top_pad;
552: ms->n_mmaps_max = mp_.n_mmaps_max;
553: ms->mmap_threshold = mp_.mmap_threshold;
554: ms->check_action = check_action;
555: ms->max_sbrked_mem = main_arena.max_system_mem;