/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
   Copyright 1998, 1999 Free Software Foundation, Inc.

Written by Gavin Romig-Koch of Cygnus Solutions (gavin@cygnus.com).  

This file is part of BFD.

This program is free software; you can redistribute it and/or modify
it under the terms of 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.

This program 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 a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include "bfd.h"
#include "sysdep.h"
#include "libiberty.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/dwarf.h"

/* dwarf1_debug is the starting point for all dwarf1 info. */

struct dwarf1_debug {

  /* The bfd we are working with. */
  bfd* abfd;

  /* List of already parsed compilation units. */
  struct dwarf1_unit* lastUnit;

  /* The buffer for the .debug section. 
     Zero indicates that the .debug section failed to load. */
  char* debug_section;

  /* Pointer to the end of the .debug_info section memory buffer. */
  char* debug_section_end;

  /* The buffer for the .line section. */
  char* line_section;

  /* End of that buffer. */
  char* line_section_end;

  /* The current or next unread die within the .debug section. */
  char* currentDie;
};

/* One dwarf1_unit for each parsed compilation unit die. */

struct dwarf1_unit {
  /* Linked starting from stash->lastUnit. */
  struct dwarf1_unit* prev;

  /* Name of the compilation unit. */
  char* name;

  /* The highest and lowest address used in the compilation unit. */
  unsigned long low_pc;
  unsigned long high_pc;

  /* Does this unit have a statement list? */
  int has_stmt_list;

  /* If any, the offset of the line number table in the .line section. */
  unsigned long stmt_list_offset;

  /* If non-zero, a pointer to the first child of this unit. */
  char* first_child;

  /* How many line entries? */
  unsigned long line_count;

  /* The decoded line number table (line_count entries). */
  struct linenumber* linenumber_table;

  /* The list of functions in this unit. */
  struct dwarf1_func* func_list;
};



/* One dwarf1_func for each parsed function die.  */

struct dwarf1_func {
  /* Linked starting from aUnit->func_list. */
  struct dwarf1_func* prev;
  
  /* Name of function. */
  char* name;
  
  /* The highest and lowest address used in the compilation unit. */
  unsigned long low_pc;
  unsigned long high_pc;
};


/* Used to return info about a parsed die. */
struct die_info {
  unsigned long length;
  unsigned long sibling;
  unsigned long low_pc;
  unsigned long high_pc;
  unsigned long stmt_list_offset;
  
  char* name; 
  
  int has_stmt_list;

  unsigned short tag;
};


/* Parsed line number information. */
struct linenumber {
  /* First address in the line. */
  unsigned long addr;

  /* The line number. */
  unsigned long linenumber;
};


/* Find the form of an attr, from the attr field. */
#define FORM_FROM_ATTR(attr)	((attr) & 0xF)	/* Implicitly specified */


/* Return a newly allocated dwarf1_unit.  It should be cleared and
   then attached into the 'stash' at 'stash->lastUnit'. */

static struct dwarf1_unit*
alloc_dwarf1_unit (stash)
  struct dwarf1_debug* stash;
{
  struct dwarf1_unit* x = 
    (struct dwarf1_unit*) bfd_zalloc (stash->abfd, 
				      sizeof (struct dwarf1_unit));
  x->prev = stash->lastUnit;
  stash->lastUnit = x;

  return x;
}

/* Return a newly allocated dwarf1_func.  It must be cleared and
   attached into 'aUnit' at 'aUnit->func_list'. */

static struct dwarf1_func*
alloc_dwarf1_func (stash, aUnit)
     struct dwarf1_debug* stash;
     struct dwarf1_unit* aUnit;
{
  struct dwarf1_func* x = 
    (struct dwarf1_func*) bfd_zalloc (stash->abfd, 
				      sizeof (struct dwarf1_func));
  x->prev = aUnit->func_list;
  aUnit->func_list = x;
  
  return x;
}

