1b0d807666f3ab5af581e4687eba31717bbde86d5nealsid/* 2b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 4b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * @APPLE_LICENSE_HEADER_START@ 5b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 6b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * This file contains Original Code and/or Modifications of Original Code 7b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * as defined in and that are subject to the Apple Public Source License 8b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * Version 2.0 (the 'License'). You may not use this file except in 9b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * compliance with the License. Please obtain a copy of the License at 10b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * http://www.opensource.apple.com/apsl/ and read it before using this 11b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * file. 12b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 13b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * The Original Code and all software distributed under the License are 14b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * Please see the License for the specific language governing rights and 19b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * limitations under the License. 20b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 21b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * @APPLE_LICENSE_HEADER_END@ 22b0d807666f3ab5af581e4687eba31717bbde86d5nealsid */ 23b0d807666f3ab5af581e4687eba31717bbde86d5nealsid/* 24b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * Copyright (c) 1989, 1993 25b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * The Regents of the University of California. All rights reserved. 26b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 27b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * Redistribution and use in source and binary forms, with or without 28b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * modification, are permitted provided that the following conditions 29b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * are met: 30b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 1. Redistributions of source code must retain the above copyright 31b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * notice, this list of conditions and the following disclaimer. 32b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 2. Redistributions in binary form must reproduce the above copyright 33b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * notice, this list of conditions and the following disclaimer in the 34b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * documentation and/or other materials provided with the distribution. 35b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 3. All advertising materials mentioning features or use of this software 36b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * must display the following acknowledgement: 37b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * This product includes software developed by the University of 38b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * California, Berkeley and its contributors. 39b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 4. Neither the name of the University nor the names of its contributors 40b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * may be used to endorse or promote products derived from this software 41b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * without specific prior written permission. 42b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 43b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * SUCH DAMAGE. 54b0d807666f3ab5af581e4687eba31717bbde86d5nealsid */ 55b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 56b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 570344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com/* 58b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * This file was copied from libc/gen/nlist.c from Darwin's source code 59b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * The version of nlist used as a base is from 10.5.2, libc-498 60b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * http://www.opensource.apple.com/darwinsource/10.5.2/Libc-498/gen/nlist.c 61b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 62b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * The full tarball is at: 63b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * http://www.opensource.apple.com/darwinsource/tarballs/apsl/Libc-498.tar.gz 64b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * 650344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com * I've modified it to be compatible with 64-bit images. 66b0d807666f3ab5af581e4687eba31717bbde86d5nealsid*/ 67b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 680344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com#include "breakpad_nlist_64.h" 69b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 700f8f72d15582907c1b78094073738ae94a295431mark@chromium.org#include <CoreFoundation/CoreFoundation.h> 710344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com#include <fcntl.h> 725da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid#include <mach-o/nlist.h> 735da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid#include <mach-o/loader.h> 745da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid#include <mach-o/fat.h> 750344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com#include <mach/mach.h> 760344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com#include <stdio.h> 775da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid#include <stdlib.h> 785da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid#include <sys/types.h> 795da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid#include <sys/uio.h> 805da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid#include <TargetConditionals.h> 810344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com#include <unistd.h> 82b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 83b0d807666f3ab5af581e4687eba31717bbde86d5nealsid/* Stuff lifted from <a.out.h> and <sys/exec.h> since they are gone */ 84b0d807666f3ab5af581e4687eba31717bbde86d5nealsid/* 85b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * Header prepended to each a.out file. 86b0d807666f3ab5af581e4687eba31717bbde86d5nealsid */ 87b0d807666f3ab5af581e4687eba31717bbde86d5nealsidstruct exec { 88b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned short a_machtype; /* machine type */ 89b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned short a_magic; /* magic number */ 90b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned long a_text; /* size of text segment */ 91b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned long a_data; /* size of initialized data */ 92b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned long a_bss; /* size of uninitialized data */ 93b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned long a_syms; /* size of symbol table */ 94b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned long a_entry; /* entry point */ 95b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned long a_trsize; /* size of text relocation */ 96b0d807666f3ab5af581e4687eba31717bbde86d5nealsid unsigned long a_drsize; /* size of data relocation */ 97b0d807666f3ab5af581e4687eba31717bbde86d5nealsid}; 98b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 99b0d807666f3ab5af581e4687eba31717bbde86d5nealsid#define OMAGIC 0407 /* old impure format */ 100b0d807666f3ab5af581e4687eba31717bbde86d5nealsid#define NMAGIC 0410 /* read-only text */ 101b0d807666f3ab5af581e4687eba31717bbde86d5nealsid#define ZMAGIC 0413 /* demand load format */ 102b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 103b0d807666f3ab5af581e4687eba31717bbde86d5nealsid#define N_BADMAG(x) \ 104b0d807666f3ab5af581e4687eba31717bbde86d5nealsid (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) 105b0d807666f3ab5af581e4687eba31717bbde86d5nealsid#define N_TXTOFF(x) \ 106b0d807666f3ab5af581e4687eba31717bbde86d5nealsid ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec)) 107b0d807666f3ab5af581e4687eba31717bbde86d5nealsid#define N_SYMOFF(x) \ 108b0d807666f3ab5af581e4687eba31717bbde86d5nealsid (N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize) 109b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 1100344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com// Traits structs for specializing function templates to handle 1110344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com// 32-bit/64-bit Mach-O files. 1120344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtemplate<typename T> 1130344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comstruct MachBits {}; 1140344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 1150344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtypedef struct nlist nlist32; 1160344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtypedef struct nlist_64 nlist64; 1170344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 1180344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtemplate<> 1190344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comstruct MachBits<nlist32> { 1200344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com typedef mach_header mach_header_type; 1210344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com typedef uint32_t word_type; 1220344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com static const uint32_t magic = MH_MAGIC; 1230344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com}; 1240344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 1250344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtemplate<> 1260344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comstruct MachBits<nlist64> { 1270344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com typedef mach_header_64 mach_header_type; 1280344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com typedef uint64_t word_type; 1290344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com static const uint32_t magic = MH_MAGIC_64; 1300344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com}; 1310344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 1320344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtemplate<typename nlist_type> 1335da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsidint 1340344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com__breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames, 1350344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com cpu_type_t cpu_type); 1365da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid 137b0d807666f3ab5af581e4687eba31717bbde86d5nealsid/* 138b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * nlist - retreive attributes from name list (string table version) 139b0d807666f3ab5af581e4687eba31717bbde86d5nealsid */ 140b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 1410344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtemplate <typename nlist_type> 1420344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comint breakpad_nlist_common(const char *name, 1430344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com nlist_type *list, 1440344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com const char **symbolNames, 1450344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com cpu_type_t cpu_type) { 1460344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com int fd = open(name, O_RDONLY, 0); 147b0d807666f3ab5af581e4687eba31717bbde86d5nealsid if (fd < 0) 1480344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 1490344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com int n = __breakpad_fdnlist(fd, list, symbolNames, cpu_type); 1500344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com close(fd); 1510344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return n; 1520344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com} 1530344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 1540344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comint breakpad_nlist(const char *name, 1550344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct nlist *list, 1560344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com const char **symbolNames, 1570344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com cpu_type_t cpu_type) { 1580344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return breakpad_nlist_common(name, list, symbolNames, cpu_type); 1590344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com} 1600344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 1610344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comint breakpad_nlist(const char *name, 1620344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct nlist_64 *list, 1630344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com const char **symbolNames, 1640344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com cpu_type_t cpu_type) { 1650344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return breakpad_nlist_common(name, list, symbolNames, cpu_type); 166b0d807666f3ab5af581e4687eba31717bbde86d5nealsid} 167b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 168b0d807666f3ab5af581e4687eba31717bbde86d5nealsid/* Note: __fdnlist() is called from kvm_nlist in libkvm's kvm.c */ 169b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 1700344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comtemplate<typename nlist_type> 1710344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.comint __breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames, 1720344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com cpu_type_t cpu_type) { 1730344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com typedef typename MachBits<nlist_type>::mach_header_type mach_header_type; 1740344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com typedef typename MachBits<nlist_type>::word_type word_type; 175b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 1760344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com const uint32_t magic = MachBits<nlist_type>::magic; 1770344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 1780344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com int maxlen = 500; 1790344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com int nreq = 0; 1800344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com for (nlist_type* q = list; 181b0d807666f3ab5af581e4687eba31717bbde86d5nealsid symbolNames[q-list] && symbolNames[q-list][0]; 182b0d807666f3ab5af581e4687eba31717bbde86d5nealsid q++, nreq++) { 183b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 184b0d807666f3ab5af581e4687eba31717bbde86d5nealsid q->n_type = 0; 185b0d807666f3ab5af581e4687eba31717bbde86d5nealsid q->n_value = 0; 186b0d807666f3ab5af581e4687eba31717bbde86d5nealsid q->n_desc = 0; 187b0d807666f3ab5af581e4687eba31717bbde86d5nealsid q->n_sect = 0; 188b0d807666f3ab5af581e4687eba31717bbde86d5nealsid q->n_un.n_strx = 0; 189b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 190b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 1910344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct exec buf; 192b0d807666f3ab5af581e4687eba31717bbde86d5nealsid if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf) || 1939dfe692010fa5ff96ba4c5dc5fa59fa63ab2ceabmark@chromium.org (N_BADMAG(buf) && *((uint32_t *)&buf) != magic && 1940f8f72d15582907c1b78094073738ae94a295431mark@chromium.org CFSwapInt32BigToHost(*((uint32_t *)&buf)) != FAT_MAGIC && 1959782bf5bc66e72f4cff27eded0861798d034862cmark@chromium.org /* The following is the big-endian ppc64 check */ 1969782bf5bc66e72f4cff27eded0861798d034862cmark@chromium.org (*((uint32_t*)&buf)) != FAT_MAGIC)) { 1970344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 198b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 199b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 200b0d807666f3ab5af581e4687eba31717bbde86d5nealsid /* Deal with fat file if necessary */ 2010344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com unsigned arch_offset = 0; 2020f8f72d15582907c1b78094073738ae94a295431mark@chromium.org if (CFSwapInt32BigToHost(*((uint32_t *)&buf)) == FAT_MAGIC || 2030344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com /* The following is the big-endian ppc64 check */ 2044ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach *((unsigned int *)&buf) == FAT_MAGIC) { 205b0d807666f3ab5af581e4687eba31717bbde86d5nealsid /* Read in the fat header */ 2060344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct fat_header fh; 2070344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lseek(fd, 0, SEEK_SET) == -1) { 2080344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 2090344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 210b0d807666f3ab5af581e4687eba31717bbde86d5nealsid if (read(fd, (char *)&fh, sizeof(fh)) != sizeof(fh)) { 2110344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 212b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 213b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 214b0d807666f3ab5af581e4687eba31717bbde86d5nealsid /* Convert fat_narchs to host byte order */ 2150f8f72d15582907c1b78094073738ae94a295431mark@chromium.org fh.nfat_arch = CFSwapInt32BigToHost(fh.nfat_arch); 216b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 217b0d807666f3ab5af581e4687eba31717bbde86d5nealsid /* Read in the fat archs */ 2180344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct fat_arch *fat_archs = 2190344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com (struct fat_arch *)malloc(fh.nfat_arch * sizeof(struct fat_arch)); 220b0d807666f3ab5af581e4687eba31717bbde86d5nealsid if (fat_archs == NULL) { 2210344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 222b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 223b0d807666f3ab5af581e4687eba31717bbde86d5nealsid if (read(fd, (char *)fat_archs, 224b0d807666f3ab5af581e4687eba31717bbde86d5nealsid sizeof(struct fat_arch) * fh.nfat_arch) != 2259dfe692010fa5ff96ba4c5dc5fa59fa63ab2ceabmark@chromium.org (ssize_t)(sizeof(struct fat_arch) * fh.nfat_arch)) { 226b0d807666f3ab5af581e4687eba31717bbde86d5nealsid free(fat_archs); 2270344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 228b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 229b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 230b0d807666f3ab5af581e4687eba31717bbde86d5nealsid /* 231b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * Convert archs to host byte ordering (a constraint of 232b0d807666f3ab5af581e4687eba31717bbde86d5nealsid * cpusubtype_getbestarch() 233b0d807666f3ab5af581e4687eba31717bbde86d5nealsid */ 2340344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com for (unsigned i = 0; i < fh.nfat_arch; i++) { 235b0d807666f3ab5af581e4687eba31717bbde86d5nealsid fat_archs[i].cputype = 2360f8f72d15582907c1b78094073738ae94a295431mark@chromium.org CFSwapInt32BigToHost(fat_archs[i].cputype); 237b0d807666f3ab5af581e4687eba31717bbde86d5nealsid fat_archs[i].cpusubtype = 2380f8f72d15582907c1b78094073738ae94a295431mark@chromium.org CFSwapInt32BigToHost(fat_archs[i].cpusubtype); 239b0d807666f3ab5af581e4687eba31717bbde86d5nealsid fat_archs[i].offset = 2400f8f72d15582907c1b78094073738ae94a295431mark@chromium.org CFSwapInt32BigToHost(fat_archs[i].offset); 241b0d807666f3ab5af581e4687eba31717bbde86d5nealsid fat_archs[i].size = 2420f8f72d15582907c1b78094073738ae94a295431mark@chromium.org CFSwapInt32BigToHost(fat_archs[i].size); 243b0d807666f3ab5af581e4687eba31717bbde86d5nealsid fat_archs[i].align = 2440f8f72d15582907c1b78094073738ae94a295431mark@chromium.org CFSwapInt32BigToHost(fat_archs[i].align); 245b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 246b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 2470344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct fat_arch *fap = NULL; 2480344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com for (unsigned i = 0; i < fh.nfat_arch; i++) { 2490344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (fat_archs[i].cputype == cpu_type) { 2500344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com fap = &fat_archs[i]; 2510344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com break; 252b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 2530344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 254b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 2550344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (!fap) { 256b0d807666f3ab5af581e4687eba31717bbde86d5nealsid free(fat_archs); 2570344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 2580344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 2590344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com arch_offset = fap->offset; 2600344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com free(fat_archs); 261b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 2620344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com /* Read in the beginning of the architecture-specific file */ 2630344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lseek(fd, arch_offset, SEEK_SET) == -1) { 2640344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 265b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 2660344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf)) { 2670344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 2680344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 2690344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 270b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 2710344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com off_t sa; /* symbol address */ 2720344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com off_t ss; /* start of strings */ 2734118773ebb628f6651e9e25c7654a260d822b4c1dmaclach register_t n; 2740344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (*((unsigned int *)&buf) == magic) { 2750344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lseek(fd, arch_offset, SEEK_SET) == -1) { 2760344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 2770344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 2780344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com mach_header_type mh; 2790344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (read(fd, (char *)&mh, sizeof(mh)) != sizeof(mh)) { 2800344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 2810344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 282b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 2830344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct load_command *load_commands = 2840344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com (struct load_command *)malloc(mh.sizeofcmds); 2850344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (load_commands == NULL) { 2860344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 2870344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 2880344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (read(fd, (char *)load_commands, mh.sizeofcmds) != 2899dfe692010fa5ff96ba4c5dc5fa59fa63ab2ceabmark@chromium.org (ssize_t)mh.sizeofcmds) { 2900344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com free(load_commands); 2910344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 2920344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 2930344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct symtab_command *stp = NULL; 2940344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com struct load_command *lcp = load_commands; 2950344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // iterate through all load commands, looking for 2960344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // LC_SYMTAB load command 2979dfe692010fa5ff96ba4c5dc5fa59fa63ab2ceabmark@chromium.org for (uint32_t i = 0; i < mh.ncmds; i++) { 2980344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lcp->cmdsize % sizeof(word_type) != 0 || 2990344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com lcp->cmdsize <= 0 || 3000344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com (char *)lcp + lcp->cmdsize > 3010344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com (char *)load_commands + mh.sizeofcmds) { 302b0d807666f3ab5af581e4687eba31717bbde86d5nealsid free(load_commands); 3030344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 304b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 3050344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lcp->cmd == LC_SYMTAB) { 3060344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lcp->cmdsize != 3070344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com sizeof(struct symtab_command)) { 308b0d807666f3ab5af581e4687eba31717bbde86d5nealsid free(load_commands); 3090344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 310b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 3110344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com stp = (struct symtab_command *)lcp; 3120344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com break; 313b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 3140344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com lcp = (struct load_command *) 3150344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com ((char *)lcp + lcp->cmdsize); 316b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 3170344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (stp == NULL) { 3180344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com free(load_commands); 3190344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 320b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 3210344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // sa points to the beginning of the symbol table 3220344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com sa = stp->symoff + arch_offset; 3230344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // ss points to the beginning of the string table 3240344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com ss = stp->stroff + arch_offset; 3250344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // n is the number of bytes in the symbol table 3260344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // each symbol table entry is an nlist structure 3270344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com n = stp->nsyms * sizeof(nlist_type); 3280344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com free(load_commands); 3290344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } else { 3300344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com sa = N_SYMOFF(buf) + arch_offset; 3310344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com ss = sa + buf.a_syms + arch_offset; 3320344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com n = buf.a_syms; 3330344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 334b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 3350344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lseek(fd, sa, SEEK_SET) == -1) { 3360344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 3370344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 3380344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 3390344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // the algorithm here is to read the nlist entries in m-sized 3400344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // chunks into q. q is then iterated over. for each entry in q, 3410344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // use the string table index(q->n_un.n_strx) to read the symbol 3420344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // name, then scan the nlist entries passed in by the user(via p), 3430344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // and look for a match 3440344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com while (n) { 3450344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com nlist_type space[BUFSIZ/sizeof (nlist_type)]; 3464118773ebb628f6651e9e25c7654a260d822b4c1dmaclach register_t m = sizeof (space); 3470344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com 3480344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (n < m) 3490344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com m = n; 3500344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (read(fd, (char *)space, m) != m) 3510344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com break; 3520344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com n -= m; 353486229ba5044ee2e7f49d2f6000e6535f2fca46cqsr@chromium.org off_t savpos = lseek(fd, 0, SEEK_CUR); 3540344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (savpos == -1) { 3550344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 3560344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 3570344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com for (nlist_type* q = space; (m -= sizeof(nlist_type)) >= 0; q++) { 3580344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com char nambuf[BUFSIZ]; 359b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 3600344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (q->n_un.n_strx == 0 || q->n_type & N_STAB) 3610344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com continue; 362b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 3630344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // seek to the location in the binary where the symbol 3640344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // name is stored & read it into memory 3650344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lseek(fd, ss+q->n_un.n_strx, SEEK_SET) == -1) { 3660344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 3670344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 3680344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (read(fd, nambuf, maxlen+1) == -1) { 3690344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 3700344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 3710344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com const char *s2 = nambuf; 3720344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com for (nlist_type *p = list; 3730344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com symbolNames[p-list] && symbolNames[p-list][0]; 3740344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com p++) { 3750344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // get the symbol name the user has passed in that 3760344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com // corresponds to the nlist entry that we're looking at 3770344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com const char *s1 = symbolNames[p - list]; 3780344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com while (*s1) { 3790344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (*s1++ != *s2++) 380b0d807666f3ab5af581e4687eba31717bbde86d5nealsid goto cont; 3810344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 3820344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (*s2) 3830344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com goto cont; 384b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 3850344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com p->n_value = q->n_value; 3860344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com p->n_type = q->n_type; 3870344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com p->n_desc = q->n_desc; 3880344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com p->n_sect = q->n_sect; 3890344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com p->n_un.n_strx = q->n_un.n_strx; 3900344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (--nreq == 0) 3910344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return nreq; 392b0d807666f3ab5af581e4687eba31717bbde86d5nealsid 3930344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com break; 3940344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com cont: ; 395b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 396b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 3970344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com if (lseek(fd, savpos, SEEK_SET) == -1) { 3980344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return -1; 3990344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com } 400b0d807666f3ab5af581e4687eba31717bbde86d5nealsid } 4010344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com return nreq; 4020344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com} 403