|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.0 (the 'License'). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License."
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: #ifndef KERNEL
26: #ifdef SHLIB
27: #include "shlib.h"
28: #endif
29:
30: #include <libc.h>
31: #include <stdlib.h>
32: #include <mach-o/loader.h>
33:
34: static void call_constructors (void);
35: static void call_destructors (void);
36: static void call_routines_for_section (const struct mach_header **headers,
37: const char *segment_name,
38: const char *section_name);
39:
40: /* Perform C++ initialization. This only works for the MH_EXECUTE and
41: MH_FVMLIB formats, since the headers must be mapped.
42:
43: crt0.o uses the trick of declaring a common symbol with the same name
44: as this function to call this routine if it is linked in for some other
45: reason, but without forcing it to be linked in itself. */
46:
47: void _cplus_init (void)
48: {
49: /* Each module which contains constructors or destructors should
50: contain an undefined reference to these symbols to ensure that
51: this initialization routine is linked in. */
52: asm (".globl .constructors_used");
53: asm (".constructors_used = 0");
54: asm (".globl .destructors_used");
55: asm (".destructors_used = 0");
56:
57: atexit (&call_destructors);
58: call_constructors ();
59: }
60:
61:
62: /* Call the appropriate contructor for each static object in the program. */
63:
64: static void call_constructors (void)
65: {
66: const struct mach_header **headers = getmachheaders ();
67:
68: call_routines_for_section (headers, "__TEXT", "__constructor");
69: free (headers);
70: }
71:
72:
73: /* Call the appropriate destructor for each static object in the program. */
74:
75: static void call_destructors (void)
76: {
77: const struct mach_header **headers = getmachheaders ();
78:
79: call_routines_for_section (getmachheaders (), "__TEXT", "__destructor");
80: free (headers);
81: }
82:
83:
84: /* Call the init functions in the specified section of each header.
85: The section is assumed to contain a sequential list of function pointers.
86: The functions are called with no arguments, and no return value is
87: expected. */
88:
89: static void call_routines_for_section (const struct mach_header **headers,
90: const char *segment_name,
91: const char *section_name)
92: {
93: unsigned int i;
94:
95: if (headers == NULL)
96: return;
97:
98: for (i = 0; headers[i] != NULL; i++)
99: {
100: const struct section *section;
101: void (**init_routines) (void);
102: unsigned int n, j;
103:
104: section = getsectbynamefromheader (headers[i],
105: segment_name,
106: section_name);
107:
108: if (section == NULL)
109: continue;
110:
111: init_routines = (void (**) (void)) section->addr;
112: n = section->size / sizeof (init_routines[0]);
113:
114: for (j = 0; j < n; j++)
115: (*init_routines[j]) ();
116: }
117: }
118:
119: #endif /* KERNEL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.