/* BFD back-end for mmo objects (MMIX-specific object-format).
   Copyright (C) 2001-2024 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 0x98u
#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.  */
    bool 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.  */
    bool symbol_consistency_override_calculated;

    /* Whether to consistency-check symbol values, in particular "Main".  */
    bool 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;
    bool retval;
  };

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

static bool 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 bool mmo_mkobject (bfd *);
static bool 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 bfd_byte *mmo_get_loc (asection *, bfd_vma, unsigned int);
static bfd_cleanup mmo_object_p (bfd *);
static void mmo_map_set_sizes (bfd *, asection *, void *);
static bool mmo_get_symbols (bfd *);
static bool mmo_create_symbol (bfd *, const char *, bfd_vma,
			       enum mmo_sym_type, unsigned int);
static bool 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 bool 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 bool mmo_internal_write_header (bfd *);
static bool mmo_internal_write_post (bfd *, int, asection *);
static bool 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 bool 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 bool mmo_write_chunk (bfd *, const bfd_byte *, unsigned int);
static bool mmo_flush_chunk (bfd *);
static bool mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *,
				 unsigned int, bfd_vma *);
static bool mmo_write_chunk_list (bfd *, mmo_data_list_type *);
static bool mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *);
static bool 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 bool mmo_new_section_hook (bfd *, asection *);
static int mmo_sort_mmo_symbols (const void *, const void *);
static bool mmo_write_object_contents (bfd *);
static bool mmo_write_section_description (bfd *, asection *);
static bool mmo_has_leading_or_trailing_zero_tetra_p (bfd *, asection *);

static const char
valid_mmo_symbol_character_set[] =
{
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  ':', '_', 126, 127, 128, 129,
  130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
  140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
  150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
  160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
  170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
  180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
  190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
  200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
  210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
  220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
  230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
  240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
  250, 251, 252, 253, 254, 255,
  0
};


/* 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)
    {
      size_t len = strlen (secname) + 1;
      char *newsecname = bfd_alloc (abfd, len);

      if (newsecname == NULL)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return NULL;
	}
      memcpy (newsecname, secname, len);
      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 bool inited = false;

  if (inited)
    return;
  inited = true;
}

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

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

  mmo_init ();

  if (bfd_stat (abfd, &statbuf) < 0
      || bfd_seek (abfd, 0, SEEK_SET) != 0
      || bfd_read (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, statbuf.st_size - 4, SEEK_SET) != 0
      || bfd_read (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_alloc (abfd, abfd->tdata.mmo_data->max_symbol_length + 1);

  if (abfd->tdata.mmo_data->lop_stab_symbol == NULL)
    {
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB: no core to allocate a symbol %d bytes long"),
	 abfd, abfd->tdata.mmo_data->max_symbol_length);
      goto bad_final;
    }

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

  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;

  return _bfd_no_cleanup;

 bad_format:
  bfd_set_error (bfd_error_wrong_format);
 bad_final:
  return NULL;
}

/* Set up the mmo tdata information.  */