/* parse_die - parse a Dwarf1 die.
   Parse the die starting at 'aDiePtr' into 'aDieInfo'.
   'abfd' must be the bfd from which the section that 'aDiePtr'
   points to was pulled from. 

   Return false if the die is invalidly formatted; true otherwise. */

static boolean
parse_die (abfd, aDieInfo, aDiePtr)
     bfd* abfd;
     struct die_info* aDieInfo;
     char*            aDiePtr;
{
  char* this_die = aDiePtr;
  char* xptr = this_die;

  memset (aDieInfo,0,sizeof(*aDieInfo));

  /* First comes the length. */
  aDieInfo->length = bfd_get_32 (abfd, xptr);
  xptr += 4;
  if (aDieInfo->length == 0)
    return false;
  if (aDieInfo->length < 6)
    {
      /* Just padding bytes. */
      aDieInfo->tag = TAG_padding;
      return true;
    }

  /* Then the tag. */
  aDieInfo->tag = bfd_get_16 (abfd, xptr);
  xptr += 2;
      
  /* Then the attributes. */
  while (xptr < (this_die + aDieInfo->length))
    {
      unsigned short attr;
      
      /* Parse the attribute based on its form.  This section 
         must handle all dwarf1 forms, but need only handle the
	 actual attributes that we care about. */

      attr = bfd_get_16 (abfd, xptr);
      xptr += 2;
      
      switch (FORM_FROM_ATTR (attr))
	{
	case FORM_DATA2:
	  xptr += 2;
	  break;
	case FORM_DATA4:
	case FORM_REF:
	  if (attr == AT_sibling)
	    aDieInfo->sibling = bfd_get_32 (abfd, xptr);
	  else if (attr == AT_stmt_list)
	    {
	      aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr);
	      aDieInfo->has_stmt_list = 1;
	    }
	  xptr += 4;
	  break;
	case FORM_DATA8:
	  xptr += 8;
	  break;
	case FORM_ADDR:
	  if (attr == AT_low_pc)
	    aDieInfo->low_pc = bfd_get_32 (abfd, xptr);
	  else if (attr == AT_high_pc)
	    aDieInfo->high_pc = bfd_get_32 (abfd, xptr);
	  xptr += 4;
	  break;
	case FORM_BLOCK2:
	  xptr += 2 + bfd_get_16 (abfd, xptr);
	  break;
	case FORM_BLOCK4:
	  xptr += 4 + bfd_get_32 (abfd, xptr);
	  break;
	case FORM_STRING:
	  if (attr == AT_name)
	    aDieInfo->name = xptr;
	  xptr += strlen (xptr) + 1;
	  break;
	}
    }

  return true;
}

/* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset'
   into 'aUnit->linenumber_table'.  Return false if an error 
   occurs; true otherwise. */
  
static boolean
parse_line_table (stash, aUnit)
  struct dwarf1_debug* stash;
  struct dwarf1_unit* aUnit;
{
  char* xptr;

  /* Load the ".line" section from the bfd if we haven't already. */ 
  if (stash->line_section == 0)
    {
      asection *msec;
      unsigned long size;
      
      msec = bfd_get_section_by_name (stash->abfd, ".line");
      if (! msec)
	return false;
	  
      size = bfd_get_section_size_before_reloc (msec);
      stash->line_section = (unsigned char*) bfd_alloc (stash->abfd, size);
      
      if (! stash->line_section)
	return false;

      if (! bfd_get_section_contents (stash->abfd, msec, stash->line_section, 0, size))
	{
	  stash->line_section = 0;
	  return false;
	}

      stash->line_section_end = stash->line_section + size;
    }

