/* BFD back-end for mmo objects (MMIX-specific object-format).
   Copyright (C) 2001-2016 Free Software Foundation, Inc.
   Written by Hans-Peter Nilsson (hp@bitrange.com).
   Infrastructure and other bits originally copied from srec.c and
   binary.c.

   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.  */


/*
SECTION
	mmo backend

	The mmo object format is used exclusively together with Professor
	Donald E.@: Knuth's educational 64-bit processor MMIX.  The simulator
	@command{mmix} which is available at
	@url{http://mmix.cs.hm.edu/src/index.html}
	understands this format.  That package also includes a combined
	assembler and linker called @command{mmixal}.  The mmo format has
	no advantages feature-wise compared to e.g. ELF.  It is a simple
	non-relocatable object format with no support for archives or
	debugging information, except for symbol value information and
	line numbers (which is not yet implemented in BFD).  See
	@url{http://mmix.cs.hm.edu/} for more
	information about MMIX.  The ELF format is used for intermediate
	object files in the BFD implementation.

@c We want to xref the symbol table node.  A feature in "chew"
@c requires that "commands" do not contain spaces in the
@c arguments.  Hence the hyphen in "Symbol-table".
@menu
@* File layout::
@* Symbol-table::
@* mmo section mapping::
@end menu

INODE
File layout, Symbol-table, mmo, mmo
SUBSECTION
	File layout

	The mmo file contents is not partitioned into named sections as
	with e.g.@: ELF.  Memory areas is formed by specifying the
	location of the data that follows.  Only the memory area
	@samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} is executable, so
	it is used for code (and constants) and the area
	@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} is used for
	writable data.  @xref{mmo section mapping}.

	There is provision for specifying ``special data'' of 65536
	different types.  We use type 80 (decimal), arbitrarily chosen the
	same as the ELF <<e_machine>> number for MMIX, filling it with
	section information normally found in ELF objects. @xref{mmo
	section mapping}.

	Contents is entered as 32-bit words, xor:ed over previous
	contents, always zero-initialized.  A word that starts with the
	byte @samp{0x98} forms a command called a @samp{lopcode}, where
	the next byte distinguished between the thirteen lopcodes.  The
	two remaining bytes, called the @samp{Y} and @samp{Z} fields, or
	the @samp{YZ} field (a 16-bit big-endian number), are used for
	various purposes different for each lopcode.  As documented in
	@url{http://mmix.cs.hm.edu/doc/mmixal.pdf},
	the lopcodes are:

	@table @code
	@item lop_quote
	0x98000001.  The next word is contents, regardless of whether it
	starts with 0x98 or not.

	@item lop_loc
	0x9801YYZZ, where @samp{Z} is 1 or 2.  This is a location
	directive, setting the location for the next data to the next
	32-bit word (for @math{Z = 1}) or 64-bit word (for @math{Z = 2}),
	plus @math{Y * 2^56}.  Normally @samp{Y} is 0 for the text segment
	and 2 for the data segment.  Beware that the low bits of non-
	tetrabyte-aligned values are silently discarded when being
	automatically incremented and when storing contents (in contrast
	to e.g. its use as current location when followed by lop_fixo
	et al before the next possibly-quoted tetrabyte contents).

	@item lop_skip
	0x9802YYZZ.  Increase the current location by @samp{YZ} bytes.

	@item lop_fixo
	0x9803YYZZ, where @samp{Z} is 1 or 2.  Store the current location
	as 64 bits into the location pointed to by the next 32-bit
	(@math{Z = 1}) or 64-bit (@math{Z = 2}) word, plus @math{Y *
	2^56}.

	@item lop_fixr
	0x9804YYZZ.  @samp{YZ} is stored into the current location plus
	@math{2 - 4 * YZ}.

	@item lop_fixrx
	0x980500ZZ.  @samp{Z} is 16 or 24.  A value @samp{L} derived from
	the following 32-bit word are used in a manner similar to
	@samp{YZ} in lop_fixr: it is xor:ed into the current location
	minus @math{4 * L}.  The first byte of the word is 0 or 1.  If it
	is 1, then @math{L = (@var{lowest 24 bits of word}) - 2^Z}, if 0,
 	then @math{L = (@var{lowest 24 bits of word})}.

	@item lop_file
	0x9806YYZZ.  @samp{Y} is the file number, @samp{Z} is count of
	32-bit words.  Set the file number to @samp{Y} and the line
	counter to 0.  The next @math{Z * 4} bytes contain the file name,
	padded with zeros if the count is not a multiple of four.  The
	same @samp{Y} may occur multiple times, but @samp{Z} must be 0 for
	all but the first occurrence.

	@item lop_line
	0x9807YYZZ.  @samp{YZ} is the line number.  Together with
	lop_file, it forms the source location for the next 32-bit word.
	Note that for each non-lopcode 32-bit word, line numbers are
	assumed incremented by one.

	@item lop_spec
	0x9808YYZZ.  @samp{YZ} is the type number.  Data until the next
	lopcode other than lop_quote forms special data of type @samp{YZ}.
	@xref{mmo section mapping}.

	Other types than 80, (or type 80 with a content that does not
	parse) is stored in sections named <<.MMIX.spec_data.@var{n}>>
	where @var{n} is the @samp{YZ}-type.  The flags for such a
	sections say not to allocate or load the data.  The vma is 0.
	Contents of multiple occurrences of special data @var{n} is
	concatenated to the data of the previous lop_spec @var{n}s.  The
	location in data or code at which the lop_spec occurred is lost.

	@item lop_pre
	0x980901ZZ.  The first lopcode in a file.  The @samp{Z} field forms the
	length of header information in 32-bit words, where the first word
	tells the time in seconds since @samp{00:00:00 GMT Jan 1 1970}.

	@item lop_post
	0x980a00ZZ.  @math{Z > 32}.  This lopcode follows after all
	content-generating lopcodes in a program.  The @samp{Z} field
	denotes the value of @samp{rG} at the beginning of the program.
	The following @math{256 - Z} big-endian 64-bit words are loaded
	into global registers @samp{$G} @dots{} @samp{$255}.

	@item lop_stab
	0x980b0000.  The next-to-last lopcode in a program.  Must follow
	immediately after the lop_post lopcode and its data.  After this
	lopcode follows all symbols in a compressed format
	(@pxref{Symbol-table}).

	@item lop_end
	0x980cYYZZ.  The last lopcode in a program.  It must follow the
	lop_stab lopcode and its data.  The @samp{YZ} field contains the
	number of 32-bit words of symbol table information after the
	preceding lop_stab lopcode.
	@end table

	Note that the lopcode "fixups"; <<lop_fixr>>, <<lop_fixrx>> and
	<<lop_fixo>> are not generated by BFD, but are handled.  They are
	generated by <<mmixal>>.

EXAMPLE
	This trivial one-label, one-instruction file:

| :Main TRAP 1,2,3

	can be represented this way in mmo:

| 0x98090101 - lop_pre, one 32-bit word with timestamp.
| <timestamp>
| 0x98010002 - lop_loc, text segment, using a 64-bit address.
|              Note that mmixal does not emit this for the file above.
| 0x00000000 - Address, high 32 bits.
| 0x00000000 - Address, low 32 bits.
| 0x98060002 - lop_file, 2 32-bit words for file-name.
| 0x74657374 - "test"
| 0x2e730000 - ".s\0\0"
| 0x98070001 - lop_line, line 1.
| 0x00010203 - TRAP 1,2,3
| 0x980a00ff - lop_post, setting $255 to 0.
| 0x00000000
| 0x00000000
| 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
| 0x203a4040   @xref{Symbol-table}.
| 0x10404020
| 0x4d206120
| 0x69016e00
| 0x81000000
| 0x980c0005 - lop_end; symbol table contained five 32-bit words.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "libiberty.h"
#include "elf/mmix.h"
#include "opcode/mmix.h"

#define LOP 0x98
#define LOP_QUOTE 0
#define LOP_LOC 1
#define LOP_SKIP 2
#define LOP_FIXO 3
#define LOP_FIXR 4
#define LOP_FIXRX 5
#define LOP_FILE 6
#define LOP_LINE 7
#define LOP_SPEC 8
#define LOP_PRE 9
#define LOP_POST 10
#define LOP_STAB 11
#define LOP_END 12

#define LOP_QUOTE_NEXT ((LOP << 24) | (LOP_QUOTE << 16) | 1)
#define SPEC_DATA_SECTION 80
#define LOP_SPEC_SECTION \
 ((LOP << 24) | (LOP_SPEC << 16) | SPEC_DATA_SECTION)

/* Must be a power of two.  If you change this to be >= 64k, you need a
   new test-case; the ld test b-loc64k.d touches chunk-size problem areas.  */
#define MMO_SEC_CONTENTS_CHUNK_SIZE (1 << 15)

/* An arbitrary number for the maximum length section name size.  */
#define MAX_SECTION_NAME_SIZE (1024 * 1024)

/* A quite arbitrary number for the maximum length section size.  */
#define MAX_ARTIFICIAL_SECTION_SIZE (1024 * 1024 * 1024)

#define MMO3_WCHAR 0x80
#define MMO3_LEFT 0x40
#define MMO3_MIDDLE 0x20
#define MMO3_RIGHT 0x10
#define MMO3_TYPEBITS 0xf
#define MMO3_REGQUAL_BITS 0xf
#define MMO3_UNDEF 2
#define MMO3_DATA 8
#define MMO3_SYMBITS 0x2f

/* Put these everywhere in new code.  */
#define FATAL_DEBUG						\
 _bfd_abort (__FILE__, __LINE__,				\
	     "Internal: Non-debugged code (test-case missing)")

#define BAD_CASE(x)				\
 _bfd_abort (__FILE__, __LINE__,		\
	     "bad case for " #x)

enum mmo_sym_type { mmo_reg_sym, mmo_undef_sym, mmo_data_sym, mmo_abs_sym};

/* When scanning the mmo file, a linked list of mmo_symbol
   structures is built to represent the symbol table (if there is
   one).  */

struct mmo_symbol
  {
    struct mmo_symbol *next;
    char *name;
    bfd_vma value;
    enum mmo_sym_type sym_type;
    unsigned int serno;
  };

struct mmo_data_list_struct
  {
    struct mmo_data_list_struct *next;
    bfd_vma where;
    bfd_size_type size;
    bfd_size_type allocated_size;
    bfd_byte data[1];
  };

typedef struct mmo_data_list_struct mmo_data_list_type;

struct mmo_symbol_trie
  {
    struct mmo_symbol_trie *left;
    struct mmo_symbol_trie *right;
    struct mmo_symbol_trie *middle;

    bfd_byte symchar;

    /* A zero name means there's nothing here.  */
    struct mmo_symbol sym;
  };

/* The mmo tdata information.  */

struct mmo_data_struct
  {
    struct mmo_symbol *symbols;
    struct mmo_symbol *symtail;
    asymbol *csymbols;

    /* File representation of time (NULL) when this file was created.  */
    bfd_byte created[4];

    /* When we're reading bytes recursively, check this occasionally.
       Also holds write errors.  */
    bfd_boolean have_error;

    /* Max symbol length that may appear in the lop_stab table.  Note that
       this table might just hold a subset of symbols for not-really large
       programs, as it can only be 65536 * 4 bytes large.  */
    int max_symbol_length;

    /* Here's the symbol we build in lop_stab.  */
    char *lop_stab_symbol;

    /* Index into lop_stab_symbol for the next character when parsing the
       symbol information.  */
    int symbol_position;

    /* When creating arbitrary sections, we need to count section numbers.  */
    int sec_no;

    /* When writing or reading byte-wise, we need to count the bytes
       within a 32-bit word.  */
    int byte_no;

    /* We also need a buffer to hold the bytes we count reading or writing.  */
    bfd_byte buf[4];

    /* Whether we've calculated symbol consistency requirement yet.  We do this
       when-needed, which must be at some time after all section
       contents is known.  */
    bfd_boolean symbol_consistency_override_calculated;

    /* Whether to consistency-check symbol values, in particular "Main".  */
    bfd_boolean ignore_symbol_consistency;
  };

typedef struct mmo_data_struct tdata_type;

struct mmo_section_data_struct
  {
    mmo_data_list_type *head;
    mmo_data_list_type *tail;
  };

#define mmo_section_data(sec) \
  ((struct mmo_section_data_struct *) (sec)->used_by_bfd)

/* These structures are used in bfd_map_over_sections constructs.  */

/* Used when writing out sections; all but the register contents section
   which is stored in reg_section.  */
struct mmo_write_sec_info
  {
    asection *reg_section;
    bfd_boolean retval;
  };

/* Used when trying to find a section corresponding to addr.  */
struct mmo_find_sec_info
  {
    asection *sec;
    bfd_vma addr;
  };

static bfd_boolean mmo_bfd_copy_private_bfd_data (bfd *, bfd *);
static void mmo_write_section_unless_reg_contents (bfd *, asection *, void *);
static void mmo_find_sec_w_addr (bfd *, asection *, void *);
static void mmo_find_sec_w_addr_grow (bfd *, asection *, void *);
static asection *mmo_make_section (bfd *, const char *);
static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
static void mmo_print_symbol (bfd *, void *, asymbol *,
			      bfd_print_symbol_type);
static void mmo_init (void);
static bfd_boolean mmo_mkobject (bfd *);
static bfd_boolean mmo_scan (bfd *);
static asection *mmo_decide_section (bfd *, bfd_vma);
static asection *mmo_get_generic_spec_data_section (bfd *, int);
static asection *mmo_get_spec_section (bfd *, int);
static INLINE bfd_byte *mmo_get_loc (asection *, bfd_vma, int);
static void mmo_xore_64 (asection *, bfd_vma vma, bfd_vma value);
static void mmo_xore_32 (asection *, bfd_vma vma, unsigned int);
static void mmo_xore_16 (asection *, bfd_vma vma, unsigned int);
static const bfd_target *mmo_object_p (bfd *);
static void mmo_map_set_sizes (bfd *, asection *, void *);
static bfd_boolean mmo_get_symbols (bfd *);
static bfd_boolean mmo_create_symbol (bfd *, const char *, bfd_vma,
				      enum mmo_sym_type, unsigned int);
static bfd_boolean mmo_get_section_contents (bfd *, asection *, void *,
					     file_ptr, bfd_size_type);
static long mmo_get_symtab_upper_bound (bfd *);
static long mmo_canonicalize_symtab (bfd *, asymbol **);
static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
static void mmo_print_symbol (bfd *, void *, asymbol *,
			      bfd_print_symbol_type);
static bfd_boolean mmo_set_section_contents (bfd *, sec_ptr, const void *,
					     file_ptr, bfd_size_type);
static int mmo_sizeof_headers (bfd *, struct bfd_link_info *);
static bfd_boolean mmo_internal_write_header (bfd *);
static bfd_boolean mmo_internal_write_post (bfd *, int, asection *);
static bfd_boolean mmo_internal_add_3_sym (bfd *, struct mmo_symbol_trie *,
					   const struct mmo_symbol *);
static unsigned int mmo_internal_3_length (bfd *, struct mmo_symbol_trie *);
static void mmo_internal_3_dump (bfd *, struct mmo_symbol_trie *);
static void mmo_beb128_out (bfd *, int, int);
static bfd_boolean mmo_internal_write_section (bfd *, asection *);
static void mmo_write_tetra (bfd *, unsigned int);
static void mmo_write_tetra_raw (bfd *, unsigned int);
static void mmo_write_octa (bfd *, bfd_vma);
static void mmo_write_octa_raw (bfd *, bfd_vma);
static bfd_boolean mmo_write_chunk (bfd *, const bfd_byte *, unsigned int);
static bfd_boolean mmo_flush_chunk (bfd *);
static bfd_boolean mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *,
					unsigned int, bfd_vma *);
