/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*
 * Copyright (c) 1989, 1993
 * The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */


/*
 * This file was copied from libc/gen/nlist.c from Darwin's source code       
 * The version of nlist used as a base is from 10.5.2, libc-498               
 * http://www.opensource.apple.com/darwinsource/10.5.2/Libc-498/gen/nlist.c   
 *                                                                            
 * The full tarball is at:                                                    
 * http://www.opensource.apple.com/darwinsource/tarballs/apsl/Libc-498.tar.gz 
 *                                                                            
 * I've modified it to be compatible with 64-bit images.
*/

#include "breakpad_nlist_64.h"

#include <CoreFoundation/CoreFoundation.h>
#include <fcntl.h>
#include <mach-o/nlist.h>
#include <mach-o/loader.h>
#include <mach-o/fat.h>
#include <mach/mach.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <TargetConditionals.h>
#include <unistd.h>

/* Stuff lifted from <a.out.h> and <sys/exec.h> since they are gone */
/*
 * Header prepended to each a.out file.
 */
struct exec {
  unsigned short  a_machtype;     /* machine type */
  unsigned short  a_magic;        /* magic number */
  unsigned long a_text;         /* size of text segment */
  unsigned long a_data;         /* size of initialized data */
  unsigned long a_bss;          /* size of uninitialized data */
  unsigned long a_syms;         /* size of symbol table */
  unsigned long a_entry;        /* entry point */
  unsigned long a_trsize;       /* size of text relocation */
  unsigned long a_drsize;       /* size of data relocation */
};

#define OMAGIC  0407            /* old impure format */
#define NMAGIC  0410            /* read-only text */
#define ZMAGIC  0413            /* demand load format */

#define N_BADMAG(x)                                                     \
  (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)
#define N_TXTOFF(x)                                     \
  ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec))
#define N_SYMOFF(x)                                                     \
  (N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize)

// Traits structs for specializing function templates to handle
// 32-bit/64-bit Mach-O files.
template<typename T>
struct MachBits {};

typedef struct nlist nlist32;
typedef struct nlist_64 nlist64;

template<>
struct MachBits<nlist32> {
  typedef mach_header mach_header_type;
  typedef uint32_t word_type;
  static const uint32_t magic = MH_MAGIC;
};

template<>
struct MachBits<nlist64> {
  typedef mach_header_64 mach_header_type;
  typedef uint64_t word_type;
  static const uint32_t magic = MH_MAGIC_64;
};

template<typename nlist_type>
int
__breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames,
                   cpu_type_t cpu_type);

/*
 * nlist - retreive attributes from name list (string table version)
 */

template <typename nlist_type>
int breakpad_nlist_common(const char *name,
                          nlist_type *list,
                          const char **symbolNames,
                          cpu_type_t cpu_type) {
  int fd = open(name, O_RDONLY, 0);
  if (fd < 0)
    return -1;
  int n = __breakpad_fdnlist(fd, list, symbolNames, cpu_type);
  close(fd);
  return n;
}

int breakpad_nlist(const char *name,
                   struct nlist *list,
                   const char **symbolNames,
                   cpu_type_t cpu_type) {
  return breakpad_nlist_common(name, list, symbolNames, cpu_type);
}

int breakpad_nlist(const char *name,
                   struct nlist_64 *list,
                   const char **symbolNames,
                   cpu_type_t cpu_type) {
  return breakpad_nlist_common(name, list, symbolNames, cpu_type);
}

/* Note: __fdnlist() is called from kvm_nlist in libkvm's kvm.c */

