[FIX] cherry-pick d89d303d37d714ced2d1a9945ae2ea054c5824c0 (#8:3,4,5) + changes
[platform/core/system/swap-probe.git] / probe_memory / libdamemalloc.c
1 /*
2  *  DA probe
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Jaewon Lim <jaewon81.lim@samsung.com>
9  * Woojin Jung <woojin2.jung@samsung.com>
10  * Juyoung Kim <j0.kim@samsung.com>
11  * Anastasia Lyupa <a.lyupa@samsung.com>
12  * Dmitry Bogatov <d.bogatov@samsung.com>
13  *
14  * This library is free software; you can redistribute it and/or modify it under
15  * the terms of the GNU Lesser General Public License as published by the
16  * Free Software Foundation; either version 2.1 of the License, or (at your option)
17  * any later version.
18  *
19  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
20  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
22  * License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with this library; if not, write to the Free Software Foundation, Inc., 51
26  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  *
28  * Contributors:
29  * - S-Core Co., Ltd
30  * - Samsung RnD Institute Russia
31  *
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <dlfcn.h>
38 #include <stdbool.h>
39 #include <memory.h>
40 #include <errno.h>
41 #include <malloc.h>
42 #include "daprobe.h"
43 #include "probeinfo.h"
44 #include "dacollection.h"
45 #include "dautil.h"
46 #include "da_memory.h"
47 #include "binproto.h"
48
49 static enum DaOptions _sopt = OPT_ALLOC;
50
51 static void* (*saved_malloc_hook)(size_t, const void*);
52 static void* malloc_hook(size_t, const void*);
53 static void* (*saved_realloc_hook)(void*, size_t, const void*);
54 static void* realloc_hook(void*, size_t, const void*);
55 static void (*saved_free_hook)(void*, const void*);
56 static void free_hook(void*, const void*);
57
58 static void install_memory_hooks()
59 {
60   __malloc_hook = malloc_hook;
61   __realloc_hook = realloc_hook;
62   __free_hook = free_hook;
63 }
64 static void teardown_memory_hooks()
65 {
66   __malloc_hook = saved_malloc_hook;
67   __realloc_hook = saved_realloc_hook;
68   __free_hook = saved_free_hook;
69 }
70
71 void memory_initialize_hook(void)
72 {
73   saved_malloc_hook = __malloc_hook;
74   saved_realloc_hook = __realloc_hook;
75   saved_free_hook = __free_hook;
76   install_memory_hooks();
77 }
78
79 static void *malloc_hook(size_t size, const void* caller)
80 {
81         DECLARE_VARIABLE_STANDARD;
82         void *pret;
83
84         teardown_memory_hooks();
85         PRE_PROBEBLOCK();
86
87         pret = malloc(size);
88
89         if(pret != NULL && getTraceState() == 0)
90         {
91                 add_memory_hash(pret, size, MEMTYPE_ALLOC, blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
92         }
93
94         POST_PACK_PROBEBLOCK_BEGIN();
95
96         PREPARE_LOCAL_BUF();
97         PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
98                           API_ID_malloc,
99                           "xp", size, caller);
100         PACK_COMMON_END(pret, newerrno, blockresult);
101         PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
102         FLUSH_LOCAL_BUF();
103
104         POST_PACK_PROBEBLOCK_END();
105
106         install_memory_hooks();
107
108         return pret;
109 }
110
111 static void free_hook(void *ptr, const void *caller)
112 {
113         DECLARE_VARIABLE_STANDARD;
114
115         teardown_memory_hooks();
116
117         PRE_PROBEBLOCK();
118
119         if(ptr != NULL && getTraceState() == 0)
120         {
121                 del_memory_hash(ptr, MEMTYPE_FREE, NULL);
122         }
123
124         free(ptr);
125
126         POST_PACK_PROBEBLOCK_BEGIN();
127
128         PREPARE_LOCAL_BUF();
129         PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
130                           API_ID_free,
131                           "pp", ptr, caller);
132         PACK_COMMON_END(0, newerrno, blockresult);
133         PACK_MEMORY(0, MEMORY_API_FREE, ptr);
134         FLUSH_LOCAL_BUF();
135
136         POST_PACK_PROBEBLOCK_END();
137
138         install_memory_hooks();
139 }
140
141 static void* realloc_hook(void *memblock, size_t size, const void* caller)
142 {
143         DECLARE_VARIABLE_STANDARD;
144         void *pret;
145
146         teardown_memory_hooks();
147
148         PRE_PROBEBLOCK();
149
150         if(memblock != NULL && getTraceState() == 0)
151         {
152                 del_memory_hash(memblock, MEMTYPE_FREE, NULL);
153         }
154
155         pret = realloc(memblock, size);
156
157         if(pret != NULL && getTraceState() == 0)
158         {
159                 add_memory_hash(pret, size, MEMTYPE_ALLOC, blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
160         }
161
162         POST_PACK_PROBEBLOCK_BEGIN();
163
164         PREPARE_LOCAL_BUF();
165         PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
166                           API_ID_realloc,
167                           "pxp", memblock, size, caller);
168         PACK_COMMON_END(pret, newerrno, blockresult);
169         PACK_MEMORY(size, MEMORY_API_ALLOC, pret);
170         FLUSH_LOCAL_BUF();
171
172         POST_PACK_PROBEBLOCK_END();
173
174         install_memory_hooks();
175
176         return pret;
177 }
178
179 static inline void adhoc_bzero(char *p, size_t size)
180 {
181         int index;
182         for (index = 0; index != size; index++)
183                 p[index] = '\0';
184 }
185
186 void *calloc(size_t nelem, size_t elsize)
187 {
188         DECLARE_VARIABLE_STANDARD;
189         void *pret;
190         size_t size = nelem * elsize;
191         PRE_PROBEBLOCK();
192
193         pret = (size < elsize) ? NULL : malloc(size);
194         if (pret) /* `memset' somewhy deadloops */
195                 adhoc_bzero(pret, nelem * elsize);
196
197         if(pret != NULL && getTraceState() == 0)
198         {
199                 add_memory_hash(pret, nelem * elsize, MEMTYPE_ALLOC, blockresult ? MEM_EXTERNAL : MEM_INTERNAL);
200     }
201
202         POST_PACK_PROBEBLOCK_BEGIN();
203
204         PREPARE_LOCAL_BUF();
205         PACK_COMMON_BEGIN(MSG_PROBE_MEMORY,
206                           API_ID_calloc,
207                           "xx", nelem, elsize);
208         PACK_COMMON_END(pret, newerrno, blockresult);
209         PACK_MEMORY(nelem * elsize, MEMORY_API_ALLOC, pret);
210         FLUSH_LOCAL_BUF();
211
212         POST_PACK_PROBEBLOCK_END();
213
214
215         return pret;
216 }