static bfd_boolean mmo_write_chunk_list (bfd *, mmo_data_list_type *);
static bfd_boolean mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *);
static bfd_boolean mmo_write_symbols_and_terminator (bfd *);
static flagword mmo_sec_flags_from_bfd_flags (flagword);
static flagword bfd_sec_flags_from_mmo_flags (flagword);
static bfd_byte mmo_get_byte (bfd *);
static void mmo_write_byte (bfd *, bfd_byte);
static bfd_boolean mmo_new_section_hook (bfd *, asection *);
static int mmo_sort_mmo_symbols (const void *, const void *);
static bfd_boolean mmo_write_object_contents (bfd *);
static bfd_boolean mmo_write_section_description (bfd *, asection *);
static bfd_boolean mmo_has_leading_or_trailing_zero_tetra_p (bfd *,
							     asection *);

/* Global "const" variables initialized once.  Must not depend on
   particular input or caller; put such things into the bfd or elsewhere.
   Look ma, no static per-invocation data!  */

static
char valid_mmo_symbol_character_set[/* A-Z a-z (we assume consecutive
				       codes; sorry EBCDIC:ers!).  */
				    + 'Z' - 'A' + 1 + 'z' - 'a' + 1
				    /* Digits.  */
				    + 10
				    /* ':' and '_'.  */
				    + 1 + 1
				    /* Codes higher than 126.  */
				    + 256 - 126
				    /* Ending zero.  */
				    + 1];


/* Get section SECNAME or create one if it doesn't exist.  When creating
   one, new memory for the name is allocated.  */

static asection *
mmo_make_section (bfd *abfd, const char *secname)
{
  asection *sec = bfd_get_section_by_name (abfd, secname);

  if (sec == NULL)
    {
      char *newsecname = strdup (secname);

      if (newsecname == NULL)
	{
	  (*_bfd_error_handler)
	    (_("%s: No core to allocate section name %s\n"),
	     bfd_get_filename (abfd), secname);
	  bfd_set_error (bfd_error_system_call);
	  return NULL;
	}
      sec = bfd_make_section (abfd, newsecname);
    }

  return sec;
}

/* Nothing to do, but keep as a placeholder if we need it.
   Note that state that might differ between bfd:s must not be initialized
   here, nor must it be static.  Add it to tdata information instead.  */

static void
mmo_init (void)
{
  static bfd_boolean inited = FALSE;
  int i = 0;
  int j = 0;
  static const char letters[]
    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:_";

  if (inited)
    return;
  inited = TRUE;

  /* Fill in the set of valid symbol characters.  */
  strcpy (valid_mmo_symbol_character_set, letters);
  i = strlen (letters);

  for (j = 126; j < 256; j++)
    valid_mmo_symbol_character_set[i++] = j;
}

/* Check whether an existing file is an mmo file.  */

static const bfd_target *
mmo_object_p (bfd *abfd)
{
  struct stat statbuf;
  bfd_byte b[4];

  mmo_init ();

  if (bfd_stat (abfd, &statbuf) < 0
      || bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
      || bfd_bread (b, 4, abfd) != 4)
    goto bad_final;

  /* All mmo files are a multiple of four bytes long.
     Only recognize version one.  */
  if ((statbuf.st_size % 4) != 0
      || b[0] != LOP || b[1] != LOP_PRE || b[2] != 1)
    goto bad_format;

  /* Get the last 32-bit word.  */
  if (bfd_seek (abfd, (file_ptr) statbuf.st_size - 4, SEEK_SET) != 0
      || bfd_bread (b, 4, abfd) != 4)
    goto bad_final;

  /* Check if the file ends in a lop_end lopcode. */
  if (b[0] != LOP || b[1] != LOP_END || ! mmo_mkobject (abfd))
    goto bad_format;

  /* Compute an upper bound on the max symbol length.  Not really
     important as all of the symbol information can only be 256k.  */
  abfd->tdata.mmo_data->max_symbol_length = (b[2] * 256 + b[3]) * 4;
  abfd->tdata.mmo_data->lop_stab_symbol
    = bfd_malloc (abfd->tdata.mmo_data->max_symbol_length + 1);

  if (abfd->tdata.mmo_data->lop_stab_symbol == NULL)
    {
      (*_bfd_error_handler)
	(_("%s: No core to allocate a symbol %d bytes long\n"),
	 bfd_get_filename (abfd), abfd->tdata.mmo_data->max_symbol_length);
      goto bad_final;
    }

  /* Read in everything.  */
  if (! mmo_scan (abfd))
    goto bad_format_free;

  if (abfd->symcount > 0)
    abfd->flags |= HAS_SYMS;

  /* You'll have to tweak this if you want to use this format for other
     arches (not recommended due to its small-size limitations).  Look at
     the ELF format for how to make it target-generic.  */
  if (! bfd_default_set_arch_mach (abfd, bfd_arch_mmix, 0))
    goto bad_format_free;

  return abfd->xvec;

 bad_format_free:
  free (abfd->tdata.mmo_data->lop_stab_symbol);
 bad_format:
  bfd_set_error (bfd_error_wrong_format);
 bad_final:
  return NULL;
}

/* Set up the mmo tdata information.  */

static bfd_boolean
mmo_mkobject (bfd *abfd)
{
  mmo_init ();

  if (abfd->tdata.mmo_data == NULL)
    {
      time_t created;

      /* All fields are zero-initialized, so we don't have to explicitly
	 initialize most.  */
      tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type));
      if (tdata == NULL)
	return FALSE;

      created = time (NULL);
      bfd_put_32 (abfd, created, tdata->created);

      abfd->tdata.mmo_data = tdata;
    }

  return TRUE;
}

static bfd_boolean
mmo_section_has_contents (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p ATTRIBUTE_UNUSED)
{
  /* The point is to match what --extract-symbols does (well, negated).  */
  return bfd_get_section_size (sec) != 0;
}

/* Find out whether we should omit symbol consistency checks for this
   bfd and cache the value.

   This function must only be called when all section contents is
   known.  However, calculating symbol consistency at the time the
   private BFD data is initialized is too late for some uses.  */

static bfd_boolean
mmo_ignore_symbol_consistency (bfd *abfd)
{
  if (!abfd->tdata.mmo_data->symbol_consistency_override_calculated)
    {
      abfd->tdata.mmo_data->ignore_symbol_consistency =
	bfd_sections_find_if (abfd, mmo_section_has_contents, NULL) == NULL;

      abfd->tdata.mmo_data->symbol_consistency_override_calculated = TRUE;
    }

  return abfd->tdata.mmo_data->ignore_symbol_consistency;
}

static bfd_boolean
mmo_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  if (bfd_get_flavour (ibfd) != bfd_target_mmo_flavour
      || bfd_get_flavour (obfd) != bfd_target_mmo_flavour)
    return TRUE;

  /* Copy the time the copied-from file was created.  If people want the
     time the file was last *modified*, they have that in the normal file
     information.  */
  memcpy (obfd->tdata.mmo_data->created, ibfd->tdata.mmo_data->created,
	  sizeof (obfd->tdata.mmo_data->created));
  return TRUE;
}

/* Helper functions for mmo_decide_section, used through
   bfd_map_over_sections.  */

static void
mmo_find_sec_w_addr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
{
  struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
  bfd_vma vma = bfd_get_section_vma (abfd, sec);

  /* Ignore sections that aren't loaded.  */
  if ((bfd_get_section_flags (abfd, sec) & (SEC_LOAD | SEC_ALLOC))
      !=  (SEC_LOAD | SEC_ALLOC))
    return;

  if (infop->addr >= vma && infop->addr < vma + sec->size)
    infop->sec = sec;
}

static void
mmo_find_sec_w_addr_grow (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
{
  struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
  bfd_vma vma = bfd_get_section_vma (abfd, sec);

  /* Ignore sections that aren't loaded.  */
  if ((bfd_get_section_flags (abfd, sec) & (SEC_LOAD | SEC_ALLOC))
      !=  (SEC_LOAD | SEC_ALLOC))
    return;

  if (infop->addr >= vma && infop->addr < vma + MAX_ARTIFICIAL_SECTION_SIZE)
    infop->sec = sec;
}

/* Find a section that corresponds to a VMA.  Automatically create .text
   or .data and set current section to it, depending on what vma.  If we
   can't deduce a section, make one up as ".MMIX.sec.N", where N is an
   increasing number.  */

static asection *
mmo_decide_section (bfd *abfd, bfd_vma vma)
{
  asection *sec = NULL;
  char sec_name[sizeof (".MMIX.sec.") + 20];
  struct mmo_find_sec_info info;

  info.addr = vma;
  info.sec = NULL;

  /* First see if there's a section that would match exactly.  */
  bfd_map_over_sections (abfd, mmo_find_sec_w_addr, &info);

  if (info.sec != NULL)
    return info.sec;

  /* If there's no such section, try and expand one of the existing ones,
     up to a limit.  Make sure we have .text and .data before we try that;
     create them corresponding to expected addresses and set flags to make
     them match the "loaded and with contents" expectation.  */
  if ((vma >> 56) == 0)
    {
      sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);

      if (sec == NULL)
	return NULL;

      if (! sec->user_set_vma && ! bfd_set_section_vma (abfd, sec, vma))
	return NULL;

      if (! bfd_set_section_flags (abfd, sec,
				   bfd_get_section_flags (abfd, sec)
				   | SEC_CODE | SEC_LOAD | SEC_ALLOC))
	return NULL;
    }
  else if ((vma >> 56) == 0x20)
    {
      sec = bfd_make_section_old_way (abfd, MMO_DATA_SECTION_NAME);

      if (sec == NULL)
	return NULL;

      if (! sec->user_set_vma && ! bfd_set_section_vma (abfd, sec, vma))
	return NULL;

      if (! bfd_set_section_flags (abfd, sec,
				   bfd_get_section_flags (abfd, sec)
				   | SEC_LOAD | SEC_ALLOC))
	return NULL;
    }

  bfd_map_over_sections (abfd, mmo_find_sec_w_addr_grow, &info);

  if (info.sec != NULL)
    return info.sec;

  /* If there's still no suitable section, make a new one.  */
  sprintf (sec_name, ".MMIX.sec.%d", abfd->tdata.mmo_data->sec_no++);
  sec = mmo_make_section (abfd, sec_name);

  if (! sec->user_set_vma && ! bfd_set_section_vma (abfd, sec, vma))
    return NULL;

  if (! bfd_set_section_flags (abfd, sec,
			       bfd_get_section_flags (abfd, sec)
			       | SEC_LOAD | SEC_ALLOC))
    return NULL;
  return sec;
}

/* Xor in a 64-bit value VALUE at VMA.  */

