2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <mach-o/ldsyms.h>
26 #include <mach-o/getsect.h>
28 #include <crt_externs.h>
29 #else /* defined(__OPENSTEP__) */
31 #include "mach-o/dyld.h" /* defines _dyld_lookup_and_bind() */
34 #if !defined(__DYNAMIC__)
35 #define DECLARE_VAR(var, type) \
37 #define SETUP_VAR(var)
38 #define USE_VAR(var) var
40 #define STRINGIFY(a) # a
41 #define DECLARE_VAR(var, type) \
42 static type * var ## _pointer = 0
43 #define SETUP_VAR(var) \
44 if ( var ## _pointer == 0) { \
45 _dyld_lookup_and_bind( STRINGIFY(_ ## var), \
46 (uint32_t *) & var ## _pointer, 0); \
48 #define USE_VAR(var) (* var ## _pointer)
50 #endif /* __OPENSTEP__ */
53 * This routine returns the highest address of the segments in the program (NOT
54 * the shared libraries). It is intended to be used as a stop gap for programs
55 * that make UNIX style assumptions about how memory is allocated. Typicly the
56 * asumptions under which this is used is that memory is contiguously allocated
57 * by the program's text and data from address 0 with no gaps. The value of
58 * this differs from the value of &_end in a UNIX program in that this routine
59 * returns the address of the end of the segment not the end of the last section
60 * in that segment as would be the value of the symbol &_end.
67 struct segment_command
*sgp
;
71 struct mach_header
*mhp
= _NSGetMachExecuteHeader();
72 #else /* defined(__OPENSTEP__) */
73 static struct mach_header
*mhp
= NULL
;
74 DECLARE_VAR(_mh_execute_header
, struct mach_header
);
75 SETUP_VAR(_mh_execute_header
);
77 mhp
= (struct mach_header
*)(& USE_VAR(_mh_execute_header
));
78 #endif /* __OPENSTEP__ */
80 sgp
= (struct segment_command
*)
81 ((char *)mhp
+ sizeof(struct mach_header
));
82 for(i
= 0; i
< mhp
->ncmds
; i
++){
83 if(sgp
->cmd
== LC_SEGMENT
)
84 if(sgp
->vmaddr
+ sgp
->vmsize
> _end
)
85 _end
= sgp
->vmaddr
+ sgp
->vmsize
;
86 sgp
= (struct segment_command
*)((char *)sgp
+ sgp
->cmdsize
);
90 #else /* defined(__LP64__) */
92 struct mach_header_64
*mhp
= _NSGetMachExecuteHeader();
93 struct segment_command_64
*sgp
;
98 sgp
= (struct segment_command_64
*)
99 ((char *)mhp
+ sizeof(struct mach_header_64
));
100 for(i
= 0; i
< mhp
->ncmds
; i
++){
101 if(sgp
->cmd
== LC_SEGMENT_64
)
102 if(sgp
->vmaddr
+ sgp
->vmsize
> _end
)
103 _end
= sgp
->vmaddr
+ sgp
->vmsize
;
104 sgp
= (struct segment_command_64
*)((char *)sgp
+ sgp
->cmdsize
);
108 #endif /* defined(__LP64__) */
112 * This returns what was the value of the UNIX link editor defined symbol
113 * _etext (the first address after the text section). Note this my or may not
114 * be the only section in the __TEXT segment.
120 const struct section
*sp
;
121 #else /* defined(__LP64__) */
122 const struct section_64
*sp
;
123 #endif /* defined(__LP64__) */
125 sp
= getsectbyname(SEG_TEXT
, SECT_TEXT
);
127 return(sp
->addr
+ sp
->size
);
133 * This returns what was the value of the UNIX link editor defined symbol
134 * _edata (the first address after the data section). Note this my or may not
135 * be the last non-zero fill section in the __DATA segment.
141 const struct section
*sp
;
142 #else /* defined(__LP64__) */
143 const struct section_64
*sp
;
144 #endif /* defined(__LP64__) */
146 sp
= getsectbyname(SEG_DATA
, SECT_DATA
);
148 return(sp
->addr
+ sp
->size
);
152 #endif /* !defined(RLD) */