|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1997 Apple Computer, Inc.
24: *
25: */
26: #include <libkern/c++/OSMetaClass.h>
27: #include <libkern/c++/OSLib.h>
28:
29: #include <sys/cdefs.h>
30:
31: __BEGIN_DECLS
32:
33: #include <string.h>
34:
35: struct mach_header;
36:
37: #include <mach/mach_types.h>
38: #include <mach-o/mach_header.h>
39: #include <mach-o/loader.h>
40: #include <stdarg.h>
41:
42: #ifdef DEBUG
43: extern int debug_iomalloc_size;
44: #endif
45:
46: #define MDECL(reqlen) \
47: typedef union { \
48: struct _mhead hdr; \
49: char _m[(reqlen) + sizeof (struct _mhead)]; \
50: } hdr_t; \
51: hdr_t
52:
53: struct _mhead {
54: size_t mlen;
55: char dat[0];
56: };
57:
58: void *kern_os_malloc(
59: size_t size)
60: {
61: MDECL(size) *mem;
62: size_t memsize = sizeof (*mem);
63:
64: if (size == 0)
65: return (0);
66:
67: mem = (hdr_t *)kalloc(memsize);
68: if (!mem)
69: return (0);
70:
71: #ifdef DEBUG
72: debug_iomalloc_size += memsize;
73: #endif
74:
75: mem->hdr.mlen = memsize;
76: (void) memset(mem->hdr.dat, 0, size);
77:
78: return (mem->hdr.dat);
79: }
80:
81: void kern_os_free(
82: void *addr)
83: {
84: struct _mhead *hdr;
85:
86: if (!addr)
87: return;
88:
89: hdr = (struct _mhead *) addr; hdr--;
90:
91: #ifdef DEBUG
92: debug_iomalloc_size -= hdr->mlen;
93: #endif
94:
95: #if 0
96: memset((vm_offset_t)hdr, 0xbb, hdr->mlen);
97: #else
98: kfree((vm_offset_t)hdr, hdr->mlen);
99: #endif
100: }
101:
102: void *kern_os_realloc(
103: void *addr,
104: size_t nsize)
105: {
106: struct _mhead *ohdr;
107: MDECL(nsize) *nmem;
108: size_t nmemsize, osize;
109:
110: if (!addr)
111: return (kern_os_malloc(nsize));
112:
113: ohdr = (struct _mhead *) addr; ohdr--;
114: osize = ohdr->mlen - sizeof (*ohdr);
115: if (nsize == osize)
116: return (addr);
117:
118: if (nsize == 0) {
119: kfree((vm_offset_t)ohdr, ohdr->mlen);
120: return (0);
121: }
122:
123: nmemsize = sizeof (*nmem);
124: nmem = (hdr_t *) kalloc(nmemsize);
125: if (!nmem){
126: kern_os_free(addr);
127: return (0);
128: }
129:
130: #ifdef DEBUG
131: debug_iomalloc_size += nmemsize;
132: #endif
133:
134: nmem->hdr.mlen = nmemsize;
135: if (nsize > osize)
136: (void) memset(&nmem->hdr.dat[osize], 0, nsize - osize);
137: (void) memcpy(nmem->hdr.dat, ohdr->dat,
138: (nsize > osize) ? osize : nsize);
139: kfree((vm_offset_t)ohdr, ohdr->mlen);
140:
141: return (nmem->hdr.dat);
142: }
143:
144: size_t kern_os_malloc_size(
145: void *addr)
146: {
147: struct _mhead *hdr;
148:
149: if (!addr)
150: return( 0);
151:
152: hdr = (struct _mhead *) addr; hdr--;
153: return( hdr->mlen - sizeof (struct _mhead));
154: }
155:
156: void __pure_virtual( void ) { panic(__FUNCTION__); }
157:
158: typedef void (*structor_t)(void);
159:
160: void OSRuntimeUnloadCPP(kmod_info_t *ki, void *)
161: {
162: structor_t *destructors = 0;
163: int size;
164:
165: if (ki && ki->address)
166: destructors = (structor_t *) getsectdatafromheader(
167: (struct mach_header *) ki->address, SEG_TEXT, "__destructor", &size);
168:
169: if (destructors) {
170: size /= sizeof(structor_t);
171:
172: for (int i = 0; i < size; i++)
173: (*destructors[i])();
174: }
175: }
176:
177: kern_return_t OSRuntimeFinalizeCPP(kmod_info_t *ki, void *)
178: {
179: void *metaHandle;
180:
181: if (OSMetaClass::modHasInstance(ki->name)) {
182: // @@@ gvdl shourld have a verbose flag
183: printf("Can't unload %s due to -\n", ki->name);
184: OSMetaClass::reportModInstances(ki->name);
185: return kOSMetaClassHasInstances;
186: }
187:
188: // Tell the meta class system that we are starting to unload
189: metaHandle = OSMetaClass::preModLoad(ki->name);
190: OSRuntimeUnloadCPP(ki, 0); // Do the actual unload
191: (void) OSMetaClass::postModLoad(metaHandle);
192:
193: return KMOD_RETURN_SUCCESS;
194: }
195:
196: // Functions used by the extenTools/kmod library project
197: kern_return_t OSRuntimeInitializeCPP(kmod_info_t *ki, void *)
198: {
199: struct mach_header *header;
200: void *metaHandle;
201: structor_t *constructors;
202: int size;
203: bool loadSuccess;
204:
205: if (!ki || !ki->address)
206: return KMOD_RETURN_FAILURE;
207: else
208: header = (struct mach_header *) ki->address;
209:
210: // Tell the meta class system that we are starting the load
211: metaHandle = OSMetaClass::preModLoad(ki->name);
212: assert(metaHandle);
213: if (!metaHandle)
214: return KMOD_RETURN_FAILURE;
215:
216: loadSuccess = true;
217: constructors = (structor_t *)
218: getsectdatafromheader(header, SEG_TEXT, "__constructor", &size);
219: if (constructors) {
220: size /= sizeof(structor_t);
221:
222: for (int i = 0; OSMetaClass::checkModLoad(metaHandle)
223: && i < size; i++)
224: (*constructors[i])();
225: loadSuccess = OSMetaClass::checkModLoad(metaHandle);
226: }
227:
228: // We failed so call all of the destructors
229: if (!loadSuccess)
230: OSRuntimeUnloadCPP(ki, 0);
231:
232: return OSMetaClass::postModLoad(metaHandle);
233: }
234:
235: static KMOD_LIB_DECL(__kernel__, 0);
236: void OSlibkernInit(void)
237: {
238: vm_address_t *headerArray = (vm_address_t *) getmachheaders();
239:
240: KMOD_INFO_NAME.address = headerArray[0]; assert(!headerArray[1]);
241: if (kOSReturnSuccess != OSRuntimeInitializeCPP(&KMOD_INFO_NAME, 0))
242: panic("OSRuntime: C++ runtime failed to initialize");
243: }
244:
245: __END_DECLS
246:
247: void * operator new( size_t size)
248: {
249: void * result;
250:
251: result = (void *) kern_os_malloc( size);
252: if( result)
253: bzero( result, size);
254: return( result);
255: }
256:
257: void operator delete( void * addr)
258: {
259: kern_os_free( addr);
260: }
261:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.