ranlib: fix it
[odcctools-svp.git] / libmacho / get_end.c
blob603c49c5672a4cec50cbb243ef5559b58696dc45
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
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@
23 #ifndef RLD
24 #include <string.h>
25 #include <mach-o/ldsyms.h>
26 #include <mach-o/getsect.h>
27 #ifndef __OPENSTEP__
29 #ifdef __LP64__
30 extern struct mach_header_64 *_NSGetMachExecuteHeader(void);
31 #else /* !defined(__LP64__) */
32 #include <crt_externs.h>
33 #endif /* !defined(__LP64__) */
35 #else /* defined(__OPENSTEP__) */
36 #ifdef __DYNAMIC__
37 #include "mach-o/dyld.h" /* defines _dyld_lookup_and_bind() */
38 #endif
40 #if !defined(__DYNAMIC__)
41 #define DECLARE_VAR(var, type) \
42 extern type var
43 #define SETUP_VAR(var)
44 #define USE_VAR(var) var
45 #else
46 #define STRINGIFY(a) # a
47 #define DECLARE_VAR(var, type) \
48 static type * var ## _pointer = 0
49 #define SETUP_VAR(var) \
50 if ( var ## _pointer == 0) { \
51 _dyld_lookup_and_bind( STRINGIFY(_ ## var), \
52 (unsigned long *) & var ## _pointer, 0); \
54 #define USE_VAR(var) (* var ## _pointer)
55 #endif
56 #endif /* __OPENSTEP__ */
59 * This routine returns the highest address of the segments in the program (NOT
60 * the shared libraries). It is intended to be used as a stop gap for programs
61 * that make UNIX style assumptions about how memory is allocated. Typicly the
62 * asumptions under which this is used is that memory is contiguously allocated
63 * by the program's text and data from address 0 with no gaps. The value of
64 * this differs from the value of &_end in a UNIX program in that this routine
65 * returns the address of the end of the segment not the end of the last section
66 * in that segment as would be the value of the symbol &_end.
68 unsigned long
69 get_end(void)
71 #ifndef __LP64__
73 static struct mach_header *mhp = NULL;
74 struct segment_command *sgp;
75 unsigned long i, _end;
76 #ifndef __OPENSTEP__
77 if(mhp == NULL)
78 mhp = _NSGetMachExecuteHeader();
79 #else /* defined(__OPENSTEP__) */
80 DECLARE_VAR(_mh_execute_header, struct mach_header);
81 SETUP_VAR(_mh_execute_header);
83 mhp = (struct mach_header *)(& USE_VAR(_mh_execute_header));
84 #endif /* __OPENSTEP__ */
85 _end = 0;
86 sgp = (struct segment_command *)
87 ((char *)mhp + sizeof(struct mach_header));
88 for(i = 0; i < mhp->ncmds; i++){
89 if(sgp->cmd == LC_SEGMENT)
90 if(sgp->vmaddr + sgp->vmsize > _end)
91 _end = sgp->vmaddr + sgp->vmsize;
92 sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize);
94 return(_end);
96 #else /* defined(__LP64__) */
98 static struct mach_header_64 *mhp = NULL;
99 struct segment_command_64 *sgp;
100 unsigned long i, _end;
102 if(mhp == NULL)
103 mhp = _NSGetMachExecuteHeader();
104 _end = 0;
105 sgp = (struct segment_command_64 *)
106 ((char *)mhp + sizeof(struct mach_header_64));
107 for(i = 0; i < mhp->ncmds; i++){
108 if(sgp->cmd == LC_SEGMENT_64)
109 if(sgp->vmaddr + sgp->vmsize > _end)
110 _end = sgp->vmaddr + sgp->vmsize;
111 sgp = (struct segment_command_64 *)((char *)sgp + sgp->cmdsize);
113 return(_end);
115 #endif /* defined(__LP64__) */
119 * This returns what was the value of the UNIX link editor defined symbol
120 * _etext (the first address after the text section). Note this my or may not
121 * be the only section in the __TEXT segment.
123 unsigned long
124 get_etext(void)
126 #ifndef __LP64__
127 const struct section *sp;
128 #else /* defined(__LP64__) */
129 const struct section_64 *sp;
130 #endif /* defined(__LP64__) */
132 sp = getsectbyname(SEG_TEXT, SECT_TEXT);
133 if(sp)
134 return(sp->addr + sp->size);
135 else
136 return(0);
140 * This returns what was the value of the UNIX link editor defined symbol
141 * _edata (the first address after the data section). Note this my or may not
142 * be the last non-zero fill section in the __DATA segment.
144 unsigned long
145 get_edata(void)
147 #ifndef __LP64__
148 const struct section *sp;
149 #else /* defined(__LP64__) */
150 const struct section_64 *sp;
151 #endif /* defined(__LP64__) */
153 sp = getsectbyname(SEG_DATA, SECT_DATA);
154 if(sp)
155 return(sp->addr + sp->size);
156 else
157 return(0);
159 #endif /* !defined(RLD) */