/* SuperH SH64-specific support for 32-bit ELF
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2007
   Free Software Foundation, Inc.

   This file is part of BFD, the Binary File Descriptor library.

   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 3 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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#define SH64_ELF

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/sh.h"
#include "elf32-sh64.h"
#include "../opcodes/sh64-opc.h"

static bfd_boolean sh64_address_in_cranges
  (asection *cranges, bfd_vma, sh64_elf_crange *);

/* Ordering functions of a crange, for the qsort and bsearch calls and for
   different endianness.  */

int
_bfd_sh64_crange_qsort_cmpb (const void *p1, const void *p2)
{
  bfd_vma a1 = bfd_getb32 (p1);
  bfd_vma a2 = bfd_getb32 (p2);

  /* Preserve order if there's ambiguous contents.  */
  if (a1 == a2)
    return (char *) p1 - (char *) p2;

  return a1 - a2;
}

int
_bfd_sh64_crange_qsort_cmpl (const void *p1, const void *p2)
{
  bfd_vma a1 = (bfd_vma) bfd_getl32 (p1);
  bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);

  /* Preserve order if there's ambiguous contents.  */
  if (a1 == a2)
    return (char *) p1 - (char *) p2;

  return a1 - a2;
}

int
_bfd_sh64_crange_bsearch_cmpb (const void *p1, const void *p2)
{
  bfd_vma a1 = *(bfd_vma *) p1;
  bfd_vma a2 = (bfd_vma) bfd_getb32 (p2);
  bfd_size_type size
    = (bfd_size_type) bfd_getb32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);

  if (a1 >= a2 + size)
    return 1;
  if (a1 < a2)
    return -1;
  return 0;
}

int
_bfd_sh64_crange_bsearch_cmpl (const void *p1, const void *p2)
{
  bfd_vma a1 = *(bfd_vma *) p1;
  bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
  bfd_size_type size
    = (bfd_size_type) bfd_getl32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);

  if (a1 >= a2 + size)
    return 1;
  if (a1 < a2)
    return -1;
  return 0;
}

/* Check whether a specific address is specified within a .cranges
   section.  Return FALSE if not found, and TRUE if found, and the region
   filled into RANGEP if non-NULL.  */

static bfd_boolean
sh64_address_in_cranges (asection *cranges, bfd_vma addr,
			 sh64_elf_crange *rangep)
{
  bfd_byte *cranges_contents;
  bfd_byte *found_rangep;
  bfd_size_type cranges_size = cranges->size;

  /* If the size is not a multiple of the cranges entry size, then
     something is badly wrong.  */
  if ((cranges_size % SH64_CRANGE_SIZE) != 0)
    return FALSE;

  /* If this section has relocations, then we can't do anything sane.  */
  if (bfd_get_section_flags (cranges->owner, cranges) & SEC_RELOC)
    return FALSE;

  /* Has some kind soul (or previous call) left processed, sorted contents
     for us?  */
  if ((bfd_get_section_flags (cranges->owner, cranges) & SEC_IN_MEMORY)
      && elf_section_data (cranges)->this_hdr.sh_type == SHT_SH5_CR_SORTED)
    cranges_contents = cranges->contents;
  else
    {
      if (!bfd_malloc_and_get_section (cranges->owner, cranges,
				       &cranges_contents))
	goto error_return;

      /* Is it sorted?  */
      if (elf_section_data (cranges)->this_hdr.sh_type
	  != SHT_SH5_CR_SORTED)
	/* Nope.  Lets sort it.  */
	qsort (cranges_contents, cranges_size / SH64_CRANGE_SIZE,
	       SH64_CRANGE_SIZE,
	       bfd_big_endian (cranges->owner)
	       ? _bfd_sh64_crange_qsort_cmpb : _bfd_sh64_crange_qsort_cmpl);

      /* Let's keep it around.  */
      cranges->contents = cranges_contents;
      bfd_set_section_flags (cranges->owner, cranges,
			     bfd_get_section_flags (cranges->owner, cranges)
			     | SEC_IN_MEMORY);

      /* It's sorted now.  */
      elf_section_data (cranges)->this_hdr.sh_type = SHT_SH5_CR_SORTED;
    }

  /* Try and find a matching range.  */
  found_rangep
    = bsearch (&addr, cranges_contents, cranges_size / SH64_CRANGE_SIZE,
	       SH64_CRANGE_SIZE,
	       bfd_big_endian (cranges->owner)
	       ? _bfd_sh64_crange_bsearch_cmpb
	       : _bfd_sh64_crange_bsearch_cmpl);

  /* Fill in a few return values if we found a matching range.  */
  if (found_rangep)
    {
      enum sh64_elf_cr_type cr_type
	= bfd_get_16 (cranges->owner,
		      SH64_CRANGE_CR_TYPE_OFFSET + found_rangep);
      bfd_vma cr_addr
	= bfd_get_32 (cranges->owner,
		      SH64_CRANGE_CR_ADDR_OFFSET
		      + (char *) found_rangep);
      bfd_size_type cr_size
	= bfd_get_32 (cranges->owner,
		      SH64_CRANGE_CR_SIZE_OFFSET
		      + (char *) found_rangep);

      rangep->cr_addr = cr_addr;
      rangep->cr_size = cr_size;
      rangep->cr_type = cr_type;

      return TRUE;
    }

  /* There is a .cranges section, but it does not have a descriptor
     matching this address.  */
  return FALSE;

error_return:
  if (cranges_contents != NULL)
    free (cranges_contents);
  return FALSE;
}

