/* Get macro information.
   Copyright (C) 2002-2009, 2014 Red Hat, Inc.
   This file is part of elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 2002.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   elfutils is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <assert.h>
#include <dwarf.h>
#include <search.h>
#include <stdlib.h>
#include <string.h>

#include <libdwP.h>

static int
get_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp)
{
  /* Get the appropriate attribute.  */
  Dwarf_Attribute attr;
  if (INTUSE(dwarf_attr) (die, name, &attr) == NULL)
    return -1;

  /* Offset into the corresponding section.  */
  return INTUSE(dwarf_formudata) (&attr, retp);
}

static int
macro_op_compare (const void *p1, const void *p2)
{
  const Dwarf_Macro_Op_Table *t1 = (const Dwarf_Macro_Op_Table *) p1;
  const Dwarf_Macro_Op_Table *t2 = (const Dwarf_Macro_Op_Table *) p2;

  if (t1->offset < t2->offset)
    return -1;
  if (t1->offset > t2->offset)
    return 1;

  if (t1->sec_index < t2->sec_index)
    return -1;
  if (t1->sec_index > t2->sec_index)
    return 1;

  return 0;
}

static void
build_table (Dwarf_Macro_Op_Table *table,
	     Dwarf_Macro_Op_Proto op_protos[static 255])
{
  unsigned ct = 0;
  for (unsigned i = 1; i < 256; ++i)
    if (op_protos[i - 1].forms != NULL)
      table->table[table->opcodes[i - 1] = ct++] = op_protos[i - 1];
    else
      table->opcodes[i - 1] = 0xff;
}

#define MACRO_PROTO(NAME, ...)					\
  Dwarf_Macro_Op_Proto NAME = ({				\
      static const uint8_t proto[] = {__VA_ARGS__};		\
      (Dwarf_Macro_Op_Proto) {sizeof proto, proto};		\
    })

enum { macinfo_data_size = offsetof (Dwarf_Macro_Op_Table, table[5]) };
static unsigned char macinfo_data[macinfo_data_size]
	__attribute__ ((aligned (__alignof (Dwarf_Macro_Op_Table))));

static __attribute__ ((constructor)) void
init_macinfo_table (void)
{
  MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
  MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
  MACRO_PROTO (p_none);

  Dwarf_Macro_Op_Proto op_protos[255] =
    {
      [DW_MACINFO_define - 1] = p_udata_str,
      [DW_MACINFO_undef - 1] = p_udata_str,
      [DW_MACINFO_vendor_ext - 1] = p_udata_str,
      [DW_MACINFO_start_file - 1] = p_udata_udata,
      [DW_MACINFO_end_file - 1] = p_none,
      /* If you are adding more elements to this array, increase
	 MACINFO_DATA_SIZE above.  */
    };

  Dwarf_Macro_Op_Table *macinfo_table = (void *) macinfo_data;
  memset (macinfo_table, 0, sizeof macinfo_data);
  build_table (macinfo_table, op_protos);
  macinfo_table->sec_index = IDX_debug_macinfo;
}

static Dwarf_Macro_Op_Table *
get_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie)
{
  assert (cudie != NULL);

  Dwarf_Attribute attr_mem, *attr
    = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
  Dwarf_Off line_offset = (Dwarf_Off) -1;
  if (attr != NULL)
    INTUSE(dwarf_formudata) (attr, &line_offset);

  Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
					     macinfo_data_size, 1);
  memcpy (table, macinfo_data, macinfo_data_size);

  table->offset = macoff;
  table->sec_index = IDX_debug_macinfo;
  table->line_offset = line_offset;
  table->is_64bit = cudie->cu->address_size == 8;
  table->comp_dir = __libdw_getcompdir (cudie);

  return table;
}

