/*
 * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "fmap.h"
#include "futility.h"

enum { FMT_NORMAL, FMT_PRETTY, FMT_FLASHROM, FMT_HUMAN };

/* global variables */
static int opt_extract = 0;
static int opt_format = FMT_NORMAL;
static int opt_overlap = 0;
static char *progname;
static void *base_of_rom;
static int opt_gaps = 0;


/* Return 0 if successful */
static int dump_fmap(const void *ptr, int argc, char *argv[])
{
  int i, retval = 0;
  char buf[80];                         // DWR: magic number
  const FmapHeader *fmh = (const FmapHeader*)ptr;
  const FmapAreaHeader *ah = (const FmapAreaHeader*)(ptr + sizeof(FmapHeader));

  if (FMT_NORMAL == opt_format) {
    snprintf(buf, FMAP_SIGNATURE_SIZE+1, "%s", fmh->fmap_signature);
    printf("fmap_signature   %s\n", buf);
    printf("fmap_version:    %d.%d\n",
           fmh->fmap_ver_major, fmh->fmap_ver_minor);
    printf("fmap_base:       0x%" PRIx64 "\n", fmh->fmap_base);
    printf("fmap_size:       0x%08x (%d)\n", fmh->fmap_size, fmh->fmap_size);
    snprintf(buf, FMAP_NAMELEN+1, "%s", fmh->fmap_name);
    printf("fmap_name:       %s\n", buf);
    printf("fmap_nareas:     %d\n", fmh->fmap_nareas);
  }

  for (i = 0; i < fmh->fmap_nareas; i++, ah++) {
    snprintf(buf, FMAP_NAMELEN+1, "%s", ah->area_name);

    if (argc) {
      int j, found=0;
      for (j = 0; j < argc; j++)
        if (!strcmp(argv[j], buf)) {
          found = 1;
          break;
        }
      if (!found) {
        continue;
      }
    }

    switch (opt_format) {
    case FMT_PRETTY:
      printf("%s %d %d\n", buf, ah->area_offset, ah->area_size);
      break;
    case FMT_FLASHROM:
      if (ah->area_size)
        printf("0x%08x:0x%08x %s\n", ah->area_offset,
               ah->area_offset + ah->area_size - 1, buf);
      break;
    default:
      printf("area:            %d\n", i+1);
      printf("area_offset:     0x%08x\n", ah->area_offset);
      printf("area_size:       0x%08x (%d)\n", ah->area_size, ah->area_size);
      printf("area_name:       %s\n", buf);
    }

    if (opt_extract) {
      char *s;
      for (s = buf; *s; s++)
        if (*s == ' ')
          *s = '_';
      FILE *fp = fopen(buf,"wb");
      if (!fp) {
        fprintf(stderr, "%s: can't open %s: %s\n",
                progname, buf, strerror(errno));
        retval = 1;
      } else {
        if (ah->area_size &&
            1 != fwrite(base_of_rom + ah->area_offset, ah->area_size, 1, fp)) {
          fprintf(stderr, "%s: can't write %s: %s\n",
                  progname, buf, strerror(errno));
          retval = 1;
        } else {
          if (FMT_NORMAL == opt_format)
            printf("saved as \"%s\"\n", buf);
        }
        fclose(fp);
      }
    }
  }

  return retval;
}


/****************************************************************************/
/* Stuff for human-readable form */

typedef struct dup_s {
  char *name;
  struct dup_s *next;
} dupe_t;

typedef struct node_s {
  char *name;
  uint32_t start;
  uint32_t size;
  uint32_t end;
  struct node_s *parent;
  int num_children;
  struct node_s **child;
  dupe_t *alias;
} node_t;

static node_t *all_nodes;

static void sort_nodes(int num, node_t *ary[])
{
  int i, j;
  node_t *tmp;

  /* bubble-sort is quick enough with only a few entries */
  for (i = 0; i < num; i++) {
    for (j = i + 1; j < num; j++) {
      if (ary[j]->start > ary[i]->start) {
        tmp = ary[i];
        ary[i] = ary[j];
        ary[j] = tmp;
      }
    }
  }
}


static void line(int indent, char *name,
                 uint32_t start, uint32_t end, uint32_t size, char *append)
{
  int i;
  for (i = 0; i < indent; i++)
    printf("  ");
  printf("%-25s  %08x    %08x    %08x%s\n", name, start, end, size,
         append ? append : "");
}

static int gapcount;
static void empty(int indent, uint32_t start, uint32_t end, char *name)
{
  char buf[80];
  if (opt_gaps) {
    sprintf(buf, "  // gap in %s", name);
    line(indent + 1, "", start, end, end - start, buf);
  }
  gapcount++;
}