static INLINE void
mmo_xore_64 (asection *sec, bfd_vma vma, bfd_vma value)
{
  bfd_byte *loc = mmo_get_loc (sec, vma, 8);
  bfd_vma prev = bfd_get_64 (sec->owner, loc);

  value ^= prev;
  bfd_put_64 (sec->owner, value, loc);
}

/* Xor in a 32-bit value VALUE at VMA.  */

static INLINE void
mmo_xore_32 (asection *sec, bfd_vma vma, unsigned int value)
{
  bfd_byte *loc = mmo_get_loc (sec, vma, 4);
  unsigned int prev = bfd_get_32 (sec->owner, loc);

  value ^= prev;
  bfd_put_32 (sec->owner, value, loc);
}

/* Xor in a 16-bit value VALUE at VMA.  */

static INLINE void
mmo_xore_16 (asection *sec, bfd_vma vma, unsigned int value)
{
  bfd_byte *loc = mmo_get_loc (sec, vma, 2);
  unsigned int prev = bfd_get_16 (sec->owner, loc);

  value ^= prev;
  bfd_put_16 (sec->owner, value, loc);
}

/* Write a 32-bit word to output file, no lop_quote generated.  */

static INLINE void
mmo_write_tetra_raw (bfd *abfd, unsigned int value)
{
  bfd_byte buf[4];

  bfd_put_32 (abfd, value, buf);

  if (bfd_bwrite (buf, 4, abfd) != 4)
    abfd->tdata.mmo_data->have_error = TRUE;
}

/* Write a 32-bit word to output file; lop_quote if necessary.  */

static INLINE void
mmo_write_tetra (bfd *abfd, unsigned int value)
{
  if (((value >> 24) & 0xff) == LOP)
    mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);

  mmo_write_tetra_raw (abfd, value);
}

/* Write a 64-bit word to output file, perhaps with lop_quoting.  */

static INLINE void
mmo_write_octa (bfd *abfd, bfd_vma value)
{
  mmo_write_tetra (abfd, (unsigned int) (value >> 32));
  mmo_write_tetra (abfd, (unsigned int) value);
}

/* Write a 64-bit word to output file, without lop_quoting.  */

static INLINE void
mmo_write_octa_raw (bfd *abfd, bfd_vma value)
{
  mmo_write_tetra_raw (abfd, (unsigned int) (value >> 32));
  mmo_write_tetra_raw (abfd, (unsigned int) value);
}

/* Write quoted contents.  Intended to be called multiple times in
   sequence, followed by a call to mmo_flush_chunk.  */

static INLINE bfd_boolean
mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
{
  bfd_boolean retval = TRUE;
  struct mmo_data_struct *mmop = abfd->tdata.mmo_data;

  /* Fill up a tetra from bytes remaining from a previous chunk.  */
  if (mmop->byte_no != 0)
    {
      while (mmop->byte_no < 4 && len != 0)
	{
	  mmop->buf[mmop->byte_no++] = *loc++;
	  len--;
	}

      if (mmop->byte_no == 4)
	{
	  mmo_write_tetra (abfd, bfd_get_32 (abfd, mmop->buf));
	  mmop->byte_no = 0;
	}
    }

  while (len >= 4)
    {
      if (loc[0] == LOP)
	mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);

      retval = (retval
		&& ! mmop->have_error
		&& 4 == bfd_bwrite (loc, 4, abfd));

      loc += 4;
      len -= 4;
    }

  if (len)
    {
      /* We must have flushed a previous remainder if we get one from
	 this chunk too.  */
      BFD_ASSERT (mmop->byte_no == 0);
      memcpy (mmop->buf, loc, len);
      mmop->byte_no = len;
    }

  if (! retval)
    mmop->have_error = TRUE;
  return retval;
}

/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to
   4 bytes.  */

static INLINE bfd_boolean
mmo_flush_chunk (bfd *abfd)
{
  if (abfd->tdata.mmo_data->byte_no != 0)
    {
      memset (abfd->tdata.mmo_data->buf + abfd->tdata.mmo_data->byte_no,
	      0, 4 - abfd->tdata.mmo_data->byte_no);
      mmo_write_tetra (abfd,
		       bfd_get_32 (abfd, abfd->tdata.mmo_data->buf));
      abfd->tdata.mmo_data->byte_no = 0;
    }

  return ! abfd->tdata.mmo_data->have_error;
}

/* Same, but from a list.  */

static INLINE bfd_boolean
mmo_write_chunk_list (bfd *abfd, mmo_data_list_type *datap)
{
  for (; datap != NULL; datap = datap->next)
    if (! mmo_write_chunk (abfd, datap->data, datap->size))
      return FALSE;

  return mmo_flush_chunk (abfd);
}

/* Write a lop_loc and some contents.  A caller needs to call
   mmo_flush_chunk after calling this function.  The location is only
   output if different than *LAST_VMAP, which is updated after this call.  */

static bfd_boolean
mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc,
		     unsigned int len, bfd_vma *last_vmap)
{
  /* Find an initial and trailing section of zero (aligned) tetras; we don't
     need to write out zeros.  FIXME: When we do this, we should emit
     section size and address specifiers, else objcopy can't always perform
     an identity translation.  Only do this if we *don't* have left-over
     data from a previous write (and will not add any) or else the vma of
     this chunk is *not* the next address, because then data isn't
     tetrabyte-aligned and we're concatenating to that left-over data.  */

  if ((vma & 3) == 0
      && (abfd->tdata.mmo_data->byte_no == 0 || vma != *last_vmap))
    {
      while (len > 4 && bfd_get_32 (abfd, loc) == 0)
	{
	  vma += 4;
	  len -= 4;
	  loc += 4;
	}

      if ((len & 3) == 0)
	while (len > 4 && bfd_get_32 (abfd, loc + len - 4) == 0)
	  len -= 4;
    }

  /* Only write out the location if it's different than the one the caller
     (supposedly) previously handled, accounting for omitted leading zeros.  */
  if (vma != *last_vmap)
    {
      /* We might be in the middle of a sequence.  */
      mmo_flush_chunk (abfd);

      /* This should not happen during normal usage, but can presumably
	 happen with an erroneous linker-script, so handle gracefully.
	 Avoid Knuth-specific terms in the message, such as "tetrabyte".
	 Note that this function will get non-4-multiple lengths and
	 unaligned vmas but those come in tuples (mostly pairs) and are
	 continuous (i.e. the if-condition above false) and they are
	 group-wise aligned.  */
      if ((vma & 3) != 0)
	{
	  (*_bfd_error_handler)
	    (_("%s: attempt to emit contents at non-multiple-of-4 address 0x%lx\n"),
	     bfd_get_filename (abfd), (unsigned long) vma);
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
	}

      /* We always write the location as 64 bits; no use saving bytes
         here.  */
      mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_LOC << 16) | 2);
      mmo_write_octa_raw (abfd, vma);
    }

  /* Update to reflect end of this chunk, with trailing zeros omitted.  */
  *last_vmap = vma + len;

  return (! abfd->tdata.mmo_data->have_error
	  && mmo_write_chunk (abfd, loc, len));
}

/* Same, but from a list.  */

static INLINE bfd_boolean
mmo_write_loc_chunk_list (bfd *abfd, mmo_data_list_type *datap)
{
  /* Get an address different than the address of the first chunk.  */
  bfd_vma last_vma = datap ? datap->where - 1 : 0;

  for (; datap != NULL; datap = datap->next)
    if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size,
			       &last_vma))
      return FALSE;

  return mmo_flush_chunk (abfd);
}

/* Make a .MMIX.spec_data.N section.  */

static asection *
mmo_get_generic_spec_data_section (bfd *abfd, int spec_data_number)
{
  asection *sec;
  char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20]
    = MMIX_OTHER_SPEC_SECTION_PREFIX;

  sprintf (secname + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX),
	   "%d", spec_data_number);

  sec = mmo_make_section (abfd, secname);

  return sec;
}

/* Make a special section for SPEC_DATA_NUMBER.  If it is the one we use
   ourselves, parse some of its data to get at the section name.  */