static Dwarf_Macro_Op_Table *
get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
		      const unsigned char *readp,
		      const unsigned char *const endp,
		      Dwarf_Die *cudie)
{
  const unsigned char *startp = readp;

  /* Request at least 3 bytes for header.  */
  if (readp + 3 > endp)
    {
    invalid_dwarf:
      __libdw_seterrno (DWARF_E_INVALID_DWARF);
      return NULL;
    }

  uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
  if (version != 4)
    {
      __libdw_seterrno (DWARF_E_INVALID_VERSION);
      return NULL;
    }

  uint8_t flags = *readp++;
  bool is_64bit = (flags & 0x1) != 0;

  Dwarf_Off line_offset = (Dwarf_Off) -1;
  if ((flags & 0x2) != 0)
    {
      line_offset = read_addr_unaligned_inc (is_64bit ? 8 : 4, dbg, readp);
      if (readp > endp)
	goto invalid_dwarf;
    }
  else if (cudie != NULL)
    {
      Dwarf_Attribute attr_mem, *attr
	= INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
      if (attr != NULL)
	INTUSE(dwarf_formudata) (attr, &line_offset);
    }

  /* """The macinfo entry types defined in this standard may, but
     might not, be described in the table""".

     I.e. these may be present.  It's tempting to simply skip them,
     but it's probably more correct to tolerate that a producer tweaks
     the way certain opcodes are encoded, for whatever reasons.  */

  MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
  MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp);
  MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
  MACRO_PROTO (p_secoffset, DW_FORM_sec_offset);
  MACRO_PROTO (p_none);

  Dwarf_Macro_Op_Proto op_protos[255] =
    {
      [DW_MACRO_GNU_define - 1] = p_udata_str,
      [DW_MACRO_GNU_undef - 1] = p_udata_str,
      [DW_MACRO_GNU_define_indirect - 1] = p_udata_strp,
      [DW_MACRO_GNU_undef_indirect - 1] = p_udata_strp,
      [DW_MACRO_GNU_start_file - 1] = p_udata_udata,
      [DW_MACRO_GNU_end_file - 1] = p_none,
      [DW_MACRO_GNU_transparent_include - 1] = p_secoffset,
      /* N.B. DW_MACRO_undef_indirectx, DW_MACRO_define_indirectx
	 should be added when 130313.1 is supported.  */
    };

  if ((flags & 0x4) != 0)
    {
      unsigned count = *readp++;
      for (unsigned i = 0; i < count; ++i)
	{
	  unsigned opcode = *readp++;

	  Dwarf_Macro_Op_Proto e;
	  get_uleb128 (e.nforms, readp); // XXX checking
	  e.forms = readp;
	  op_protos[opcode - 1] = e;

	  readp += e.nforms;
	  if (readp > endp)
	    {
	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
	      return NULL;
	    }
	}
    }

  size_t ct = 0;
  for (unsigned i = 1; i < 256; ++i)
    if (op_protos[i - 1].forms != NULL)
      ++ct;

  /* We support at most 0xfe opcodes defined in the table, as 0xff is
     a value that means that given opcode is not stored at all.  But
     that should be fine, as opcode 0 is not allocated.  */
  assert (ct < 0xff);

  size_t macop_table_size = offsetof (Dwarf_Macro_Op_Table, table[ct]);

  Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
					     macop_table_size, 1);

  *table = (Dwarf_Macro_Op_Table) {
    .offset = macoff,
    .sec_index = IDX_debug_macro,
    .line_offset = line_offset,
    .header_len = readp - startp,
    .version = version,
    .is_64bit = is_64bit,

    /* NULL if CUDIE is NULL or DW_AT_comp_dir is absent.  */
    .comp_dir = __libdw_getcompdir (cudie),
  };
  build_table (table, op_protos);

  return table;
}

static Dwarf_Macro_Op_Table *
cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff,
		const unsigned char *startp,
		const unsigned char *const endp,
		Dwarf_Die *cudie)
{
  Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index };
  Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops,
					macro_op_compare);
  if (found != NULL)
    return *found;

  Dwarf_Macro_Op_Table *table = sec_index == IDX_debug_macro
    ? get_table_for_offset (dbg, macoff, startp, endp, cudie)
    : get_macinfo_table (dbg, macoff, cudie);

  if (table == NULL)
    return NULL;

  Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops,
					macro_op_compare);
  if (unlikely (ret == NULL))
    {
      __libdw_seterrno (DWARF_E_NOMEM);
      return NULL;
    }

  return *ret;
}

