Exemple #1
0
void
md_begin ()
{
  char *retval = NULL;
  unsigned int i = 0;

  /* initialize hash table */

  op_hash = hash_new ();
  if (op_hash == NULL)
    as_fatal ("Could not initialize hash table");

  /* loop until you see the end of the list */

  while (*m88k_opcodes[i].name)
    {
      char *name = m88k_opcodes[i].name;

      /* hash each mnemonic and record its position */

      retval = hash_insert (op_hash, name, &m88k_opcodes[i]);

      if (retval != NULL && *retval != '\0')
	as_fatal ("Can't hash instruction '%s':%s",
		 m88k_opcodes[i].name, retval);

      /* skip to next unique mnemonic or end of list */

      for (i++; !strcmp (m88k_opcodes[i].name, name); i++)
	;
    }
}
Exemple #2
0
/*
 *			frag_grow()
 *
 * Try to augment current frag by nchars chars.
 * If there is no room, close of the current frag with a ".fill 0"
 * and begin a new frag. Unless the new frag has nchars chars available
 * do not return. Do not set up any fields of *now_frag.
 */
void
frag_grow(
    unsigned int nchars)
{
    if(frags.chunk_size == 0) {
        know(flagseen['n']);
        as_fatal("with -n a section directive must be seen before assembly "
                 "can begin");
    }
    if ((int)(obstack_room(&frags)) < nchars) {
        unsigned int n,oldn;
        long oldc;

        frag_wane (frag_now);
        frag_new (0);
        oldn=(unsigned)-1;
        oldc=frags.chunk_size;
        frags.chunk_size=2*nchars;
        while((int)(n=obstack_room(&frags)) < nchars && n < oldn) {
            frag_wane(frag_now);
            frag_new(0);
            oldn=n;
        }
        frags.chunk_size=oldc;
    }
    if ((int)(obstack_room(&frags)) < nchars)
        as_fatal ("Can't extend frag %d. chars", nchars);
}
Exemple #3
0
/* This function is called once, at assembler startup time.  It should
   set up all the tables, etc. that the MD part of the assembler will need.  */
void
md_begin(
void)
{
	const char *retval = NULL;
	int lose = 0;
	register unsigned int i = 0;

	op_hash = hash_new();
	if (op_hash == NULL)
	as_fatal("Virtual memory exhausted");

	while (i < NUMOPCODES) {
		const char *name = pa_opcodes[i].name;
		retval = hash_insert(op_hash, (char *)name,
				     (char *)&pa_opcodes[i]);
		if(retval != NULL && *retval != '\0')  {
			as_fatal("Internal error: can't hash `%s': %s\n",
			pa_opcodes[i].name, retval);
			lose = 1;
		}
		++i;
	}

	if (lose)
		as_fatal ("Broken assembler.  No assembly attempted.");
}
Exemple #4
0
void
input_scrub_include_sb (sb *from, char *position, int is_expansion)
{
  if (macro_nest > max_macro_nest)
    as_fatal (_("macros nested too deeply"));
  ++macro_nest;

#ifdef md_macro_start
  if (is_expansion)
    {
      md_macro_start ();
    }
#endif

  next_saved_file = input_scrub_push (position);

  sb_new (&from_sb);
  from_sb_is_expansion = is_expansion;
  if (from->len >= 1 && from->ptr[0] != '\n')
    {
      /* Add the sentinel required by read.c.  */
      sb_add_char (&from_sb, '\n');
    }
  sb_scrub_and_add_sb (&from_sb, from);
  sb_index = 1;

  /* These variables are reset by input_scrub_push.  Restore them
     since we are, after all, still at the same point in the file.  */
  logical_input_line = next_saved_file->logical_input_line;
  logical_input_file = next_saved_file->logical_input_file;
}
Exemple #5
0
void
gas_cgen_swap_fixups (int i)
{
  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    {
      as_fatal ("index into stored_fixups[] out of bounds");
      return;
    }

  if (num_fixups == 0)
    gas_cgen_restore_fixups (i);

  else if (stored_fixups[i].num_fixups_in_chain == 0)
    gas_cgen_save_fixups (i);

  else
    {
      int tmp;
      struct fixup tmp_fixup;

      tmp = stored_fixups[i].num_fixups_in_chain;
      stored_fixups[i].num_fixups_in_chain = num_fixups;
      num_fixups = tmp;

      for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
	{
	  tmp_fixup = stored_fixups[i].fixup_chain [tmp];
	  stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
	  fixups [tmp] = tmp_fixup;
	}
    }
}
Exemple #6
0
void
frag_grow (unsigned int nchars)
{
  if (obstack_room (&frchain_now->frch_obstack) < nchars)
    {
      unsigned int n;
      long oldc;

      frag_wane (frag_now);
      frag_new (0);
      oldc = frchain_now->frch_obstack.chunk_size;
      /* Try to allocate a bit more than needed right now.  But don't do
         this if we would waste too much memory.  Especially necessary
	 for extremely big (like 2GB initialized) frags.  */
      if (nchars < 0x10000)
	frchain_now->frch_obstack.chunk_size = 2 * nchars;
      else
        frchain_now->frch_obstack.chunk_size = nchars + 0x10000;
      frchain_now->frch_obstack.chunk_size += SIZEOF_STRUCT_FRAG;
      if (frchain_now->frch_obstack.chunk_size > 0)
	while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars
	       && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars)
	  {
	    frag_wane (frag_now);
	    frag_new (0);
	  }
      frchain_now->frch_obstack.chunk_size = oldc;
    }
  if (obstack_room (&frchain_now->frch_obstack) < nchars)
    as_fatal (_("can't extend frag %u chars"), nchars);
}
static void
sb_check (sb *ptr, size_t len)
{
  size_t want = ptr->len + len;

  if (want > ptr->max)
    {
      size_t max;

      want += MALLOC_OVERHEAD + 1;
      if ((ssize_t) want < 0)
	as_fatal ("string buffer overflow");
#if GCC_VERSION >= 3004
      max = (size_t) 1 << (CHAR_BIT * sizeof (want)
			   - (sizeof (want) <= sizeof (long)
			      ? __builtin_clzl ((long) want)
			      : __builtin_clzll ((long long) want)));
#else
      max = 128;
      while (want > max)
	max <<= 1;
#endif
      max -= MALLOC_OVERHEAD + 1;
      ptr->max = max;
      ptr->ptr = xrealloc (ptr->ptr, max + 1);
    }
}
Exemple #8
0
/* This function is called once, at assembler startup time.  It should
   set up all the tables, etc. that the MD part of the assembler will need.  */