static asection *
mmo_get_spec_section (bfd *abfd, int spec_data_number)
{
  char *secname;
  asection *sec;
  bfd_byte buf[4];
  unsigned int secname_length;
  unsigned int i;
  bfd_vma section_length;
  bfd_vma section_vma;
  mmo_data_list_type *loc;
  flagword flags;
  long orig_pos;

  /* If this isn't the "special" special data, then make a placeholder
     section.  */
  if (spec_data_number != SPEC_DATA_SECTION)
    return mmo_get_generic_spec_data_section (abfd, spec_data_number);

  /* Seek back to this position if there was a format error.  */
  orig_pos = bfd_tell (abfd);

  /* Read the length (in 32-bit words).  */
  if (bfd_bread (buf, 4, abfd) != 4)
    goto format_error;

  if (buf[0] == LOP)
    {
      if (buf[1] != LOP_QUOTE)
	goto format_error;

      if (bfd_bread (buf, 4, abfd) != 4)
	goto format_error;
    }

  /* We don't care to keep the name length accurate.  It's
     zero-terminated.  */
  secname_length = bfd_get_32 (abfd, buf) * 4;

  /* Check section name length for sanity.  */
  if (secname_length > MAX_SECTION_NAME_SIZE)
    goto format_error;

  /* This should be free'd regardless if a section is created.  */
  secname = bfd_malloc (secname_length + 1);
  secname[secname_length] = 0;

  for (i = 0; i < secname_length / 4; i++)
    {
      if (bfd_bread (secname + i * 4, 4, abfd) != 4)
	goto format_error_free;

      if (secname[i * 4] == (char) LOP)
	{
	  /* A bit of overkill, but we handle char 0x98 in a section name,
	     and recognize misparsing.  */
	  if (secname[i * 4 + 1] != LOP_QUOTE
	      || bfd_bread (secname + i * 4, 4, abfd) != 4)
	    /* Whoops.  We thought this was a name, and now we found a
	       non-lop_quote lopcode before we parsed the whole length of
	       the name.  Signal end-of-file in the same manner.  */
	      goto format_error_free;
	}
    }

  /* Get the section flags.  */
  if (bfd_bread (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
    goto format_error_free;

  flags = bfd_get_32 (abfd, buf);

  /* Get the section length.  */
  if (bfd_bread (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
    goto format_error_free;

  section_length = (bfd_vma) bfd_get_32 (abfd, buf) << 32;

  /* That's the first, high-part.  Now get the low part.  */

  if (bfd_bread (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
    goto format_error_free;

  section_length |= (bfd_vma) bfd_get_32 (abfd, buf);

  /* Check the section length for sanity.  */
  if (section_length > MAX_ARTIFICIAL_SECTION_SIZE)
    goto format_error_free;

  /* Get the section VMA.  */
  if (bfd_bread (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
    goto format_error_free;

  section_vma = (bfd_vma) bfd_get_32 (abfd, buf) << 32;

  /* That's the first, high-part.  Now get the low part.  */
  if (bfd_bread (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
    goto format_error_free;

  section_vma |= (bfd_vma) bfd_get_32 (abfd, buf);

  sec = mmo_make_section (abfd, secname);
  free (secname);
  if (sec == NULL)
    goto format_error;

  /* We allocate a buffer here for the advertised size, with head room for
     tetrabyte alignment.  */
  loc = bfd_zmalloc (section_length + 3
		     + sizeof (struct mmo_data_list_struct));
  if (loc == NULL)
    goto format_error;

  /* Use a TETRA-rounded size for the allocated buffer; we set the
     "visible" section size below.  */
  loc->size = (section_length + 3) & ~3;

  /* Add in the section flags we found to those bfd entered during this
     process and set the contents.  */
  if (! bfd_set_section_flags (abfd, sec,
			       bfd_sec_flags_from_mmo_flags (flags)
			       | bfd_get_section_flags (abfd, sec)
			       | (section_length != 0 ? SEC_HAS_CONTENTS : 0))
      || ! bfd_set_section_size (abfd, sec, sec->size + section_length)
      /* Set VMA only for the first occurrence.  */
      || (! sec->user_set_vma
	  && ! bfd_set_section_vma  (abfd, sec, section_vma)))
    {
      /* If we get an error for any of the calls above, signal more than
	 just a format error for the spec section.  */
      return NULL;
    }

  loc->next = NULL;
  if (mmo_section_data (sec)->tail != NULL)
    mmo_section_data (sec)->tail->next = loc;
  else
    mmo_section_data (sec)->head = loc;
  mmo_section_data (sec)->tail = loc;
  loc->where = section_vma;

  return sec;

 format_error_free:
  free (secname);
 format_error:
  if (bfd_seek (abfd, orig_pos, SEEK_SET) != 0)
    return NULL;

  return mmo_get_generic_spec_data_section (abfd, spec_data_number);
}

/* Read a byte, but read from file in multiples of 32-bit words.  */

static bfd_byte
mmo_get_byte (bfd *abfd)
{
  bfd_byte retval;

  if (abfd->tdata.mmo_data->byte_no == 0)
    {
      if (! abfd->tdata.mmo_data->have_error
	  && bfd_bread (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
	{
	  abfd->tdata.mmo_data->have_error = TRUE;

	  /* A value somewhat safe against tripping on some inconsistency
	     when mopping up after this error.  */
	  return 128;
	}
    }

  retval = abfd->tdata.mmo_data->buf[abfd->tdata.mmo_data->byte_no];
  abfd->tdata.mmo_data->byte_no = (abfd->tdata.mmo_data->byte_no + 1) % 4;

  return retval;
}

/* Write a byte, in multiples of 32-bit words.  */

static void
mmo_write_byte (bfd *abfd, bfd_byte value)
{
  abfd->tdata.mmo_data->buf[(abfd->tdata.mmo_data->byte_no++ % 4)] = value;
  if ((abfd->tdata.mmo_data->byte_no % 4) == 0)
    {
      if (! abfd->tdata.mmo_data->have_error
	  && bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
	abfd->tdata.mmo_data->have_error = TRUE;
    }
}

/* Create a symbol.  */

static bfd_boolean
mmo_create_symbol (bfd *abfd, const char *symname, bfd_vma addr, enum
		   mmo_sym_type sym_type, unsigned int serno)
{
  struct mmo_symbol *n;

  n = (struct mmo_symbol *) bfd_alloc (abfd, sizeof (struct mmo_symbol));
  if (n == NULL)
    return FALSE;

  n->name = bfd_alloc (abfd, strlen (symname) + 1);
  if (n->name == NULL)
    return FALSE;

  strcpy (n->name, symname);

  n->value = addr;
  n->sym_type = sym_type;
  n->serno = serno;

  if (abfd->tdata.mmo_data->symbols == NULL)
    abfd->tdata.mmo_data->symbols = n;
  else
    abfd->tdata.mmo_data->symtail->next = n;
  abfd->tdata.mmo_data->symtail = n;
  n->next = NULL;

  ++abfd->symcount;

  /* Check that :Main equals the last octa of the .MMIX.reg_contents
     section, as it's the one place we're sure to pass when reading a mmo
     object.  For written objects, we do it while setting the symbol
     table.  */
  if (strcmp (symname, MMIX_START_SYMBOL_NAME) == 0
      && bfd_get_start_address (abfd) != addr
      && !mmo_ignore_symbol_consistency (abfd))
    {
      (*_bfd_error_handler)
	(_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"),
	 bfd_get_filename (abfd));
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  return TRUE;
}

/* Read in symbols.  */

static bfd_boolean
mmo_get_symbols (bfd *abfd)
{
/*
INODE
Symbol-table, mmo section mapping, File layout, mmo
SUBSECTION
	Symbol table format

	From mmixal.w (or really, the generated mmixal.tex) in the
	MMIXware package which also contains the @command{mmix} simulator:
	``Symbols are stored and retrieved by means of a @samp{ternary
	search trie}, following ideas of Bentley and Sedgewick. (See
	ACM--SIAM Symp.@: on Discrete Algorithms @samp{8} (1997), 360--369;
	R.@:Sedgewick, @samp{Algorithms in C} (Reading, Mass.@:
	Addison--Wesley, 1998), @samp{15.4}.)  Each trie node stores a
	character, and there are branches to subtries for the cases where
	a given character is less than, equal to, or greater than the
	character in the trie.  There also is a pointer to a symbol table
	entry if a symbol ends at the current node.''

	So it's a tree encoded as a stream of bytes.  The stream of bytes
	acts on a single virtual global symbol, adding and removing
	characters and signalling complete symbol points.  Here, we read
	the stream and create symbols at the completion points.

	First, there's a control byte <<m>>.  If any of the listed bits
	in <<m>> is nonzero, we execute what stands at the right, in
	the listed order:

| (MMO3_LEFT)
| 0x40 - Traverse left trie.
|        (Read a new command byte and recurse.)
|
| (MMO3_SYMBITS)
| 0x2f - Read the next byte as a character and store it in the
|        current character position; increment character position.
|        Test the bits of <<m>>:
|
|        (MMO3_WCHAR)
|        0x80 - The character is 16-bit (so read another byte,
|               merge into current character.
|
|        (MMO3_TYPEBITS)
|        0xf  - We have a complete symbol; parse the type, value
|               and serial number and do what should be done
|               with a symbol.  The type and length information
|               is in j = (m & 0xf).
|
|               (MMO3_REGQUAL_BITS)
|	        j == 0xf: A register variable.  The following
|                         byte tells which register.
|               j <= 8:   An absolute symbol.  Read j bytes as the
|                         big-endian number the symbol equals.
|                         A j = 2 with two zero bytes denotes an
|                         unknown symbol.
|               j > 8:    As with j <= 8, but add (0x20 << 56)
|                         to the value in the following j - 8
|                         bytes.
|
|               Then comes the serial number, as a variant of
|               uleb128, but better named ubeb128:
|               Read bytes and shift the previous value left 7
|               (multiply by 128).  Add in the new byte, repeat
|               until a byte has bit 7 set.  The serial number
|               is the computed value minus 128.
|
|        (MMO3_MIDDLE)
|        0x20 - Traverse middle trie.  (Read a new command byte
|               and recurse.)  Decrement character position.
|
| (MMO3_RIGHT)
| 0x10 - Traverse right trie.  (Read a new command byte and
|        recurse.)

	Let's look again at the <<lop_stab>> for the trivial file
	(@pxref{File layout}).

| 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
| 0x203a4040
| 0x10404020
| 0x4d206120
| 0x69016e00
| 0x81000000

	This forms the trivial trie (note that the path between ``:'' and
	``M'' is redundant):

| 203a	   ":"
| 40       /
| 40      /
| 10      \
| 40      /
| 40     /
| 204d  "M"
| 2061  "a"
| 2069  "i"
| 016e  "n" is the last character in a full symbol, and
|       with a value represented in one byte.
| 00    The value is 0.
| 81    The serial number is 1.  */

  bfd_byte m = mmo_get_byte (abfd);

  /* Check first if we have a bad hair day.  */
  if (abfd->tdata.mmo_data->have_error)
    return FALSE;

  if (m & MMO3_LEFT)
    /* Traverse left trie. */
    mmo_get_symbols (abfd);

  if (m & MMO3_SYMBITS)
    {
      bfd_byte c = mmo_get_byte (abfd);
      bfd_byte j = m & MMO3_TYPEBITS;
      bfd_vma addr = 0;
      enum mmo_sym_type sym_type;
      unsigned int serno = 0;
      bfd_byte k;

      if (m & MMO3_WCHAR)
	{
	  bfd_byte c2 = mmo_get_byte (abfd);

	  /* A two-byte character.  We can't grok this, but neither can
	     mmotype, for other cases than the second byte being zero.  */

	  if (c != 0)
	    {
	      abfd->tdata.mmo_data->lop_stab_symbol
		[abfd->tdata.mmo_data->symbol_position] = 0;

	      (*_bfd_error_handler)
		(_("%s: unsupported wide character sequence"
		   " 0x%02X 0x%02X after symbol name starting with `%s'\n"),
		 bfd_get_filename (abfd), c, c2,
		 abfd->tdata.mmo_data->lop_stab_symbol);
	      bfd_set_error (bfd_error_bad_value);
	      abfd->tdata.mmo_data->have_error = TRUE;
	      return FALSE;
	    }
	  else
	    c = c2;
	}

      abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position++] = c;
      abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position] = 0;

      if (j & MMO3_REGQUAL_BITS)
	{
	  if (j == MMO3_REGQUAL_BITS)
	    {
	      sym_type = mmo_reg_sym;
	      addr = mmo_get_byte (abfd);
	    }
	  else if (j <= 8)
	    {
	      unsigned int i;

	      for (i = 0; i < j; i++)
		addr = (addr << 8) + mmo_get_byte (abfd);

	      if (addr == 0 && j == MMO3_UNDEF)
		sym_type = mmo_undef_sym;
	      else
		sym_type = mmo_abs_sym;
	    }
	  else
	    {
	      unsigned int i;

	      for (i = MMO3_DATA; i < j; i++)
		addr = (addr << 8) + mmo_get_byte (abfd);

	      addr += (bfd_vma) 0x20 << 56;
	      sym_type = mmo_data_sym;
	    }

	  /* Get the serial number.  */
	  do
	    {
	      k = mmo_get_byte (abfd);
	      serno = (serno << 7) + k;
	    }
	  while (k < 128);
	  serno -= 128;

	  /* Got it.  Now enter it.  Skip a leading ":".  */
	  if (! abfd->tdata.mmo_data->have_error
	      && ! mmo_create_symbol (abfd,
				      abfd->tdata.mmo_data->lop_stab_symbol
				      + 1,
				      addr, sym_type, serno))
	    abfd->tdata.mmo_data->have_error = TRUE;
	}

      if (m & MMO3_MIDDLE)
	/* Traverse middle trie. */
	mmo_get_symbols (abfd);

      abfd->tdata.mmo_data->symbol_position--;
    }

  if (m & MMO3_RIGHT)
    /* Traverse right trie.  */
    mmo_get_symbols (abfd);

  return ! abfd->tdata.mmo_data->have_error;
}

/* Get the location of memory area [VMA..VMA + SIZE - 1], which we think
   is in section SEC.  Adjust and reallocate zero-initialized contents.
   If there's new contents, allocate to the next multiple of
   MMO_SEC_CONTENTS_CHUNK_SIZE.  */

static INLINE bfd_byte *
mmo_get_loc (asection *sec, bfd_vma vma, int size)
{
  bfd_size_type allocated_size;
  struct mmo_section_data_struct *sdatap = mmo_section_data (sec);
  struct mmo_data_list_struct *datap = sdatap->head;
  struct mmo_data_list_struct *entry;

  /* First search the list to see if we have the requested chunk in one
     piece, or perhaps if we have a suitable chunk with room to fit.  */
  for (; datap != NULL; datap = datap->next)
    {
      if (datap->where <= vma
	  && datap->where + datap->size >= vma + size)
	return datap->data + vma - datap->where;
      else if (datap->where <= vma
	       && datap->where + datap->allocated_size >= vma + size
	       /* Only munch on the "allocated size" if it does not
		  overlap the next chunk.  */
	       && (datap->next == NULL || datap->next->where >= vma + size))
	{
	  /* There was room allocated, but the size wasn't set to include
	     it.  Do that now.  */
	  datap->size += (vma + size) - (datap->where + datap->size);

	  /* Update the section size.  This happens only if we update the
	     32-bit-aligned chunk size.  Callers that have
	     non-32-bit-aligned sections should do all allocation and
	     size-setting by themselves or at least set the section size
	     after the last allocating call to this function.  */
	  if (vma + size > sec->vma + sec->size)
	    sec->size += (vma + size) - (sec->vma + sec->size);

	  return datap->data + vma - datap->where;
	}
    }

  /* Not found; allocate a new block.  First check in case we get a
     request for a size split up over several blocks; we'll have to return
     NULL for those cases, requesting the caller to split up the request.
     Requests with an address aligned on MMO_SEC_CONTENTS_CHUNK_SIZE bytes and
     for no more than MMO_SEC_CONTENTS_CHUNK_SIZE will always get resolved.  */

  for (datap = sdatap->head; datap != NULL; datap = datap->next)
    if ((datap->where <= vma && datap->where + datap->size > vma)
	|| (datap->where < vma + size
	    && datap->where + datap->size >= vma + size))
      return NULL;

  allocated_size
    = (size + MMO_SEC_CONTENTS_CHUNK_SIZE - 1) & ~(MMO_SEC_CONTENTS_CHUNK_SIZE - 1);
  entry = (mmo_data_list_type *)
    bfd_zalloc (sec->owner, sizeof (mmo_data_list_type) + allocated_size);
  if (entry == NULL)
    return NULL;
  entry->where = vma;
  entry->size = size;
  entry->allocated_size = allocated_size;

  datap = sdatap->head;

  /* Sort the records by address.  Optimize for the common case of adding
     a record to the end of the list.  */
  if (sdatap->tail != NULL && entry->where >= sdatap->tail->where)
    {
      sdatap->tail->next = entry;
      entry->next = NULL;
      sdatap->tail = entry;
    }
  else
    {
      mmo_data_list_type **look;
      for (look = &sdatap->head;
	   *look != NULL && (*look)->where < entry->where;
	   look = &(*look)->next)
	;
      entry->next = *look;
      *look = entry;
      if (entry->next == NULL)
	{
	  sdatap->tail = entry;

	  /* We get here for the first time (at other times too) for this
	     section.  Say we have contents.  */
	  if (! bfd_set_section_flags (sec->owner, sec,
				       bfd_get_section_flags (sec->owner, sec)
				       | SEC_HAS_CONTENTS))
	    return NULL;
	}
    }

  /* Update the section size.  This happens only when we add contents and
     re-size as we go.  The section size will then be aligned to 32 bits.  */
  if (vma + size > sec->vma + sec->size)
    sec->size += (vma + size) - (sec->vma + sec->size);
  return entry->data;
}

/* Set sizes once we've read in all sections.  */

static void
mmo_map_set_sizes (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
		   void *ignored ATTRIBUTE_UNUSED)
{
  sec->lma = sec->vma;
}

/* Read the mmo file and turn it into sections.  */

static bfd_boolean
mmo_scan (bfd *abfd)
{
  unsigned int i;
  unsigned int lineno = 1;
  bfd_boolean error = FALSE;
  bfd_vma vma = 0;
  asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
  asection *non_spec_sec = NULL;
  bfd_vma non_spec_vma = 0;
  bfd_size_type nbytes_read = 0;
  /* Buffer with room to read a 64-bit value.  */
  bfd_byte buf[8];
  long stab_loc = -1;
  char *file_names[256];

  abfd->symcount = 0;
  memset (file_names, 0, sizeof (file_names));

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto error_return;

  while ((nbytes_read = bfd_bread (buf, 4, abfd)) == 4)
    {
      if (buf[0] == LOP)
	{
	  unsigned int y = bfd_get_8 (abfd, buf + 2);
	  unsigned int z = bfd_get_8 (abfd, buf + 3);

	  /* Change back to the original section for lopcodes other
	     than LOP_QUOTE that comes after a LOP_SPEC.  */
	  if ((buf[1] != LOP_QUOTE || y != 0 || z != 1)
	      && non_spec_sec != NULL)
	    {
	      sec = non_spec_sec;
	      vma = non_spec_vma;
	      non_spec_sec = NULL;
	    }

	  switch (buf[1])
	    {
	    default:
	      (*_bfd_error_handler)
		(_("%s: invalid mmo file: unsupported lopcode `%d'\n"),
		 bfd_get_filename (abfd), buf[1]);
	      bfd_set_error (bfd_error_bad_value);
	      goto error_return;

	    case LOP_QUOTE:
	      /* Quote the next 32-bit word.  */
	      if (y != 0 || z != 1)
		{
		  (*_bfd_error_handler)
		    (_("%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"),
		     bfd_get_filename (abfd), y*256+z);
		  bfd_set_error (bfd_error_bad_value);
		  goto error_return;
		}
	      if (bfd_bread (buf, 4, abfd) != 4)
		goto error_return;

	      vma &= ~3;
	      mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf));
	      vma += 4;
	      lineno++;
	      break;

	    case LOP_LOC:
	      /* Set vma (and section).  */
	      vma = (bfd_vma) y << 56;
	      if (z == 1)
		{
		  /* Get a 32-bit value.  */
		  if (bfd_bread (buf, 4, abfd) != 4)
		    goto error_return;

		  vma += bfd_get_32 (abfd, buf);
		}
	      else if (z == 2)
		{
		  /* Get a 64-bit value.  */
		  if (bfd_bread (buf, 8, abfd) != 8)
		    goto error_return;

		  vma += bfd_get_64 (abfd, buf);
		}
	      else
		{
		  (*_bfd_error_handler)
		    (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"),
		     bfd_get_filename (abfd), z);
		  bfd_set_error (bfd_error_bad_value);
		  goto error_return;
		}

	      /* When we decide which section the data goes into, we might
		 create the section.  If that happens, make sure the VMA at
		 creation time is tetra-aligned.  */
	      sec = mmo_decide_section (abfd, vma & ~3);
	      if (sec == NULL)
		goto error_return;
	      break;

	    case LOP_SKIP:
	      /* Move forward within the same section.  */
	      vma += y * 256 + z;

	      sec = mmo_decide_section (abfd, vma);
	      if (sec == NULL)
		goto error_return;
	      break;

	    case LOP_FIXO:
	      /* A fixup: Store the current vma somewhere.  Position using
		 same format as LOP_LOC.  */
	      {
		bfd_vma p = (bfd_vma) y << 56;
		asection *fixosec;

		if (z == 1)
		  {
		    /* Get a 32-bit value.  */
		    if (bfd_bread (buf, 4, abfd) != 4)
		      goto error_return;

		    p += bfd_get_32 (abfd, buf);
		  }
		else if (z == 2)
		  {
		    /* Get a 64-bit value.  */
		    if (bfd_bread (buf, 8, abfd) != 8)
		      goto error_return;

		    p += bfd_get_64 (abfd, buf);
		  }
		else
		  {
		    (*_bfd_error_handler)
		      (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"),
		       bfd_get_filename (abfd), z);
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }

		/* The section where we store this address might be a
		   different one than the current section.  */
		fixosec = mmo_decide_section (abfd, p);
		if (fixosec == NULL)
		  goto error_return;
		mmo_xore_64 (fixosec, p, vma);
	      }
	    break;

	    case LOP_FIXR:
	      /* A fixup: Store YZ of this lopcode into YZ at vma - 4 * yz.  */
	      {
		unsigned int yz = (y * 256 + z);
		bfd_vma p = vma + 2 - 4 * yz;
		asection *fixrsec = mmo_decide_section (abfd, p);
		if (fixrsec == NULL)
		  goto error_return;
		mmo_xore_16 (fixrsec, p, yz);
	      }
	    break;

	    case LOP_FIXRX:
	      /* A fixup, similar to lop_fixr, but taking larger numbers
		 and can change branches into the opposite direction
		 (gasp!).  */
	      {
		bfd_vma delta;
		bfd_vma p;
		asection *fixrsec;

		if (y != 0)
		  {
		    (*_bfd_error_handler)
		      (_("%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"),
		       bfd_get_filename (abfd), y);
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }

		if (z != 16 && z != 24)
		  {
		    (*_bfd_error_handler)
		      (_("%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"),
		       bfd_get_filename (abfd), z);
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }

		/* Get the next 32-bit value.  */
		if (bfd_bread (buf, 4, abfd) != 4)
		  goto error_return;

		delta = bfd_get_32 (abfd, buf);

		/* Do an, ehm, involved calculation for the location of
		   the fixup.  See mmixal documentation for a verbose
		   explanation.  We follow it verbosely here for the
		   readers delight.  */
		if (buf[0] == 0)
		  p = vma - 4 * delta;
		else if (buf[0] == 1)
		  p = vma - 4 * ((delta & 0xffffff) - (1 << z));
		else
		  {
		    (*_bfd_error_handler)
		      (_("%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"),
		       bfd_get_filename (abfd), buf[0]);
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }

		fixrsec = mmo_decide_section (abfd, vma);
		if (fixrsec == NULL)
		  goto error_return;
		mmo_xore_32 (fixrsec, p, delta);
	      }
	    break;

	    case LOP_FILE:
	      /* Set current file and perhaps the file name.  Reset line
		 number.  */
	      if (z != 0)
		{
		  char *fname = bfd_malloc (z * 4 + 1);

		  if (fname == NULL)
		    {
		      (*_bfd_error_handler)
			(_("%s: cannot allocate file name for file number %d, %d bytes\n"),
			 bfd_get_filename (abfd), y, z * 4 + 1);
		      bfd_set_error (bfd_error_system_call);
		      goto error_return;
		    }

		  fname[z * 4] = 0;

		  for (i = 0; i < z; i++)
		    {
		      if (bfd_bread (fname + i * 4, 4, abfd) != 4)
			{
			  free (fname);
			  goto error_return;
			}
		    }

		  if (file_names[y] != NULL)
		    {
		      (*_bfd_error_handler)
			(_("%s: invalid mmo file: file number %d `%s',"
			   " was already entered as `%s'\n"),
			 bfd_get_filename (abfd), y, fname, file_names[y]);
		      bfd_set_error (bfd_error_bad_value);
		      goto error_return;
		    }

		  file_names[y] = fname;
		}

	      if (file_names[y] == NULL)
		{
		  (*_bfd_error_handler)
		    (_("%s: invalid mmo file: file name for number %d"
		       " was not specified before use\n"),
		     bfd_get_filename (abfd), y);
		  bfd_set_error (bfd_error_bad_value);
		  goto error_return;
		}

	      lineno = 0;
	      break;

	    case LOP_LINE:
	      /* Set line number.  */
	      lineno = y * 256 + z;
	      /* FIXME: Create a sequence of mmo-specific line number
		 entries for each section, then translate into canonical
		 format.  */
	      break;

	    case LOP_SPEC:
	      /* Special data follows until the next non-lop_quote
		 lopcode.  */
	      non_spec_sec = sec;
	      non_spec_vma = vma;
	      sec = mmo_get_spec_section (abfd, y * 256 + z);
	      if (sec == NULL)
		goto error_return;

	      vma = sec->vma;
	      break;

	    case LOP_PRE:
	      {
		/* We ignore header information, except we read in the
		   creation time from the first 32-bit word with the time
		   in seconds since era.  */
		if (z >= 1
		    && bfd_bread (abfd->tdata.mmo_data->created, 4,
				 abfd) != 4)
		  goto error_return;

		for (i = 1; i < z; i++)
		  if (bfd_bread (buf, 4, abfd) != 4)
		    goto error_return;
	      }
	      break;

	    case LOP_POST:
	      /* This tells of the contents of registers $Z..$255 at
		 startup.  We make a section out of it, with VMA = Z * 8,
		 but only if Z != 255 or the contents is non-zero.  */
	      {
		asection *rsec;
		bfd_byte *loc;
		bfd_vma first_octa;
		bfd_vma startaddr_octa;

		/* Read first octaword outside loop to simplify logic when
		   excluding the Z == 255, octa == 0 case.  */
		if (bfd_bread (buf, 8, abfd) != 8)
		  goto error_return;

		first_octa = bfd_get_64 (abfd, buf);

		/* Don't emit contents for the trivial case which is
		   always present; $255 pointing to Main.  */
		if (z != 255)
		  {
		    rsec
		      = bfd_make_section_old_way (abfd,
						  MMIX_REG_CONTENTS_SECTION_NAME);
		    rsec->flags |= SEC_LINKER_CREATED;
		    rsec->vma = z * 8;
		    loc = mmo_get_loc (rsec, z * 8, (255 - z) * 8);
		    bfd_put_64 (abfd, first_octa, loc);

		    for (i = z + 1; i < 255; i++)
		      {
			if (bfd_bread (loc + (i - z) * 8, 8, abfd) != 8)
			  goto error_return;
		      }

		    /* Read out the last octabyte, and use it to set the
		       start address.  */
		    if (bfd_bread (buf, 8, abfd) != 8)
		      goto error_return;

		    startaddr_octa = bfd_get_64 (abfd, buf);
		  }
		else
		  startaddr_octa = first_octa;

		if (! bfd_set_start_address (abfd, startaddr_octa))
		  {
		    /* Currently this can't fail, but this should handle
		       future failures.  */
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }
	      }
	      break;

	    case LOP_STAB:
	      /* We read in the symbols now, not later.  */
	      if (y != 0 || z != 0)
		{
		  (*_bfd_error_handler)
		    (_("%s: invalid mmo file: fields y and z of lop_stab"
		       " non-zero, y: %d, z: %d\n"),
		     bfd_get_filename (abfd), y, z);
		  bfd_set_error (bfd_error_bad_value);
		  goto error_return;
		}

	      /* Save the location, so we can check that YZ in the LOP_END
		 is correct.  */
	      stab_loc = bfd_tell (abfd);

	      /* It's not said that an MMO can be without symbols (though
		 mmixal will refuse to assemble files without Main), but
		 it seems it would still be a valid mmo-file, so allow it.
		 We detect the absence of a symbol area in that the upper
		 limit is computed (from the lop_end YZ field) as 0.
		 Don't call mmo_get_symbols; it can only detect the end of
		 a valid symbol trie, not the absence of one.  */
	      if (abfd->tdata.mmo_data->max_symbol_length != 0
		  && ! mmo_get_symbols (abfd))
		goto error_return;
	      break;

	    case LOP_END:
	      {
		/* This must be the last 32-bit word in an mmo file.
		   Let's find out.  */
		struct stat statbuf;
		file_ptr curpos = bfd_tell (abfd);

		if (bfd_stat (abfd, &statbuf) < 0)
		  goto error_return;

		if (statbuf.st_size != curpos)
		  {
		    (*_bfd_error_handler)
		      (_("%s: invalid mmo file: lop_end not last item in"
			 " file\n"),
		       bfd_get_filename (abfd));
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }

		/* Check that the YZ field is right.  Subtract the size of
		   this LOP_END in the calculation; YZ does not include
		   it.  */
		if ((long) (y * 256 + z) * 4 != (curpos - stab_loc) - 4)
		  {
		    (*_bfd_error_handler)
		      (_("%s: invalid mmo file: YZ of lop_end (%ld)"
			 " not equal to the number of tetras to the preceding"
			 " lop_stab (%ld)\n"),
		       bfd_get_filename (abfd), (long) (y * 256 + z),
		       (curpos - stab_loc - 4)/4);
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }

		bfd_map_over_sections (abfd, mmo_map_set_sizes, NULL);
		goto done;
	      }
	    }
	}
      else
	{
	  /* This wasn't a lopcode, so store it in the current section.  */
	  mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf));
	  vma += 4;
	  vma &= ~3;
	  lineno++;
	}
    }

  /* We know this file is a multiple of four bytes (checked in
     mmo_object_p), so if we got something other than 0, this was a bad
     file (although it's more likely we'll get 0 in that case too).
     If we got end-of-file, then there was no lop_stab, so the file has
     invalid format.  */

  if (nbytes_read != 0)
    bfd_set_error (bfd_error_system_call);
  else
    bfd_set_error (bfd_error_bad_value);

 error_return:
  error = TRUE;
 done:
  /* Mark the .text and .data section with their normal attribute if they
     contain anything.  This is not redundant wrt. mmo_decide_section,
     since that code might never execute, and conversely the alloc+code
     section flags must be set then.  */
  sec = bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
  if (sec != NULL
      && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
      && ! bfd_set_section_flags (abfd, sec,
				  bfd_get_section_flags (abfd, sec)
				  | SEC_ALLOC | SEC_LOAD | SEC_CODE))
    error = TRUE;

  sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
  if (sec != NULL
      && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
      && ! bfd_set_section_flags (abfd, sec,
				  bfd_get_section_flags (abfd, sec)
				  | SEC_ALLOC | SEC_LOAD))
    error = TRUE;

  /* Free whatever resources we took.  */
  for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++)
    if (file_names[i])
      free (file_names[i]);
  return ! error;
}

/* A hook to set up object file dependent section information.  For mmo,
   we point out the shape of allocated section contents.  */

static bfd_boolean
mmo_new_section_hook (bfd *abfd, asection *newsect)
{
  if (!newsect->used_by_bfd)
    {
      /* We zero-fill all fields and assume NULL is represented by an all
	 zero-bit pattern.  */
      newsect->used_by_bfd
	= bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct));
      if (!newsect->used_by_bfd)
	return FALSE;
    }

  /* Always align to at least 32-bit words.  */
  newsect->alignment_power = 2;
  return _bfd_generic_new_section_hook (abfd, newsect);
}

/* We already have section contents loaded for sections that have
   contents.  */

static bfd_boolean
mmo_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
			  asection *sec,
			  void * location,
			  file_ptr offset,
			  bfd_size_type bytes_to_do)
{
  /* Iterate over diminishing chunk sizes, copying contents, like
     mmo_set_section_contents.  */
  while (bytes_to_do)
    {
      /* A minor song-and-dance to make sure we're not bitten by the
	 distant possibility of the cast from bfd_vma to int making the
	 chunk zero-sized.  */
      int chunk_size
	= (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
      bfd_byte *loc;

      do
	loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
      while (loc == NULL && (chunk_size /= 2) != 0);

      if (chunk_size == 0)
	return FALSE;

      memcpy (location, loc, chunk_size);

      location = (bfd_byte *) location + chunk_size;
      bytes_to_do -= chunk_size;
      offset += chunk_size;
    }
  return TRUE;
}

/* Return the amount of memory needed to read the symbol table.  */

static long
mmo_get_symtab_upper_bound (bfd *abfd)
{
  return (abfd->symcount + 1) * sizeof (asymbol *);
}

/* Sort mmo symbols by serial number.  */

static int
mmo_sort_mmo_symbols (const void *arg1, const void *arg2)
{
  const struct mmo_symbol *sym1 = *(const struct mmo_symbol **) arg1;
  const struct mmo_symbol *sym2 = *(const struct mmo_symbol **) arg2;

  /* Sort by serial number first.  */
  if (sym1->serno < sym2->serno)
    return -1;
  else if (sym1->serno > sym2->serno)
    return 1;

  /* Then sort by address of the table entries.  */
  return ((const char *) arg1 - (const char *) arg2);
}

/* Translate the symbol table.  */

static long
mmo_canonicalize_symtab (bfd *abfd, asymbol **alocation)
{
  unsigned int symcount = bfd_get_symcount (abfd);
  asymbol *csymbols;
  unsigned int i;

  csymbols = abfd->tdata.mmo_data->csymbols;
  if (csymbols == NULL && symcount != 0)
    {
      asymbol *c;
      struct mmo_symbol *s;
      struct mmo_symbol **msp;

      /* First we store the symbols into the table we'll return, then we
	 qsort it on the serial number, with secondary on the address of
	 the symbol, to preserve order if there would be non-unique serial
	 numbers.  */
      for (s = abfd->tdata.mmo_data->symbols,
	     msp = (struct mmo_symbol **) alocation;
	   s != NULL;
	   s = s->next, ++msp)
	*msp = s;

      *msp = NULL;

      qsort (alocation, symcount, sizeof (struct mmo_symbol *),
	     mmo_sort_mmo_symbols);

      csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
      if (csymbols == NULL)
	return -1;
      abfd->tdata.mmo_data->csymbols = csymbols;

      for (msp = (struct mmo_symbol **) alocation, c = csymbols;
	   *msp != NULL;
	   msp++, ++c)
	{
	  s = *msp;
	  c->the_bfd = abfd;
	  c->name = s->name;
	  c->value = s->value;
	  c->flags = BSF_GLOBAL;

	  if (s->sym_type == mmo_data_sym)
	    {
	      c->section
		= bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);

	      if (c->section == NULL)
		c->section = bfd_abs_section_ptr;
	      else
		c->value -= c->section->vma;
	    }
	  else if (s->sym_type == mmo_undef_sym)
	    c->section = bfd_und_section_ptr;
	  else if (s->sym_type == mmo_reg_sym)
	    {
	      c->section
		= bfd_make_section_old_way (abfd, MMIX_REG_SECTION_NAME);
	      c->section->flags |= SEC_LINKER_CREATED;
	    }
	  else
	    {
	      asection *textsec
		= bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
	      asection *datasec;

	      if (textsec != NULL
		  && c->value >= textsec->vma
		  && c->value <= textsec->vma + textsec->size)
		{
		  c->section = textsec;
		  c->value -= c->section->vma;
		}
	      /* In mmo, symbol types depend on the VMA.  Therefore, if
		 the data section isn't within the usual bounds, its
		 symbols are marked as absolute.  Correct that.  This
		 means we can't have absolute symbols with values matching
		 data section addresses, but we also can't have with
		 absolute symbols with values matching text section
		 addresses.  For such needs, use the ELF format.  */
	      else if ((datasec
			= bfd_get_section_by_name (abfd,
						   MMO_DATA_SECTION_NAME))
		       != NULL
		       && c->value >= datasec->vma
		       && c->value <= datasec->vma + datasec->size)
		{
		  c->section = datasec;
		  c->value -= c->section->vma;
		}
	      else
		c->section = bfd_abs_section_ptr;
	    }

	  c->udata.p = NULL;
	}
    }

  /* Last, overwrite the incoming table with the right-type entries.  */
  for (i = 0; i < symcount; i++)
    *alocation++ = csymbols++;
  *alocation = NULL;

  return symcount;
}

/* Get information about a symbol.  */

static void
mmo_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
		     asymbol *symbol, symbol_info *ret)
{
  bfd_symbol_info (symbol, ret);
}

static void
mmo_print_symbol (bfd *abfd, void *afile, asymbol *symbol,
		  bfd_print_symbol_type how)
{
  FILE *file = (FILE *) afile;

  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      break;
    default:
      bfd_print_symbol_vandf (abfd, file, symbol);

      fprintf (file, " %-5s %s",
	       symbol->section->name,
	       symbol->name);
    }
}

/* We can't map a file directly into executable code, so the
   size of header information is irrelevant.  */

static int
mmo_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
		    struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  return 0;
}

/* Write the (section-neutral) file preamble.  */

static bfd_boolean
mmo_internal_write_header (bfd *abfd)
{
  const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};

  if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4)
    return FALSE;

  /* Copy creation time of original file.  */
  if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4)
    return FALSE;

  return TRUE;
}