static ptrdiff_t
read_macros (Dwarf *dbg, int sec_index,
	     Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *),
	     void *arg, ptrdiff_t offset, bool accept_0xff,
	     Dwarf_Die *cudie)
{
  Elf_Data *d = dbg->sectiondata[sec_index];
  if (unlikely (d == NULL || d->d_buf == NULL))
    {
      __libdw_seterrno (DWARF_E_NO_ENTRY);
      return -1;
    }

  if (unlikely (macoff >= d->d_size))
    {
      __libdw_seterrno (DWARF_E_INVALID_DWARF);
      return -1;
    }

  const unsigned char *const startp = d->d_buf + macoff;
  const unsigned char *const endp = d->d_buf + d->d_size;

  Dwarf_Macro_Op_Table *table = cache_op_table (dbg, sec_index, macoff,
						startp, endp, cudie);
  if (table == NULL)
    return -1;

  if (offset == 0)
    offset = table->header_len;

  assert (offset >= 0);
  assert (offset < endp - startp);
  const unsigned char *readp = startp + offset;

  while (readp < endp)
    {
      unsigned int opcode = *readp++;
      if (opcode == 0)
	/* Nothing more to do.  */
	return 0;

      if (unlikely (opcode == 0xff && ! accept_0xff))
	{
	  /* See comment below at dwarf_getmacros for explanation of
	     why we are doing this.  */
	  __libdw_seterrno (DWARF_E_INVALID_OPCODE);
	  return -1;
	}

      unsigned int idx = table->opcodes[opcode - 1];
      if (idx == 0xff)
	{
	  __libdw_seterrno (DWARF_E_INVALID_OPCODE);
	  return -1;
	}

      Dwarf_Macro_Op_Proto *proto = &table->table[idx];

      /* A fake CU with bare minimum data to fool dwarf_formX into
	 doing the right thing with the attributes that we put out.
	 We arbitrarily pretend it's version 4.  */
      Dwarf_CU fake_cu = {
	.dbg = dbg,
	.version = 4,
	.offset_size = table->is_64bit ? 8 : 4,
      };

      Dwarf_Attribute attributes[proto->nforms];
      for (Dwarf_Word i = 0; i < proto->nforms; ++i)
	{
	  /* We pretend this is a DW_AT_GNU_macros attribute so that
	     DW_FORM_sec_offset forms get correctly interpreted as
	     offset into .debug_macro.  */
	  attributes[i].code = DW_AT_GNU_macros;
	  attributes[i].form = proto->forms[i];
	  attributes[i].valp = (void *) readp;
	  attributes[i].cu = &fake_cu;

	  size_t len = __libdw_form_val_len (dbg, &fake_cu,
					     proto->forms[i], readp, endp);
	  if (len == (size_t) -1)
	    return -1;

	  readp += len;
	}

      Dwarf_Macro macro = {
	.table = table,
	.opcode = opcode,
	.attributes = attributes,
      };

      if (callback (&macro, arg) != DWARF_CB_OK)
	return readp - startp;
    }

  return 0;
}

/* Token layout:

   - The highest bit is used for distinguishing between callers that
     know that opcode 0xff may have one of two incompatible meanings.
     The mask that we use for selecting this bit is
     DWARF_GETMACROS_START.

   - The rest of the token (31 or 63 bits) encodes address inside the
     macro unit.

   Besides, token value of 0 signals end of iteration and -1 is
   reserved for signaling errors.  That means it's impossible to
   represent maximum offset of a .debug_macro unit to new-style
   callers (which in practice decreases the permissible macro unit
   size by another 1 byte).  */

