/* obj-format for ieee-695 records.
   Copyright 1991, 1992, 1993, 1994, 1997, 2000
   Free Software Foundation, Inc.

   This file is part of GAS, the GNU Assembler.

   GAS 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, or (at your option)
   any later version.

   GAS 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 GAS; see the file COPYING.  If not, write to the Free
   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */

/* Created by Steve Chamberlain <steve@cygnus.com>.  */

/* This will hopefully become the port through which bfd and gas talk,
   for the moment, only ieee is known to work well.  */

#include "bfd.h"
#include "as.h"
#include "subsegs.h"
#include "output-file.h"
#include "frags.h"

bfd *abfd;

/* How many addresses does the .align take?  */

static relax_addressT
relax_align (address, alignment)
     /* Address now.  */
     register relax_addressT address;

     /* Alignment (binary).  */
     register long alignment;
{
  relax_addressT mask;
  relax_addressT new_address;

  mask = ~((~0) << alignment);
  new_address = (address + mask) & (~mask);
  return (new_address - address);
}

/* Calculate the size of the frag chain
   and create a bfd section to contain all of it.  */

static void
size_section (abfd, idx)
     bfd *abfd;
     unsigned int idx;
{
  asection *sec;
  unsigned int size = 0;
  fragS *frag = segment_info[idx].frag_root;

  while (frag)
    {
      if (frag->fr_address != size)
	{
	  printf (_("Out of step\n"));
	  size = frag->fr_address;
	}
      size += frag->fr_fix;
      switch (frag->fr_type)
	{
	case rs_fill:
	case rs_org:
	  size += frag->fr_offset * frag->fr_var;
	  break;
	case rs_align:
	case rs_align_code:
	  {
	    addressT off;

	    off = relax_align (size, frag->fr_offset);
	    if (frag->fr_subtype != 0 && off > frag->fr_subtype)
	      off = 0;
	    size += off;
	  }
	}
      frag = frag->fr_next;
    }
  if (size)
    {
      char *name = segment_info[idx].name;

      if (name == (char *) NULL)
	name = ".data";

      segment_info[idx].user_stuff =
	(char *) (sec = bfd_make_section (abfd, name));
      /* Make it output through itself.  */
      sec->output_section = sec;
      sec->flags |= SEC_HAS_CONTENTS;
      bfd_set_section_size (abfd, sec, size);
    }
}

/* Run through a frag chain and write out the data to go with it.  */

static void
fill_section (abfd, idx)
     bfd *abfd;
     unsigned int idx;
{
  asection *sec = segment_info[idx].user_stuff;

  if (sec)
    {
      fragS *frag = segment_info[idx].frag_root;
      unsigned int offset = 0;
      while (frag)
	{
	  unsigned int fill_size;
	  unsigned int count;
	  switch (frag->fr_type)
	    {
	    case rs_fill:
	    case rs_align:
	    case rs_org:
	      if (frag->fr_fix)
		{
		  bfd_set_section_contents (abfd,
					    sec,
					    frag->fr_literal,
					    frag->fr_address,
					    frag->fr_fix);
		}
	      offset += frag->fr_fix;
	      fill_size = frag->fr_var;
	      if (fill_size)
		{
		  unsigned int off = frag->fr_fix;
		  for (count = frag->fr_offset; count; count--)
		    {
		      bfd_set_section_contents (abfd, sec,
						frag->fr_literal +
						frag->fr_fix,
						frag->fr_address + off,
						fill_size);
		      off += fill_size;
		    }
		}
	      break;
	    default:
	      abort ();
	    }
	  frag = frag->fr_next;
	}
    }
}

/* Count the relocations in a chain.  */

static unsigned int
count_entries_in_chain (idx)
     unsigned int idx;
{
  unsigned int nrelocs;
  fixS *fixup_ptr;

  /* Count the relocations.  */
  fixup_ptr = segment_info[idx].fix_root;
  nrelocs = 0;
  while (fixup_ptr != (fixS *) NULL)
    {
      fixup_ptr = fixup_ptr->fx_next;
      nrelocs++;
    }
  return nrelocs;
}

/* Output all the relocations for a section.  */