void
md_begin()
{
  register char *retval = NULL;
  int lose = 0;
  register unsigned int i = 0;

  op_hash = hash_new();
  if (op_hash == NULL)
    as_fatal("Virtual memory exhausted");

  while (i < NUMOPCODES)
    {
      const char *name = i860_opcodes[i].name;
      retval = hash_insert(op_hash, name, &i860_opcodes[i]);
      if(retval != NULL && *retval != '\0')
	{
	  fprintf (stderr, "internal error: can't hash `%s': %s\n",
		   i860_opcodes[i].name, retval);
	  lose = 1;
	}
      do
	{
	  if (i860_opcodes[i].match & i860_opcodes[i].lose)
	    {
	      fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
		       i860_opcodes[i].name, i860_opcodes[i].args);
	      lose = 1;
	    }
	  ++i;
	} while (i < NUMOPCODES
		 && !strcmp(i860_opcodes[i].name, name));
    }

  if (lose)
    as_fatal ("Broken assembler.  No assembly attempted.");

  for (i = '0'; i < '8'; ++i)
    octal[i] = 1;
  for (i = '0'; i <= '9'; ++i)
    toHex[i] = i - '0';
  for (i = 'a'; i <= 'f'; ++i)
    toHex[i] = i + 10 - 'a';
  for (i = 'A'; i <= 'F'; ++i)
    toHex[i] = i + 10 - 'A';
}
Exemple #9
0
static void
dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item)
{
  const char *error_string;

  if ((error_string = hash_jam (dwcfi_hash, name, (char *) item)))
    as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
	      name, error_string);
}
Exemple #10
0
static void
tag_insert (const char *name, symbolS *symbolP)
{
  const char *error_string;

  if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
    as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
	      name, error_string);
}
Exemple #11
0
/*
 *			frag_new()
 *
 * Call this to close off a completed frag, and start up a new (empty)
 * frag, in the same subsegment as the old frag.
 * [frchain_now remains the same but frag_now is updated.]
 * Because this calculates the correct value of fr_fix by
 * looking at the obstack 'frags', it needs to know how many
 * characters at the end of the old frag belong to (the maximal)
 * fr_var: the rest must belong to fr_fix.
 * It doesn't actually set up the old frag's fr_var: you may have
 * set fr_var == 1, but allocated 10 chars to the end of the frag:
 * in this case you pass old_frags_var_max_size == 10.
 *
 * Make a new frag, initialising some components. Link new frag at end
 * of frchain_now.
 */
void
frag_new(
    int old_frags_var_max_size)	/* Number of chars (already allocated on obstack
				   frags) in variable_length part of frag. */
{
    register    fragS * former_last_fragP;
    /*    char   *throw_away_pointer; JF unused */
    register    frchainS * frchP;
    long	tmp;		/* JF */

    if(frags.chunk_size == 0) {
        know(flagseen['n']);
        as_fatal("with -n a section directive must be seen before assembly "
                 "can begin");
    }

    frag_now->fr_fix = (char *) (obstack_next_free (&frags)) -
                       (frag_now->fr_literal) - old_frags_var_max_size;
    /* Fix up old frag's fr_fix. */

    obstack_finish (&frags);
    /* This will align the obstack so the */
    /* next struct we allocate on it will */
    /* begin at a correct boundary. */
    frchP = frchain_now;
    know (frchP);
    former_last_fragP = frchP->frch_last;
    know (former_last_fragP);
    know (former_last_fragP == frag_now);
    obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
    /* We expect this will begin at a correct */
    /* boundary for a struct. */
    tmp=obstack_alignment_mask(&frags);
    obstack_alignment_mask(&frags)=0;		/* Turn off alignment */
    /* If we ever hit a machine
    where strings must be
    aligned, we Lose Big */
    frag_now=(fragS *)obstack_finish(&frags);
    obstack_alignment_mask(&frags)=tmp;		/* Restore alignment */

    /* Just in case we don't get zero'd bytes */
    memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);

    /*    obstack_unaligned_done (&frags, &frag_now); */
    /*    know (frags.obstack_c_next_free == frag_now->fr_literal); */
    /* Generally, frag_now->points to an */
    /* address rounded up to next alignment. */
    /* However, characters will add to obstack */
    /* frags IMMEDIATELY after the struct frag, */
    /* even if they are not starting at an */
    /* alignment address. */
    former_last_fragP->fr_next = frag_now;
    frchP->frch_last = frag_now;
    frag_now->fr_next = NULL;
}				/* frag_new() */
Exemple #12
0
/*
 *			symbol_assign_index()
 *
 * Assigns the next index to the given symbol.
 *
 * Asserts that the symbol has not been assigned an index yet.
 *
 */
