]>
git.saurik.com Git - apple/libc.git/blob - gen/nlist.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 #include <sys/types.h>
65 /* Stuff lifted from <a.out.h> and <sys/exec.h> since they are gone */
67 * Header prepended to each a.out file.
70 unsigned short a_machtype
; /* machine type */
71 unsigned short a_magic
; /* magic number */
72 unsigned long a_text
; /* size of text segment */
73 unsigned long a_data
; /* size of initialized data */
74 unsigned long a_bss
; /* size of uninitialized data */
75 unsigned long a_syms
; /* size of symbol table */
76 unsigned long a_entry
; /* entry point */
77 unsigned long a_trsize
; /* size of text relocation */
78 unsigned long a_drsize
; /* size of data relocation */
81 #define OMAGIC 0407 /* old impure format */
82 #define NMAGIC 0410 /* read-only text */
83 #define ZMAGIC 0413 /* demand load format */
86 (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)
88 ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec))
90 (N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize)
92 #include <mach/mach.h>
93 #include <mach-o/nlist.h>
95 #include <mach-o/loader.h>
96 #include <mach-o/fat.h>
99 * CPUSUBTYPE_SUPPORT should be changed to non-zero once the
100 * cpusubtype_* routines are available in libc.
102 #define CPUSUBTYPE_SUPPORT 0
105 * nlist - retreive attributes from name list (string table version)
115 fd
= open(name
, O_RDONLY
, 0);
118 n
= __fdnlist(fd
, list
);
123 /* Note: __fdnlist() is called from kvm_nlist in libkvm's kvm.c */
130 register struct nlist
*p
, *q
;
131 register char *s1
, *s2
;
134 off_t sa
; /* symbol address */
135 off_t ss
; /* start of strings */
137 struct nlist space
[BUFSIZ
/sizeof (struct nlist
)];
138 unsigned arch_offset
= 0;
141 for (q
= list
, nreq
= 0; q
->n_un
.n_name
&& q
->n_un
.n_name
[0]; q
++, nreq
++) {
146 n
= strlen(q
->n_un
.n_name
);
150 if (read(fd
, (char *)&buf
, sizeof(buf
)) != sizeof(buf
) ||
151 (N_BADMAG(buf
) && *((long *)&buf
) != MH_MAGIC
&&
152 NXSwapBigLongToHost(*((long *)&buf
)) != FAT_MAGIC
)) {
156 /* Deal with fat file if necessary */
157 if (NXSwapBigLongToHost(*((long *)&buf
)) == FAT_MAGIC
) {
158 struct host_basic_info hbi
;
159 struct fat_header fh
;
160 struct fat_arch
*fat_archs
, *fap
;
164 /* Get our host info */
165 host
= mach_host_self();
166 i
= HOST_BASIC_INFO_COUNT
;
167 if (host_info(host
, HOST_BASIC_INFO
,
168 (host_info_t
)(&hbi
), &i
) != KERN_SUCCESS
) {
171 mach_port_deallocate(mach_task_self(), host
);
173 /* Read in the fat header */
174 lseek(fd
, 0, SEEK_SET
);
175 if (read(fd
, (char *)&fh
, sizeof(fh
)) != sizeof(fh
)) {
179 /* Convert fat_narchs to host byte order */
180 fh
.nfat_arch
= NXSwapBigLongToHost(fh
.nfat_arch
);
182 /* Read in the fat archs */
183 fat_archs
= (struct fat_arch
*)malloc(fh
.nfat_arch
*
184 sizeof(struct fat_arch
));
185 if (fat_archs
== NULL
) {
188 if (read(fd
, (char *)fat_archs
,
189 sizeof(struct fat_arch
) * fh
.nfat_arch
) !=
190 sizeof(struct fat_arch
) * fh
.nfat_arch
) {
196 * Convert archs to host byte ordering (a constraint of
197 * cpusubtype_getbestarch()
199 for (i
= 0; i
< fh
.nfat_arch
; i
++) {
200 fat_archs
[i
].cputype
=
201 NXSwapBigLongToHost(fat_archs
[i
].cputype
);
202 fat_archs
[i
].cpusubtype
=
203 NXSwapBigLongToHost(fat_archs
[i
].cpusubtype
);
204 fat_archs
[i
].offset
=
205 NXSwapBigLongToHost(fat_archs
[i
].offset
);
207 NXSwapBigLongToHost(fat_archs
[i
].size
);
209 NXSwapBigLongToHost(fat_archs
[i
].align
);
212 #if CPUSUBTYPE_SUPPORT
213 fap
= cpusubtype_getbestarch(hbi
.cpu_type
, hbi
.cpu_subtype
,
214 fat_archs
, fh
.nfat_arch
);
215 #else CPUSUBTYPE_SUPPORT
216 #warning Use the cpusubtype functions!!!
218 for (i
= 0; i
< fh
.nfat_arch
; i
++) {
219 if (fat_archs
[i
].cputype
== hbi
.cpu_type
) {
224 #endif CPUSUBTYPE_SUPPORT
229 arch_offset
= fap
->offset
;
232 /* Read in the beginning of the architecture-specific file */
233 lseek(fd
, arch_offset
, SEEK_SET
);
234 if (read(fd
, (char *)&buf
, sizeof(buf
)) != sizeof(buf
)) {
239 if (*((long *)&buf
) == MH_MAGIC
) {
240 struct mach_header mh
;
241 struct load_command
*load_commands
, *lcp
;
242 struct symtab_command
*stp
;
245 lseek(fd
, arch_offset
, SEEK_SET
);
246 if (read(fd
, (char *)&mh
, sizeof(mh
)) != sizeof(mh
)) {
249 load_commands
= (struct load_command
*)malloc(mh
.sizeofcmds
);
250 if (load_commands
== NULL
) {
253 if (read(fd
, (char *)load_commands
, mh
.sizeofcmds
) !=
260 for (i
= 0; i
< mh
.ncmds
; i
++) {
261 if (lcp
->cmdsize
% sizeof(long) != 0 ||
263 (char *)lcp
+ lcp
->cmdsize
>
264 (char *)load_commands
+ mh
.sizeofcmds
) {
268 if (lcp
->cmd
== LC_SYMTAB
) {
270 sizeof(struct symtab_command
)) {
274 stp
= (struct symtab_command
*)lcp
;
277 lcp
= (struct load_command
*)
278 ((char *)lcp
+ lcp
->cmdsize
);
284 sa
= stp
->symoff
+ arch_offset
;
285 ss
= stp
->stroff
+ arch_offset
;
286 n
= stp
->nsyms
* sizeof(struct nlist
);
290 sa
= N_SYMOFF(buf
) + arch_offset
;
291 ss
= sa
+ buf
.a_syms
+ arch_offset
;
295 lseek(fd
, sa
, SEEK_SET
);
302 if (read(fd
, (char *)space
, m
) != m
)
305 savpos
= lseek(fd
, 0, SEEK_CUR
);
306 for (q
= space
; (m
-= sizeof(struct nlist
)) >= 0; q
++) {
309 if (q
->n_un
.n_strx
== 0 || q
->n_type
& N_STAB
)
311 lseek(fd
, ss
+q
->n_un
.n_strx
, SEEK_SET
);
312 read(fd
, nambuf
, maxlen
+1);
313 for (p
= list
; p
->n_un
.n_name
&& p
->n_un
.n_name
[0]; p
++) {
322 p
->n_value
= q
->n_value
;
323 p
->n_type
= q
->n_type
;
324 p
->n_desc
= q
->n_desc
;
325 p
->n_sect
= q
->n_sect
;
332 lseek(fd
, savpos
, SEEK_SET
);