void
do_relocs_for (idx)
     unsigned int idx;
{
  unsigned int nrelocs;
  arelent **reloc_ptr_vector;
  arelent *reloc_vector;
  asymbol **ptrs;
  asection *section = (asection *) (segment_info[idx].user_stuff);
  unsigned int i;
  fixS *from;

  if (section)
    {
      nrelocs = count_entries_in_chain (idx);

      reloc_ptr_vector =
	(arelent **) malloc ((nrelocs + 1) * sizeof (arelent *));
      reloc_vector = (arelent *) malloc (nrelocs * sizeof (arelent));
      ptrs = (asymbol **) malloc (nrelocs * sizeof (asymbol *));
      from = segment_info[idx].fix_root;
      for (i = 0; i < nrelocs; i++)
	{
	  arelent *to = reloc_vector + i;
	  asymbol *s;
	  reloc_ptr_vector[i] = to;
	  to->howto = (reloc_howto_type *) (from->fx_r_type);

#if 0
	  /* We can't represent complicated things in a reloc yet.  */
	  if (from->fx_addsy == 0 || from->fx_subsy != 0)
	    abort ();
#endif

	  s = &(from->fx_addsy->sy_symbol.sy);
	  to->address = ((char *) (from->fx_frag->fr_address +
				   from->fx_where))
	    - ((char *) (&(from->fx_frag->fr_literal)));
	  to->addend = from->fx_offset;
	  /* If we know the symbol which we want to relocate to, turn
	     this reloaction into a section relative.

	     If this relocation is pcrelative, and we know the
	     destination, we still want to keep the relocation - since
	     the linker might relax some of the bytes, but it stops
	     being pc relative and turns into an absolute relocation.  */
	  if (s)
	    {
	      if ((s->flags & BSF_UNDEFINED) == 0)
		{
		  to->section = s->section;

		  /* We can refer directly to the value field here,
		     rather than using S_GET_VALUE, because this is
		     only called after do_symbols, which sets up the
		     value field.  */
		  to->addend += s->value;

		  to->sym_ptr_ptr = 0;
		  if (to->howto->pcrel_offset)
		    /* This is a pcrel relocation, the addend should
		       be adjusted.  */
		    to->addend -= to->address + 1;
		}
	      else
		{
		  to->section = 0;
		  *ptrs = &(from->fx_addsy->sy_symbol.sy);
		  to->sym_ptr_ptr = ptrs;

		  if (to->howto->pcrel_offset)
		    /* This is a pcrel relocation, the addend should
		       be adjusted.  */
		    to->addend -= to->address - 1;
		}
	    }
	  else
	    to->section = 0;

	  ptrs++;
	  from = from->fx_next;
	}

      /* Attatch to the section.  */
      section->orelocation = reloc_ptr_vector;
      section->reloc_count = nrelocs;
      section->flags |= SEC_LOAD;
    }
}

/* Do the symbols.  */

static void
do_symbols (abfd)
     bfd *abfd;
{
  extern symbolS *symbol_rootP;
  symbolS *ptr;
  asymbol **symbol_ptr_vec;
  asymbol *symbol_vec;
  unsigned int count = 0;
  unsigned int index;

  for (ptr = symbol_rootP;
       ptr != (symbolS *) NULL;
       ptr = ptr->sy_next)
    {
      if (SEG_NORMAL (ptr->sy_symbol.seg))
	{
	  ptr->sy_symbol.sy.section =
	    (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff);
	  S_SET_VALUE (ptr, S_GET_VALUE (ptr) + ptr->sy_frag->fr_address);
	  if (ptr->sy_symbol.sy.flags == 0)
	    ptr->sy_symbol.sy.flags = BSF_LOCAL;
	}
      else
	{
	  switch (ptr->sy_symbol.seg)
	    {
	    case SEG_ABSOLUTE:
	      ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE;
	      ptr->sy_symbol.sy.section = 0;
	      break;
	    case SEG_UNKNOWN:
	      ptr->sy_symbol.sy.flags = BSF_UNDEFINED;
	      ptr->sy_symbol.sy.section = 0;
	      break;
	    default:
	      abort ();
	    }
	}
      ptr->sy_symbol.sy.value = S_GET_VALUE (ptr);
      count++;
    }
  symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *));

  index = 0;
  for (ptr = symbol_rootP;
       ptr != (symbolS *) NULL;
       ptr = ptr->sy_next)
    {
      symbol_ptr_vec[index] = &(ptr->sy_symbol.sy);
      index++;
    }
  symbol_ptr_vec[index] = 0;
  abfd->outsymbols = symbol_ptr_vec;
  abfd->symcount = count;
}

/* The generic as->bfd converter. Other backends may have special case
   code.  */

void
bfd_as_write_hook ()
{
  int i;

  for (i = SEG_E0; i < SEG_UNKNOWN; i++)
    size_section (abfd, i);

  for (i = SEG_E0; i < SEG_UNKNOWN; i++)
    fill_section (abfd, i);

  do_symbols (abfd);

  for (i = SEG_E0; i < SEG_UNKNOWN; i++)
    do_relocs_for (i);
}

S_SET_SEGMENT (x, y)
     symbolS *x;
     int y;
{
  x->sy_symbol.seg = y;
}

S_IS_DEFINED (x)
     symbolS *x;
{
  if (SEG_NORMAL (x->sy_symbol.seg))
    {
      return 1;
    }
  switch (x->sy_symbol.seg)
    {
    case SEG_UNKNOWN:
      return 0;
    default:
      abort ();
    }
}

S_IS_EXTERNAL (x)
{
  abort ();
}

S_GET_DESC (x)
{
  abort ();
}