  xptr = stash->line_section + aUnit->stmt_list_offset;
  if (xptr < stash->line_section_end)
    {
      unsigned long eachLine;

      char* tblend;
      unsigned long base;

      /* First comes the length. */
      tblend = bfd_get_32 (stash->abfd, xptr) + xptr;
      xptr += 4;

      /* Then the base address for each address in the table. */
      base = bfd_get_32 (stash->abfd, xptr);
      xptr += 4;

      /* How many line entrys?
	 10 = 4 (line number) + 2 (pos in line) + 4 (address in line) */
      aUnit->line_count = (tblend - xptr) / 10;

      /* Allocate an array for the entries. */
      aUnit->linenumber_table = (struct linenumber*)
	bfd_alloc (stash->abfd, 
		   sizeof (struct linenumber) * aUnit->line_count);
	
      for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
	{
	  /* A line number. */
	  aUnit->linenumber_table[eachLine].linenumber
	    = bfd_get_32 (stash->abfd, xptr);
	  xptr += 4;

	  /* Skip the position within the line. */
	  xptr += 2;

	  /* And finally the address. */
	  aUnit->linenumber_table[eachLine].addr 
	    = base + bfd_get_32 (stash->abfd, xptr);
	  xptr += 4;
	}
    }

  return true;
}

/* Parse each function die in a compilation unit 'aUnit'.
   The first child die of 'aUnit' should be in 'aUnit->first_child',
   the result is placed in 'aUnit->func_list'.
   Return false if error; true otherwise. */

static boolean
parse_functions_in_unit (stash, aUnit)
     struct dwarf1_debug* stash;
     struct dwarf1_unit* aUnit;
{
  char* eachDie;

  if (aUnit->first_child)
    for (eachDie = aUnit->first_child;
	 eachDie < stash->debug_section_end;
	 )
      {
	struct die_info eachDieInfo;
	
	if (! parse_die (stash->abfd, &eachDieInfo, eachDie))
	  return false;
	
	if (eachDieInfo.tag == TAG_global_subroutine
	    || eachDieInfo.tag == TAG_subroutine
	    || eachDieInfo.tag == TAG_inlined_subroutine
	    || eachDieInfo.tag == TAG_entry_point)
	  {
	    struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit);
	    
	    aFunc->name = eachDieInfo.name;
	    aFunc->low_pc = eachDieInfo.low_pc;
	    aFunc->high_pc = eachDieInfo.high_pc;
	  }
	
	/* Move to next sibling, if none, end loop */
	if (eachDieInfo.sibling)
	  eachDie = stash->debug_section + eachDieInfo.sibling;
	else
	  break;
      }
  
  return true;
}

/* Find the nearest line to 'addr' in 'aUnit'.
   Return whether we found the line (or a function) without error. */

static boolean
dwarf1_unit_find_nearest_line (stash, aUnit, addr, 
		       filename_ptr, functionname_ptr,
		       linenumber_ptr)
  struct dwarf1_debug* stash;
  struct dwarf1_unit* aUnit;
  unsigned long addr;
  const char **filename_ptr;
  const char **functionname_ptr;
  unsigned int *linenumber_ptr;
{
  int line_p = false;
  int func_p = false;

  if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
    {
      if (aUnit->has_stmt_list)
	{
	  unsigned long i;
	  struct dwarf1_func* eachFunc;

	  if (! aUnit->linenumber_table)
	    {
	      if (! parse_line_table (stash, aUnit))
		return false;
	    }

	  if (! aUnit->func_list)
	    {
	      if (! parse_functions_in_unit (stash, aUnit))
		return false;
	    }

	  for (i = 0; i < aUnit->line_count; i++)
	    {
	      if (aUnit->linenumber_table[i].addr <= addr
		  && addr < aUnit->linenumber_table[i+1].addr)
		{
		  *filename_ptr = aUnit->name;
		  *linenumber_ptr = aUnit->linenumber_table[i].linenumber;
		  line_p = true;
		  break;
		}
	    }

	  for (eachFunc = aUnit->func_list; 
	       eachFunc; 
	       eachFunc = eachFunc->prev)
	    {
	      if (eachFunc->low_pc <= addr
		  && addr < eachFunc->high_pc)
		{
		  *functionname_ptr = eachFunc->name;
		  func_p = true;
		  break;
		}
	    }
	}
    }

  return line_p || func_p;
}




