]>
git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSRuntime.cpp
e5ddca485c3db2a692f8c83eea74ace87c10444d
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1997 Apple Computer, Inc.
26 #include <libkern/c++/OSMetaClass.h>
27 #include <libkern/c++/OSLib.h>
28 #include <libkern/c++/OSSymbol.h>
29 #include <libkern/c++/OSBoolean.h>
31 #include <sys/cdefs.h>
39 #include <mach/mach_types.h>
40 #include <mach-o/mach_header.h>
44 extern int debug_iomalloc_size
;
47 #define MDECL(reqlen) \
50 char _m[(reqlen) + sizeof (struct _mhead)]; \
63 size_t memsize
= sizeof (*mem
);
68 mem
= (hdr_t
*)kalloc(memsize
);
73 debug_iomalloc_size
+= memsize
;
76 mem
->hdr
.mlen
= memsize
;
77 (void) memset(mem
->hdr
.dat
, 0, size
);
79 return (mem
->hdr
.dat
);
90 hdr
= (struct _mhead
*) addr
; hdr
--;
93 debug_iomalloc_size
-= hdr
->mlen
;
97 memset((vm_offset_t
)hdr
, 0xbb, hdr
->mlen
);
99 kfree((vm_offset_t
)hdr
, hdr
->mlen
);
103 void *kern_os_realloc(
109 size_t nmemsize
, osize
;
112 return (kern_os_malloc(nsize
));
114 ohdr
= (struct _mhead
*) addr
; ohdr
--;
115 osize
= ohdr
->mlen
- sizeof (*ohdr
);
124 nmemsize
= sizeof (*nmem
);
125 nmem
= (hdr_t
*) kalloc(nmemsize
);
132 debug_iomalloc_size
+= (nmemsize
- ohdr
->mlen
);
135 nmem
->hdr
.mlen
= nmemsize
;
137 (void) memset(&nmem
->hdr
.dat
[osize
], 0, nsize
- osize
);
138 (void) memcpy(nmem
->hdr
.dat
, ohdr
->dat
,
139 (nsize
> osize
) ? osize
: nsize
);
140 kfree((vm_offset_t
)ohdr
, ohdr
->mlen
);
142 return (nmem
->hdr
.dat
);
145 size_t kern_os_malloc_size(
153 hdr
= (struct _mhead
*) addr
; hdr
--;
154 return( hdr
->mlen
- sizeof (struct _mhead
));
157 void __pure_virtual( void ) { panic(__FUNCTION__
); }
159 typedef void (*structor_t
)(void);
161 void OSRuntimeUnloadCPPForSegment(struct segment_command
* segment
) {
163 struct section
* section
;
165 for (section
= firstsect(segment
);
167 section
= nextsect(segment
, section
)) {
169 if (strcmp(section
->sectname
, "__destructor") == 0) {
170 structor_t
* destructors
= (structor_t
*)section
->addr
;
173 int num_destructors
= section
->size
/ sizeof(structor_t
);
175 for (int i
= 0; i
< num_destructors
; i
++) {
178 } /* if (destructors) */
179 } /* if (strcmp...) */
180 } /* for (section...) */
185 void OSRuntimeUnloadCPP(kmod_info_t
*ki
, void *)
187 if (ki
&& ki
->address
) {
189 struct segment_command
* segment
;
190 struct mach_header
*header
;
192 OSSymbol::checkForPageUnload((void *) ki
->address
,
193 (void *) (ki
->address
+ ki
->size
));
195 header
= (struct mach_header
*)ki
->address
;
196 segment
= firstsegfromheader(header
);
198 for (segment
= firstsegfromheader(header
);
200 segment
= nextseg(segment
)) {
202 OSRuntimeUnloadCPPForSegment(segment
);
207 kern_return_t
OSRuntimeFinalizeCPP(kmod_info_t
*ki
, void *)
211 if (OSMetaClass::modHasInstance(ki
->name
)) {
212 // @@@ gvdl should have a verbose flag
213 printf("Can't unload %s due to -\n", ki
->name
);
214 OSMetaClass::reportModInstances(ki
->name
);
215 return kOSMetaClassHasInstances
;
218 // Tell the meta class system that we are starting to unload
219 metaHandle
= OSMetaClass::preModLoad(ki
->name
);
220 OSRuntimeUnloadCPP(ki
, 0); // Do the actual unload
221 (void) OSMetaClass::postModLoad(metaHandle
);
223 return KMOD_RETURN_SUCCESS
;
226 // Functions used by the extenTools/kmod library project
227 kern_return_t
OSRuntimeInitializeCPP(kmod_info_t
*ki
, void *)
229 struct mach_header
*header
;
232 struct segment_command
* segment
;
233 struct segment_command
* failure_segment
;
235 if (!ki
|| !ki
->address
)
236 return KMOD_RETURN_FAILURE
;
238 header
= (struct mach_header
*) ki
->address
;
240 // Tell the meta class system that we are starting the load
241 metaHandle
= OSMetaClass::preModLoad(ki
->name
);
244 return KMOD_RETURN_FAILURE
;
249 /* Scan the header for all sections named "__constructor", in any
250 * segment, and invoke the constructors within those sections.
252 for (segment
= firstsegfromheader(header
);
253 segment
!= 0 && load_success
;
254 segment
= nextseg(segment
)) {
256 struct section
* section
;
258 /* Record the current segment in the event of a failure.
260 failure_segment
= segment
;
262 for (section
= firstsect(segment
);
263 section
!= 0 && load_success
;
264 section
= nextsect(segment
, section
)) {
266 if (strcmp(section
->sectname
, "__constructor") == 0) {
267 structor_t
* constructors
= (structor_t
*)section
->addr
;
270 // FIXME: can we break here under the assumption that
271 // section names are unique within a segment?
273 int num_constructors
= section
->size
/ sizeof(structor_t
);
274 int hit_null_constructor
= 0;
277 i
< num_constructors
&&
278 OSMetaClass::checkModLoad(metaHandle
);
281 if (constructors
[i
]) {
282 (*constructors
[i
])();
283 } else if (!hit_null_constructor
) {
284 hit_null_constructor
= 1;
285 printf("Error! Null constructor in segment %s.\n",
289 load_success
= OSMetaClass::checkModLoad(metaHandle
);
291 } /* if (constructors) */
292 } /* if (strcmp...) */
293 } /* for (section...) */
294 } /* for (segment...) */
297 // We failed so call all of the destructors
300 /* Scan the header for all sections named "__constructor", in any
301 * segment, and invoke the constructors within those sections.
303 for (segment
= firstsegfromheader(header
);
304 segment
!= failure_segment
&& segment
!= 0;
305 segment
= nextseg(segment
)) {
307 OSRuntimeUnloadCPPForSegment(segment
);
309 } /* for (segment...) */
312 return OSMetaClass::postModLoad(metaHandle
);
315 static KMOD_LIB_DECL(__kernel__
, 0);
316 void OSlibkernInit(void)
318 vm_address_t
*headerArray
= (vm_address_t
*) getmachheaders();
320 KMOD_INFO_NAME
.address
= headerArray
[0]; assert(!headerArray
[1]);
321 if (kOSReturnSuccess
!= OSRuntimeInitializeCPP(&KMOD_INFO_NAME
, 0))
322 panic("OSRuntime: C++ runtime failed to initialize");
324 OSBoolean::initialize();
329 void * operator new( size_t size
)
333 result
= (void *) kern_os_malloc( size
);
335 bzero( result
, size
);
339 void operator delete( void * addr
)