S_GET_SEGMENT (x)
     symbolS *x;
{
  return x->sy_symbol.seg;
}

S_SET_EXTERNAL (x)
     symbolS *x;
{
  x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
}

S_SET_NAME (x, y)
     symbolS *x;
     char *y;
{
  x->sy_symbol.sy.name = y;
}

S_GET_OTHER (x)
{
  abort ();
}

S_IS_DEBUG (x)
{
  abort ();
}

#ifndef segment_name
char *
segment_name ()
{
  abort ();
}
#endif

void
obj_read_begin_hook ()
{
}

static void
obj_ieee_section (ignore)
     int ignore;
{
  extern char *input_line_pointer;
  extern char is_end_of_line[];
  char *p = input_line_pointer;
  char *s = p;
  int i;

  /* Look up the name, if it doesn't exist, make it.  */
  while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p])
    {
      p++;
    }
  for (i = SEG_E0; i < SEG_UNKNOWN; i++)
    {
      if (segment_info[i].hadone)
	{
	  if (strncmp (segment_info[i].name, s, p - s) == 0)
	    goto ok;
	}
      else
	break;
    }
  if (i == SEG_UNKNOWN)
    {
      as_bad (_("too many sections"));
      return;
    }

  segment_info[i].hadone = 1;
  segment_info[i].name = malloc (p - s + 1);
  memcpy (segment_info[i].name, s, p - s);
  segment_info[i].name[p - s] = 0;
ok:
  subseg_set (i, 0);
  while (!is_end_of_line[*p])
    p++;
  input_line_pointer = p;
}

void cons ();
void s_ignore ();

void s_globl ();
const pseudo_typeS obj_pseudo_table[] =
{
  {"section", obj_ieee_section, 0},
  {"data.b" , cons            , 1},
  {"data.w" , cons            , 2},
  {"data.l" , cons            , 4},
  {"export" , s_globl         , 0},
  {"option" , s_ignore        , 0},
  {"end"    , s_ignore        , 0},
  {"import" , s_ignore        , 0},
  {"sdata"  , stringer        , 0},
  0,
};

void
obj_symbol_new_hook (symbolP)
     symbolS *symbolP;
{
  symbolP->sy_symbol.sy.the_bfd = abfd;
}

#if 1
extern void
write_object_file ()
{
  int i;
  struct frchain *frchain_ptr;
  struct frag *frag_ptr;

  abfd = bfd_openw (out_file_name, "ieee");

  if (abfd == 0)
    {
      as_perror (_("FATAL: Can't create %s"), out_file_name);
      exit (EXIT_FAILURE);
    }
  bfd_set_format (abfd, bfd_object);
  bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
  subseg_set (1, 0);
  subseg_set (2, 0);
  subseg_set (3, 0);
  for (frchain_ptr = frchain_root;
       frchain_ptr != (struct frchain *) NULL;
       frchain_ptr = frchain_ptr->frch_next)
    {
      /* Run through all the sub-segments and align them up.  Also
	 close any open frags.  We tack a .fill onto the end of the
	 frag chain so that any .align's size can be worked by looking
	 at the next frag.  */

      subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
#ifndef SUB_SEGMENT_ALIGN
#define SUB_SEGMENT_ALIGN(SEG) 2
#endif
      frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0);
      frag_wane (frag_now);
      frag_now->fr_fix = 0;
      know (frag_now->fr_next == NULL);
    }

  /* Now build one big frag chain for each segment, linked through
     fr_next.  */
  for (i = SEG_E0; i < SEG_UNKNOWN; i++)
    {
      fragS **prev_frag_ptr_ptr;
      struct frchain *next_frchain_ptr;

#if 0
      struct frag **head_ptr = segment_info[i].frag_root;
#endif

      segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
#if 0
      /* I'm not sure what this is for.  */
      for (frchain_ptr = segment_info[i].frchainP->frch_root;
	   frchain_ptr != (struct frchain *) NULL;
	   frchain_ptr = frchain_ptr->frch_next)
	{
	  *head_ptr = frchain_ptr;
	  head_ptr = &frchain_ptr->next;
	}
#endif
    }

  for (i = SEG_E0; i < SEG_UNKNOWN; i++)
    relax_segment (segment_info[i].frag_root, i);

  /* Now the addresses of the frags are correct within the segment.  */

  bfd_as_write_hook ();
  bfd_close (abfd);
}

#endif

H_SET_TEXT_SIZE (a, b)
{
  abort ();
}

H_GET_TEXT_SIZE ()
{
  abort ();
}

H_SET_BSS_SIZE ()
{
  abort ();
}

H_SET_STRING_SIZE ()
{
  abort ();
}

H_SET_RELOCATION_SIZE ()
{
  abort ();
}

H_SET_MAGIC_NUMBER ()
{
  abort ();
}

H_GET_FILE_SIZE ()
{
  abort ();
}

H_GET_TEXT_RELOCATION_SIZE ()
{
  abort ();
}