/* Write the LOP_POST record, with global register initializations.
   Z is the Z field of the LOP_POST, corresponding to 255 - number of
   registers at DATA.  The Z = 255 field is filled in with the
   start-address.  */

static bfd_boolean
mmo_internal_write_post (bfd *abfd, int z, asection *sec)
{
  int i;
  bfd_byte buf[8];
  mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_POST << 16) | z);

  for (i = z; i < 255; i++)
    {
      bfd_byte *data = mmo_get_loc (sec, i * 8, 8);

      if (bfd_bwrite (data, 8, abfd) != 8)
	return FALSE;
    }

  /* For Z == $255, we always emit the start location; supposedly Main,
     but we have it handy at bfd_get_start_address.  If we're called with
     Z == 255, don't assume DATA is valid.  */
  bfd_put_64 (abfd, bfd_get_start_address (abfd), buf);

  return ! abfd->tdata.mmo_data->have_error && bfd_bwrite (buf, 8, abfd) == 8;
}

/* Translate to and from BFD flags.  This is to make sure that we don't
   get bitten by BFD flag number changes.  */

static flagword
mmo_sec_flags_from_bfd_flags (flagword flags)
{
  flagword oflags = 0;

  if (flags & SEC_ALLOC)
    oflags |= MMO_SEC_ALLOC;
  if (flags & SEC_LOAD)
    oflags |= MMO_SEC_LOAD;
  if (flags & SEC_RELOC)
    oflags |= MMO_SEC_RELOC;
  if (flags & SEC_READONLY)
    oflags |= MMO_SEC_READONLY;
  if (flags & SEC_CODE)
    oflags |= MMO_SEC_CODE;
  if (flags & SEC_DATA)
    oflags |= MMO_SEC_DATA;
  if (flags & SEC_NEVER_LOAD)
    oflags |= MMO_SEC_NEVER_LOAD;
  if (flags & SEC_IS_COMMON)
    oflags |= MMO_SEC_IS_COMMON;
  if (flags & SEC_DEBUGGING)
    oflags |= MMO_SEC_DEBUGGING;

  return oflags;
}

