1/*	$NetBSD: debugrm.c,v 1.4 2018/04/01 22:35:22 christos Exp $	*/
2
3/*	$KAME: debugrm.c,v 1.6 2001/12/13 16:07:46 sakane Exp $	*/
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#define NONEED_DRM
35
36#include "config.h"
37
38#include <sys/types.h>
39#include <sys/param.h>
40
41#include <stdio.h>
42#include <string.h>
43#include <stdlib.h>
44#include <time.h>
45#include <err.h>
46
47#include "debugrm.h"
48
49#include "vmbuf.h"	/* need to mask vmbuf.c functions. */
50
51#define DRMLISTSIZE 1024
52
53struct drm_list_t {
54	const void *ptr;
55	char msg[100];
56};
57static struct drm_list_t drmlist[DRMLISTSIZE];
58
59static int drm_unknown;
60
61static void DRM_add(const void *, const char *);
62static void DRM_del(const void *);
63static void DRM_setmsg(char *, size_t, const void *, size_t, const char *,
64    size_t, const char *);
65
66void
67DRM_init(void)
68{
69	size_t i;
70	drm_unknown = 0;
71	for (i = 0; i < __arraycount(drmlist); i++)
72		drmlist[i].ptr = 0;
73}
74
75void
76DRM_dump(void)
77{
78	FILE *fp;
79	size_t i;
80
81	fp = fopen(DRMDUMPFILE, "w");
82	if (fp == NULL)
83		err(1, "fopen");	/*XXX*/
84	fprintf(fp, "drm_unknown=%d\n", drm_unknown);
85	for (i = 0; i < __arraycount(drmlist); i++) {
86		if (drmlist[i].ptr)
87			fprintf(fp, "%s\n", drmlist[i].msg);
88	}
89	fclose(fp);
90}
91
92static void
93DRM_add(const void *p, const char *msg)
94{
95	size_t i;
96	for (i = 0; i < __arraycount(drmlist); i++) {
97		if (!drmlist[i].ptr) {
98			drmlist[i].ptr = p;
99			strlcpy(drmlist[i].msg, msg, sizeof(drmlist[i].msg));
100			return;
101		}
102	}
103}
104
105static void
106DRM_del(const void *p)
107{
108	size_t i;
109
110	if (!p)
111		return;
112
113	for (i = 0; i < __arraycount(drmlist); i++) {
114		if (drmlist[i].ptr == p) {
115			drmlist[i].ptr = 0;
116			return;
117		}
118	}
119	drm_unknown++;
120}
121
122static void
123DRM_setmsg(char *buf, size_t buflen, const void *ptr, size_t size,
124    const char *file, size_t line, const char *func)
125{
126	time_t t;
127	struct tm *tm;
128	int len;
129
130	t = time(NULL);
131	tm = localtime(&t);
132	len = strftime(buf, buflen, "%Y/%m/%d:%T ", tm);
133
134	snprintf(buf + len, buflen - len, "%p %6d %s:%d:%s",
135		ptr, size, file, line, func);
136}
137
138void *
139DRM_malloc(const char *file, size_t line, const char *func, size_t size)
140{
141	void *p;
142
143	p = malloc(size);
144	if (p) {
145		char buf[1024];
146		DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
147		DRM_add(p, buf);
148	}
149
150	return p;
151}
152
153void *
154DRM_calloc(const char *file, size_t line, const char *func, size_t number,
155    size_t size)
156{
157	void *p;
158
159	p = calloc(number, size);
160	if (p) {
161		char buf[1024];
162		DRM_setmsg(buf, sizeof(buf), p, number * size, file, line, func);
163		DRM_add(p, buf);
164	}
165	return p;
166}
167
168void *
169DRM_realloc(const char *file, size_t line, const char *func, void *ptr,
170    size_t size)
171{
172	void *p;
173
174	p = realloc(ptr, size);
175	if (p) {
176		char buf[1024];
177		if (ptr && p != ptr) {
178			DRM_del(ptr);
179			DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
180			DRM_add(p, buf);
181		}
182	}
183
184	return p;
185}
186
187void
188DRM_free(const char *file, size_t line, const char *func, void *ptr)
189{
190	DRM_del(ptr);
191	free(ptr);
192}
193
194char *
195DRM_strdup(const char *file, size_t line, const char *func, const char *str)
196{
197	char *p;
198
199	p = strdup(str);
200
201	if (p) {
202		char buf[1024];
203		DRM_setmsg(buf, sizeof(buf), p, strlen(p), file, line, func);
204		DRM_add(p, buf);
205	}
206
207	return p;
208}
209
210/*
211 * mask vmbuf.c functions.
212 */
213void *
214DRM_vmalloc(const char *file, size_t line, const char *func, size_t size)
215{
216	void *p;
217
218	p = vmalloc(size);
219	if (p) {
220		char buf[1024];
221		DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
222		DRM_add(p, buf);
223	}
224
225	return p;
226}
227
228void *
229DRM_vrealloc(const char *file, size_t line, const char *func, void *ptr,
230    size_t size)
231{
232	void *p;
233
234	p = vrealloc(ptr, size);
235	if (p) {
236		char buf[1024];
237		if (ptr && p != ptr) {
238			DRM_del(ptr);
239			DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
240			DRM_add(p, buf);
241		}
242	}
243
244	return p;
245}
246
247void
248DRM_vfree(const char *file, size_t line, const char *func, void *ptr)
249{
250	DRM_del(ptr);
251	vfree(ptr);
252}
253
254void *
255DRM_vdup(const char *file, size_t line, const char *func, void *ptr)
256{
257	void *p;
258
259	p = vdup(ptr);
260	if (p) {
261		char buf[1024];
262		DRM_setmsg(buf, sizeof(buf), p, 0, file, line, func);
263		DRM_add(p, buf);
264	}
265
266	return p;
267}
268