static bool
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_zalloc (abfd, 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 bool
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_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 bool
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 bool
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_section_vma (sec);

  /* Ignore sections that aren't loaded.  */
  if ((bfd_section_flags (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_section_vma (sec);

  /* Ignore sections that aren't loaded.  */
  if ((bfd_section_flags (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 (sec, vma))
	return NULL;

      if (!bfd_set_section_flags (sec, (bfd_section_flags (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 (sec, vma))
	return NULL;

      if (!bfd_set_section_flags (sec, (bfd_section_flags (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 || (!sec->user_set_vma && !bfd_set_section_vma (sec, vma)))
    return NULL;

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

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

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

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

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

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

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

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

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

      value ^= prev;
      bfd_put_16 (sec->owner, value, loc);
    }
  return 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_write (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 bool
mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
{
  bool 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_write (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 bool
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 bool
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 bool
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
	    /* xgettext:c-format */
	    (_("%pB: attempt to emit contents at non-multiple-of-4"
	       " address %#" PRIx64 ""),
	     abfd, (uint64_t) 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 bool
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_read (buf, 4, abfd) != 4)
    goto format_error;

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

      if (bfd_read (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_read (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_read (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_read (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_read (buf, 4, abfd) != 4)))
    goto format_error_free;

  flags = bfd_get_32 (abfd, buf);

  /* Get the section length.  */
  if (bfd_read (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_read (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_read (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_read (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_read (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_read (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_read (buf, 4, abfd) != 4
      || (buf[0] == LOP
	  && (buf[1] != LOP_QUOTE || bfd_read (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_zalloc (abfd, (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 (sec,
			      (bfd_sec_flags_from_mmo_flags (flags)
			       | bfd_section_flags (sec)
			       | (section_length != 0 ? SEC_HAS_CONTENTS : 0)))
      || !bfd_set_section_size (sec, sec->size + section_length)
      /* Set VMA only for the first occurrence.  */
      || (!sec->user_set_vma && !bfd_set_section_vma (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_read (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.  */
      if (abfd->tdata.mmo_data->have_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_write (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
	abfd->tdata.mmo_data->have_error = true;
    }
}

/* Create a symbol.  */

static bool
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
	(_("%pB: invalid mmo file: initialization value for $255"
	   " is not `Main'\n"),
	 abfd);
      bfd_set_error (bfd_error_bad_value);
      return false;
    }

  return true;
}

/* Read in symbols.  */

static bool
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
		/* xgettext:c-format */
		(_("%pB: unsupported wide character sequence"
		   " 0x%02X 0x%02X after symbol name starting with `%s'\n"),
		 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;
	}

      if (abfd->tdata.mmo_data->symbol_position
	  >= abfd->tdata.mmo_data->max_symbol_length)
	{
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: symbol name exceeds given max length of %d"),
	     abfd, abfd->tdata.mmo_data->max_symbol_length);
	  abfd->tdata.mmo_data->have_error = true;
	  return false;
	}
      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 bfd_byte *
mmo_get_loc (asection *sec, bfd_vma vma, unsigned 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->size >= size
	  && datap->size - size >= vma - datap->where)
	return datap->data + (vma - datap->where);
      else if (datap->where <= vma
	       && datap->allocated_size >= size
	       && datap->allocated_size - size >= vma - datap->where
	       /* 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 - datap->where + 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 - sec->vma + size > sec->size)
	    sec->size = vma - sec->vma + 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->size > vma - datap->where)
	|| (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, (bfd_section_flags (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 - sec->vma + size > sec->size)
    sec->size = vma - sec->vma + 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 bool
mmo_scan (bfd *abfd)
{
  unsigned int i;
  unsigned int lineno ATTRIBUTE_UNUSED = 1;
  bool error = false;
  bfd_vma vma = 0;
  asection *sec = NULL;
  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];
  file_ptr stab_loc = -1;
  char *file_names[256];

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

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

  while ((nbytes_read = bfd_read (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
		/* xgettext:c-format */
		(_("%pB: invalid mmo file: unsupported lopcode `%d'\n"),
		 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
		    /* xgettext:c-format */
		    (_("%pB: invalid mmo file: expected YZ = 1"
		       " got YZ = %d for lop_quote\n"),
		     abfd, y*256+z);
		  bfd_set_error (bfd_error_bad_value);
		  goto error_return;
		}
	      if (bfd_read (buf, 4, abfd) != 4)
		goto error_return;

	      vma &= ~3;
	      if (sec == NULL)
		sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
	      if (!mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf)))
		{
		  bfd_set_error (bfd_error_bad_value);
		  goto error_return;
		}
	      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_read (buf, 4, abfd) != 4)
		    goto error_return;

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

		  vma += bfd_get_64 (abfd, buf);
		}
	      else
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB: invalid mmo file: expected z = 1 or z = 2,"
		       " got z = %d for lop_loc\n"),
		     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_read (buf, 4, abfd) != 4)
		      goto error_return;

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

		    p += bfd_get_64 (abfd, buf);
		  }
		else
		  {
		    _bfd_error_handler
		      /* xgettext:c-format */
		      (_("%pB: invalid mmo file: expected z = 1 or z = 2,"
			 " got z = %d for lop_fixo\n"),
		       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;
		if (!mmo_xore_64 (fixosec, p, vma))
		  {
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }
	      }
	    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;
		if (!mmo_xore_16 (fixrsec, p, yz))
		  {
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }
	      }
	    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
		      /* xgettext:c-format */
		      (_("%pB: invalid mmo file: expected y = 0,"
			 " got y = %d for lop_fixrx\n"),
		       abfd, y);
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }

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

		/* Get the next 32-bit value.  */
		if (bfd_read (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
		      /* xgettext:c-format */
		      (_("%pB: invalid mmo file: leading byte of operand word"
			 " must be 0 or 1, got %d for lop_fixrx\n"),
		       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;
		if (!mmo_xore_32 (fixrsec, p, delta))
		  {
		    bfd_set_error (bfd_error_bad_value);
		    goto error_return;
		  }
	      }
	    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
			/* xgettext:c-format */
			(_("%pB: cannot allocate file name for file number %d,"
			   " %d bytes\n"),
			 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_read (fname + i * 4, 4, abfd) != 4)
			{
			  free (fname);
			  goto error_return;
			}
		    }

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

		  file_names[y] = fname;
		}

	      if (file_names[y] == NULL)
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB: invalid mmo file: file name for number %d"
		       " was not specified before use\n"),
		     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_read (abfd->tdata.mmo_data->created, 4,
				 abfd) != 4)
		  goto error_return;

		for (i = 1; i < z; i++)
		  if (bfd_read (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_read (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);
		    if (!loc)
		      {
			bfd_set_error (bfd_error_bad_value);
			goto error_return;
		      }
		    bfd_put_64 (abfd, first_octa, loc);

		    for (i = z + 1; i < 255; i++)
		      {
			if (bfd_read (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_read (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
		    /* xgettext:c-format */
		    (_("%pB: invalid mmo file: fields y and z of lop_stab"
		       " non-zero, y: %d, z: %d\n"),
		     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
		      /* xgettext:c-format */
		      (_("%pB: invalid mmo file: lop_end not last item in"
			 " file\n"),
		       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
		      /* xgettext:c-format */
		      (_("%pB: invalid mmo file: YZ of lop_end (%ld)"
			 " not equal to the number of tetras to the preceding"
			 " lop_stab (%ld)\n"),
		       abfd, (long) (y * 256 + z),
		       (long) (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.  */
	  if (sec == NULL)
	    sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
	  if (!mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf)))
	    {
	      bfd_set_error (bfd_error_bad_value);
	      goto error_return;
	    }
	  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_section_flags (sec) & SEC_HAS_CONTENTS)
      && !bfd_set_section_flags (sec, (bfd_section_flags (sec)
				       | SEC_ALLOC | SEC_LOAD | SEC_CODE)))
    error = true;

  sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
  if (sec != NULL
      && (bfd_section_flags (sec) & SEC_HAS_CONTENTS)
      && !bfd_set_section_flags (sec, (bfd_section_flags (sec)
				       | SEC_ALLOC | SEC_LOAD | SEC_DATA)))
    error = true;

  /* Free whatever resources we took.  */
  for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); 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 bool
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 bool
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 bool
mmo_internal_write_header (bfd *abfd)
{
  const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};

  if (bfd_write (lop_pre_bfd, 4, abfd) != 4)
    return false;

  /* Copy creation time of original file.  */
  if (bfd_write (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 bool
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_write (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_write (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 bool
mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec)
{
  bfd_vma secaddr = bfd_section_vma (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 bool
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_section_vma (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_section_vma (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 (startswith (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_section_flags (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_section_flags (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 bool
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_section_flags (sec)));
  mmo_write_octa (abfd, sec->size);
  mmo_write_octa (abfd, bfd_section_vma (sec));
  return true;
}

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

static bool
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 bool
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
	/* xgettext:c-format */
	(_("%pB: invalid symbol table: duplicate symbol `%s'\n"),
	 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 bool
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;

  if (count != 0)
    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.  */
	    bfd_vma vma_start = bfd_get_start_address (abfd);

	    _bfd_error_handler
	      /* xgettext:c-format */
	      (_("%pB: bad symbol definition: `Main' set to %" PRIx64 " rather"
		 " than the start address %" PRIx64 "\n"),
	       abfd, mainvalue, vma_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
	/* xgettext:c-format */
	(_("%pB: warning: symbol table too large for mmo, larger than 65535"
	   " 32-bit words: %d.  Only `Main' will be emitted.\n"),
	 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_write (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
	/* xgettext:c-format */
	(_("%pB: internal error, symbol table changed size from %d to %d"
	   " words\n"),
	 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_write (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
	return false;
    }

  bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf);
  return bfd_write (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_section_flags (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
	    /* xgettext:c-format */
	    (_("%pB: internal error, internal register section %pA had"
	       " contents\n"),
	     abfd, sec);
	  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 bool
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
	      (_("%pB: no initialized registers; section length 0\n"),
	       abfd);
	  else if (sec->vma > (256 - 32) * 8)
	    /* Provide better error message for the case of too many
	       global registers.  */
	    _bfd_error_handler
	      /* xgettext:c-format */
	      (_("%pB: too many initialized registers; section length %" PRId64),
	       abfd, (int64_t) sec->size);
	  else
	    _bfd_error_handler
	      /* xgettext:c-format */
	      (_("%pB: invalid start address for initialized registers of"
		 " length %" PRId64 ": %#" PRIx64),
	       abfd, (int64_t) sec->size, (uint64_t) 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_bool_bfd_asymbol_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_nearest_line_with_alt _bfd_nosymbols_find_nearest_line_with_alt
#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_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_group_name bfd_generic_group_name
#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
#define mmo_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
#define mmo_bfd_define_start_stop bfd_generic_define_start_stop

/* 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
#define mmo_init_private_section_data _bfd_generic_init_private_section_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.  */
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
  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_bool_bfd_false_error,
    mmo_mkobject,
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error,
  },
  {				/* bfd_write_contents */
    _bfd_bool_bfd_false_error,
    mmo_write_object_contents,
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error,
  },

  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
};
