1 /**	$MirOS: src/libexec/ld.so/util.c,v 1.4 2008/10/16 14:56:05 tg Exp $ */
2 /*	$OpenBSD: util.c,v 1.18 2004/06/14 15:07:36 millert Exp $	*/
3 
4 /*
5  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29 
30 #include <sys/param.h>
31 #include <sys/mman.h>
32 #include <sys/sysctl.h>
33 #include <string.h>
34 #include "archdep.h"
35 
36 __RCSID("$MirOS: src/libexec/ld.so/util.c,v 1.4 2008/10/16 14:56:05 tg Exp $");
37 
38 /*
39  * Static vars usable after bootstrapping.
40  */
41 static void *_dl_malloc_pool = 0;
42 static long *_dl_malloc_free = 0;
43 
44 char *
_dl_strdup(const char * orig)45 _dl_strdup(const char *orig)
46 {
47 	char *newstr;
48 	int len;
49 
50 	len = _dl_strlen(orig)+1;
51 	newstr = _dl_malloc(len);
52 	_dl_strlcpy(newstr, orig, len);
53 	return (newstr);
54 }
55 
56 #define	_dl_round_page(x)	(((x) + (__LDPGSZ - 1)) & ~(__LDPGSZ - 1))
57 
58 /*
59  * The following malloc/free code is a very simplified implementation
60  * of a malloc function. However, we do not need to be very complex here
61  * because we only free memory when 'dlclose()' is called and we can
62  * reuse at least the memory allocated for the object descriptor. We have
63  * one dynamic string allocated, the library name and it is likely that
64  * we can reuse that one to without a lot of complex colapsing code.
65  */
66 void *
_dl_malloc(size_t need)67 _dl_malloc(size_t need)
68 {
69 	long *p, *t, *n, have;
70 
71 	need = (need + 8 + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1);
72 
73 	if ((t = _dl_malloc_free) != 0) {	/* Try free list first */
74 		n = (long *)&_dl_malloc_free;
75 		while (t && t[-1] < need) {
76 			n = t;
77 			t = (long *)*t;
78 		}
79 		if (t) {
80 			*n = *t;
81 			_dl_memset(t, 0, t[-1] - sizeof(long));
82 			return((void *)t);
83 		}
84 	}
85 	have = _dl_round_page((long)_dl_malloc_pool) - (long)_dl_malloc_pool;
86 	if (need > have) {
87 		if (have >= 8 + DL_MALLOC_ALIGN) {
88 			p = _dl_malloc_pool;
89 			*p = have;
90 			_dl_free((void *)(p + 1));	/* move to freelist */
91 		}
92 		_dl_malloc_pool = (void *)_dl_mmap((void *)0,
93 		    _dl_round_page(need), PROT_READ|PROT_WRITE,
94 		    MAP_ANON|MAP_PRIVATE, -1, 0);
95 		if (_dl_malloc_pool == 0 || _dl_malloc_pool == MAP_FAILED ) {
96 			_dl_printf("Dynamic loader failure: malloc.\n");
97 			_dl_exit(7);
98 		}
99 	}
100 	p = _dl_malloc_pool;
101 	_dl_malloc_pool += need;
102 	_dl_memset(p, 0, need);
103 	*p = need;
104 	return((void *)(p + 1));
105 }
106 
107 void
_dl_free(void * p)108 _dl_free(void *p)
109 {
110 	long *t = (long *)p;
111 
112 	*t = (long)_dl_malloc_free;
113 	_dl_malloc_free = p;
114 }
115 
116 
117 unsigned int
_dl_random(void)118 _dl_random(void)
119 {
120 	int mib[2];
121 	unsigned int rnd;
122 	size_t len;
123 
124 	mib[0] = CTL_KERN;
125 	mib[1] = KERN_ARND;
126 	len = sizeof(rnd);
127 	_dl_sysctl(mib, 2, &rnd, &len, NULL, 0);
128 
129 	return (rnd);
130 }
131 
132 void *
_dl_memcpy(void * dst,const void * src,size_t len)133 _dl_memcpy(void *dst, const void *src, size_t len)
134 {
135 	_dl_bcopy(src, dst, len);
136 	return (dst);
137 }
138