/* obj-format for ieee-695 records.
   Copyright (C) 1991, 92, 93, 94, 95, 1997, 1998 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)
     register relax_addressT address;	/* Address now. */
     register long alignment;	/* Alignment (binary). */
{
  relax_addressT mask;
  relax_addressT new_address;

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

/* calculate the size of the frag chain and create a bfd section
   to contain all of it */
static void
DEFUN (size_section, (abfd, idx),
       bfd * abfd AND
       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
DEFUN (fill_section, (abfd, idx),
       bfd * abfd AND
       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
DEFUN (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
DEFUN (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
DEFUN (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
DEFUN_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
DEFUN_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;

      /*	struct frag **head_ptr = segment_info[i].frag_root;*/

      segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
#if 0
      /* Im 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 ();
}

/* end of obj-ieee.c */