void
symbol_assign_index(
struct symbol *symbolP)
{
  if (symbolP->sy_prev_by_index != NULL)
    {
      as_fatal("symbol %s already has an index", symbolP->sy_name);
    }
  symbolP->sy_prev_by_index = symbol_lastIndexedP;
  symbol_lastIndexedP = symbolP;
}
Exemple #13
0
static void
queue_fixup (int opindex, int opinfo, expressionS *expP)
{
  /* We need to generate a fixup for this expression.  */
  if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
    as_fatal (_("too many fixups"));
  fixups[num_fixups].exp     = *expP;
  fixups[num_fixups].opindex = opindex;
  fixups[num_fixups].opinfo  = opinfo;
  ++ num_fixups;
}
Exemple #14
0
void
output_file_create (char *name)
{
  if (name[0] == '-' && name[1] == '\0')
    as_fatal (_("can't open a bfd on stdout %s"), name);

  else if (!(stdoutput = bfd_openw (name, TARGET_FORMAT)))
    {
      bfd_error_type err = bfd_get_error ();

      if (err == bfd_error_invalid_target)
	as_fatal (_("selected target format '%s' unknown"), TARGET_FORMAT);
      else
	as_fatal (_("can't create %s: %s"), name, bfd_errmsg (err));
    }

  bfd_set_format (stdoutput, bfd_object);
  bfd_set_arch_mach (stdoutput, TARGET_ARCH, TARGET_MACH);
  if (flag_traditional_format)
    stdoutput->flags |= BFD_TRADITIONAL_FORMAT;
}
Exemple #15
0
void
gas_cgen_restore_fixups (int i)
{
  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    {
      as_fatal ("index into stored_fixups[] out of bounds");
      return;
    }

  num_fixups = stored_fixups[i].num_fixups_in_chain;
  memcpy (fixups, stored_fixups[i].fixup_chain,
	  (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
  stored_fixups[i].num_fixups_in_chain = 0;
}
Exemple #16
0
/*
 *			symbol_table_insert()
 *
 * Die if we can't insert the symbol.
 *
 */
void
symbol_table_insert(
struct symbol *symbolP)
{
  register char *	error_string;

  know( symbolP );
  know( symbolP -> sy_name );
  if ( * (error_string = hash_jam (sy_hash, symbolP -> sy_name, (char *)symbolP)))
    {
      as_fatal( "Inserting \"%s\" into symbol table failed: %s",
	      symbolP -> sy_name, error_string);
    }
}
Exemple #17
0
void
gas_cgen_save_fixups (int i)
{
  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    {
      as_fatal ("index into stored_fixups[] out of bounds");
      return;
    }

  stored_fixups[i].num_fixups_in_chain = num_fixups;
  memcpy (stored_fixups[i].fixup_chain, fixups,
	  sizeof (fixups[0]) * num_fixups);
  num_fixups = 0;
}
Exemple #18
0
/*
 *			symbol_table_insert()
 *
 * Die if we can't insert the symbol.
 *
 */
void
symbol_table_insert(
struct symbol *symbolP)
{
  const char *	error_string;

  know( symbolP );
  know( symbolP -> sy_name );
  error_string = hash_jam (sy_hash, symbolP -> sy_name, (char *)symbolP);
  if (error_string != NULL && error_string[0] != '\0')
    {
      as_fatal( "Inserting \"%s\" into symbol table failed: %s",
	      symbolP -> sy_name, error_string);
    }
}
Exemple #19
0
void
md_begin ()
{
  int i;

  init_defaults ();

  insn_hash = hash_new ();
  if (insn_hash == NULL)
    as_fatal ("Virtual memory exhausted");

  for (i = 0; i < pdp11_num_opcodes; i++)
    hash_insert (insn_hash, pdp11_opcodes[i].name, (PTR)(pdp11_opcodes + i));
  for (i = 0; i < pdp11_num_aliases; i++)
    hash_insert (insn_hash, pdp11_aliases[i].name, (PTR)(pdp11_aliases + i));
}
Exemple #20
0
void
output_file_close (char *filename)
{
  bfd_boolean res;

  if (stdoutput == NULL)
    return;
    
  /* Close the bfd.  */
  res = bfd_close (stdoutput);

  /* Prevent an infinite loop - if the close failed we will call as_fatal
     which will call xexit() which may call this function again...  */
  stdoutput = NULL;

  if (! res)
    as_fatal (_("can't close %s: %s"), filename,
	      bfd_errmsg (bfd_get_error ()));
}
Exemple #21
0
void
frag_grow (unsigned int nchars)
{
  if (obstack_room (&frchain_now->frch_obstack) < nchars)
    {
      long oldc;
      long newc;

      /* Try to allocate a bit more than needed right now.  But don't do
         this if we would waste too much memory.  Especially necessary
         for extremely big (like 2GB initialized) frags.  */
      if (nchars < 0x10000)
        newc = 2 * nchars;
      else
        newc = nchars + 0x10000;
      newc += SIZEOF_STRUCT_FRAG;

      /* Check for possible overflow.  */
      if (newc < 0)
        as_fatal (_("can't extend frag %u chars"), nchars);

      /* Force to allocate at least NEWC bytes, but not less than the
         default.  */
      oldc = obstack_chunk_size (&frchain_now->frch_obstack);
      if (newc > oldc)
	obstack_chunk_size (&frchain_now->frch_obstack) = newc;

      while (obstack_room (&frchain_now->frch_obstack) < nchars)
        {
          /* Not enough room in this frag.  Close it and start a new one.
             This must be done in a loop because the created frag may not
             be big enough if the current obstack chunk is used.  */
          frag_wane (frag_now);
          frag_new (0);
        }

      /* Restore the old chunk size.  */
      obstack_chunk_size (&frchain_now->frch_obstack) = oldc;
    }
}
Exemple #22
0
void
input_scrub_include_sb (sb *from, char *position, int is_expansion)
{
  int newline;

  if (macro_nest > max_macro_nest)
    as_fatal (_("macros nested too deeply"));
  ++macro_nest;

#ifdef md_macro_start
  if (is_expansion)
    {
      md_macro_start ();
    }
#endif

  next_saved_file = input_scrub_push (position);

  /* Allocate sufficient space: from->len + optional newline.  */
  newline = from->len >= 1 && from->ptr[0] != '\n';
  sb_build (&from_sb, from->len + newline);
  from_sb_is_expansion = is_expansion;
  if (newline)
    {
      /* Add the sentinel required by read.c.  */
      sb_add_char (&from_sb, '\n');
    }
  sb_scrub_and_add_sb (&from_sb, from);

  /* Make sure the parser looks at defined contents when it scans for
     e.g. end-of-line at the end of a macro.  */
  sb_terminate (&from_sb);

  sb_index = 1;

  /* These variables are reset by input_scrub_push.  Restore them
     since we are, after all, still at the same point in the file.  */
  logical_input_line = next_saved_file->logical_input_line;
  logical_input_file = next_saved_file->logical_input_file;
}
Exemple #23
0
static int
out_header (asection *sec, expressionS *exp)
{
  symbolS *start_sym;
  symbolS *end_sym;

  subseg_set (sec, 0);
  start_sym = symbol_temp_new_now ();;
  end_sym = symbol_temp_make ();

  /* Total length of the information.  */
  exp->X_op = O_subtract;
  exp->X_add_symbol = end_sym;
  exp->X_op_symbol = start_sym;

  switch (DWARF2_FORMAT (sec))
    {
    case dwarf2_format_32bit:
      exp->X_add_number = -4;
      emit_expr (exp, 4);
      return 4;

    case dwarf2_format_64bit:
      exp->X_add_number = -12;
      out_four (-1);
      emit_expr (exp, 8);
      return 8;

    case dwarf2_format_64bit_irix:
      exp->X_add_number = -8;
      emit_expr (exp, 8);
      return 8;
    }

  as_fatal (_("internal error: unknown dwarf2 format"));
  return 0;
}
void
obj_som_copyright (int unused ATTRIBUTE_UNUSED)
{
  char *copyright, c;

  if (copyright_seen)
    {
      as_bad (_("Only one .copyright pseudo-op per file!"));
      ignore_rest_of_line ();
      return;
    }

  SKIP_WHITESPACE ();
  if (*input_line_pointer == '\"')
    {
      copyright = input_line_pointer;
      ++input_line_pointer;
      while (is_a_char (next_char_of_string ()))
	;
      c = *input_line_pointer;
      *input_line_pointer = '\000';
    }
  else
    {
      as_bad (_("Expected quoted string"));
      ignore_rest_of_line ();
      return;
    }

  copyright_seen = 1;
  if (!bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright))
    as_fatal (_("attaching copyright header %s: %s"),
	      stdoutput->filename, bfd_errmsg (bfd_get_error ()));

  *input_line_pointer = c;
  demand_empty_rest_of_line ();
}
void
obj_som_version (int unused ATTRIBUTE_UNUSED)
{
  char *version, c;

  if (version_seen)
    {
      as_bad (_("Only one .version pseudo-op per file!"));
      ignore_rest_of_line ();
      return;
    }

  SKIP_WHITESPACE ();
  if (*input_line_pointer == '\"')
    {
      version = input_line_pointer;
      ++input_line_pointer;
      while (is_a_char (next_char_of_string ()))
	;
      c = *input_line_pointer;
      *input_line_pointer = '\000';
    }
  else
    {
      as_bad (_("Expected quoted string"));
      ignore_rest_of_line ();
      return;
    }

  version_seen = 1;
  if (!bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version))
    as_fatal (_("attaching version header %s: %s"),
	      stdoutput->filename, bfd_errmsg (bfd_get_error ()));

  *input_line_pointer = c;
  demand_empty_rest_of_line ();
}
Exemple #26
0
void
add_debug_prefix_map (const char *arg)
{
  debug_prefix_map *map;
  const char *p;
  char *o;

  p = strchr (arg, '=');
  if (!p)
    {
      as_fatal (_("invalid argument '%s' to -fdebug-prefix-map"), arg);
      return;
    }
  map = (struct debug_prefix_map *) xmalloc (sizeof (debug_prefix_map));
  o = xstrdup (arg);
  map->old_prefix = o;
  map->old_len = p - arg;
  o[map->old_len] = 0;
  p++;
  map->new_prefix = xstrdup (p);
  map->new_len = strlen (p);
  map->next = debug_prefix_maps;
  debug_prefix_maps = map;
}
Exemple #27
0
void
md_begin (void)
{
  const char *retval = NULL;
  int i;

  /* initialize hash table */

  op_hash = hash_new ();

  /* loop until you see the end of the list */

  for (i = 0; i < spu_num_opcodes; i++)
    {
      /* hash each mnemonic and record its position */

      retval = hash_insert (op_hash, spu_opcodes[i].mnemonic,
			    (void *) &spu_opcodes[i]);

      if (retval != NULL && strcmp (retval, "exists") != 0)
	as_fatal (_("Can't hash instruction '%s':%s"),
		  spu_opcodes[i].mnemonic, retval);
    }
}
Exemple #28
0
void
dwarf2_finish (void)
{
  segT line_seg;
  struct line_seg *s;
  segT info_seg;
  int emit_other_sections = 0;
  int empty_debug_line = 0;

  info_seg = bfd_get_section_by_name (stdoutput, ".debug_info");
  emit_other_sections = info_seg == NULL || !seg_not_empty_p (info_seg);

  line_seg = bfd_get_section_by_name (stdoutput, ".debug_line");
  empty_debug_line = line_seg == NULL || !seg_not_empty_p (line_seg);

  /* We can't construct a new debug_line section if we already have one.
     Give an error.  */
  if (all_segs && !empty_debug_line)
    as_fatal ("duplicate .debug_line sections");

  if ((!all_segs && emit_other_sections)
      || (!emit_other_sections && !empty_debug_line))
    /* If there is no line information and no non-empty .debug_info
       section, or if there is both a non-empty .debug_info and a non-empty
       .debug_line, then we do nothing.  */
    return;

  /* Calculate the size of an address for the target machine.  */
  sizeof_address = DWARF2_ADDR_SIZE (stdoutput);

  /* Create and switch to the line number section.  */
  line_seg = subseg_new (".debug_line", 0);
  bfd_set_section_flags (stdoutput, line_seg, SEC_READONLY | SEC_DEBUGGING);

  /* For each subsection, chain the debug entries together.  */
  for (s = all_segs; s; s = s->next)
    {
      struct line_subseg *lss = s->head;
      struct line_entry **ptail = lss->ptail;

      while ((lss = lss->next) != NULL)
	{
	  *ptail = lss->head;
	  ptail = lss->ptail;
	}
    }

  out_debug_line (line_seg);

  /* If this is assembler generated line info, and there is no
     debug_info already, we need .debug_info and .debug_abbrev
     sections as well.  */
  if (emit_other_sections)
    {
      segT abbrev_seg;
      segT aranges_seg;
      segT ranges_seg;

      gas_assert (all_segs);

      info_seg = subseg_new (".debug_info", 0);
      abbrev_seg = subseg_new (".debug_abbrev", 0);
      aranges_seg = subseg_new (".debug_aranges", 0);

      bfd_set_section_flags (stdoutput, info_seg,
			     SEC_READONLY | SEC_DEBUGGING);
      bfd_set_section_flags (stdoutput, abbrev_seg,
			     SEC_READONLY | SEC_DEBUGGING);
      bfd_set_section_flags (stdoutput, aranges_seg,
			     SEC_READONLY | SEC_DEBUGGING);

      record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1);

      if (all_segs->next == NULL)
	ranges_seg = NULL;
      else
	{
	  ranges_seg = subseg_new (".debug_ranges", 0);
	  bfd_set_section_flags (stdoutput, ranges_seg,
				 SEC_READONLY | SEC_DEBUGGING);
	  record_alignment (ranges_seg, ffs (2 * sizeof_address) - 1);
	  out_debug_ranges (ranges_seg);
	}

      out_debug_aranges (aranges_seg, info_seg);
      out_debug_abbrev (abbrev_seg, info_seg, line_seg);
      out_debug_info (info_seg, abbrev_seg, line_seg, ranges_seg);
    }
}
Exemple #29
0
/*
 * section_new() (for non-zerofill sections) switches to a new section, creating
 * it if needed, and creates a fresh fragment.  If it is the current section
 * nothing happens except checks to make sure the type, attributes and
 * sizeof_stub are the same.  The segment and section names will be trimed to
 * fit in the section structure and is the responsiblity of the caller to
 * report errors if they don't.  For zerofill sections only the struct frchain
 * for the section is returned after possibly being created (these section are
 * never made the current section and no frags are ever touched).
 *
 * Globals on input:
 *    frchain_now points to the (possibly none) struct frchain for the current
 *    section.
 *    frag_now points at an incomplete frag for current section.
 *    If frag_now == NULL, then there is no old, incomplete frag, so the old
 *    frag is not closed off.
 *
 * Globals on output:
 *    frchain_now points to the (possibly new) struct frchain for this section.
 *    frchain_root updated if needed (for the first section created).
 *    frag_now is set to the last (possibly new) frag in the section.
 *    now_seg is set to the Mach-O section number (frch_nsect field) except
 *     it is not set for section types of S_ZEROFILL or S_THREAD_LOCAL_ZEROFILL.
 */
