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