/* -*- c-file-style: "GNU" -*- */
/*
 * Copyright (C) CNRS, INRIA, Université Bordeaux 1, Télécom SudParis
 * See COPYING in top-level directory.
 *
 *
 * binary.c
 *
 * Wrapper to include the good library for parsing of binary files
 *
 *  Created on: 2 juil. 2011
 *      Author: Damien Martin-Guillerez <damien.martin-guillerez@inria.fr>
 */

#ifndef ENABLE_BINARY_INSTRUMENTATION
#error "This file is for binary instrumentation only"
#endif

#include "binary.h"

#include "eztrace-instrumentation/errors.h"

#include <eztrace-core/eztrace_config.h>
#include <eztrace-core/eztrace_types.h>
#include <stdlib.h>
#include <string.h>

struct ezt_instrumented_function *read_function_array(void* bin, zzt_symbol*sym) {

  /* get the size of the array */
  size_t size = sym->symbol_size;
  if (size <= 0)
    size = 1024;

  /* allocate an array and copy the symbol to it */
  struct ezt_instrumented_function * buf = malloc(size);
  if(buf == NULL)
    return NULL;

  read_symbol(bin, sym, buf, size);
  return buf;
}

char** read_zstring_array(void* bin, char* symbol) {
  char** result;
  char* buf;
  char buf2[4096];

  zzt_symbol* sym = get_symbol(bin, symbol);
  int bytes = get_binary_bits(bin) >> 3;
  if (sym == NULL)
    return NULL;

  size_t size = sym->symbol_size;
  if (size <= 0)
    size = 1024;
  buf = malloc(size);
  if (buf == NULL)
    return NULL;

  uint32_t* val32 = (uint32_t*)buf;
  word_uint* val64 = (word_uint*)buf;

  size = read_symbol(bin, sym, buf, size) / bytes;

  result = (char**)malloc(size * sizeof(char*));

  size_t i = 0;
  for (i = 0; i < size; i++) {
    zzt_word w = (bytes == 4) ? val32[i] : val64[i];
    if (w == 0) {
      result[i] = 0;
      free(buf);
      return result;
    }
    read_zstring(bin, sym, w, buf2, 1024);
    // printf("\t[%d] %p %s\n", i, (void*)w, buf2);
    result[i] = strdup(buf2);
  }
  free(buf);
  return result;
}

void free_zstring_array(char** strarray) {
  int i = 0;
  while (strarray[i] != NULL) {
    free(strarray[i]);
    i++;
  }
  free(strarray);
}