static ptrdiff_t
token_from_offset (ptrdiff_t offset, bool accept_0xff)
{
  if (offset == -1 || offset == 0)
    return offset;

  /* Make sure the offset didn't overflow into the flag bit.  */
  if ((offset & DWARF_GETMACROS_START) != 0)
    {
      __libdw_seterrno (DWARF_E_TOO_BIG);
      return -1;
    }

  if (accept_0xff)
    offset |= DWARF_GETMACROS_START;

  return offset;
}

static ptrdiff_t
offset_from_token (ptrdiff_t token, bool *accept_0xffp)
{
  *accept_0xffp = (token & DWARF_GETMACROS_START) != 0;
  token &= ~DWARF_GETMACROS_START;

  return token;
}

static ptrdiff_t
gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
			  int (*callback) (Dwarf_Macro *, void *),
			  void *arg, ptrdiff_t offset, bool accept_0xff,
			  Dwarf_Die *cudie)
{
  assert (offset >= 0);

  if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size)
    {
      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
      return -1;
    }

  return read_macros (dbg, IDX_debug_macro, macoff,
		      callback, arg, offset, accept_0xff, cudie);
}

static ptrdiff_t
macro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
			  int (*callback) (Dwarf_Macro *, void *),
			  void *arg, ptrdiff_t offset, Dwarf_Die *cudie)
{
  assert (offset >= 0);

  return read_macros (dbg, IDX_debug_macinfo, macoff,
		      callback, arg, offset, true, cudie);
}

ptrdiff_t
dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
		     int (*callback) (Dwarf_Macro *, void *),
		     void *arg, ptrdiff_t token)
{
  if (dbg == NULL)
    {
      __libdw_seterrno (DWARF_E_NO_DWARF);
      return -1;
    }

  bool accept_0xff;
  ptrdiff_t offset = offset_from_token (token, &accept_0xff);
  assert (accept_0xff);

  offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset,
				     accept_0xff, NULL);

  return token_from_offset (offset, accept_0xff);
}

ptrdiff_t
dwarf_getmacros (cudie, callback, arg, token)
     Dwarf_Die *cudie;
     int (*callback) (Dwarf_Macro *, void *);
     void *arg;
     ptrdiff_t token;
{
  if (cudie == NULL)
    {
      __libdw_seterrno (DWARF_E_NO_DWARF);
      return -1;
    }

  /* This function might be called from a code that expects to see
     DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones.  It is fine to
     serve most DW_MACRO_{GNU_,}* opcodes to such code, because those
     whose values are the same as DW_MACINFO_* ones also have the same
     behavior.  It is not very likely that a .debug_macro section
     would only use the part of opcode space that it shares with
     .debug_macinfo, but it is possible.  Serving the opcodes that are
     only valid in DW_MACRO_{GNU_,}* domain is OK as well, because
     clients in general need to be ready that newer standards define
     more opcodes, and have coping mechanisms for unfamiliar opcodes.

     The one exception to the above rule is opcode 0xff, which has
     concrete semantics in .debug_macinfo, but falls into vendor block
     in .debug_macro, and can be assigned to do whatever.  There is
     some small probability that the two opcodes would look
     superficially similar enough that a client would be confused and
     misbehave as a result.  For this reason, we refuse to serve
     through this interface 0xff's originating from .debug_macro
     unless the TOKEN that we obtained indicates the call originates
     from a new-style caller.  See above for details on what
     information is encoded into tokens.  */

  bool accept_0xff;
  ptrdiff_t offset = offset_from_token (token, &accept_0xff);

  /* DW_AT_macro_info */
  if (dwarf_hasattr (cudie, DW_AT_macro_info))
    {
      Dwarf_Word macoff;
      if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0)
	return -1;
      offset = macro_info_getmacros_off (cudie->cu->dbg, macoff,
					 callback, arg, offset, cudie);
    }
  else
    {
      /* DW_AT_GNU_macros, DW_AT_macros */
      Dwarf_Word macoff;
      if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0)
	return -1;
      offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff,
					 callback, arg, offset, accept_0xff,
					 cudie);
    }

  return token_from_offset (offset, accept_0xff);
}