static flagword
bfd_sec_flags_from_mmo_flags (flagword flags)
{
  flagword oflags = 0;

  if (flags & MMO_SEC_ALLOC)
    oflags |= SEC_ALLOC;
  if (flags & MMO_SEC_LOAD)
    oflags |= SEC_LOAD;
  if (flags & MMO_SEC_RELOC)
    oflags |= SEC_RELOC;
  if (flags & MMO_SEC_READONLY)
    oflags |= SEC_READONLY;
  if (flags & MMO_SEC_CODE)
    oflags |= SEC_CODE;
  if (flags & MMO_SEC_DATA)
    oflags |= SEC_DATA;
  if (flags & MMO_SEC_NEVER_LOAD)
    oflags |= SEC_NEVER_LOAD;
  if (flags & MMO_SEC_IS_COMMON)
    oflags |= SEC_IS_COMMON;
  if (flags & MMO_SEC_DEBUGGING)
    oflags |= SEC_DEBUGGING;

  return oflags;
}

/* Return TRUE iff the leading or trailing tetrabyte in SEC is defined and
   is 0.  */

static bfd_boolean
mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec)
{
  bfd_vma secaddr = bfd_get_section_vma (abfd, sec);

  if (sec->size < 4)
    return FALSE;

  if (bfd_get_32 (abfd, mmo_get_loc (sec, secaddr, 4)) == 0
      && bfd_get_32 (abfd,
		     mmo_get_loc (sec, secaddr + sec->size - 4, 4)) == 0)
    return TRUE;

  return FALSE;
}

/* Write a section.  */

static bfd_boolean
mmo_internal_write_section (bfd *abfd, asection *sec)
{
  /* We do it differently depending on what section this is:

   ".text": Output, prepended by information about the first source file
   (not yet implemented.)

   ".data": Output.

   (".MMIX.reg_contents": Not handled here.)

   Anything else: Output inside a lop_spec 80, in the format described
   above.  */

  if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0)
    {
      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);

      /* Because leading and trailing zeros are omitted in output, we need to
	 specify the section boundaries so they're correct when the file
	 is read in again.  That's also the case if this section is
	 specified as not within its usual boundaries or alignments.  */
      if (sec->size != 0
	  && (secaddr + sec->size >= (bfd_vma) 1 << 56
	      || (secaddr & 3) != 0
	      || (sec->size & 3) != 0
	      || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
	{
	  if (!mmo_write_section_description (abfd, sec))
	    return FALSE;
	}

      /* FIXME: Output source file name and line number.  */
      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
    }
  else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0)
    {
      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);

      /* Same goes as for MMO_TEXT_SECTION_NAME above.  */
      if (sec->size != 0
	  && (secaddr < (bfd_vma) 0x20 << 56
	      || secaddr + sec->size >= (bfd_vma) 0x21 << 56
	      || (secaddr & 3) != 0
	      || (sec->size & 3) != 0
	      || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
	{
	  if (!mmo_write_section_description (abfd, sec))
	    return FALSE;
	}

      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
    }
  else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
    /* Not handled here.  */
    {
      /* This would normally be an abort call since this can't happen, but
         we don't do that.  */
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }
  else if (CONST_STRNEQ (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX))
    {
      int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX));

      mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n);
      return (! abfd->tdata.mmo_data->have_error
	      && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
    }
  /* Ignore sections that are just allocated or empty; we write out
     _contents_ here.  */
  else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0
	   && sec->size != 0)
    {
      if (!mmo_write_section_description (abfd, sec))
	return FALSE;

      /* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
	 loaded.  */
      if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
	return (! abfd->tdata.mmo_data->have_error
		&& mmo_write_loc_chunk_list (abfd,
					 mmo_section_data (sec)->head));
      return (! abfd->tdata.mmo_data->have_error
	      && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
    }

  /* Some section without contents.  */
  return TRUE;
}

/* Write the description of a section, extended-mmo-style.  */