template<typename nlist_type>
int __breakpad_fdnlist(int fd, nlist_type *list, const char **symbolNames,
                       cpu_type_t cpu_type) {
  typedef typename MachBits<nlist_type>::mach_header_type mach_header_type;
  typedef typename MachBits<nlist_type>::word_type word_type;

  const uint32_t magic = MachBits<nlist_type>::magic;

  int maxlen = 500;
  int nreq = 0;
  for (nlist_type* q = list;
       symbolNames[q-list] && symbolNames[q-list][0];
       q++, nreq++) {

    q->n_type = 0;
    q->n_value = 0;
    q->n_desc = 0;
    q->n_sect = 0;
    q->n_un.n_strx = 0;
  }

  struct exec buf;
  if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf) ||
      (N_BADMAG(buf) && *((uint32_t *)&buf) != magic &&
        CFSwapInt32BigToHost(*((uint32_t *)&buf)) != FAT_MAGIC &&
       /* The following is the big-endian ppc64 check */
       (*((uint32_t*)&buf)) != FAT_MAGIC)) {
    return -1;
  }

  /* Deal with fat file if necessary */
  unsigned arch_offset = 0;
  if (CFSwapInt32BigToHost(*((uint32_t *)&buf)) == FAT_MAGIC ||
      /* The following is the big-endian ppc64 check */
      *((unsigned int *)&buf) == FAT_MAGIC) {
    /* Read in the fat header */
    struct fat_header fh;
    if (lseek(fd, 0, SEEK_SET) == -1) {
      return -1;
    }
    if (read(fd, (char *)&fh, sizeof(fh)) != sizeof(fh)) {
      return -1;
    }

    /* Convert fat_narchs to host byte order */
    fh.nfat_arch = CFSwapInt32BigToHost(fh.nfat_arch);

    /* Read in the fat archs */
    struct fat_arch *fat_archs =
        (struct fat_arch *)malloc(fh.nfat_arch * sizeof(struct fat_arch));
    if (fat_archs == NULL) {
      return -1;
    }
    if (read(fd, (char *)fat_archs,
             sizeof(struct fat_arch) * fh.nfat_arch) !=
        (ssize_t)(sizeof(struct fat_arch) * fh.nfat_arch)) {
      free(fat_archs);
      return -1;
    }

    /*
     * Convert archs to host byte ordering (a constraint of
     * cpusubtype_getbestarch()
     */
    for (unsigned i = 0; i < fh.nfat_arch; i++) {
      fat_archs[i].cputype =
        CFSwapInt32BigToHost(fat_archs[i].cputype);
      fat_archs[i].cpusubtype =
        CFSwapInt32BigToHost(fat_archs[i].cpusubtype);
      fat_archs[i].offset =
        CFSwapInt32BigToHost(fat_archs[i].offset);
      fat_archs[i].size =
        CFSwapInt32BigToHost(fat_archs[i].size);
      fat_archs[i].align =
        CFSwapInt32BigToHost(fat_archs[i].align);
    }

    struct fat_arch *fap = NULL;
    for (unsigned i = 0; i < fh.nfat_arch; i++) {
      if (fat_archs[i].cputype == cpu_type) {
        fap = &fat_archs[i];
        break;
      }
    }

    if (!fap) {
      free(fat_archs);
      return -1;
    }
    arch_offset = fap->offset;
    free(fat_archs);

    /* Read in the beginning of the architecture-specific file */
    if (lseek(fd, arch_offset, SEEK_SET) == -1) {
      return -1;
    }
    if (read(fd, (char *)&buf, sizeof(buf)) != sizeof(buf)) {
      return -1;
    }
  }

  off_t sa;  /* symbol address */
  off_t ss;  /* start of strings */
  register_t n;
  if (*((unsigned int *)&buf) == magic) {
    if (lseek(fd, arch_offset, SEEK_SET) == -1) {
      return -1;
    }
    mach_header_type mh;
    if (read(fd, (char *)&mh, sizeof(mh)) != sizeof(mh)) {
      return -1;
    }

    struct load_command *load_commands =
        (struct load_command *)malloc(mh.sizeofcmds);
    if (load_commands == NULL) {
      return -1;
    }
    if (read(fd, (char *)load_commands, mh.sizeofcmds) !=
        (ssize_t)mh.sizeofcmds) {
      free(load_commands);
      return -1;
    }
    struct symtab_command *stp = NULL;
    struct load_command *lcp = load_commands;
    // iterate through all load commands, looking for
    // LC_SYMTAB load command
    for (uint32_t i = 0; i < mh.ncmds; i++) {
      if (lcp->cmdsize % sizeof(word_type) != 0 ||
          lcp->cmdsize <= 0 ||
          (char *)lcp + lcp->cmdsize >
          (char *)load_commands + mh.sizeofcmds) {
        free(load_commands);
        return -1;
      }
      if (lcp->cmd == LC_SYMTAB) {
        if (lcp->cmdsize !=
            sizeof(struct symtab_command)) {
          free(load_commands);
          return -1;
        }
        stp = (struct symtab_command *)lcp;
        break;
      }
      lcp = (struct load_command *)
        ((char *)lcp + lcp->cmdsize);
    }
    if (stp == NULL) {
      free(load_commands);
      return -1;
    }
    // sa points to the beginning of the symbol table
    sa = stp->symoff + arch_offset;
    // ss points to the beginning of the string table
    ss = stp->stroff + arch_offset;
    // n is the number of bytes in the symbol table
    // each symbol table entry is an nlist structure
    n = stp->nsyms * sizeof(nlist_type);
    free(load_commands);
  } else {
    sa = N_SYMOFF(buf) + arch_offset;
    ss = sa + buf.a_syms + arch_offset;
    n = buf.a_syms;
  }

  if (lseek(fd, sa, SEEK_SET) == -1) {
    return -1;
  }

  // the algorithm here is to read the nlist entries in m-sized
  // chunks into q.  q is then iterated over. for each entry in q,
  // use the string table index(q->n_un.n_strx) to read the symbol 
  // name, then scan the nlist entries passed in by the user(via p),
  // and look for a match
  while (n) {
    nlist_type space[BUFSIZ/sizeof (nlist_type)];
    register_t m = sizeof (space);

    if (n < m)
      m = n;
    if (read(fd, (char *)space, m) != m)
      break;
    n -= m;
    off_t savpos = lseek(fd, 0, SEEK_CUR);
    if (savpos == -1) {
      return -1;
    }
    for (nlist_type* q = space; (m -= sizeof(nlist_type)) >= 0; q++) {
      char nambuf[BUFSIZ];

      if (q->n_un.n_strx == 0 || q->n_type & N_STAB)
        continue;

      // seek to the location in the binary where the symbol
      // name is stored & read it into memory
      if (lseek(fd, ss+q->n_un.n_strx, SEEK_SET) == -1) {
        return -1;
      }
      if (read(fd, nambuf, maxlen+1) == -1) {
        return -1;
      }
      const char *s2 = nambuf;
      for (nlist_type *p = list; 
           symbolNames[p-list] && symbolNames[p-list][0];
           p++) {
        // get the symbol name the user has passed in that 
        // corresponds to the nlist entry that we're looking at
        const char *s1 = symbolNames[p - list];
        while (*s1) {
          if (*s1++ != *s2++)
            goto cont;
        }
        if (*s2)
          goto cont;

        p->n_value = q->n_value;
        p->n_type = q->n_type;
        p->n_desc = q->n_desc;
        p->n_sect = q->n_sect;
        p->n_un.n_strx = q->n_un.n_strx;
        if (--nreq == 0)
          return nreq;

        break;
      cont:           ;
      }
    }
    if (lseek(fd, savpos, SEEK_SET) == -1) {
      return -1;
    }
  }
  return nreq;
}
