xref: /netbsd-src/external/gpl2/libmalloc/dist/malloc-find.c (revision 478e07dd80b73ca7b8dd26ada880f65ffb83aad5)
1 /*	$NetBSD: malloc-find.c,v 1.1.1.1 2016/01/13 21:42:18 christos Exp $	*/
2 
3 /* Find the starting address of a malloc'd block, from anywhere inside it.
4    Copyright (C) 1995 Free Software Foundation, Inc.
5 
6 This file is part of the GNU C Library.  Its master source is NOT part of
7 the C library, however.  The master source lives in /gd/gnu/lib.
8 
9 The GNU C Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13 
14 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 Library General Public License for more details.
18 
19 You should have received a copy of the GNU Library General Public
20 License along with the GNU C Library; see the file COPYING.LIB.  If
21 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
22 Cambridge, MA 02139, USA.  */
23 
24 #ifndef	_MALLOC_INTERNAL
25 #define _MALLOC_INTERNAL
26 #include <malloc.h>
27 #endif
28 
29 /* Given an address in the middle of a malloc'd object,
30    return the address of the beginning of the object.  */
31 
32 __ptr_t
malloc_find_object_address(ptr)33 malloc_find_object_address (ptr)
34      __ptr_t ptr;
35 {
36   __malloc_size_t block = BLOCK (ptr);
37   int type = _heapinfo[block].busy.type;
38 
39   if (type == 0)
40     {
41       /* The object is one or more entire blocks.  */
42       __malloc_ptrdiff_t sizevalue = _heapinfo[block].busy.info.size;
43 
44       if (sizevalue < 0)
45 	/* This is one of the blocks after the first.  SIZEVALUE
46 	   says how many blocks to go back to find the first.  */
47 	block += sizevalue;
48 
49       /* BLOCK is now the first block of the object.
50 	 Its start is the start of the object.  */
51       return ADDRESS (block);
52     }
53   else
54     {
55       /* Get the size of fragments in this block.  */
56       __malloc_size_t size = 1 << type;
57 
58       /* Turn off the low bits to find the start address of the fragment.  */
59       return _heapbase + (((char *) ptr - _heapbase) & ~(size - 1));
60     }
61 }
62