util.c revision 1.7
1107852Ssam/*	$OpenBSD: util.c,v 1.7 2002/07/24 00:13:55 deraadt Exp $	*/
2112394Ssam
3112394Ssam/*
4112394Ssam * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
5112394Ssam *
6112394Ssam * Redistribution and use in source and binary forms, with or without
7112394Ssam * modification, are permitted provided that the following conditions
8112394Ssam * are met:
9112394Ssam * 1. Redistributions of source code must retain the above copyright
10112394Ssam *    notice, this list of conditions and the following disclaimer.
11112394Ssam * 2. Redistributions in binary form must reproduce the above copyright
12112394Ssam *    notice, this list of conditions and the following disclaimer in the
13112394Ssam *    documentation and/or other materials provided with the distribution.
14112394Ssam * 3. All advertising materials mentioning features or use of this software
15112394Ssam *    must display the following acknowledgement:
16112394Ssam *	This product includes software developed under OpenBSD by
17112394Ssam *	Per Fogelstrom, Opsycon AB, Sweden.
18112394Ssam * 4. The name of the author may not be used to endorse or promote products
19112394Ssam *    derived from this software without specific prior written permission.
20112394Ssam *
21112394Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22112394Ssam * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23112394Ssam * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24112394Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25112394Ssam * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26112394Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27107852Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28134911Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29117852Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30123261Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31107852Ssam * SUCH DAMAGE.
32107852Ssam *
33107852Ssam */
34112394Ssam
35108833Ssam#include <sys/types.h>
36108833Ssam#include <sys/mman.h>
37108833Ssam#include <string.h>
38112394Ssam#include "archdep.h"
39108833Ssam
40108833Ssam/*
41108833Ssam * Static vars usable after bootstrapping.
42112394Ssam */
43112098Ssamstatic void *_dl_malloc_base;
44112098Ssamstatic void *_dl_malloc_pool = 0;
45112098Ssamstatic long *_dl_malloc_free = 0;
46112394Ssam
47112394Ssamchar *
48112394Ssam_dl_strdup(const char *orig)
49112394Ssam{
50117852Ssam	char *newstr;
51117852Ssam	int len;
52117852Ssam
53117852Ssam	len = _dl_strlen(orig)+1;
54112394Ssam	newstr = _dl_malloc(len);
55112394Ssam	_dl_strlcpy(newstr, orig, len);
56112394Ssam	return (newstr);
57112394Ssam}
58107852Ssam
59107852Ssam/*
60123261Ssam *  The following malloc/free code is a very simplified implementation
61123261Ssam *  of a malloc function. However, we do not need to be very complex here
62123261Ssam *  because we only free memory when 'dlclose()' is called and we can
63123261Ssam *  reuse at least the memory allocated for the object descriptor. We have
64123261Ssam *  one dynamic string allocated, the library name and it is likely that
65 *  we can reuse that one to without a lot of complex colapsing code.
66 */
67
68void *
69_dl_malloc(size_t size)
70{
71	long *p, *t, *n;
72
73	size = (size + 8 + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1);
74
75	if ((t = _dl_malloc_free) != 0) {	/* Try free list first */
76		n = (long *)&_dl_malloc_free;
77		while (t && t[-1] < size) {
78			n = t;
79			t = (long *)*t;
80		}
81		if (t) {
82			*n = *t;
83			_dl_memset(t, 0, t[-1] - 4);
84			return((void *)t);
85		}
86	}
87	if (_dl_malloc_pool == 0 ||
88	    _dl_malloc_pool + size > _dl_malloc_base + 4096) {
89		_dl_malloc_pool = (void *)_dl_mmap((void *)0, 4096,
90		    PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
91		if (_dl_malloc_pool == 0 || _dl_malloc_pool == MAP_FAILED ) {
92			_dl_printf("Dynamic loader failure: malloc.\n");
93			_dl_exit(7);
94		}
95		_dl_malloc_base = _dl_malloc_pool;
96	}
97	p = _dl_malloc_pool;
98	_dl_malloc_pool += size;
99	_dl_memset(p, 0, size);
100	*p = size;
101	return((void *)(p + 1));
102}
103
104void
105_dl_free(void *p)
106{
107	long *t = (long *)p;
108
109	*t = (long)_dl_malloc_free;
110	_dl_malloc_free = p;
111}
112