frchainS *
section_new(
    char *segname,
    char *sectname,
    uint32_t type,
    uint32_t attributes,
    uint32_t sizeof_stub)
{
    frchainS *frcP;
    frchainS **lastPP;
    uint32_t last_nsect;

    if(frags.chunk_size == 0)
        /*
         * This line is use instead of:
         * 	 obstack_begin(&frags, 5000);
         * which the only difference is that frags are allocated on 4 byte
         * boundaries instead of the default.  The problem with the default
         * is that on some RISC machines the obstack uses 8 (the alignment
         * of a double after a char in a struct) and then the common use of:
         * 	frag_now->fr_fix = obstack_next_free(&frags) -
         *			   frag_now->fr_literal;
         * can get an extra 4 bytes that are not in the frag because of the
         * 8 byte alignment where only 4 byte alignment for frags are
         * needed.
         */
        _obstack_begin(&frags, 5000, 4,
                       obstack_chunk_alloc, obstack_chunk_free);

    /*
     * Determine if this section has been seen.
     */
    last_nsect = 0;
    for(frcP = *(lastPP = &frchain_root);
            frcP != NULL;
            frcP = *(lastPP = &frcP->frch_next)) {
        if(strncmp(frcP->frch_section.segname, segname,
                   sizeof(frcP->frch_section.segname)) == 0 &&
                strncmp(frcP->frch_section.sectname, sectname,
                        sizeof(frcP->frch_section.sectname)) == 0)
            break;
        last_nsect = frcP->frch_nsect;
    }

    /*
     * If this section has been seen make sure it's type and attributes
     * for this call are the same as when the section was created.
     */
    if(frcP != NULL) {
        if((frcP->frch_section.flags & SECTION_TYPE) != type) {
            as_warn("section type does not match previous section type");
        }
        if(type == S_SYMBOL_STUBS &&
                frcP->frch_section.reserved2 != sizeof_stub) {
            as_warn("section stub size does not match previous section "
                    "stub size");
        }
        frcP->frch_section.flags |= attributes;
    }

    /*
     * If the current section is the same as for this call there is nothing
     * more to do.
     */
    if(frcP != NULL && (frchain_now == frcP || type == S_ZEROFILL ||
                        type == S_THREAD_LOCAL_ZEROFILL)) {
        if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL)
            now_seg = frcP->frch_nsect;
        return(frcP);
    }

    /*
     * For non-zerofill sections it will be made the current section so deal
     * with the current frag.
     */
    if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL) {
        /*
         * If there is any current frag in the old section close it off.
         */
        if(frag_now != NULL) {
            frag_now->fr_fix = obstack_next_free(&frags) -
                               frag_now->fr_literal;
            frag_wane(frag_now);
        }

        /*
         * We must do the obstack_finish(), so the next object we put on
         * obstack frags will not appear to start at the fr_literal of the
         * current frag.  Also, it ensures that the next object will begin
         * on a address that is aligned correctly for the engine that runs
         * the assembler.
         */
        (void)obstack_finish(&frags);
    }

    /*
     * If this section exists since it is not the current section switch to
     * it by making it the current chain and create a new frag in it.
     */
    if(frcP != NULL) {
        if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL)
            now_seg = frcP->frch_nsect;
        /*
         * For a zerofill section no frags are created here and since it
         * exists just return a pointer to the section.
         */
        if((frcP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL ||
                (frcP->frch_section.flags & SECTION_TYPE) ==
                S_THREAD_LOCAL_ZEROFILL) {
            return(frcP);
        }
        else {
            /*
             * Make this section the current section.
             */
            frchain_now = frcP;
            if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL)
                now_seg = frchain_now->frch_nsect;

            /*
             * Make a fresh frag for the section.
             */
            frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
            memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
            frag_now->fr_next = NULL;

            /*
             * Append the new frag to the existing frchain.
             */
            frchain_now->frch_last->fr_next = frag_now;
            frchain_now->frch_last = frag_now;
        }
    }
    else {
        /*
         * This section does not exist so create a new frchainS struct fill
         * it in, link it to the chain
         */
        frcP = (frchainS *)xmalloc(sizeof(frchainS));
        memset(frcP, '\0', sizeof(frchainS));
        strncpy(frcP->frch_section.segname, segname,
                sizeof(frcP->frch_section.segname));
        strncpy(frcP->frch_section.sectname, sectname,
                sizeof(frcP->frch_section.sectname));
        frcP->frch_section.flags = attributes | type;
        frcP->frch_section.reserved2 = sizeof_stub;

        if(last_nsect + 1 > MAX_SECT)
            as_fatal("too many sections (maximum %d)\n", MAX_SECT);
        frcP->frch_nsect = last_nsect + 1;
        if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL)
            now_seg = frcP->frch_nsect;

        *lastPP = frcP;

        /*
         * For zerofill sections no frag is created here so just return.
         * For non-zerofill section create the sections new frag and
         * make the section the current chain.
         */
        if(type == S_ZEROFILL || type == S_THREAD_LOCAL_ZEROFILL) {
            return(frcP);
        }
        else {
            /*
             * Make a fresh frag for the new section.
             */
            frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
            memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
            frag_now->fr_next = NULL;

            /*
             * Append the new frag to new frchain.
             */
            frcP->frch_root = frag_now;
            frcP->frch_last = frag_now;

            /*
             * Make this section the current section.
             */
            frchain_now = frcP;
        }
    }
    return(frchain_now);
}
Exemple #30
0
int
atof_generic (/* return pointer to just AFTER number we read.  */
	      char **address_of_string_pointer,
	      /* At most one per number.  */
	      const char *string_of_decimal_marks,
	      const char *string_of_decimal_exponent_marks,
	      FLONUM_TYPE *address_of_generic_floating_point_number)
{
  int return_value;		/* 0 means OK.  */
  char *first_digit;
  unsigned int number_of_digits_before_decimal;
  unsigned int number_of_digits_after_decimal;
  long decimal_exponent;
  unsigned int number_of_digits_available;
  char digits_sign_char;

  /*
   * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
   * It would be simpler to modify the string, but we don't; just to be nice
   * to caller.
   * We need to know how many digits we have, so we can allocate space for
   * the digits' value.
   */

  char *p;
  char c;
  int seen_significant_digit;

#ifdef ASSUME_DECIMAL_MARK_IS_DOT
  assert (string_of_decimal_marks[0] == '.'
	  && string_of_decimal_marks[1] == 0);
#define IS_DECIMAL_MARK(c)	((c) == '.')
#else
#define IS_DECIMAL_MARK(c)	(0 != strchr (string_of_decimal_marks, (c)))
#endif

  first_digit = *address_of_string_pointer;
  c = *first_digit;

  if (c == '-' || c == '+')
    {
      digits_sign_char = c;
      first_digit++;
    }
  else
    digits_sign_char = '+';

  switch (first_digit[0])
    {
    case 'n':
    case 'N':
      if (!strncasecmp ("nan", first_digit, 3))
	{
	  address_of_generic_floating_point_number->sign = 0;
	  address_of_generic_floating_point_number->exponent = 0;
	  address_of_generic_floating_point_number->leader =
	    address_of_generic_floating_point_number->low;
	  *address_of_string_pointer = first_digit + 3;
	  return 0;
	}
      break;

    case 'i':
    case 'I':
      if (!strncasecmp ("inf", first_digit, 3))
	{
	  address_of_generic_floating_point_number->sign =
	    digits_sign_char == '+' ? 'P' : 'N';
	  address_of_generic_floating_point_number->exponent = 0;
	  address_of_generic_floating_point_number->leader =
	    address_of_generic_floating_point_number->low;

	  first_digit += 3;
	  if (!strncasecmp ("inity", first_digit, 5))
	    first_digit += 5;

	  *address_of_string_pointer = first_digit;

	  return 0;
	}
      break;
    }

  number_of_digits_before_decimal = 0;
  number_of_digits_after_decimal = 0;
  decimal_exponent = 0;
  seen_significant_digit = 0;
  for (p = first_digit;
       (((c = *p) != '\0')
	&& (!c || !IS_DECIMAL_MARK (c))
	&& (!c || !strchr (string_of_decimal_exponent_marks, c)));
       p++)
    {
      if (ISDIGIT (c))
	{
	  if (seen_significant_digit || c > '0')
	    {
	      ++number_of_digits_before_decimal;
	      seen_significant_digit = 1;
	    }
	  else
	    {
	      first_digit++;
	    }
	}
      else
	{
	  break;		/* p -> char after pre-decimal digits.  */
	}
    }				/* For each digit before decimal mark.  */

#ifndef OLD_FLOAT_READS
  /* Ignore trailing 0's after the decimal point.  The original code here
   * (ifdef'd out) does not do this, and numbers like
   *	4.29496729600000000000e+09	(2**31)
   * come out inexact for some reason related to length of the digit
   * string.
   */
  if (c && IS_DECIMAL_MARK (c))
    {
      unsigned int zeros = 0;	/* Length of current string of zeros */

      for (p++; (c = *p) && ISDIGIT (c); p++)
	{
	  if (c == '0')
	    {
	      zeros++;
	    }
	  else
	    {
	      number_of_digits_after_decimal += 1 + zeros;
	      zeros = 0;
	    }
	}
    }
#else
  if (c && IS_DECIMAL_MARK (c))
    {
      for (p++;
	   (((c = *p) != '\0')
	    && (!c || !strchr (string_of_decimal_exponent_marks, c)));
	   p++)
	{
	  if (ISDIGIT (c))
	    {
	      /* This may be retracted below.  */
	      number_of_digits_after_decimal++;

	      if ( /* seen_significant_digit || */ c > '0')
		{
		  seen_significant_digit = TRUE;
		}
	    }
	  else
	    {
	      if (!seen_significant_digit)
		{
		  number_of_digits_after_decimal = 0;
		}
	      break;
	    }
	}			/* For each digit after decimal mark.  */
    }

  while (number_of_digits_after_decimal
	 && first_digit[number_of_digits_before_decimal
			+ number_of_digits_after_decimal] == '0')
    --number_of_digits_after_decimal;
#endif

  if (flag_m68k_mri)
    {
      while (c == '_')
	c = *++p;
    }
  if (c && strchr (string_of_decimal_exponent_marks, c))
    {
      char digits_exponent_sign_char;

      c = *++p;
      if (flag_m68k_mri)
	{
	  while (c == '_')
	    c = *++p;
	}
      if (c && strchr ("+-", c))
	{
	  digits_exponent_sign_char = c;
	  c = *++p;
	}
      else
	{
	  digits_exponent_sign_char = '+';
	}

      for (; (c); c = *++p)
	{
	  if (ISDIGIT (c))
	    {
	      decimal_exponent = decimal_exponent * 10 + c - '0';
	      /*
	       * BUG! If we overflow here, we lose!
	       */
	    }
	  else
	    {
	      break;
	    }
	}

      if (digits_exponent_sign_char == '-')
	{
	  decimal_exponent = -decimal_exponent;
	}
    }

  *address_of_string_pointer = p;

  number_of_digits_available =
    number_of_digits_before_decimal + number_of_digits_after_decimal;
  return_value = 0;
  if (number_of_digits_available == 0)
    {
      address_of_generic_floating_point_number->exponent = 0;	/* Not strictly necessary */
      address_of_generic_floating_point_number->leader
	= -1 + address_of_generic_floating_point_number->low;
      address_of_generic_floating_point_number->sign = digits_sign_char;
      /* We have just concocted (+/-)0.0E0 */

    }
  else
    {
      int count;		/* Number of useful digits left to scan.  */

      LITTLENUM_TYPE *digits_binary_low;
      unsigned int precision;
      unsigned int maximum_useful_digits;
      unsigned int number_of_digits_to_use;
      unsigned int more_than_enough_bits_for_digits;
      unsigned int more_than_enough_littlenums_for_digits;
      unsigned int size_of_digits_in_littlenums;
      unsigned int size_of_digits_in_chars;
      FLONUM_TYPE power_of_10_flonum;
      FLONUM_TYPE digits_flonum;

      precision = (address_of_generic_floating_point_number->high
		   - address_of_generic_floating_point_number->low
		   + 1);	/* Number of destination littlenums.  */

      /* Includes guard bits (two littlenums worth) */
      maximum_useful_digits = (((precision - 2))
			       * ( (LITTLENUM_NUMBER_OF_BITS))
			       * 1000000 / 3321928)
	+ 2;			/* 2 :: guard digits.  */

      if (number_of_digits_available > maximum_useful_digits)
	{
	  number_of_digits_to_use = maximum_useful_digits;
	}
      else
	{
	  number_of_digits_to_use = number_of_digits_available;
	}

      /* Cast these to SIGNED LONG first, otherwise, on systems with
	 LONG wider than INT (such as Alpha OSF/1), unsignedness may
	 cause unexpected results.  */
      decimal_exponent += ((long) number_of_digits_before_decimal
			   - (long) number_of_digits_to_use);

      more_than_enough_bits_for_digits
	= (number_of_digits_to_use * 3321928 / 1000000 + 1);

      more_than_enough_littlenums_for_digits
	= (more_than_enough_bits_for_digits
	   / LITTLENUM_NUMBER_OF_BITS)
	+ 2;

      /* Compute (digits) part. In "12.34E56" this is the "1234" part.
	 Arithmetic is exact here. If no digits are supplied then this
	 part is a 0 valued binary integer.  Allocate room to build up
	 the binary number as littlenums.  We want this memory to
	 disappear when we leave this function.  Assume no alignment
	 problems => (room for n objects) == n * (room for 1
	 object).  */

      size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
      size_of_digits_in_chars = size_of_digits_in_littlenums
	* sizeof (LITTLENUM_TYPE);

      digits_binary_low = (LITTLENUM_TYPE *)
	alloca (size_of_digits_in_chars);

      memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);

      /* Digits_binary_low[] is allocated and zeroed.  */

      /*
       * Parse the decimal digits as if * digits_low was in the units position.
       * Emit a binary number into digits_binary_low[].
       *
       * Use a large-precision version of:
       * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
       */

      for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
	{
	  c = *p;
	  if (ISDIGIT (c))
	    {
	      /*
	       * Multiply by 10. Assume can never overflow.
	       * Add this digit to digits_binary_low[].
	       */

	      long carry;
	      LITTLENUM_TYPE *littlenum_pointer;
	      LITTLENUM_TYPE *littlenum_limit;

	      littlenum_limit = digits_binary_low
		+ more_than_enough_littlenums_for_digits
		- 1;

	      carry = c - '0';	/* char -> binary */

	      for (littlenum_pointer = digits_binary_low;
		   littlenum_pointer <= littlenum_limit;
		   littlenum_pointer++)
		{
		  long work;

		  work = carry + 10 * (long) (*littlenum_pointer);
		  *littlenum_pointer = work & LITTLENUM_MASK;
		  carry = work >> LITTLENUM_NUMBER_OF_BITS;
		}

	      if (carry != 0)
		{
		  /*
		   * We have a GROSS internal error.
		   * This should never happen.
		   */
		  as_fatal (_("failed sanity check"));
		}
	    }
	  else
	    {
	      ++count;		/* '.' doesn't alter digits used count.  */
	    }
	}

      /*
       * Digits_binary_low[] properly encodes the value of the digits.
       * Forget about any high-order littlenums that are 0.
       */
      while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
	     && size_of_digits_in_littlenums >= 2)
	size_of_digits_in_littlenums--;

      digits_flonum.low = digits_binary_low;
      digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
      digits_flonum.leader = digits_flonum.high;
      digits_flonum.exponent = 0;
      /*
       * The value of digits_flonum . sign should not be important.
       * We have already decided the output's sign.
       * We trust that the sign won't influence the other parts of the number!
       * So we give it a value for these reasons:
       * (1) courtesy to humans reading/debugging
       *     these numbers so they don't get excited about strange values
       * (2) in future there may be more meaning attached to sign,
       *     and what was
       *     harmless noise may become disruptive, ill-conditioned (or worse)
       *     input.
       */
      digits_flonum.sign = '+';

      {
	/*
	 * Compute the mantssa (& exponent) of the power of 10.
	 * If successful, then multiply the power of 10 by the digits
	 * giving return_binary_mantissa and return_binary_exponent.
	 */

	LITTLENUM_TYPE *power_binary_low;
	int decimal_exponent_is_negative;
	/* This refers to the "-56" in "12.34E-56".  */
	/* FALSE: decimal_exponent is positive (or 0) */
	/* TRUE:  decimal_exponent is negative */
	FLONUM_TYPE temporary_flonum;
	LITTLENUM_TYPE *temporary_binary_low;
	unsigned int size_of_power_in_littlenums;
	unsigned int size_of_power_in_chars;

	size_of_power_in_littlenums = precision;
	/* Precision has a built-in fudge factor so we get a few guard bits.  */

	decimal_exponent_is_negative = decimal_exponent < 0;
	if (decimal_exponent_is_negative)
	  {
	    decimal_exponent = -decimal_exponent;
	  }

	/* From now on: the decimal exponent is > 0. Its sign is separate.  */

	size_of_power_in_chars = size_of_power_in_littlenums
	  * sizeof (LITTLENUM_TYPE) + 2;

	power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
	temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
	memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
	*power_binary_low = 1;
	power_of_10_flonum.exponent = 0;
	power_of_10_flonum.low = power_binary_low;
	power_of_10_flonum.leader = power_binary_low;
	power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
	power_of_10_flonum.sign = '+';
	temporary_flonum.low = temporary_binary_low;
	temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
	/*
	 * (power) == 1.
	 * Space for temporary_flonum allocated.
	 */

	/*
	 * ...
	 *
	 * WHILE	more bits
	 * DO	find next bit (with place value)
	 *	multiply into power mantissa
	 * OD
	 */
	{
	  int place_number_limit;
	  /* Any 10^(2^n) whose "n" exceeds this */
	  /* value will fall off the end of */
	  /* flonum_XXXX_powers_of_ten[].  */
	  int place_number;
	  const FLONUM_TYPE *multiplicand;	/* -> 10^(2^n) */

	  place_number_limit = table_size_of_flonum_powers_of_ten;

	  multiplicand = (decimal_exponent_is_negative
			  ? flonum_negative_powers_of_ten
			  : flonum_positive_powers_of_ten);

	  for (place_number = 1;/* Place value of this bit of exponent.  */
	       decimal_exponent;/* Quit when no more 1 bits in exponent.  */
	       decimal_exponent >>= 1, place_number++)
	    {
	      if (decimal_exponent & 1)
		{
		  if (place_number > place_number_limit)
		    {
		      /* The decimal exponent has a magnitude so great
			 that our tables can't help us fragment it.
			 Although this routine is in error because it
			 can't imagine a number that big, signal an
			 error as if it is the user's fault for
			 presenting such a big number.  */
		      return_value = ERROR_EXPONENT_OVERFLOW;
		      /* quit out of loop gracefully */
		      decimal_exponent = 0;
		    }
		  else
		    {
#ifdef TRACE
		      printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
			      place_number);

		      flonum_print (&power_of_10_flonum);
		      (void) putchar ('\n');
#endif
#ifdef TRACE
		      printf ("multiplier:\n");
		      flonum_print (multiplicand + place_number);
		      (void) putchar ('\n');
#endif
		      flonum_multip (multiplicand + place_number,
				     &power_of_10_flonum, &temporary_flonum);
#ifdef TRACE
		      printf ("after multiply:\n");
		      flonum_print (&temporary_flonum);
		      (void) putchar ('\n');
#endif
		      flonum_copy (&temporary_flonum, &power_of_10_flonum);
#ifdef TRACE
		      printf ("after copy:\n");
		      flonum_print (&power_of_10_flonum);
		      (void) putchar ('\n');
#endif
		    } /* If this bit of decimal_exponent was computable.*/
		} /* If this bit of decimal_exponent was set.  */
	    } /* For each bit of binary representation of exponent */
#ifdef TRACE
	  printf ("after computing power_of_10_flonum:\n");
	  flonum_print (&power_of_10_flonum);
	  (void) putchar ('\n');
#endif
	}

      }

      /*
       * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
       * It may be the number 1, in which case we don't NEED to multiply.
       *
       * Multiply (decimal digits) by power_of_10_flonum.
       */

      flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
      /* Assert sign of the number we made is '+'.  */
      address_of_generic_floating_point_number->sign = digits_sign_char;

    }