static bfd_boolean
mmo_write_section_description (bfd *abfd, asection *sec)
{
  /* Keep the following document-comment formatted the way it is.  */
/*
INODE
mmo section mapping, , Symbol-table, mmo
SUBSECTION
	mmo section mapping

	The implementation in BFD uses special data type 80 (decimal) to
	encapsulate and describe named sections, containing e.g.@: debug
	information.  If needed, any datum in the encapsulation will be
	quoted using lop_quote.  First comes a 32-bit word holding the
	number of 32-bit words containing the zero-terminated zero-padded
	segment name.  After the name there's a 32-bit word holding flags
	describing the section type.  Then comes a 64-bit big-endian word
	with the section length (in bytes), then another with the section
	start address.  Depending on the type of section, the contents
	might follow, zero-padded to 32-bit boundary.  For a loadable
	section (such as data or code), the contents might follow at some
	later point, not necessarily immediately, as a lop_loc with the
	same start address as in the section description, followed by the
	contents.  This in effect forms a descriptor that must be emitted
	before the actual contents.  Sections described this way must not
	overlap.

	For areas that don't have such descriptors, synthetic sections are
	formed by BFD.  Consecutive contents in the two memory areas
	@samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} and
	@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} are entered in
	sections named <<.text>> and <<.data>> respectively.  If an area
	is not otherwise described, but would together with a neighboring
	lower area be less than @samp{0x40000000} bytes long, it is joined
	with the lower area and the gap is zero-filled.  For other cases,
	a new section is formed, named <<.MMIX.sec.@var{n}>>.  Here,
	@var{n} is a number, a running count through the mmo file,
	starting at 0.

EXAMPLE
	A loadable section specified as:

| .section secname,"ax"
| TETRA 1,2,3,4,-1,-2009
| BYTE 80

	and linked to address @samp{0x4}, is represented by the sequence:

| 0x98080050 - lop_spec 80
| 0x00000002 - two 32-bit words for the section name
| 0x7365636e - "secn"
| 0x616d6500 - "ame\0"
| 0x00000033 - flags CODE, READONLY, LOAD, ALLOC
| 0x00000000 - high 32 bits of section length
| 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits
| 0x00000000 - high 32 bits of section address
| 0x00000004 - section address is 4
| 0x98010002 - 64 bits with address of following data
| 0x00000000 - high 32 bits of address
| 0x00000004 - low 32 bits: data starts at address 4
| 0x00000001 - 1
| 0x00000002 - 2
| 0x00000003 - 3
| 0x00000004 - 4
| 0xffffffff - -1
| 0xfffff827 - -2009
| 0x50000000 - 80 as a byte, padded with zeros.

	Note that the lop_spec wrapping does not include the section
	contents.  Compare this to a non-loaded section specified as:

| .section thirdsec
| TETRA 200001,100002
| BYTE 38,40

	This, when linked to address @samp{0x200000000000001c}, is
	represented by:

| 0x98080050 - lop_spec 80
| 0x00000002 - two 32-bit words for the section name
| 0x7365636e - "thir"
| 0x616d6500 - "dsec"
| 0x00000010 - flag READONLY
| 0x00000000 - high 32 bits of section length
| 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits
| 0x20000000 - high 32 bits of address
| 0x0000001c - low 32 bits of address 0x200000000000001c
| 0x00030d41 - 200001
| 0x000186a2 - 100002
| 0x26280000 - 38, 40 as bytes, padded with zeros

	For the latter example, the section contents must not be
	loaded in memory, and is therefore specified as part of the
	special data.  The address is usually unimportant but might
	provide information for e.g.@: the DWARF 2 debugging format.  */

  mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION);
  mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4);
  mmo_write_chunk (abfd, (bfd_byte *) sec->name, strlen (sec->name));
  mmo_flush_chunk (abfd);
  /* FIXME: We can get debug sections (.debug_line & Co.) with a section
     flag still having SEC_RELOC set.  Investigate.  This might be true
     for all alien sections; perhaps mmo.em should clear that flag.  Might
     be related to weak references.  */
  mmo_write_tetra (abfd,
		   mmo_sec_flags_from_bfd_flags
		   (bfd_get_section_flags (abfd, sec)));
  mmo_write_octa (abfd, sec->size);
  mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec));
  return TRUE;
}

/* We save up all data before output.  */

