]>
git.saurik.com Git - apple/libc.git/blob - gen/nlist.c
2 * Copyright (c) 1999, 2008 Apple 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@
24 * Copyright (c) 1989, 1993
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 /* temporarily comment this file out for LP64, until code can be modified */
60 #include <sys/types.h>
65 #include <malloc_private.h>
67 /* Stuff lifted from <a.out.h> and <sys/exec.h> since they are gone */
69 * Header prepended to each a.out file.
72 unsigned short a_machtype
; /* machine type */
73 unsigned short a_magic
; /* magic number */
74 unsigned long a_text
; /* size of text segment */
75 unsigned long a_data
; /* size of initialized data */
76 unsigned long a_bss
; /* size of uninitialized data */
77 unsigned long a_syms
; /* size of symbol table */
78 unsigned long a_entry
; /* entry point */
79 unsigned long a_trsize
; /* size of text relocation */
80 unsigned long a_drsize
; /* size of data relocation */
83 #define OMAGIC 0407 /* old impure format */
84 #define NMAGIC 0410 /* read-only text */
85 #define ZMAGIC 0413 /* demand load format */
88 (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)
90 ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec))
92 (N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize)
94 #include <mach/mach.h>
95 #include <mach-o/nlist.h>
97 #include <mach-o/loader.h>
98 #include <mach-o/fat.h>
101 * CPUSUBTYPE_SUPPORT should be changed to non-zero once the
102 * cpusubtype_* routines are available in libc.
104 #define CPUSUBTYPE_SUPPORT 0
106 int __fdnlist(int fd
, struct nlist
*list
);
109 * nlist - retreive attributes from name list (string table version)
119 fd
= open(name
, O_RDONLY
, 0);
122 n
= __fdnlist(fd
, list
);
127 /* Note: __fdnlist() is called from kvm_nlist in libkvm's kvm.c */
134 register struct nlist
*p
, *q
;
135 register char *s1
, *s2
;
138 off_t sa
; /* symbol address */
139 off_t ss
; /* start of strings */
141 struct nlist space
[BUFSIZ
/sizeof (struct nlist
)];
142 unsigned arch_offset
= 0;
145 for (q
= list
, nreq
= 0; q
->n_un
.n_name
&& q
->n_un
.n_name
[0]; q
++, nreq
++) {
150 n
= strlen(q
->n_un
.n_name
);
154 if (read(fd
, (char *)&buf
, sizeof(buf
)) != sizeof(buf
) ||
155 (N_BADMAG(buf
) && *((uint32_t *)&buf
) != MH_MAGIC
&&
156 OSSwapBigToHostInt32(*((uint32_t *)&buf
)) != FAT_MAGIC
)) {
160 /* Deal with fat file if necessary */
161 if (OSSwapBigToHostInt32(*((uint32_t *)&buf
)) == FAT_MAGIC
) {
162 struct host_basic_info hbi
;
163 struct fat_header fh
;
164 struct fat_arch
*fat_archs
, *fap
;
168 /* Get our host info */
169 host
= mach_host_self();
170 i
= HOST_BASIC_INFO_COUNT
;
171 if (host_info(host
, HOST_BASIC_INFO
,
172 (host_info_t
)(&hbi
), &i
) != KERN_SUCCESS
) {
175 mach_port_deallocate(mach_task_self(), host
);
177 /* Read in the fat header */
178 lseek(fd
, 0, SEEK_SET
);
179 if (read(fd
, (char *)&fh
, sizeof(fh
)) != sizeof(fh
)) {
183 /* Convert fat_narchs to host byte order */
184 fh
.nfat_arch
= OSSwapBigToHostInt32(fh
.nfat_arch
);
186 /* Read in the fat archs */
187 fat_archs
= (struct fat_arch
*)reallocarray(NULL
, fh
.nfat_arch
,
188 sizeof(struct fat_arch
));
189 if (fat_archs
== NULL
) {
192 if (read(fd
, (char *)fat_archs
,
193 sizeof(struct fat_arch
) * fh
.nfat_arch
) !=
194 sizeof(struct fat_arch
) * fh
.nfat_arch
) {
200 * Convert archs to host byte ordering (a constraint of
201 * cpusubtype_getbestarch()
203 for (i
= 0; i
< fh
.nfat_arch
; i
++) {
204 fat_archs
[i
].cputype
=
205 OSSwapBigToHostInt32(fat_archs
[i
].cputype
);
206 fat_archs
[i
].cpusubtype
=
207 OSSwapBigToHostInt32(fat_archs
[i
].cpusubtype
);
208 fat_archs
[i
].offset
=
209 OSSwapBigToHostInt32(fat_archs
[i
].offset
);
211 OSSwapBigToHostInt32(fat_archs
[i
].size
);
213 OSSwapBigToHostInt32(fat_archs
[i
].align
);
216 #if CPUSUBTYPE_SUPPORT
217 fap
= cpusubtype_getbestarch(hbi
.cpu_type
, hbi
.cpu_subtype
,
218 fat_archs
, fh
.nfat_arch
);
221 for (i
= 0; i
< fh
.nfat_arch
; i
++) {
222 if (fat_archs
[i
].cputype
== hbi
.cpu_type
) {
227 #endif /* CPUSUBTYPE_SUPPORT */
232 arch_offset
= fap
->offset
;
235 /* Read in the beginning of the architecture-specific file */
236 lseek(fd
, arch_offset
, SEEK_SET
);
237 if (read(fd
, (char *)&buf
, sizeof(buf
)) != sizeof(buf
)) {
242 if (*((uint32_t *)&buf
) == MH_MAGIC
) {
243 struct mach_header mh
;
244 struct load_command
*load_commands
, *lcp
;
245 struct symtab_command
*stp
;
248 lseek(fd
, arch_offset
, SEEK_SET
);
249 if (read(fd
, (char *)&mh
, sizeof(mh
)) != sizeof(mh
)) {
252 load_commands
= (struct load_command
*)malloc(mh
.sizeofcmds
);
253 if (load_commands
== NULL
) {
256 if (read(fd
, (char *)load_commands
, mh
.sizeofcmds
) !=
263 for (i
= 0; i
< mh
.ncmds
; i
++) {
264 if (lcp
->cmdsize
% sizeof(uint32_t) != 0 ||
266 (char *)lcp
+ lcp
->cmdsize
>
267 (char *)load_commands
+ mh
.sizeofcmds
) {
271 if (lcp
->cmd
== LC_SYMTAB
) {
273 sizeof(struct symtab_command
)) {
277 stp
= (struct symtab_command
*)lcp
;
280 lcp
= (struct load_command
*)
281 ((char *)lcp
+ lcp
->cmdsize
);
287 sa
= stp
->symoff
+ arch_offset
;
288 ss
= stp
->stroff
+ arch_offset
;
289 n
= stp
->nsyms
* sizeof(struct nlist
);
293 sa
= N_SYMOFF(buf
) + arch_offset
;
294 ss
= sa
+ buf
.a_syms
+ arch_offset
;
298 lseek(fd
, sa
, SEEK_SET
);
305 if (read(fd
, (char *)space
, m
) != m
)
308 savpos
= lseek(fd
, 0, SEEK_CUR
);
309 for (q
= space
; (m
-= sizeof(struct nlist
)) >= 0; q
++) {
312 if (q
->n_un
.n_strx
== 0 || q
->n_type
& N_STAB
)
314 lseek(fd
, ss
+q
->n_un
.n_strx
, SEEK_SET
);
315 read(fd
, nambuf
, maxlen
+1);
316 for (p
= list
; p
->n_un
.n_name
&& p
->n_un
.n_name
[0]; p
++) {
325 p
->n_value
= q
->n_value
;
326 p
->n_type
= q
->n_type
;
327 p
->n_desc
= q
->n_desc
;
328 p
->n_sect
= q
->n_sect
;
335 lseek(fd
, savpos
, SEEK_SET
);
340 #endif /* !__LP64__ */