]>
git.saurik.com Git - apple/libc.git/blob - gen.subproj/nlist.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. All advertising materials mentioning features or use of this software
34 * must display the following acknowledgement:
35 * This product includes software developed by the University of
36 * California, Berkeley and its contributors.
37 * 4. Neither the name of the University nor the names of its contributors
38 * may be used to endorse or promote products derived from this software
39 * without specific prior written permission.
41 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 #include <sys/types.h>
62 /* Stuff lifted from <a.out.h> and <sys/exec.h> since they are gone */
64 * Header prepended to each a.out file.
67 unsigned short a_machtype
; /* machine type */
68 unsigned short a_magic
; /* magic number */
69 unsigned long a_text
; /* size of text segment */
70 unsigned long a_data
; /* size of initialized data */
71 unsigned long a_bss
; /* size of uninitialized data */
72 unsigned long a_syms
; /* size of symbol table */
73 unsigned long a_entry
; /* entry point */
74 unsigned long a_trsize
; /* size of text relocation */
75 unsigned long a_drsize
; /* size of data relocation */
78 #define OMAGIC 0407 /* old impure format */
79 #define NMAGIC 0410 /* read-only text */
80 #define ZMAGIC 0413 /* demand load format */
83 (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)
85 ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec))
87 (N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize)
89 #include <mach/mach.h>
90 #include <mach-o/nlist.h>
92 #include <mach-o/loader.h>
93 #include <mach-o/fat.h>
96 * CPUSUBTYPE_SUPPORT should be changed to non-zero once the
97 * cpusubtype_* routines are available in libc.
99 #define CPUSUBTYPE_SUPPORT 0
102 * nlist - retreive attributes from name list (string table version)
112 fd
= open(name
, O_RDONLY
, 0);
115 n
= __fdnlist(fd
, list
);
120 /* Note: __fdnlist() is called from kvm_nlist in libkvm's kvm.c */
127 register struct nlist
*p
, *q
;
128 register char *s1
, *s2
;
131 off_t sa
; /* symbol address */
132 off_t ss
; /* start of strings */
134 struct nlist space
[BUFSIZ
/sizeof (struct nlist
)];
135 unsigned arch_offset
= 0;
138 for (q
= list
, nreq
= 0; q
->n_un
.n_name
&& q
->n_un
.n_name
[0]; q
++, nreq
++) {
143 n
= strlen(q
->n_un
.n_name
);
147 if (read(fd
, (char *)&buf
, sizeof(buf
)) != sizeof(buf
) ||
148 (N_BADMAG(buf
) && *((long *)&buf
) != MH_MAGIC
&&
149 NXSwapBigLongToHost(*((long *)&buf
)) != FAT_MAGIC
)) {
153 /* Deal with fat file if necessary */
154 if (NXSwapBigLongToHost(*((long *)&buf
)) == FAT_MAGIC
) {
155 struct host_basic_info hbi
;
156 struct fat_header fh
;
157 struct fat_arch
*fat_archs
, *fap
;
160 /* Get our host info */
161 i
= HOST_BASIC_INFO_COUNT
;
162 if (host_info(mach_host_self(), HOST_BASIC_INFO
,
163 (host_info_t
)(&hbi
), &i
) != KERN_SUCCESS
) {
167 /* Read in the fat header */
168 lseek(fd
, 0, SEEK_SET
);
169 if (read(fd
, (char *)&fh
, sizeof(fh
)) != sizeof(fh
)) {
173 /* Convert fat_narchs to host byte order */
174 fh
.nfat_arch
= NXSwapBigLongToHost(fh
.nfat_arch
);
176 /* Read in the fat archs */
177 fat_archs
= (struct fat_arch
*)malloc(fh
.nfat_arch
*
178 sizeof(struct fat_arch
));
179 if (fat_archs
== NULL
) {
182 if (read(fd
, (char *)fat_archs
,
183 sizeof(struct fat_arch
) * fh
.nfat_arch
) !=
184 sizeof(struct fat_arch
) * fh
.nfat_arch
) {
190 * Convert archs to host byte ordering (a constraint of
191 * cpusubtype_getbestarch()
193 for (i
= 0; i
< fh
.nfat_arch
; i
++) {
194 fat_archs
[i
].cputype
=
195 NXSwapBigLongToHost(fat_archs
[i
].cputype
);
196 fat_archs
[i
].cpusubtype
=
197 NXSwapBigLongToHost(fat_archs
[i
].cpusubtype
);
198 fat_archs
[i
].offset
=
199 NXSwapBigLongToHost(fat_archs
[i
].offset
);
201 NXSwapBigLongToHost(fat_archs
[i
].size
);
203 NXSwapBigLongToHost(fat_archs
[i
].align
);
206 #if CPUSUBTYPE_SUPPORT
207 fap
= cpusubtype_getbestarch(hbi
.cpu_type
, hbi
.cpu_subtype
,
208 fat_archs
, fh
.nfat_arch
);
209 #else CPUSUBTYPE_SUPPORT
210 #warning Use the cpusubtype functions!!!
212 for (i
= 0; i
< fh
.nfat_arch
; i
++) {
213 if (fat_archs
[i
].cputype
== hbi
.cpu_type
) {
218 #endif CPUSUBTYPE_SUPPORT
223 arch_offset
= fap
->offset
;
226 /* Read in the beginning of the architecture-specific file */
227 lseek(fd
, arch_offset
, SEEK_SET
);
228 if (read(fd
, (char *)&buf
, sizeof(buf
)) != sizeof(buf
)) {
233 if (*((long *)&buf
) == MH_MAGIC
) {
234 struct mach_header mh
;
235 struct load_command
*load_commands
, *lcp
;
236 struct symtab_command
*stp
;
239 lseek(fd
, arch_offset
, SEEK_SET
);
240 if (read(fd
, (char *)&mh
, sizeof(mh
)) != sizeof(mh
)) {
243 load_commands
= (struct load_command
*)malloc(mh
.sizeofcmds
);
244 if (load_commands
== NULL
) {
247 if (read(fd
, (char *)load_commands
, mh
.sizeofcmds
) !=
254 for (i
= 0; i
< mh
.ncmds
; i
++) {
255 if (lcp
->cmdsize
% sizeof(long) != 0 ||
257 (char *)lcp
+ lcp
->cmdsize
>
258 (char *)load_commands
+ mh
.sizeofcmds
) {
262 if (lcp
->cmd
== LC_SYMTAB
) {
264 sizeof(struct symtab_command
)) {
268 stp
= (struct symtab_command
*)lcp
;
271 lcp
= (struct load_command
*)
272 ((char *)lcp
+ lcp
->cmdsize
);
278 sa
= stp
->symoff
+ arch_offset
;
279 ss
= stp
->stroff
+ arch_offset
;
280 n
= stp
->nsyms
* sizeof(struct nlist
);
284 sa
= N_SYMOFF(buf
) + arch_offset
;
285 ss
= sa
+ buf
.a_syms
+ arch_offset
;
289 lseek(fd
, sa
, SEEK_SET
);
296 if (read(fd
, (char *)space
, m
) != m
)
299 savpos
= lseek(fd
, 0, SEEK_CUR
);
300 for (q
= space
; (m
-= sizeof(struct nlist
)) >= 0; q
++) {
303 if (q
->n_un
.n_strx
== 0 || q
->n_type
& N_STAB
)
305 lseek(fd
, ss
+q
->n_un
.n_strx
, SEEK_SET
);
306 read(fd
, nambuf
, maxlen
+1);
307 for (p
= list
; p
->n_un
.n_name
&& p
->n_un
.n_name
[0]; p
++) {
316 p
->n_value
= q
->n_value
;
317 p
->n_type
= q
->n_type
;
318 p
->n_desc
= q
->n_desc
;
319 p
->n_sect
= q
->n_sect
;
326 lseek(fd
, savpos
, SEEK_SET
);