/* The DWARF 1 version of find_nearest line.
   Return true if the line is found without error. */

boolean
_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
                              filename_ptr, functionname_ptr, linenumber_ptr)
     bfd *abfd;
     asection *section;
     asymbol **symbols ATTRIBUTE_UNUSED;
     bfd_vma offset;
     const char **filename_ptr;
     const char **functionname_ptr;
     unsigned int *linenumber_ptr;
{
  struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info;

  struct dwarf1_unit* eachUnit;

  /* What address are we looking for? */
  bfd_vma addr = offset + section->vma;

  *filename_ptr = NULL;
  *functionname_ptr = NULL;
  *linenumber_ptr = 0;
  

  if (! stash)
    {
      asection *msec;
      unsigned long size;
      
      stash = elf_tdata (abfd)->dwarf1_find_line_info =
	(struct dwarf1_debug*) bfd_zalloc (abfd, sizeof (struct dwarf1_debug));
      
      if (! stash)
	return false;
      
      msec = bfd_get_section_by_name (abfd, ".debug");
      if (! msec)
	{
	  /* No dwarf1 info.  Note that at this point the stash
	     has been allocated, but contains zeros, this lets
	     future calls to this function fail quicker. */
	  return false;
	}

      size = bfd_get_section_size_before_reloc (msec);
      stash->debug_section = (unsigned char*) bfd_alloc (abfd, size);
      
      if (! stash->debug_section)
	return false;

      if (! bfd_get_section_contents (abfd, msec, stash->debug_section, 0, size))
	{
	  stash->debug_section = 0;
	  return false;
	}

      stash->debug_section_end = stash->debug_section + size;
      stash->currentDie = stash->debug_section;
      stash->abfd = abfd;
    }

  /* A null debug_section indicates that there was no dwarf1 info
     or that an error occured while setting up the stash. */

  if (! stash->debug_section)
    return false;
  

  /* Look at the previously parsed units to see if any contain
     the addr. */
  for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev)
    {
      if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc)
	return dwarf1_unit_find_nearest_line (stash, eachUnit, addr,
					      filename_ptr, 
					      functionname_ptr, 
					      linenumber_ptr);
    }

  while (stash->currentDie < stash->debug_section_end)
    {
      struct die_info aDieInfo;

      if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie))
	return false;
      
      if (aDieInfo.tag == TAG_compile_unit)
	{
	  struct dwarf1_unit* aUnit
	    = alloc_dwarf1_unit (stash);
	  
	  aUnit->name = aDieInfo.name;
	  aUnit->low_pc = aDieInfo.low_pc;
	  aUnit->high_pc = aDieInfo.high_pc;
	  aUnit->has_stmt_list = aDieInfo.has_stmt_list;
	  aUnit->stmt_list_offset = aDieInfo.stmt_list_offset;
	  
	  /* A die has a child if it's followed by a die that is
	     not it's sibling. */
	  if (aDieInfo.sibling 
	      && stash->currentDie + aDieInfo.length 
                    < stash->debug_section_end
	      && stash->currentDie + aDieInfo.length 
	            != stash->debug_section + aDieInfo.sibling)
	    aUnit->first_child = stash->currentDie + aDieInfo.length;
	  else
	    aUnit->first_child = 0;

	  if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
	    return dwarf1_unit_find_nearest_line (stash, aUnit, addr, 
						  filename_ptr, 
						  functionname_ptr, 
						  linenumber_ptr);
	}
      
      if (aDieInfo.sibling != 0)
	stash->currentDie = stash->debug_section + aDieInfo.sibling;
      else
	stash->currentDie += aDieInfo.length;
    }

  return false;
}


/* EOF */
