/* obj-format for ieee-695 records.
   Copyright (C) 1991, 92, 93, 94, 95, 97, 98, 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 ();
}