static void show(node_t *p, int indent, int show_first)
{
  int i;
  dupe_t *alias;
  if (show_first) {
    line(indent, p->name, p->start, p->end, p->size, 0);
    for (alias = p->alias; alias; alias = alias->next)
      line(indent, alias->name, p->start, p->end, p->size, "  // DUPLICATE");
  }
  sort_nodes(p->num_children, p->child);
  for (i = 0; i < p->num_children; i++) {
      if (i == 0 && p->end != p->child[i]->end)
        empty(indent, p->child[i]->end, p->end, p->name);
      show(p->child[i], indent + show_first, 1);
      if (i < p->num_children - 1 && p->child[i]->start != p->child[i+1]->end)
        empty(indent, p->child[i+1]->end, p->child[i]->start, p->name);
      if (i == p->num_children - 1 && p->child[i]->start != p->start)
        empty(indent, p->start, p->child[i]->start, p->name);
  }
}

static int overlaps(int i, int j)
{
  node_t *a = all_nodes + i;
  node_t *b = all_nodes + j;

  return ((a->start < b->start) && (b->start < a->end) &&
          (b->start < a->end) && (a->end < b->end));
}

static int encloses(int i, int j)
{
  node_t *a = all_nodes + i;
  node_t *b = all_nodes + j;

  return ((a->start <= b->start) &&
          (a->end >= b->end));
}

static int duplicates(int i, int j)
{
  node_t *a = all_nodes + i;
  node_t *b = all_nodes + j;

  return ((a->start == b->start) &&
          (a->end == b->end));
}

static void add_dupe(int i, int j, int numnodes)
{
  int k;
  dupe_t *alias;

  alias = (dupe_t *)malloc(sizeof(dupe_t));
  alias->name = all_nodes[j].name;
  alias->next = all_nodes[i].alias;
  all_nodes[i].alias = alias;
  for (k = j; k < numnodes; k++ )
    all_nodes[k] = all_nodes[k + 1];
}

static void add_child(node_t *p, int n)
{
  int i;
  if (p->num_children && !p->child) {
    p->child = (struct node_s **)calloc(p->num_children, sizeof(node_t *));
    if (!p->child) {
      perror("calloc failed");
      exit(1);
    }
  }
  for (i = 0; i < p->num_children; i++)
    if (!p->child[i]) {
      p->child[i] = all_nodes + n;
      return;
    }
}

static int human_fmap(void *p)
{
  FmapHeader *fmh;
  FmapAreaHeader *ah;
  int i, j, errorcnt=0;
  int numnodes;

  fmh = (FmapHeader *)p;
  ah = (FmapAreaHeader *)(fmh + 1);

  /* The challenge here is to generate a directed graph from the
   * arbitrarily-ordered FMAP entries, and then to prune it until it's as
   * simple (and deep) as possible. Overlapping regions are not allowed.
   * Duplicate regions are okay, but may require special handling. */

  /* Convert the FMAP info into our format. */
  numnodes = fmh->fmap_nareas;

  /* plus one for the all-enclosing "root" */
  all_nodes = (node_t *)calloc(numnodes+1, sizeof(node_t));
  if (!all_nodes) {
    perror("calloc failed");
    exit(1);
  }
  for (i = 0; i < numnodes; i++) {
    char buf[FMAP_NAMELEN+1];
    strncpy(buf, ah[i].area_name, FMAP_NAMELEN);
    buf[FMAP_NAMELEN] = '\0';
    if (!(all_nodes[i].name = strdup(buf))) {
      perror("strdup failed");
      exit(1);
    }
    all_nodes[i].start = ah[i].area_offset;
    all_nodes[i].size = ah[i].area_size;
    all_nodes[i].end = ah[i].area_offset + ah[i].area_size;
  }
  /* Now add the root node */
  all_nodes[numnodes].name = strdup("-entire flash-");
  all_nodes[numnodes].start = fmh->fmap_base;
  all_nodes[numnodes].size = fmh->fmap_size;
  all_nodes[numnodes].end = fmh->fmap_base + fmh->fmap_size;


  /* First, coalesce any duplicates */
  for (i = 0; i < numnodes; i++) {
    for (j = i + 1; j < numnodes; j++) {
      if (duplicates(i, j)) {
        add_dupe(i, j, numnodes);
        numnodes--;
      }
    }
  }

  /* Each node should have at most one parent, which is the smallest enclosing
   * node. Duplicate nodes "enclose" each other, but if there's already a
   * relationship in one direction, we won't create another. */
  for (i = 0; i < numnodes; i++) {
    /* Find the smallest parent, which might be the root node. */
    int k = numnodes;
    for (j = 0; j < numnodes; j++) {    /* full O(N^2), not triangular */
      if (i == j)
        continue;
      if (overlaps(i, j)) {
        printf("ERROR: %s and %s overlap\n",
               all_nodes[i].name, all_nodes[j].name);
        printf("  %s: 0x%x - 0x%x\n", all_nodes[i].name,
               all_nodes[i].start, all_nodes[i].end);
        printf("  %s: 0x%x - 0x%x\n", all_nodes[j].name,
               all_nodes[j].start, all_nodes[j].end);
        if (opt_overlap < 2) {
          printf("Use more -h args to ignore this error\n");
          errorcnt++;
        }
        continue;
      }
      if (encloses(j, i) && all_nodes[j].size < all_nodes[k].size)
        k = j;
    }
    all_nodes[i].parent = all_nodes + k;
  }
  if (errorcnt)
    return 1;

  /* Force those deadbeat parents to recognize their children */
  for (i = 0; i < numnodes; i++)        /* how many */
    if (all_nodes[i].parent)
      all_nodes[i].parent->num_children++;
  for (i = 0; i < numnodes; i++)        /* here they are */
    if (all_nodes[i].parent)
      add_child(all_nodes[i].parent, i);

  /* Ready to go */
  printf("# name                     start       end         size\n");
  show(all_nodes + numnodes, 0, opt_gaps);

  if (gapcount && !opt_gaps)
    printf("\nWARNING: unused regions found. Use -H to see them\n");

  return 0;
}