static bfd_boolean
mmo_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
			  const void *location, file_ptr offset,
			  bfd_size_type bytes_to_do)
{
  /* Iterate over diminishing chunk sizes, copying contents.  */
  while (bytes_to_do)
    {
      /* A minor song-and-dance to make sure we're not bitten by the
	 distant possibility of the cast from bfd_vma to int making the
	 chunk zero-sized.  */
      int chunk_size
	= (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
      bfd_byte *loc;

      do
	loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
      while (loc == NULL && (chunk_size /= 2) != 0);

      if (chunk_size == 0)
	return FALSE;

      memcpy (loc, location, chunk_size);

      location = (bfd_byte *) location + chunk_size;
      bytes_to_do -= chunk_size;
      offset += chunk_size;
    }
  return TRUE;
}

/* Add a symbol to a trie-tree.  */

static bfd_boolean
mmo_internal_add_3_sym (bfd *abfd, struct mmo_symbol_trie *rootp,
			const struct mmo_symbol *symp)
{
  const char *name = symp->name;
  struct mmo_symbol_trie *trie = rootp;
  struct mmo_symbol_trie **triep = NULL;

  while (*name && trie != NULL)
    {
      if (*name < trie->symchar)
	{
	  triep = &trie->left;
	  trie = trie->left;
	}
      else if (*name > trie->symchar)
	{
	  triep = &trie->right;
	  trie = trie->right;
	}
      else if (*name == trie->symchar)
	{
	  triep = &trie->middle;
	  name++;

	  /* Make sure "trie" points to where we should fill in the
	     current symbol whenever we've iterated through "name".  We
	     would lose the right position if we encounter "foobar" then
	     "foo".  */
	  if (*name)
	    trie = trie->middle;
	}
    }

  while (*name != 0)
    {
      /* Create middle branches for the rest of the characters.  */
      trie = bfd_zalloc (abfd, sizeof (struct mmo_symbol_trie));
      *triep = trie;
      trie->symchar = *name++;
      triep = &trie->middle;
    }

  /* We discover a duplicate symbol rather late in the process, but still;
     we discover it and bail out.  */
  if (trie->sym.name != NULL)
    {
      (*_bfd_error_handler)
	(_("%s: invalid symbol table: duplicate symbol `%s'\n"),
	 bfd_get_filename (abfd), trie->sym.name);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  memcpy (&trie->sym, symp, sizeof *symp);
  return TRUE;
}

/* Find out the length of the serialized version of a trie in bytes.  */

static unsigned int
mmo_internal_3_length (bfd *abfd, struct mmo_symbol_trie *trie)
{
  /* First, one for the control byte.  */
  unsigned int length = 1;

  if (trie == NULL)
    return 0;

  /* Add in the recursion to the left.  */
  length += mmo_internal_3_length (abfd, trie->left);

  /* Add in the middle trie and the character.  */
  length += 1 + mmo_internal_3_length (abfd, trie->middle);

  /* Add in the recursion to the right.  */
  length += mmo_internal_3_length (abfd, trie->right);

  /* Add in bytes for the symbol (if this is an endnode). */
  if (trie->sym.name != NULL)
    {
      unsigned int serno = trie->sym.serno;

      /* First what it takes to encode the value. */
      if (trie->sym.sym_type == mmo_reg_sym)
	length++;
      else if (trie->sym.sym_type == mmo_undef_sym)
	length += 2;
      else
	{
	  bfd_vma value = trie->sym.value;

	  /* Coded in one to eight following bytes.  */
	  if (trie->sym.sym_type == mmo_data_sym)
	    value -= (bfd_vma) 0x20 << 56;

	  do
	    {
	      value >>= 8;
	      length++;
	    }
	  while (value != 0);
	}

      /* Find out what it takes to encode the serial number.  */
      do
	{
	  serno >>= 7;
	  length++;
	}
      while (serno != 0);
    }

  return length;
}

/* Helper function for outputting the serial number of a symbol, output as
   a variant of leb128 (see dwarf2 documentation) which could be called
   beb128.  Using a helper function and recursion simplifies debugging.  */

static void
mmo_beb128_out (bfd *abfd, int serno, int marker)
{
  if (serno & ~0x7f)
    mmo_beb128_out (abfd, serno >> 7, 0);
  mmo_write_byte (abfd, marker | (serno & 0x7f));
}

/* Serialize a trie.  */

static void
mmo_internal_3_dump (bfd *abfd, struct mmo_symbol_trie *trie)
{
  bfd_byte control = 0;

  if (trie == NULL)
    return;

  if (trie->left)
    control |= MMO3_LEFT;

  if (trie->middle)
    control |= MMO3_MIDDLE;

  if (trie->right)
    control |= MMO3_RIGHT;

  if (trie->sym.name != NULL)
    {
      /* Encode the symbol type and length of value bytes.  */
      if (trie->sym.sym_type == mmo_reg_sym)
	control |= MMO3_REGQUAL_BITS;
      else if (trie->sym.sym_type == mmo_undef_sym)
	control |= MMO3_UNDEF;
      else
	{
	  bfd_vma value = trie->sym.value;

	  /* Coded in 1..8 following bytes.  */
	  if (trie->sym.sym_type == mmo_data_sym)
	    {
	      control |= MMO3_DATA;
	      value -= (bfd_vma) 0x20 << 56;
	    }

	  do
	    {
	      value >>= 8;
	      control++;
	    }
	  while (value != 0);
	}
    }

  /* The control byte is output before recursing.  */
  mmo_write_byte (abfd, control);

  mmo_internal_3_dump (abfd, trie->left);

  if (control & MMO3_SYMBITS)
    {
      mmo_write_byte (abfd, trie->symchar);

      if (trie->sym.name != NULL)
	{
	  if (trie->sym.sym_type == mmo_reg_sym)
	    mmo_write_byte (abfd, trie->sym.value);
	  else if (trie->sym.sym_type == mmo_undef_sym)
	    {
	      mmo_write_byte (abfd, 0);
	      mmo_write_byte (abfd, 0);
	    }
	  else
	    {
	      bfd_vma value = trie->sym.value;

	      bfd_byte byte_n = control & 15;

	      /* Coded in 1..8 following bytes.  Note that the value is
		 shifted out big-endian.  */
	      if (trie->sym.sym_type == mmo_data_sym)
		{
		  value -= (bfd_vma) 0x20 << 56;
		  byte_n -= 8;
		}

	      do
		{
		  mmo_write_byte (abfd, (value >> ((byte_n - 1) * 8)) & 0xff);
		  byte_n--;
		}
	      while (byte_n != 0);
	    }

	  mmo_beb128_out (abfd, trie->sym.serno, 128);
	}
      mmo_internal_3_dump (abfd, trie->middle);
    }
  mmo_internal_3_dump (abfd, trie->right);
}

/* Write symbols in mmo format.  Also write the lop_end terminator.  */

static bfd_boolean
mmo_write_symbols_and_terminator (bfd *abfd)
{
  int count = bfd_get_symcount (abfd);
  asymbol **table;
  asymbol **orig_table = bfd_get_outsymbols (abfd);
  int serno;
  struct mmo_symbol_trie root;
  int trie_len;
  int i;
  bfd_byte buf[4];

  /* Create a symbol for "Main".  */
  asymbol *fakemain = bfd_make_empty_symbol (abfd);

  fakemain->flags = BSF_GLOBAL;
  fakemain->value = bfd_get_start_address (abfd);
  fakemain->name = MMIX_START_SYMBOL_NAME;
  fakemain->section = bfd_abs_section_ptr;

  memset (&root, 0, sizeof (root));

  /* Make all symbols take a left turn.  */
  root.symchar = 0xff;

  /* There must always be a ":Main", so we'll add one if there are no
     symbols.  Make sure we have room for it.  */
  table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *));
  if (table == NULL)
    return FALSE;

  memcpy (table, orig_table, count * sizeof (asymbol *));

  /* Move :Main (if there is one) to the first position.  This is
     necessary to get the same layout of the trie-tree when linking as
     when objcopying the result as in the objcopy.exp test "simple objcopy
     of executable".  It also automatically takes care of assigning serial
     number 1 to :Main (as is mandatory).  */
  for (i = 0; i < count; i++)
    if (table[i] != NULL
	&& strcmp (table[i]->name, MMIX_START_SYMBOL_NAME) == 0
	&& (table[i]->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL)
      {
	asymbol *mainsym = table[i];
	bfd_vma mainvalue
	  = (mainsym->value
	     + mainsym->section->output_section->vma
	     + mainsym->section->output_offset);
	memcpy (table + 1, orig_table, i * sizeof (asymbol *));
	table[0] = mainsym;

	/* Check that the value assigned to :Main is the same as the entry
	   address.  The default linker script asserts this.  This is as
	   good a place as any to check this consistency. */
	if (mainvalue != bfd_get_start_address (abfd)
	    && !mmo_ignore_symbol_consistency (abfd))
	  {
	    /* Arbitrary buffer to hold the printable representation of a
	       vma.  */
	    char vmas_main[40];
	    char vmas_start[40];
	    bfd_vma vma_start = bfd_get_start_address (abfd);

	    sprintf_vma (vmas_main, mainvalue);
	    sprintf_vma (vmas_start, vma_start);

	    (*_bfd_error_handler)
	      (_("%s: Bad symbol definition: `Main' set to %s rather"
		 " than the start address %s\n"),
	       bfd_get_filename (abfd), vmas_main, vmas_start);
	    bfd_set_error (bfd_error_bad_value);
	    return FALSE;
	  }
	break;
      }
  if (i == count && count != 0)
    {
      /* When there are symbols, there must be a :Main.  There was no
	 :Main, so we need to add it manually.  */
      memcpy (table + 1, orig_table, count * sizeof (asymbol *));
      table[0] = fakemain;
      count++;
    }

  /* Don't bother inspecting symbols in plugin dummy objects; their
     symbols aren't fully inspectable.  */
  if ((abfd->flags & BFD_PLUGIN) == 0)
    {
      for (i = 0, serno = 1; i < count && table[i] != NULL; i++)
	{
	  asymbol *s = table[i];

	  /* It's not enough to consult bfd_is_local_label, since it does not
	     mean "local" in the sense of linkable-and-observable-after-link.
	     Let's just check the BSF_GLOBAL flag.

	     Also, don't export symbols with characters not in the
	     allowed set.  */
	  if ((s->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL
	      && strspn (s->name,
			 valid_mmo_symbol_character_set) == strlen (s->name))
	    {
	      struct mmo_symbol sym;
	      memset (&sym, 0, sizeof (sym));

	      /* Need to strip const here; strdup:ing would leak and the
		 existing string must be safe to reuse.  */
	      sym.name = (char *) s->name;
	      sym.value =
		s->value
		+ s->section->output_section->vma
		+ s->section->output_offset;

	      if (bfd_is_und_section (s->section))
		sym.sym_type = mmo_undef_sym;
	      else if (strcmp (s->section->name, MMO_DATA_SECTION_NAME) == 0
		       /* The encoding of data symbols require that the "rest"
			  of the value fits in 6 bytes, so the upper two bytes
			  must be 0x2000.  All other symbols get to be the
			  absolute type.  */
		       && (sym.value >> 48) == 0x2000)
		sym.sym_type = mmo_data_sym;
	      else if (strcmp (s->section->name, MMIX_REG_SECTION_NAME) == 0)
		sym.sym_type = mmo_reg_sym;
	      else if (strcmp (s->section->name,
			       MMIX_REG_CONTENTS_SECTION_NAME) == 0)
		{
		  sym.sym_type = mmo_reg_sym;
		  sym.value /= 8;
		}
	      else
		sym.sym_type = mmo_abs_sym;

	      /* FIXME: We assume the order of the received symbols is an
		 ordered mapping of the serial numbers.  This is not
		 necessarily true if we e.g. objcopy a mmo file to another and
		 there are gaps in the numbering.  Not sure if this can
		 happen.  Not sure what to do.  */
	      sym.serno = serno++;

	      if (! mmo_internal_add_3_sym (abfd, &root, &sym))
		return FALSE;
	    }
	}
    }

  /* Change the root node to be a ":"-prefix.  */
  root.symchar = ':';
  root.middle = root.left;
  root.right = NULL;
  root.left = NULL;

  /* We have to find out if we can fit the whole symbol table in the mmo
     symtab.  It would be bad to assume we can always fit it in 262144
     bytes.  If we can't, just leave the Main symbol.  */
  trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;

  if (trie_len > 0xffff)
    {
      /* Test this code by using a lower limit in the test above and check
	 that the single "Main" symbol is emitted and handled properly.
	 There's no specific test-case.  */
      struct mmo_symbol sym;

      (*_bfd_error_handler)
	(_("%s: warning: symbol table too large for mmo, larger than 65535"
	   " 32-bit words: %d.  Only `Main' will be emitted.\n"),
	 bfd_get_filename (abfd), trie_len);

      memset (&sym, 0, sizeof (sym));
      sym.sym_type = mmo_abs_sym;
      sym.name = MMIX_START_SYMBOL_NAME;
      sym.serno = 1;
      sym.value = bfd_get_start_address (abfd);

      /* Then patch up a symbol table to be just the ":Main" symbol.  */
      memset (&root, 0, sizeof (root));
      root.left = root.middle;
      root.symchar = 0xff;
      root.middle = NULL;
      root.right = NULL;

      if (! mmo_internal_add_3_sym (abfd, &root, &sym))
	return FALSE;

      root.symchar = ':';
      root.middle = root.left;
      root.right = NULL;
      root.left = NULL;

      trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;
    }

  /* Reset the written-bytes counter.  */
  abfd->tdata.mmo_data->byte_no = 0;

  /* Put out the lop_stab mark.  */
  bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf);
  if (bfd_bwrite (buf, 4, abfd) != 4)
    return FALSE;

  /* Dump out symbols.  */
  mmo_internal_3_dump (abfd, &root);

  if (trie_len != (abfd->tdata.mmo_data->byte_no + 3)/4)
    {
      /* I haven't seen this trig.  It seems no use claiming this case
	 isn't debugged and abort if we get here.  Instead emit a
	 diagnostic and fail "normally".  */
      (*_bfd_error_handler)
	(_("%s: internal error, symbol table changed size from %d to %d"
	   " words\n"),
	 bfd_get_filename (abfd), trie_len,
	 (abfd->tdata.mmo_data->byte_no + 3)/4);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  /* Dump out remaining bytes in the buffer and handle I/O errors by
     propagating errors.  */
  if ((abfd->tdata.mmo_data->byte_no % 4) != 0
      || abfd->tdata.mmo_data->have_error)
    {
      memset (abfd->tdata.mmo_data->buf + (abfd->tdata.mmo_data->byte_no % 4),
	      0, 4 - (abfd->tdata.mmo_data->byte_no % 4));

      if (abfd->tdata.mmo_data->have_error
	  || bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
	return FALSE;
    }

  bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf);
  return bfd_bwrite (buf, 4, abfd) == 4;
}

/* Write section unless it is the register contents section.  For that, we
   instead store the section in the supplied pointer.  This function is
   used through bfd_map_over_sections.  */

static void
mmo_write_section_unless_reg_contents (bfd *abfd, asection *sec, void *p)
{
  struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p;

  if (! infop->retval)
    return;

  if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
    {
      infop->reg_section = sec;
      return;
    }

  /* Exclude the convenience register section.  */
  if (strcmp (sec->name, MMIX_REG_SECTION_NAME) == 0)
    {
      if (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
	{
	  /* Make sure it hasn't got contents.  It seems impossible to
	     make it carry contents, so we don't have a test-case for
	     this.  */
	  (*_bfd_error_handler)
	    (_("%s: internal error, internal register section %s had"
	       " contents\n"),
	     bfd_get_filename (abfd), sec->name);
	  bfd_set_error (bfd_error_bad_value);
	  infop->retval = FALSE;
	  return;
	}

      return;
    }

  infop->retval = mmo_internal_write_section (abfd, sec);
}

/* Do the actual output of a file.  Assumes mmo_set_section_contents is
   already called. */

static bfd_boolean
mmo_write_object_contents (bfd *abfd)
{
  struct mmo_write_sec_info wsecinfo;

  /* First, there are a few words of preamble.  */
  if (! mmo_internal_write_header (abfd))
    return FALSE;

  wsecinfo.reg_section = NULL;
  wsecinfo.retval = TRUE;

  bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents,
			 &wsecinfo);

  if (! wsecinfo.retval)
    return FALSE;

  if (wsecinfo.reg_section != NULL)
    {
      asection *sec = wsecinfo.reg_section;
      unsigned int z = (unsigned int) (sec->vma / 8);

      /* Registers 0..31 must not be global.  Do sanity check on the "vma"
	 of the register contents section and check that it corresponds to
	 the length of the section.  */
      if (z < 32 || z >= 255 || (sec->vma & 7) != 0
	  || sec->vma != 256 * 8 - sec->size - 8)
	{
	  bfd_set_error (bfd_error_bad_value);

	  if (sec->size == 0)
	    /* There must always be at least one such register.  */
	    (*_bfd_error_handler)
	      (_("%s: no initialized registers; section length 0\n"),
	       bfd_get_filename (abfd));
	  else if (sec->vma > (256 - 32) * 8)
	    /* Provide better error message for the case of too many
	       global registers.  */
	    (*_bfd_error_handler)
	      (_("%s: too many initialized registers; section length %ld\n"),
	       bfd_get_filename (abfd),
	       (long) sec->size);
	  else
	    (*_bfd_error_handler)
	      (_("%s: invalid start address for initialized registers of"
		 " length %ld: 0x%lx%08lx\n"),
	       bfd_get_filename (abfd),
	       (long) sec->size,
	       (unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma));

	  return FALSE;
	}

      if (! mmo_internal_write_post (abfd, z, sec))
	return FALSE;
    }
  else
    if (! mmo_internal_write_post (abfd, 255, NULL))
      return FALSE;

  return mmo_write_symbols_and_terminator (abfd);
}

/* If there's anything in particular in a mmo bfd that we want to free,
   make this a real function.  Only do this if you see major memory
   thrashing; zealous free:ing will cause unwanted behavior, especially if
   you "free" memory allocated with "bfd_alloc", or even "bfd_release" a
   block allocated with "bfd_alloc"; they're really allocated from an
   obstack, and we don't know what was allocated there since this
   particular allocation.  */

#define	mmo_close_and_cleanup _bfd_generic_close_and_cleanup
#define mmo_bfd_free_cached_info _bfd_generic_bfd_free_cached_info

/* Perhaps we need to adjust this one; mmo labels (originally) without a
   leading ':' might more appropriately be called local.  */
#define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name
#define mmo_bfd_is_target_special_symbol  \
  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)

#define mmo_get_symbol_version_string \
  _bfd_nosymbols_get_symbol_version_string

/* Is this one really used or defined by anyone?  */
#define mmo_get_lineno _bfd_nosymbols_get_lineno

/* FIXME: We can do better on this one, if we have a dwarf2 .debug_line
   section or if MMO line numbers are implemented.  */
#define mmo_find_nearest_line _bfd_nosymbols_find_nearest_line
#define mmo_find_line _bfd_nosymbols_find_line
#define mmo_find_inliner_info _bfd_nosymbols_find_inliner_info
#define mmo_make_empty_symbol _bfd_generic_make_empty_symbol
#define mmo_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define mmo_read_minisymbols _bfd_generic_read_minisymbols
#define mmo_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol

#define mmo_get_section_contents_in_window \
  _bfd_generic_get_section_contents_in_window
#define mmo_bfd_get_relocated_section_contents \
  bfd_generic_get_relocated_section_contents
#define mmo_bfd_gc_sections bfd_generic_gc_sections
#define mmo_bfd_lookup_section_flags bfd_generic_lookup_section_flags
#define mmo_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define mmo_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define mmo_bfd_link_just_syms _bfd_generic_link_just_syms
#define mmo_bfd_copy_link_hash_symbol_type \
  _bfd_generic_copy_link_hash_symbol_type
#define mmo_bfd_final_link _bfd_generic_final_link
#define mmo_bfd_link_split_section _bfd_generic_link_split_section
#define mmo_bfd_link_check_relocs  _bfd_generic_link_check_relocs

/* Strictly speaking, only MMIX uses this restricted format, but let's not
   stop anybody from shooting themselves in the foot.  */
#define mmo_set_arch_mach bfd_default_set_arch_mach
#define mmo_bfd_relax_section bfd_generic_relax_section
#define mmo_bfd_merge_sections bfd_generic_merge_sections
#define mmo_bfd_is_group_section bfd_generic_is_group_section
#define mmo_bfd_discard_group bfd_generic_discard_group
#define mmo_section_already_linked \
  _bfd_generic_section_already_linked
#define mmo_bfd_define_common_symbol bfd_generic_define_common_symbol

/* We want to copy time of creation, otherwise we'd use
   BFD_JUMP_TABLE_COPY (_bfd_generic).  */
#define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
#define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
#define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
#define mmo_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
#define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
#define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data

const bfd_target mmix_mmo_vec =
{
  "mmo",			/* name */
  bfd_target_mmo_flavour,
  BFD_ENDIAN_BIG,		/* target byte order */
  BFD_ENDIAN_BIG,		/* target headers byte order */

  /* FIXME: Might need adjustments.  */
  (HAS_RELOC | EXEC_P |		/* object flags */
   HAS_LINENO | HAS_DEBUG |
   HAS_SYMS | HAS_LOCALS | WP_TEXT),

  /* FIXME: Might need adjustments.  */
  (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
   | SEC_READONLY | SEC_EXCLUDE | SEC_DEBUGGING | SEC_IN_MEMORY),
				/* section flags */
  0,				/* leading underscore */
  ' ',				/* ar_pad_char */
  16,				/* ar_max_namelen */
  0,				/* match priority.  */
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */

  {
    _bfd_dummy_target,
    mmo_object_p,		/* bfd_check_format */
    _bfd_dummy_target,
    _bfd_dummy_target,
  },
  {
    bfd_false,
    mmo_mkobject,
    bfd_false,
    bfd_false,
  },
  {				/* bfd_write_contents */
    bfd_false,
    mmo_write_object_contents,
    bfd_false,
    bfd_false,
  },

  BFD_JUMP_TABLE_GENERIC (mmo),
  BFD_JUMP_TABLE_COPY (mmo),
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
  BFD_JUMP_TABLE_SYMBOLS (mmo),
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
  BFD_JUMP_TABLE_WRITE (mmo),
  BFD_JUMP_TABLE_LINK (mmo),
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

  NULL,

  NULL
};