/* Determine what ADDR points to in SEC, and fill in a range descriptor in
   *RANGEP if it's non-NULL.  */

enum sh64_elf_cr_type
sh64_get_contents_type (asection *sec, bfd_vma addr, sh64_elf_crange *rangep)
{
  asection *cranges;

  /* Fill in the range with the boundaries of the section as a default.  */
  if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
      && elf_elfheader (sec->owner)->e_type == ET_EXEC)
    {
      rangep->cr_addr = bfd_get_section_vma (sec->owner, sec);
      rangep->cr_size = sec->size;
      rangep->cr_type = CRT_NONE;
    }
  else
    return FALSE;

  /* If none of the pertinent bits are set, then it's a SHcompact (or at
     least not SHmedia).  */
  if ((elf_section_data (sec)->this_hdr.sh_flags
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == 0)
    {
      enum sh64_elf_cr_type cr_type
	= ((bfd_get_section_flags (sec->owner, sec) & SEC_CODE) != 0
	   ? CRT_SH5_ISA16 : CRT_DATA);
      rangep->cr_type = cr_type;
      return cr_type;
    }

  /* If only the SHF_SH5_ISA32 bit is set, then we have SHmedia.  */
  if ((elf_section_data (sec)->this_hdr.sh_flags
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == SHF_SH5_ISA32)
    {
      rangep->cr_type = CRT_SH5_ISA32;
      return CRT_SH5_ISA32;
    }

  /* Otherwise, we have to look up the .cranges section.  */
  cranges = bfd_get_section_by_name (sec->owner, SH64_CRANGES_SECTION_NAME);

  if (cranges == NULL)
    /* A mixed section but there's no .cranges section.  This is probably
       bad input; it does not comply to specs.  */
    return CRT_NONE;

  /* If this call fails, we will still have CRT_NONE in rangep->cr_type
     and that will be suitable to return.  */
  sh64_address_in_cranges (cranges, addr, rangep);

  return rangep->cr_type;
}

/* This is a simpler exported interface for the benefit of gdb et al.  */

bfd_boolean
sh64_address_is_shmedia (asection *sec, bfd_vma addr)
{
  sh64_elf_crange dummy;
  return sh64_get_contents_type (sec, addr, &dummy) == CRT_SH5_ISA32;
}