/* End of human-reable stuff */
/****************************************************************************/

static int do_dump_fmap(int argc, char *argv[])
{
  int c;
  int errorcnt = 0;
  struct stat sb;
  int fd;
  const char *fmap;
  int retval = 1;

  progname = strrchr(argv[0], '/');
  if (progname)
    progname++;
  else
    progname = argv[0];

  opterr = 0;                           /* quiet, you */
  while ((c = getopt(argc, argv, ":xpfhH")) != -1) {
    switch (c) {
    case 'x':
      opt_extract = 1;
      break;
    case 'p':
      opt_format = FMT_PRETTY;
      break;
    case 'f':
      opt_format = FMT_FLASHROM;
      break;
    case 'H':
      opt_gaps = 1;
      /* fallthrough */
    case 'h':
      opt_format = FMT_HUMAN;
      opt_overlap++;
      break;
    case '?':
      fprintf(stderr, "%s: unrecognized switch: -%c\n",
              progname, optopt);
      errorcnt++;
      break;
    case ':':
      fprintf(stderr, "%s: missing argument to -%c\n",
              progname, optopt);
      errorcnt++;
      break;
    default:
      errorcnt++;
      break;
    }
  }

  if (errorcnt || optind >= argc) {
    fprintf(stderr,
      "\nUsage:  %s [-x] [-p|-f|-h] FLASHIMAGE [NAME...]\n\n"
      "Display (and extract with -x) the FMAP components from a BIOS image.\n"
      "The -p option makes the output easier to parse by scripts.\n"
      "The -f option emits the FMAP in the format used by flashrom.\n"
      "\n"
      "Specify one or more NAMEs to only print sections that exactly match.\n"
      "\n"
      "The -h option shows the whole FMAP in human-readable form.\n"
      "  Use -H to also display any gaps.\n"
      "\n",
      progname);
    return 1;
  }

  if (0 != stat(argv[optind], &sb)) {
    fprintf(stderr, "%s: can't stat %s: %s\n",
            progname,
            argv[optind],
            strerror(errno));
    return 1;
  }

  fd = open(argv[optind], O_RDONLY);
  if (fd < 0) {
    fprintf(stderr, "%s: can't open %s: %s\n",
            progname,
            argv[optind],
            strerror(errno));
    return 1;
  }
  if (FMT_NORMAL == opt_format)
    printf("opened %s\n", argv[optind]);

  base_of_rom = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
  if (base_of_rom == (char*)-1) {
    fprintf(stderr, "%s: can't mmap %s: %s\n",
            progname,
            argv[optind],
            strerror(errno));
    close(fd);
    return 1;
  }
  close(fd);                            /* done with this now */

  fmap = FmapFind((char*) base_of_rom, sb.st_size);
  if (fmap) {
    switch (opt_format) {
    case FMT_HUMAN:
      retval = human_fmap((void *)fmap);
      break;
    case FMT_NORMAL:
      printf("hit at 0x%08x\n", (uint32_t) (fmap - (char*) base_of_rom));
      /* fallthrough */
    default:
      retval = dump_fmap(fmap, argc-optind-1, argv+optind+1);
    }
  }

  if (0 != munmap(base_of_rom, sb.st_size)) {
    fprintf(stderr, "%s: can't munmap %s: %s\n",
            progname,
            argv[optind],
            strerror(errno));
    return 1;
  }

  return retval;
}

DECLARE_FUTIL_COMMAND(dump_fmap, do_dump_fmap,
                      "Display FMAP contents from a firmware image");
