]> git.llucax.com Git - software/druntime.git/blob - src/compiler/dmd/memory.d
Fixed the static data area range calculation. Previous behavior was causing only...
[software/druntime.git] / src / compiler / dmd / memory.d
1 /**
2  * This module exposes functionality for inspecting and manipulating memory.
3  *
4  * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
5  *            All rights reserved.
6  * License:
7  *  This software is provided 'as-is', without any express or implied
8  *  warranty. In no event will the authors be held liable for any damages
9  *  arising from the use of this software.
10  *
11  *  Permission is granted to anyone to use this software for any purpose,
12  *  including commercial applications, and to alter it and redistribute it
13  *  freely, in both source and binary form, subject to the following
14  *  restrictions:
15  *
16  *  o  The origin of this software must not be misrepresented; you must not
17  *     claim that you wrote the original software. If you use this software
18  *     in a product, an acknowledgment in the product documentation would be
19  *     appreciated but is not required.
20  *  o  Altered source versions must be plainly marked as such, and must not
21  *     be misrepresented as being the original software.
22  *  o  This notice may not be removed or altered from any source
23  *     distribution.
24  * Authors:   Walter Bright, Sean Kelly
25  */
26 module rt.memory;
27
28
29 private
30 {
31     version( linux )
32     {
33         version = SimpleLibcStackEnd;
34
35         version( SimpleLibcStackEnd )
36         {
37             extern (C) extern void* __libc_stack_end;
38         }
39     }
40     extern (C) void gc_addRange( void* p, size_t sz );
41     extern (C) void gc_removeRange( void *p );
42 }
43
44
45 /**
46  *
47  */
48 extern (C) void* rt_stackBottom()
49 {
50     version( Windows )
51     {
52         asm
53         {
54             naked;
55             mov EAX,FS:4;
56             ret;
57         }
58     }
59     else version( linux )
60     {
61         version( SimpleLibcStackEnd )
62         {
63             return __libc_stack_end;
64         }
65         else
66         {
67             // See discussion: http://autopackage.org/forums/viewtopic.php?t=22
68                 static void** libc_stack_end;
69
70                 if( libc_stack_end == libc_stack_end.init )
71                 {
72                     void* handle = dlopen( null, RTLD_NOW );
73                     libc_stack_end = cast(void**) dlsym( handle, "__libc_stack_end" );
74                     dlclose( handle );
75                 }
76                 return *libc_stack_end;
77         }
78     }
79     else
80     {
81         static assert( false, "Operating system not supported." );
82     }
83 }
84
85
86 /**
87  *
88  */
89 extern (C) void* rt_stackTop()
90 {
91     version( D_InlineAsm_X86 )
92     {
93         asm
94         {
95             naked;
96             mov EAX, ESP;
97             ret;
98         }
99     }
100     else
101     {
102             static assert( false, "Architecture not supported." );
103     }
104 }
105
106
107 private
108 {
109     version( Windows )
110     {
111         extern (C)
112         {
113             extern int _xi_a;   // &_xi_a just happens to be start of data segment
114             extern int _edata;  // &_edata is start of BSS segment
115             extern int _end;    // &_end is past end of BSS
116         }
117     }
118     else version( linux )
119     {
120         extern (C)
121         {
122             extern int _data;
123             extern int __data_start;
124             extern int _end;
125             extern int _data_start__;
126             extern int _data_end__;
127             extern int _bss_start__;
128             extern int _bss_end__;
129             extern int __fini_array_end;
130         }
131
132             alias __data_start  Data_Start;
133             alias _end          Data_End;
134     }
135 }
136
137
138 void initStaticDataGC()
139 {
140     version( Windows )
141     {
142         gc_addRange( &_xi_a, cast(size_t) &_end - cast(size_t) &_xi_a );
143     }
144     else version( linux )
145     {
146         gc_addRange( &__data_start, cast(size_t) &_end - cast(size_t) &__data_start );
147     }
148     else
149     {
150         static assert( false, "Operating system not supported." );
151     }
152 }