OSDN Git Service

daily update
[pf3gnuchains/pf3gnuchains3x.git] / bfd / mmo.c
index 96c654e..eee27c3 100644 (file)
--- a/bfd/mmo.c
+++ b/bfd/mmo.c
@@ -1,25 +1,27 @@
 /* BFD back-end for mmo objects (MMIX-specific object-format).
-   Copyright 2001, 2002
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
    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 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 2 of the License, or
-(at your option) any later version.
+   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.
+   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.  */
 
-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
 SECTION
@@ -61,6 +63,12 @@ SUBSECTION
        @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
@@ -71,12 +79,6 @@ SUBSECTION
        @url{http://www-cs-faculty.stanford.edu/~knuth/mmixal-intro.ps.gz},
        the lopcodes are:
 
-       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}.
-
        @table @code
        @item lop_quote
        0x98000001.  The next word is contents, regardless of whether it
@@ -195,8 +197,8 @@ EXAMPLE
 | 0x81000000
 | 0x980c0005 - lop_end; symbol table contained five 32-bit words.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "libiberty.h"
 #include "elf/mmix.h"
@@ -260,7 +262,7 @@ enum mmo_sym_type { mmo_reg_sym, mmo_undef_sym, mmo_data_sym, mmo_abs_sym};
 struct mmo_symbol
   {
     struct mmo_symbol *next;
-    const char *name;
+    char *name;
     bfd_vma value;
     enum mmo_sym_type sym_type;
     unsigned int serno;
@@ -302,7 +304,7 @@ struct mmo_data_struct
 
     /* When we're reading bytes recursively, check this occasionally.
        Also holds write errors.  */
-    boolean have_error;
+    bfd_boolean have_error;
 
     /* Max symbol length that may appear in the lop_stab table.  Note that
        this table might just hold a subset of symbols for not-really large
@@ -335,6 +337,9 @@ struct mmo_section_data_struct
     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
@@ -342,7 +347,7 @@ struct mmo_section_data_struct
 struct mmo_write_sec_info
   {
     asection *reg_section;
-    boolean retval;
+    bfd_boolean retval;
   };
 
 /* Used when trying to find a section corresponding to addr.  */
@@ -352,81 +357,74 @@ struct mmo_find_sec_info
     bfd_vma addr;
   };
 
-static boolean mmo_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
-static void mmo_write_section_unless_reg_contents
- PARAMS ((bfd *, asection *, PTR));
-static void mmo_find_sec_w_addr PARAMS ((bfd *, asection *, PTR));
-static void mmo_find_sec_w_addr_grow PARAMS ((bfd *, asection *, PTR));
-static asection *mmo_make_section PARAMS ((bfd *, const char *));
-static void mmo_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
-static void mmo_print_symbol
- PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
-static void mmo_init PARAMS ((void));
-static boolean mmo_mkobject PARAMS ((bfd *));
-static boolean mmo_scan PARAMS ((bfd *));
-static asection *mmo_decide_section PARAMS ((bfd *, bfd_vma));
-static asection *mmo_get_generic_spec_data_section PARAMS ((bfd *, int));
-static asection *mmo_get_spec_section PARAMS ((bfd *, int));
-static INLINE bfd_byte *mmo_get_loc PARAMS ((asection *, bfd_vma, int));
-static void mmo_xore_64 PARAMS ((asection *, bfd_vma vma, bfd_vma value));
-static void mmo_xore_32 PARAMS ((asection *, bfd_vma vma, unsigned int));
-static void mmo_xore_16 PARAMS ((asection *, bfd_vma vma, unsigned int));
-static const bfd_target *mmo_object_p PARAMS ((bfd *));
-static void mmo_map_set_sizes PARAMS ((bfd *, asection *, PTR));
-static boolean mmo_get_symbols PARAMS ((bfd *));
-static boolean mmo_create_symbol PARAMS ((bfd *, const char *, bfd_vma,
-                                         enum mmo_sym_type, unsigned int));
-static boolean mmo_get_section_contents
-  PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
-static long mmo_get_symtab_upper_bound PARAMS ((bfd *));
-static long mmo_get_symtab PARAMS ((bfd *, asymbol **));
-static void mmo_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
-static void mmo_print_symbol PARAMS ((bfd *, PTR, asymbol *,
-                                     bfd_print_symbol_type));
-static boolean mmo_set_section_contents
-  PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
-static int mmo_sizeof_headers PARAMS ((bfd *, boolean));
-static long mmo_get_reloc_upper_bound PARAMS ((bfd *, asection *));
-
-static boolean mmo_internal_write_header PARAMS ((bfd *));
-static boolean mmo_internal_write_post PARAMS ((bfd *, int, asection *));
-static boolean mmo_internal_add_3_sym
- PARAMS ((bfd *, struct mmo_symbol_trie *, const struct mmo_symbol *));
-static unsigned int mmo_internal_3_length
- PARAMS ((bfd *, struct mmo_symbol_trie *));
-static void mmo_internal_3_dump
- PARAMS ((bfd *, struct mmo_symbol_trie *));
-static void mmo_beb128_out PARAMS ((bfd *, int, int));
-static boolean mmo_internal_write_section
-  PARAMS ((bfd *, asection *));
-static void mmo_write_tetra PARAMS ((bfd *, unsigned int));
-static void mmo_write_tetra_raw PARAMS ((bfd *, unsigned int));
-static void mmo_write_octa PARAMS ((bfd *, bfd_vma));
-static void mmo_write_octa_raw PARAMS ((bfd *, bfd_vma));
-static boolean mmo_write_chunk
-  PARAMS ((bfd *, const bfd_byte *, unsigned int));
-static boolean mmo_flush_chunk PARAMS ((bfd *));
-static boolean mmo_write_loc_chunk
-  PARAMS ((bfd *, bfd_vma, const bfd_byte *, unsigned int, bfd_vma *));
-static boolean mmo_write_chunk_list PARAMS ((bfd *, mmo_data_list_type *));
-static boolean mmo_write_loc_chunk_list
-  PARAMS ((bfd *, mmo_data_list_type *));
-static boolean mmo_write_symbols_and_terminator PARAMS ((bfd *));
-static flagword mmo_sec_flags_from_bfd_flags PARAMS ((flagword));
-static flagword bfd_sec_flags_from_mmo_flags PARAMS ((flagword));
-static bfd_byte mmo_get_byte PARAMS ((bfd *));
-static void mmo_write_byte PARAMS ((bfd *, bfd_byte));
-static boolean mmo_new_section_hook PARAMS ((bfd *, asection *));
-static int mmo_sort_mmo_symbols PARAMS ((const PTR, const PTR));
-static boolean mmo_write_object_contents PARAMS ((bfd *));
-static long mmo_canonicalize_reloc
-  PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
+static bfd_boolean mmo_bfd_copy_private_bfd_data (bfd *, bfd *);
+static void mmo_write_section_unless_reg_contents (bfd *, asection *, void *);
+static void mmo_find_sec_w_addr (bfd *, asection *, void *);
+static void mmo_find_sec_w_addr_grow (bfd *, asection *, void *);
+static asection *mmo_make_section (bfd *, const char *);
+static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
+static void mmo_print_symbol (bfd *, void *, asymbol *, 
+                             bfd_print_symbol_type);
+static void mmo_init (void);
+static bfd_boolean mmo_mkobject (bfd *);
+static bfd_boolean mmo_scan (bfd *);
+static asection *mmo_decide_section (bfd *, bfd_vma);
+static asection *mmo_get_generic_spec_data_section (bfd *, int);
+static asection *mmo_get_spec_section (bfd *, int);
+static INLINE bfd_byte *mmo_get_loc (asection *, bfd_vma, int);
+static void mmo_xore_64 (asection *, bfd_vma vma, bfd_vma value);
+static void mmo_xore_32 (asection *, bfd_vma vma, unsigned int);
+static void mmo_xore_16 (asection *, bfd_vma vma, unsigned int);
+static const bfd_target *mmo_object_p (bfd *);
+static void mmo_map_set_sizes (bfd *, asection *, void *);
+static bfd_boolean mmo_get_symbols (bfd *);
+static bfd_boolean mmo_create_symbol (bfd *, const char *, bfd_vma,
+                                     enum mmo_sym_type, unsigned int);
+static bfd_boolean mmo_get_section_contents (bfd *, asection *, void *,
+                                            file_ptr, bfd_size_type);
+static long mmo_get_symtab_upper_bound (bfd *);
+static long mmo_canonicalize_symtab (bfd *, asymbol **);
+static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
+static void mmo_print_symbol (bfd *, void *, asymbol *,
+                             bfd_print_symbol_type);
+static bfd_boolean mmo_set_section_contents (bfd *, sec_ptr, const void *,
+                                            file_ptr, bfd_size_type);
+static int mmo_sizeof_headers (bfd *, struct bfd_link_info *);
+static bfd_boolean mmo_internal_write_header (bfd *);
+static bfd_boolean mmo_internal_write_post (bfd *, int, asection *);
+static bfd_boolean mmo_internal_add_3_sym (bfd *, struct mmo_symbol_trie *,
+                                          const struct mmo_symbol *);
+static unsigned int mmo_internal_3_length (bfd *, struct mmo_symbol_trie *);
+static void mmo_internal_3_dump (bfd *, struct mmo_symbol_trie *);
+static void mmo_beb128_out (bfd *, int, int);
+static bfd_boolean mmo_internal_write_section (bfd *, asection *);
+static void mmo_write_tetra (bfd *, unsigned int);
+static void mmo_write_tetra_raw (bfd *, unsigned int);
+static void mmo_write_octa (bfd *, bfd_vma);
+static void mmo_write_octa_raw (bfd *, bfd_vma);
+static bfd_boolean mmo_write_chunk (bfd *, const bfd_byte *, unsigned int);
+static bfd_boolean mmo_flush_chunk (bfd *);
+static bfd_boolean mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *,
+                                       unsigned int, bfd_vma *);
+static bfd_boolean mmo_write_chunk_list (bfd *, mmo_data_list_type *);
+static bfd_boolean mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *);
+static bfd_boolean mmo_write_symbols_and_terminator (bfd *);
+static flagword mmo_sec_flags_from_bfd_flags (flagword);
+static flagword bfd_sec_flags_from_mmo_flags (flagword);
+static bfd_byte mmo_get_byte (bfd *);
+static void mmo_write_byte (bfd *, bfd_byte);
+static bfd_boolean mmo_new_section_hook (bfd *, asection *);
+static int mmo_sort_mmo_symbols (const void *, const void *);
+static bfd_boolean mmo_write_object_contents (bfd *);
+static bfd_boolean mmo_write_section_description (bfd *, asection *);
+static bfd_boolean mmo_has_leading_or_trailing_zero_tetra_p (bfd *,
+                                                            asection *);
 
 /* Global "const" variables initialized once.  Must not depend on
    particular input or caller; put such things into the bfd or elsewhere.
    Look ma, no static per-invocation data!  */
 
-static unsigned
+static
 char valid_mmo_symbol_character_set[/* A-Z a-z (we assume consecutive
                                       codes; sorry EBCDIC:ers!).  */
                                    + 'Z' - 'A' + 1 + 'z' - 'a' + 1
@@ -444,9 +442,7 @@ char valid_mmo_symbol_character_set[/* A-Z a-z (we assume consecutive
    one, new memory for the name is allocated.  */
 
 static asection *
-mmo_make_section (abfd, secname)
-     bfd *abfd;
-     const char *secname;
+mmo_make_section (bfd *abfd, const char *secname)
 {
   asection *sec = bfd_get_section_by_name (abfd, secname);
 
@@ -473,9 +469,9 @@ mmo_make_section (abfd, secname)
    here, nor must it be static.  Add it to tdata information instead.  */
 
 static void
-mmo_init ()
+mmo_init (void)
 {
-  static boolean inited = false;
+  static bfd_boolean inited = FALSE;
   int i = 0;
   int j = 0;
   static const char letters[]
@@ -483,7 +479,7 @@ mmo_init ()
 
   if (inited)
     return;
-  inited = true;
+  inited = TRUE;
 
   /* Fill in the set of valid symbol characters.  */
   strcpy (valid_mmo_symbol_character_set, letters);
@@ -496,8 +492,7 @@ mmo_init ()
 /* Check whether an existing file is an mmo file.  */
 
 static const bfd_target *
-mmo_object_p (abfd)
-     bfd *abfd;
+mmo_object_p (bfd *abfd)
 {
   struct stat statbuf;
   bfd_byte b[4];
@@ -563,9 +558,8 @@ mmo_object_p (abfd)
 
 /* Set up the mmo tdata information.  */
 
-static boolean
-mmo_mkobject (abfd)
-     bfd *abfd;
+static bfd_boolean
+mmo_mkobject (bfd *abfd)
 {
   mmo_init ();
 
@@ -577,7 +571,7 @@ mmo_mkobject (abfd)
         initialize most.  */
       tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type));
       if (tdata == NULL)
-       return false;
+       return FALSE;
 
       created = time (NULL);
       bfd_put_32 (abfd, created, tdata->created);
@@ -585,34 +579,29 @@ mmo_mkobject (abfd)
       abfd->tdata.mmo_data = tdata;
     }
 
-  return true;
+  return TRUE;
 }
 
-static boolean
-mmo_bfd_copy_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+static bfd_boolean
+mmo_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   if (bfd_get_flavour (ibfd) != bfd_target_mmo_flavour
       || bfd_get_flavour (obfd) != bfd_target_mmo_flavour)
-    return true;
+    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;
+  return TRUE;
 }
 
 /* Helper functions for mmo_decide_section, used through
    bfd_map_over_sections.  */
 
 static void
-mmo_find_sec_w_addr (abfd, sec, p)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *sec;
-     PTR p;
+mmo_find_sec_w_addr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
 {
   struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
   bfd_vma vma = bfd_get_section_vma (abfd, sec);
@@ -622,15 +611,12 @@ mmo_find_sec_w_addr (abfd, sec, p)
       !=  (SEC_LOAD | SEC_ALLOC))
     return;
 
-  if (infop->addr >= vma && infop->addr < vma + sec->_raw_size)
+  if (infop->addr >= vma && infop->addr < vma + sec->size)
     infop->sec = sec;
 }
 
 static void
-mmo_find_sec_w_addr_grow (abfd, sec, p)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *sec;
-     PTR p;
+mmo_find_sec_w_addr_grow (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
 {
   struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
   bfd_vma vma = bfd_get_section_vma (abfd, sec);
@@ -650,9 +636,7 @@ mmo_find_sec_w_addr_grow (abfd, sec, p)
    increasing number.  */
 
 static asection *
-mmo_decide_section (abfd, vma)
-     bfd *abfd;
-     bfd_vma vma;
+mmo_decide_section (bfd *abfd, bfd_vma vma)
 {
   asection *sec = NULL;
   char sec_name[sizeof (".MMIX.sec.") + 20];
@@ -721,10 +705,7 @@ mmo_decide_section (abfd, vma)
 /* Xor in a 64-bit value VALUE at VMA.  */
 
 static INLINE void
-mmo_xore_64 (sec, vma, value)
-     asection *sec;
-     bfd_vma vma;
-     bfd_vma value;
+mmo_xore_64 (asection *sec, bfd_vma vma, bfd_vma value)
 {
   bfd_byte *loc = mmo_get_loc (sec, vma, 8);
   bfd_vma prev = bfd_get_64 (sec->owner, loc);
@@ -736,10 +717,7 @@ mmo_xore_64 (sec, vma, value)
 /* Xor in a 32-bit value VALUE at VMA.  */
 
 static INLINE void
-mmo_xore_32 (sec, vma, value)
-     asection *sec;
-     bfd_vma vma;
-     unsigned int value;
+mmo_xore_32 (asection *sec, bfd_vma vma, unsigned int value)
 {
   bfd_byte *loc = mmo_get_loc (sec, vma, 4);
   unsigned int prev = bfd_get_32 (sec->owner, loc);
@@ -751,10 +729,7 @@ mmo_xore_32 (sec, vma, value)
 /* Xor in a 16-bit value VALUE at VMA.  */
 
 static INLINE void
-mmo_xore_16 (sec, vma, value)
-     asection *sec;
-     bfd_vma vma;
-     unsigned int value;
+mmo_xore_16 (asection *sec, bfd_vma vma, unsigned int value)
 {
   bfd_byte *loc = mmo_get_loc (sec, vma, 2);
   unsigned int prev = bfd_get_16 (sec->owner, loc);
@@ -766,24 +741,20 @@ mmo_xore_16 (sec, vma, value)
 /* Write a 32-bit word to output file, no lop_quote generated.  */
 
 static INLINE void
-mmo_write_tetra_raw (abfd, value)
-     bfd *abfd;
-     unsigned int value;
+mmo_write_tetra_raw (bfd *abfd, unsigned int value)
 {
   bfd_byte buf[4];
 
   bfd_put_32 (abfd, value, buf);
 
-  if (bfd_bwrite ((PTR) buf, 4, abfd) != 4)
-    abfd->tdata.mmo_data->have_error = true;
+  if (bfd_bwrite (buf, 4, abfd) != 4)
+    abfd->tdata.mmo_data->have_error = TRUE;
 }
 
 /* Write a 32-bit word to output file; lop_quote if necessary.  */
 
 static INLINE void
-mmo_write_tetra (abfd, value)
-     bfd *abfd;
-     unsigned int value;
+mmo_write_tetra (bfd *abfd, unsigned int value)
 {
   if (((value >> 24) & 0xff) == LOP)
     mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);
@@ -794,9 +765,7 @@ mmo_write_tetra (abfd, value)
 /* Write a 64-bit word to output file, perhaps with lop_quoting.  */
 
 static INLINE void
-mmo_write_octa (abfd, value)
-     bfd *abfd;
-     bfd_vma value;
+mmo_write_octa (bfd *abfd, bfd_vma value)
 {
   mmo_write_tetra (abfd, (unsigned int) (value >> 32));
   mmo_write_tetra (abfd, (unsigned int) value);
@@ -805,9 +774,7 @@ mmo_write_octa (abfd, value)
 /* Write a 64-bit word to output file, without lop_quoting.  */
 
 static INLINE void
-mmo_write_octa_raw (abfd, value)
-     bfd *abfd;
-     bfd_vma value;
+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);
@@ -816,13 +783,10 @@ mmo_write_octa_raw (abfd, value)
 /* Write quoted contents.  Intended to be called multiple times in
    sequence, followed by a call to mmo_flush_chunk.  */
 
-static INLINE boolean
-mmo_write_chunk (abfd, loc, len)
-     bfd *abfd;
-     const bfd_byte *loc;
-     unsigned int len;
+static INLINE bfd_boolean
+mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
 {
-  boolean retval = true;
+  bfd_boolean retval = TRUE;
 
   /* Fill up a tetra from bytes remaining from a previous chunk.  */
   if (abfd->tdata.mmo_data->byte_no != 0)
@@ -848,7 +812,7 @@ mmo_write_chunk (abfd, loc, len)
 
       retval = (retval
                && ! abfd->tdata.mmo_data->have_error
-               && 4 == bfd_bwrite ((PTR) loc, 4, abfd));
+               && 4 == bfd_bwrite (loc, 4, abfd));
 
       loc += 4;
       len -= 4;
@@ -861,16 +825,15 @@ mmo_write_chunk (abfd, loc, len)
     }
 
   if (! retval)
-    abfd->tdata.mmo_data->have_error = true;
+    abfd->tdata.mmo_data->have_error = TRUE;
   return retval;
 }
 
 /* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to
    4 bytes.  */
 
-static INLINE boolean
-mmo_flush_chunk (abfd)
-     bfd *abfd;
+static INLINE bfd_boolean
+mmo_flush_chunk (bfd *abfd)
 {
   if (abfd->tdata.mmo_data->byte_no != 0)
     {
@@ -886,14 +849,12 @@ mmo_flush_chunk (abfd)
 
 /* Same, but from a list.  */
 
-static INLINE boolean
-mmo_write_chunk_list (abfd, datap)
-     bfd *abfd;
-     mmo_data_list_type *datap;
+static INLINE bfd_boolean
+mmo_write_chunk_list (bfd *abfd, mmo_data_list_type *datap)
 {
   for (; datap != NULL; datap = datap->next)
     if (! mmo_write_chunk (abfd, datap->data, datap->size))
-      return false;
+      return FALSE;
 
   return mmo_flush_chunk (abfd);
 }
@@ -902,13 +863,9 @@ mmo_write_chunk_list (abfd, datap)
    mmo_flush_chunk after calling this function.  The location is only
    output if different than *LAST_VMAP, which is updated after this call.  */
 
-static boolean
-mmo_write_loc_chunk (abfd, vma, loc, len, last_vmap)
-     bfd *abfd;
-     bfd_vma vma;
-     const bfd_byte *loc;
-     unsigned int len;
-     bfd_vma *last_vmap;
+static bfd_boolean
+mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc,
+                    unsigned int len, bfd_vma *last_vmap)
 {
   /* Find an initial and trailing section of zero tetras; we don't need to
      write out zeros.  FIXME: When we do this, we should emit section size
@@ -953,10 +910,8 @@ mmo_write_loc_chunk (abfd, vma, loc, len, last_vmap)
 
 /* Same, but from a list.  */
 
-static INLINE boolean
-mmo_write_loc_chunk_list (abfd, datap)
-     bfd *abfd;
-     mmo_data_list_type *datap;
+static INLINE bfd_boolean
+mmo_write_loc_chunk_list (bfd *abfd, mmo_data_list_type *datap)
 {
   /* Get an address different than the address of the first chunk.  */
   bfd_vma last_vma = datap ? datap->where - 1 : 0;
@@ -964,7 +919,7 @@ mmo_write_loc_chunk_list (abfd, datap)
   for (; datap != NULL; datap = datap->next)
     if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size,
                               &last_vma))
-      return false;
+      return FALSE;
 
   return mmo_flush_chunk (abfd);
 }
@@ -972,9 +927,7 @@ mmo_write_loc_chunk_list (abfd, datap)
 /* Make a .MMIX.spec_data.N section.  */
 
 static asection *
-mmo_get_generic_spec_data_section (abfd, spec_data_number)
-     bfd *abfd;
-     int spec_data_number;
+mmo_get_generic_spec_data_section (bfd *abfd, int spec_data_number)
 {
   asection *sec;
   char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20]
@@ -992,11 +945,9 @@ mmo_get_generic_spec_data_section (abfd, spec_data_number)
    ourselves, parse some of its data to get at the section name.  */
 
 static asection *
-mmo_get_spec_section (abfd, spec_data_number)
-     bfd *abfd;
-     int spec_data_number;
+mmo_get_spec_section (bfd *abfd, int spec_data_number)
 {
-  bfd_byte *secname;
+  char *secname;
   asection *sec;
   bfd_byte buf[4];
   unsigned int secname_length;
@@ -1045,7 +996,7 @@ mmo_get_spec_section (abfd, spec_data_number)
       if (bfd_bread (secname + i * 4, 4, abfd) != 4)
        goto format_error_free;
 
-      if (secname[i * 4] == LOP)
+      if (secname[i * 4] == (char) LOP)
        {
          /* A bit of overkill, but we handle char 0x98 in a section name,
             and recognize misparsing.  */
@@ -1125,8 +1076,7 @@ mmo_get_spec_section (abfd, spec_data_number)
                               bfd_sec_flags_from_mmo_flags (flags)
                               | bfd_get_section_flags (abfd, sec)
                               | (section_length != 0 ? SEC_HAS_CONTENTS : 0))
-      || ! bfd_set_section_size (abfd, sec,
-                                sec->_cooked_size + section_length)
+      || ! bfd_set_section_size (abfd, sec, sec->size + section_length)
       /* Set VMA only for the first occurrence.  */
       || (! sec->user_set_vma
          && ! bfd_set_section_vma  (abfd, sec, section_vma)))
@@ -1137,12 +1087,11 @@ mmo_get_spec_section (abfd, spec_data_number)
     }
 
   loc->next = NULL;
-  if (((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail != NULL)
-    ((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail->next
-      = loc;
+  if (mmo_section_data (sec)->tail != NULL)
+    mmo_section_data (sec)->tail->next = loc;
   else
-    ((struct mmo_section_data_struct *) (sec->used_by_bfd))->head = loc;
-  ((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail = loc;
+    mmo_section_data (sec)->head = loc;
+  mmo_section_data (sec)->tail = loc;
   loc->where = section_vma;
 
   return sec;
@@ -1159,8 +1108,7 @@ mmo_get_spec_section (abfd, spec_data_number)
 /* Read a byte, but read from file in multiples of 32-bit words.  */
 
 static bfd_byte
-mmo_get_byte (abfd)
-     bfd *abfd;
+mmo_get_byte (bfd *abfd)
 {
   bfd_byte retval;
 
@@ -1169,7 +1117,7 @@ mmo_get_byte (abfd)
       if (! abfd->tdata.mmo_data->have_error
          && bfd_bread (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
        {
-         abfd->tdata.mmo_data->have_error = true;
+         abfd->tdata.mmo_data->have_error = TRUE;
 
          /* A value somewhat safe against tripping on some inconsistency
             when mopping up after this error.  */
@@ -1186,40 +1134,34 @@ mmo_get_byte (abfd)
 /* Write a byte, in multiples of 32-bit words.  */
 
 static void
-mmo_write_byte (abfd, value)
-     bfd *abfd;
-     bfd_byte value;
+mmo_write_byte (bfd *abfd, bfd_byte value)
 {
   abfd->tdata.mmo_data->buf[(abfd->tdata.mmo_data->byte_no++ % 4)] = value;
   if ((abfd->tdata.mmo_data->byte_no % 4) == 0)
     {
       if (! abfd->tdata.mmo_data->have_error
          && bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
-       abfd->tdata.mmo_data->have_error = true;
+       abfd->tdata.mmo_data->have_error = TRUE;
     }
 }
 
 /* Create a symbol.  */
 
-static boolean
-mmo_create_symbol (abfd, symname, addr, sym_type, serno)
-     bfd *abfd;
-     const char *symname;
-     bfd_vma addr;
-     enum mmo_sym_type sym_type;
-     unsigned int serno;
+static bfd_boolean
+mmo_create_symbol (bfd *abfd, const char *symname, bfd_vma addr, enum
+                  mmo_sym_type sym_type, unsigned int serno)
 {
   struct mmo_symbol *n;
 
   n = (struct mmo_symbol *) bfd_alloc (abfd, sizeof (struct mmo_symbol));
   if (n == NULL)
-    return false;
+    return FALSE;
 
   n->name = bfd_alloc (abfd, strlen (symname) + 1);
   if (n->name == NULL)
-    return false;
+    return FALSE;
 
-  strcpy ((PTR) n->name, symname);
+  strcpy (n->name, symname);
 
   n->value = addr;
   n->sym_type = sym_type;
@@ -1245,17 +1187,16 @@ mmo_create_symbol (abfd, symname, addr, sym_type, serno)
        (_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"),
         bfd_get_filename (abfd));
       bfd_set_error (bfd_error_bad_value);
-      return false;
+      return FALSE;
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Read in symbols.  */
 
-static boolean
-mmo_get_symbols (abfd)
-     bfd *abfd;
+static bfd_boolean
+mmo_get_symbols (bfd *abfd)
 {
 /*
 INODE
@@ -1360,7 +1301,7 @@ SUBSECTION
 
   /* Check first if we have a bad hair day.  */
   if (abfd->tdata.mmo_data->have_error)
-    return false;
+    return FALSE;
 
   if (m & MMO3_LEFT)
     /* Traverse left trie. */
@@ -1388,13 +1329,13 @@ SUBSECTION
                [abfd->tdata.mmo_data->symbol_position] = 0;
 
              (*_bfd_error_handler)
-               (_("%s: unsupported wide character sequence\
- 0x%02X 0x%02X after symbol name starting with `%s'\n"),
+               (_("%s: unsupported wide character sequence"
                 " 0x%02X 0x%02X after symbol name starting with `%s'\n"),
                 bfd_get_filename (abfd), c, c2,
                 abfd->tdata.mmo_data->lop_stab_symbol);
              bfd_set_error (bfd_error_bad_value);
-             abfd->tdata.mmo_data->have_error = true;
-             return false;
+             abfd->tdata.mmo_data->have_error = TRUE;
+             return FALSE;
            }
          else
            c = c2;
@@ -1448,7 +1389,7 @@ SUBSECTION
                                      abfd->tdata.mmo_data->lop_stab_symbol
                                      + 1,
                                      addr, sym_type, serno))
-           abfd->tdata.mmo_data->have_error = true;
+           abfd->tdata.mmo_data->have_error = TRUE;
        }
 
       if (m & MMO3_MIDDLE)
@@ -1471,14 +1412,10 @@ SUBSECTION
    MMO_SEC_CONTENTS_CHUNK_SIZE.  */
 
 static INLINE bfd_byte *
-mmo_get_loc (sec, vma, size)
-     asection *sec;
-     bfd_vma vma;
-     int size;
+mmo_get_loc (asection *sec, bfd_vma vma, int size)
 {
   bfd_size_type allocated_size;
-  struct mmo_section_data_struct *sdatap
-    = (struct mmo_section_data_struct *) sec->used_by_bfd;
+  struct mmo_section_data_struct *sdatap = mmo_section_data (sec);
   struct mmo_data_list_struct *datap = sdatap->head;
   struct mmo_data_list_struct *entry;
 
@@ -1504,8 +1441,8 @@ mmo_get_loc (sec, vma, size)
             non-32-bit-aligned sections should do all allocation and
             size-setting by themselves or at least set the section size
             after the last allocating call to this function.  */
-         if (vma + size > sec->vma + sec->_raw_size)
-           sec->_raw_size += (vma + size) - (sec->vma + sec->_raw_size);
+         if (vma + size > sec->vma + sec->size)
+           sec->size += (vma + size) - (sec->vma + sec->size);
 
          return datap->data + vma - datap->where;
        }
@@ -1567,32 +1504,28 @@ mmo_get_loc (sec, vma, size)
 
   /* Update the section size.  This happens only when we add contents and
      re-size as we go.  The section size will then be aligned to 32 bits.  */
-  if (vma + size > sec->vma + sec->_raw_size)
-    sec->_raw_size += (vma + size) - (sec->vma + sec->_raw_size);
+  if (vma + size > sec->vma + sec->size)
+    sec->size += (vma + size) - (sec->vma + sec->size);
   return entry->data;
 }
 
 /* Set sizes once we've read in all sections.  */
 
 static void
-mmo_map_set_sizes (abfd, sec, ignored)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *sec;
-     PTR ignored ATTRIBUTE_UNUSED;
+mmo_map_set_sizes (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
+                  void *ignored ATTRIBUTE_UNUSED)
 {
-  sec->_cooked_size = sec->_raw_size;
   sec->lma = sec->vma;
 }
 
 /* Read the mmo file and turn it into sections.  */
 
-static boolean
-mmo_scan (abfd)
-     bfd *abfd;
+static bfd_boolean
+mmo_scan (bfd *abfd)
 {
   unsigned int i;
   unsigned int lineno = 1;
-  boolean error = false;
+  bfd_boolean error = FALSE;
   bfd_vma vma = 0;
   asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
   asection *non_spec_sec = NULL;
@@ -1836,8 +1769,8 @@ mmo_scan (abfd)
                  if (file_names[y] != NULL)
                    {
                      (*_bfd_error_handler)
-                       (_("%s: invalid mmo file: file number %d `%s',\
- was already entered as `%s'\n"),
+                       (_("%s: invalid mmo file: file number %d `%s',"
                         " was already entered as `%s'\n"),
                         bfd_get_filename (abfd), y, fname, file_names[y]);
                      bfd_set_error (bfd_error_bad_value);
                      goto error_return;
@@ -1849,8 +1782,8 @@ mmo_scan (abfd)
              if (file_names[y] == NULL)
                {
                  (*_bfd_error_handler)
-                   (_("%s: invalid mmo file: file name for number %d\
- was not specified before use\n"),
+                   (_("%s: invalid mmo file: file name for number %d"
                     " was not specified before use\n"),
                     bfd_get_filename (abfd), y);
                  bfd_set_error (bfd_error_bad_value);
                  goto error_return;
@@ -1920,6 +1853,7 @@ mmo_scan (abfd)
                    rsec
                      = bfd_make_section_old_way (abfd,
                                                  MMIX_REG_CONTENTS_SECTION_NAME);
+                   rsec->flags |= SEC_LINKER_CREATED;
                    rsec->vma = z * 8;
                    loc = mmo_get_loc (rsec, z * 8, (255 - z) * 8);
                    bfd_put_64 (abfd, first_octa, loc);
@@ -1955,8 +1889,8 @@ mmo_scan (abfd)
              if (y != 0 || z != 0)
                {
                  (*_bfd_error_handler)
-                   (_("%s: invalid mmo file: fields y and z of lop_stab\
- non-zero, y: %d, z: %d\n"),
+                   (_("%s: invalid mmo file: fields y and z of lop_stab"
                     " non-zero, y: %d, z: %d\n"),
                     bfd_get_filename (abfd), y, z);
                  bfd_set_error (bfd_error_bad_value);
                  goto error_return;
@@ -1983,7 +1917,7 @@ mmo_scan (abfd)
                /* This must be the last 32-bit word in an mmo file.
                   Let's find out.  */
                struct stat statbuf;
-               long curpos = bfd_tell (abfd);
+               file_ptr curpos = bfd_tell (abfd);
 
                if (bfd_stat (abfd, &statbuf) < 0)
                  goto error_return;
@@ -1991,8 +1925,8 @@ mmo_scan (abfd)
                if (statbuf.st_size != curpos)
                  {
                    (*_bfd_error_handler)
-                     (_("%s: invalid mmo file: lop_end not last item in\
- file\n"),
+                     (_("%s: invalid mmo file: lop_end not last item in"
                       " file\n"),
                       bfd_get_filename (abfd));
                    bfd_set_error (bfd_error_bad_value);
                    goto error_return;
@@ -2004,8 +1938,9 @@ mmo_scan (abfd)
                if ((long) (y * 256 + z) * 4 != (curpos - stab_loc) - 4)
                  {
                    (*_bfd_error_handler)
-                     (_("%s: invalid mmo file: YZ of lop_end (%ld)\
- not equal to the number of tetras to the preceding lop_stab (%ld)\n"),
+                     (_("%s: invalid mmo file: YZ of lop_end (%ld)"
+                        " not equal to the number of tetras to the preceding"
+                        " lop_stab (%ld)\n"),
                       bfd_get_filename (abfd), (long) (y * 256 + z),
                       (curpos - stab_loc - 4)/4);
                    bfd_set_error (bfd_error_bad_value);
@@ -2039,7 +1974,7 @@ mmo_scan (abfd)
     bfd_set_error (bfd_error_bad_value);
 
  error_return:
-  error = true;
+  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,
@@ -2051,7 +1986,7 @@ mmo_scan (abfd)
       && ! bfd_set_section_flags (abfd, sec,
                                  bfd_get_section_flags (abfd, sec)
                                  | SEC_ALLOC | SEC_LOAD | SEC_CODE))
-    error = true;
+    error = TRUE;
 
   sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
   if (sec != NULL
@@ -2059,7 +1994,7 @@ mmo_scan (abfd)
       && ! bfd_set_section_flags (abfd, sec,
                                  bfd_get_section_flags (abfd, sec)
                                  | SEC_ALLOC | SEC_LOAD))
-    error = true;
+    error = TRUE;
 
   /* Free whatever resources we took.  */
   for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++)
@@ -2071,34 +2006,33 @@ mmo_scan (abfd)
 /* A hook to set up object file dependent section information.  For mmo,
    we point out the shape of allocated section contents.  */
 
-static boolean
-mmo_new_section_hook (abfd, newsect)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *newsect;
+static bfd_boolean
+mmo_new_section_hook (bfd *abfd, asection *newsect)
 {
-  /* We zero-fill all fields and assume NULL is represented by an all
-     zero-bit pattern.  */
-  newsect->used_by_bfd =
-    (PTR) bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct));
-
   if (!newsect->used_by_bfd)
-    return false;
+    {
+      /* 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 true;
+  return _bfd_generic_new_section_hook (abfd, newsect);
 }
 
 /* We already have section contents loaded for sections that have
    contents.  */
 
-static boolean
-mmo_get_section_contents (abfd, sec, location, offset, bytes_to_do)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *sec ATTRIBUTE_UNUSED;
-     PTR location ATTRIBUTE_UNUSED;
-     file_ptr offset ATTRIBUTE_UNUSED;
-     bfd_size_type bytes_to_do ATTRIBUTE_UNUSED;
+static bfd_boolean
+mmo_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
+                         asection *sec,
+                         void * location,
+                         file_ptr offset,
+                         bfd_size_type bytes_to_do)
 {
   /* Iterate over diminishing chunk sizes, copying contents, like
      mmo_set_section_contents.  */
@@ -2116,7 +2050,7 @@ mmo_get_section_contents (abfd, sec, location, offset, bytes_to_do)
       while (loc == NULL && (chunk_size /= 2) != 0);
 
       if (chunk_size == 0)
-       return false;
+       return FALSE;
 
       memcpy (location, loc, chunk_size);
 
@@ -2124,14 +2058,13 @@ mmo_get_section_contents (abfd, sec, location, offset, bytes_to_do)
       bytes_to_do -= chunk_size;
       offset += chunk_size;
     }
-  return true;
+  return TRUE;
 }
 
 /* Return the amount of memory needed to read the symbol table.  */
 
 static long
-mmo_get_symtab_upper_bound (abfd)
-     bfd *abfd ATTRIBUTE_UNUSED;
+mmo_get_symtab_upper_bound (bfd *abfd)
 {
   return (abfd->symcount + 1) * sizeof (asymbol *);
 }
@@ -2139,9 +2072,7 @@ mmo_get_symtab_upper_bound (abfd)
 /* Sort mmo symbols by serial number.  */
 
 static int
-mmo_sort_mmo_symbols (arg1, arg2)
-     const PTR arg1;
-     const PTR arg2;
+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;
@@ -2159,16 +2090,14 @@ mmo_sort_mmo_symbols (arg1, arg2)
 /* Translate the symbol table.  */
 
 static long
-mmo_get_symtab (abfd, alocation)
-     bfd *abfd;
-     asymbol **alocation;
+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)
+  if (csymbols == NULL && symcount != 0)
     {
       asymbol *c;
       struct mmo_symbol *s;
@@ -2190,8 +2119,8 @@ mmo_get_symtab (abfd, alocation)
             mmo_sort_mmo_symbols);
 
       csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
-      if (csymbols == NULL && symcount != 0)
-       return false;
+      if (csymbols == NULL)
+       return -1;
       abfd->tdata.mmo_data->csymbols = csymbols;
 
       for (msp = (struct mmo_symbol **) alocation, c = csymbols;
@@ -2220,19 +2149,38 @@ mmo_get_symtab (abfd, alocation)
            {
              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->_cooked_size)
+                 && 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;
            }
@@ -2252,20 +2200,15 @@ mmo_get_symtab (abfd, alocation)
 /* Get information about a symbol.  */
 
 static void
-mmo_get_symbol_info (ignore_abfd, symbol, ret)
-     bfd *ignore_abfd ATTRIBUTE_UNUSED;
-     asymbol *symbol;
-     symbol_info *ret;
+mmo_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+                    asymbol *symbol, symbol_info *ret)
 {
   bfd_symbol_info (symbol, ret);
 }
 
 static void
-mmo_print_symbol (abfd, afile, symbol, how)
-     bfd *abfd;
-     PTR afile;
-     asymbol *symbol;
-     bfd_print_symbol_type how;
+mmo_print_symbol (bfd *abfd, void *afile, asymbol *symbol,
+                 bfd_print_symbol_type how)
 {
   FILE *file = (FILE *) afile;
 
@@ -2275,7 +2218,7 @@ mmo_print_symbol (abfd, afile, symbol, how)
       fprintf (file, "%s", symbol->name);
       break;
     default:
-      bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
+      bfd_print_symbol_vandf (abfd, file, symbol);
 
       fprintf (file, " %-5s %s",
               symbol->section->name,
@@ -2287,29 +2230,27 @@ mmo_print_symbol (abfd, afile, symbol, how)
    size of header information is irrelevant.  */
 
 static int
-mmo_sizeof_headers (abfd, exec)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     boolean exec ATTRIBUTE_UNUSED;
+mmo_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+                   struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 /* Write the (section-neutral) file preamble.  */
 
-static boolean
-mmo_internal_write_header (abfd)
-     bfd *abfd;
+static bfd_boolean
+mmo_internal_write_header (bfd *abfd)
 {
   const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};
 
   if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4)
-    return false;
+    return FALSE;
 
   /* Copy creation time of original file.  */
   if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4)
-    return false;
+    return FALSE;
 
-  return true;
+  return TRUE;
 }
 
 /* Write the LOP_POST record, with global register initializations.
@@ -2317,11 +2258,8 @@ mmo_internal_write_header (abfd)
    registers at DATA.  The Z = 255 field is filled in with the
    start-address.  */
 
-static boolean
-mmo_internal_write_post (abfd, z, sec)
-     bfd *abfd;
-     int z;
-     asection *sec;
+static bfd_boolean
+mmo_internal_write_post (bfd *abfd, int z, asection *sec)
 {
   int i;
   bfd_byte buf[8];
@@ -2332,7 +2270,7 @@ mmo_internal_write_post (abfd, z, sec)
       bfd_byte *data = mmo_get_loc (sec, i * 8, 8);
 
       if (bfd_bwrite (data, 8, abfd) != 8)
-       return false;
+       return FALSE;
     }
 
   /* For Z == $255, we always emit the start location; supposedly Main,
@@ -2347,8 +2285,7 @@ mmo_internal_write_post (abfd, z, sec)
    get bitten by BFD flag number changes.  */
 
 static flagword
-mmo_sec_flags_from_bfd_flags (flags)
-     flagword flags;
+mmo_sec_flags_from_bfd_flags (flagword flags)
 {
   flagword oflags = 0;
 
@@ -2375,8 +2312,7 @@ mmo_sec_flags_from_bfd_flags (flags)
 }
 
 static flagword
-bfd_sec_flags_from_mmo_flags (flags)
-     flagword flags;
+bfd_sec_flags_from_mmo_flags (flagword flags)
 {
   flagword oflags = 0;
 
@@ -2402,12 +2338,29 @@ bfd_sec_flags_from_mmo_flags (flags)
   return oflags;
 }
 
+/* Return TRUE iff the leading or trailing tetrabyte in SEC is defined and
+   is 0.  */
+
+static bfd_boolean
+mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec)
+{
+  bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
+
+  if (sec->size < 4)
+    return FALSE;
+
+  if (bfd_get_32 (abfd, mmo_get_loc (sec, secaddr, 4)) == 0
+      && bfd_get_32 (abfd,
+                    mmo_get_loc (sec, secaddr + sec->size - 4, 4)) == 0)
+    return TRUE;
+
+  return FALSE;
+}
+
 /* Write a section.  */
 
-static boolean
-mmo_internal_write_section (abfd, sec)
-     bfd *abfd;
-     asection *sec;
+static bfd_boolean
+mmo_internal_write_section (bfd *abfd, asection *sec)
 {
   /* We do it differently depending on what section this is:
 
@@ -2422,40 +2375,88 @@ mmo_internal_write_section (abfd, sec)
    above.  */
 
   if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0)
-    /* FIXME: Output source file name and line number.  */
-    return
-      mmo_write_loc_chunk_list (abfd,
-                               ((struct mmo_section_data_struct *)
-                                (sec->used_by_bfd))->head);
+    {
+      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
+
+      /* Because leading and trailing zeros are omitted in output, we need to
+        specify the section boundaries so they're correct when the file
+        is read in again.  That's also the case if this section is
+        specified as not within its usual boundaries or alignments.  */
+      if (sec->size != 0
+         && (secaddr + sec->size >= (bfd_vma) 1 << 56
+             || (secaddr & 3) != 0
+             || (sec->size & 3) != 0
+             || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
+       {
+         if (!mmo_write_section_description (abfd, sec))
+           return FALSE;
+       }
+
+      /* FIXME: Output source file name and line number.  */
+      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
+    }
   else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0)
-    return
-      mmo_write_loc_chunk_list (abfd,
-                               ((struct mmo_section_data_struct *)
-                                (sec->used_by_bfd))->head);
+    {
+      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
+
+      /* Same goes as for MMO_TEXT_SECTION_NAME above.  */
+      if (sec->size != 0
+         && (secaddr < (bfd_vma) 0x20 << 56
+             || secaddr + sec->size >= (bfd_vma) 0x21 << 56
+             || (secaddr & 3) != 0
+             || (sec->size & 3) != 0
+             || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
+       {
+         if (!mmo_write_section_description (abfd, sec))
+           return FALSE;
+       }
+
+      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
+    }
   else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
     /* Not handled here.  */
     {
       /* This would normally be an abort call since this can't happen, but
          we don't do that.  */
       bfd_set_error (bfd_error_bad_value);
-      return false;
+      return FALSE;
     }
-  else if (strncmp (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX,
-                   strlen (MMIX_OTHER_SPEC_SECTION_PREFIX)) == 0)
+  else if (CONST_STRNEQ (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX))
     {
       int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX));
+
       mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n);
       return (! abfd->tdata.mmo_data->have_error
-             && mmo_write_chunk_list (abfd,
-                                      ((struct mmo_section_data_struct *)
-                                       (sec->used_by_bfd))->head));
+             && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
     }
   /* Ignore sections that are just allocated or empty; we write out
      _contents_ here.  */
   else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0
-          && sec->_raw_size != 0)
+          && sec->size != 0)
     {
-      /* Keep the document-comment formatted the way it is.  */
+      if (!mmo_write_section_description (abfd, sec))
+       return FALSE;
+
+      /* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
+        loaded.  */
+      if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
+       return (! abfd->tdata.mmo_data->have_error
+               && mmo_write_loc_chunk_list (abfd,
+                                        mmo_section_data (sec)->head));
+      return (! abfd->tdata.mmo_data->have_error
+             && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
+    }
+
+  /* Some section without contents.  */
+  return TRUE;
+}
+
+/* Write the description of a section, extended-mmo-style.  */
+
+static bfd_boolean
+mmo_write_section_description (bfd *abfd, asection *sec)
+{
+  /* Keep the following document-comment formatted the way it is.  */
 /*
 INODE
 mmo section mapping, , Symbol-table, mmo
@@ -2548,46 +2549,28 @@ EXAMPLE
        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, sec->name, strlen (sec->name));
-      mmo_flush_chunk (abfd);
-      /* FIXME: We can get debug sections (.debug_line & Co.) with a
-        section flag still having SEC_RELOC set.  Investigate.  This
-        might be true for all alien sections; perhaps mmo.em should clear
-        that flag.  Might be related to weak references.  */
-      mmo_write_tetra (abfd,
-                      mmo_sec_flags_from_bfd_flags
-                      (bfd_get_section_flags (abfd, sec)));
-      mmo_write_octa (abfd, sec->_raw_size);
-      mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec));
-
-      /* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
-        loaded.  */
-      if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
-         return 
-           ! abfd->tdata.mmo_data->have_error
-           && mmo_write_loc_chunk_list (abfd,
-                                        ((struct mmo_section_data_struct *)
-                                         (sec->used_by_bfd))->head);
-      return
-       ! abfd->tdata.mmo_data->have_error
-       && mmo_write_chunk_list (abfd,
-                                ((struct mmo_section_data_struct *)
-                                 (sec->used_by_bfd))->head);
-    }
-  return true;
+  mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION);
+  mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4);
+  mmo_write_chunk (abfd, (bfd_byte *) sec->name, strlen (sec->name));
+  mmo_flush_chunk (abfd);
+  /* FIXME: We can get debug sections (.debug_line & Co.) with a section
+     flag still having SEC_RELOC set.  Investigate.  This might be true
+     for all alien sections; perhaps mmo.em should clear that flag.  Might
+     be related to weak references.  */
+  mmo_write_tetra (abfd,
+                  mmo_sec_flags_from_bfd_flags
+                  (bfd_get_section_flags (abfd, sec)));
+  mmo_write_octa (abfd, sec->size);
+  mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec));
+  return TRUE;
 }
 
 /* We save up all data before output.  */
 
-static boolean
-mmo_set_section_contents (abfd, sec, location, offset, bytes_to_do)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     sec_ptr sec;
-     PTR location;
-     file_ptr offset;
-     bfd_size_type bytes_to_do;
+static bfd_boolean
+mmo_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
+                         const void *location, file_ptr offset,
+                         bfd_size_type bytes_to_do)
 {
   /* Iterate over diminishing chunk sizes, copying contents.  */
   while (bytes_to_do)
@@ -2604,7 +2587,7 @@ mmo_set_section_contents (abfd, sec, location, offset, bytes_to_do)
       while (loc == NULL && (chunk_size /= 2) != 0);
 
       if (chunk_size == 0)
-       return false;
+       return FALSE;
 
       memcpy (loc, location, chunk_size);
 
@@ -2612,16 +2595,14 @@ mmo_set_section_contents (abfd, sec, location, offset, bytes_to_do)
       bytes_to_do -= chunk_size;
       offset += chunk_size;
     }
-  return true;
+  return TRUE;
 }
 
 /* Add a symbol to a trie-tree.  */
 
-static boolean
-mmo_internal_add_3_sym (abfd, rootp, symp)
-     bfd *abfd;
-     struct mmo_symbol_trie *rootp;
-     const struct mmo_symbol *symp;
+static bfd_boolean
+mmo_internal_add_3_sym (bfd *abfd, struct mmo_symbol_trie *rootp,
+                       const struct mmo_symbol *symp)
 {
   const char *name = symp->name;
   struct mmo_symbol_trie *trie = rootp;
@@ -2670,19 +2651,17 @@ mmo_internal_add_3_sym (abfd, rootp, symp)
        (_("%s: invalid symbol table: duplicate symbol `%s'\n"),
         bfd_get_filename (abfd), trie->sym.name);
       bfd_set_error (bfd_error_bad_value);
-      return false;
+      return FALSE;
     }
 
   memcpy (&trie->sym, symp, sizeof *symp);
-  return true;
+  return TRUE;
 }
 
 /* Find out the length of the serialized version of a trie in bytes.  */
 
 static unsigned int
-mmo_internal_3_length (abfd, trie)
-     bfd *abfd;
-     struct mmo_symbol_trie *trie;
+mmo_internal_3_length (bfd *abfd, struct mmo_symbol_trie *trie)
 {
   /* First, one for the control byte.  */
   unsigned int length = 1;
@@ -2742,10 +2721,7 @@ mmo_internal_3_length (abfd, trie)
    beb128.  Using a helper function and recursion simplifies debugging.  */
 
 static void
-mmo_beb128_out (abfd, serno, marker)
-     bfd *abfd;
-     int serno;
-     int marker;
+mmo_beb128_out (bfd *abfd, int serno, int marker)
 {
   if (serno & ~0x7f)
     mmo_beb128_out (abfd, serno >> 7, 0);
@@ -2755,9 +2731,7 @@ mmo_beb128_out (abfd, serno, marker)
 /* Serialize a trie.  */
 
 static void
-mmo_internal_3_dump (abfd, trie)
-     bfd *abfd;
-     struct mmo_symbol_trie *trie;
+mmo_internal_3_dump (bfd *abfd, struct mmo_symbol_trie *trie)
 {
   bfd_byte control = 0;
 
@@ -2849,9 +2823,8 @@ mmo_internal_3_dump (abfd, trie)
 
 /* Write symbols in mmo format.  Also write the lop_end terminator.  */
 
-static boolean
-mmo_write_symbols_and_terminator (abfd)
-     bfd *abfd;
+static bfd_boolean
+mmo_write_symbols_and_terminator (bfd *abfd)
 {
   int count = bfd_get_symcount (abfd);
   asymbol *maintable[2];
@@ -2882,7 +2855,7 @@ mmo_write_symbols_and_terminator (abfd)
      symbols.  Make sure we have room for it.  */
   table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *));
   if (table == NULL)
-    return false;
+    return FALSE;
 
   memcpy (table, orig_table, count * sizeof (asymbol *));
 
@@ -2918,11 +2891,11 @@ mmo_write_symbols_and_terminator (abfd)
            sprintf_vma (vmas_start, vma_start);
 
            (*_bfd_error_handler)
-             (_("%s: Bad symbol definition: `Main' set to %s rather\
- than the start address %s\n"),
+             (_("%s: Bad symbol definition: `Main' set to %s rather"
               " than the start address %s\n"),
               bfd_get_filename (abfd), vmas_main, vmas_start);
            bfd_set_error (bfd_error_bad_value);
-           return false;
+           return FALSE;
          }
        break;
       }
@@ -2951,7 +2924,9 @@ mmo_write_symbols_and_terminator (abfd)
          struct mmo_symbol sym;
          memset (&sym, 0, sizeof (sym));
 
-         sym.name = s->name;
+         /* 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
@@ -2985,7 +2960,7 @@ mmo_write_symbols_and_terminator (abfd)
          sym.serno = serno++;
 
          if (! mmo_internal_add_3_sym (abfd, &root, &sym))
-           return false;
+           return FALSE;
        }
     }
 
@@ -3008,8 +2983,8 @@ mmo_write_symbols_and_terminator (abfd)
       struct mmo_symbol sym;
 
       (*_bfd_error_handler)
-       (_("%s: warning: symbol table too large for mmo, larger than 65535\
- 32-bit words: %d.  Only `Main' will be emitted.\n"),
+       (_("%s: warning: symbol table too large for mmo, larger than 65535"
         " 32-bit words: %d.  Only `Main' will be emitted.\n"),
         bfd_get_filename (abfd), trie_len);
 
       memset (&sym, 0, sizeof (sym));
@@ -3026,7 +3001,7 @@ mmo_write_symbols_and_terminator (abfd)
       root.right = NULL;
 
       if (! mmo_internal_add_3_sym (abfd, &root, &sym))
-       return false;
+       return FALSE;
 
       root.symchar = ':';
       root.middle = root.left;
@@ -3042,7 +3017,7 @@ mmo_write_symbols_and_terminator (abfd)
   /* Put out the lop_stab mark.  */
   bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf);
   if (bfd_bwrite (buf, 4, abfd) != 4)
-    return false;
+    return FALSE;
 
   /* Dump out symbols.  */
   mmo_internal_3_dump (abfd, &root);
@@ -3053,12 +3028,12 @@ mmo_write_symbols_and_terminator (abfd)
         isn't debugged and abort if we get here.  Instead emit a
         diagnostic and fail "normally".  */
       (*_bfd_error_handler)
-       (_("%s: internal error, symbol table changed size from %d to %d\
- words\n"),
+       (_("%s: internal error, symbol table changed size from %d to %d"
         " words\n"),
         bfd_get_filename (abfd), trie_len,
         (abfd->tdata.mmo_data->byte_no + 3)/4);
       bfd_set_error (bfd_error_bad_value);
-      return false;
+      return FALSE;
     }
 
   /* Dump out remaining bytes in the buffer and handle I/O errors by
@@ -3071,7 +3046,7 @@ mmo_write_symbols_and_terminator (abfd)
 
       if (abfd->tdata.mmo_data->have_error
          || bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
-       return false;
+       return FALSE;
     }
 
   bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf);
@@ -3083,10 +3058,7 @@ mmo_write_symbols_and_terminator (abfd)
    used through bfd_map_over_sections.  */
 
 static void
-mmo_write_section_unless_reg_contents (abfd, sec, p)
-     bfd *abfd;
-     asection *sec;
-     PTR p;
+mmo_write_section_unless_reg_contents (bfd *abfd, asection *sec, void *p)
 {
   struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p;
 
@@ -3108,11 +3080,11 @@ mmo_write_section_unless_reg_contents (abfd, sec, p)
             make it carry contents, so we don't have a test-case for
             this.  */
          (*_bfd_error_handler)
-           (_("%s: internal error, internal register section %s had\
- contents\n"),
+           (_("%s: internal error, internal register section %s had"
             " contents\n"),
             bfd_get_filename (abfd), sec->name);
          bfd_set_error (bfd_error_bad_value);
-         infop->retval = false;
+         infop->retval = FALSE;
          return;
        }
 
@@ -3125,24 +3097,23 @@ mmo_write_section_unless_reg_contents (abfd, sec, p)
 /* Do the actual output of a file.  Assumes mmo_set_section_contents is
    already called. */
 
-static boolean
-mmo_write_object_contents (abfd)
-     bfd *abfd;
+static bfd_boolean
+mmo_write_object_contents (bfd *abfd)
 {
   struct mmo_write_sec_info wsecinfo;
 
   /* First, there are a few words of preamble.  */
   if (! mmo_internal_write_header (abfd))
-    return false;
+    return FALSE;
 
   wsecinfo.reg_section = NULL;
-  wsecinfo.retval = true;
+  wsecinfo.retval = TRUE;
 
   bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents,
-                        (PTR) &wsecinfo);
+                        &wsecinfo);
 
   if (! wsecinfo.retval)
-    return false;
+    return FALSE;
 
   if (wsecinfo.reg_section != NULL)
     {
@@ -3153,11 +3124,11 @@ mmo_write_object_contents (abfd)
         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->_raw_size - 8)
+         || sec->vma != 256 * 8 - sec->size - 8)
        {
          bfd_set_error (bfd_error_bad_value);
 
-         if (sec->_raw_size == 0)
+         if (sec->size == 0)
            /* There must always be at least one such register.  */
            (*_bfd_error_handler)
              (_("%s: no initialized registers; section length 0\n"),
@@ -3168,53 +3139,28 @@ mmo_write_object_contents (abfd)
            (*_bfd_error_handler)
              (_("%s: too many initialized registers; section length %ld\n"),
               bfd_get_filename (abfd),
-              (long) sec->_raw_size);
+              (long) sec->size);
          else
            (*_bfd_error_handler)
-             (_("%s: invalid start address for initialized registers of\
- length %ld: 0x%lx%08lx\n"),
+             (_("%s: invalid start address for initialized registers of"
               " length %ld: 0x%lx%08lx\n"),
               bfd_get_filename (abfd),
-              (long) sec->_raw_size,
+              (long) sec->size,
               (unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma));
 
-         return false;
+         return FALSE;
        }
 
       if (! mmo_internal_write_post (abfd, z, sec))
-       return false;
+       return FALSE;
     }
   else
     if (! mmo_internal_write_post (abfd, 255, NULL))
-      return false;
+      return FALSE;
 
   return mmo_write_symbols_and_terminator (abfd);
 }
 
-/* Return the size of a NULL pointer, so we support linking in an mmo
-   object.  */
-
-static long
-mmo_get_reloc_upper_bound (abfd, sec)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *sec ATTRIBUTE_UNUSED;
-{
-  return sizeof (PTR);
-}
-
-/* Similarly canonicalize relocs to empty, filling in the terminating NULL
-   pointer.  */
-
-long
-mmo_canonicalize_reloc (abfd, section, relptr, symbols)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     sec_ptr section ATTRIBUTE_UNUSED;
-     arelent **relptr;
-     asymbol **symbols ATTRIBUTE_UNUSED;
-{
-  *relptr = NULL;
-  return 0;
-}
-
 /* 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
@@ -3229,6 +3175,8 @@ mmo_canonicalize_reloc (abfd, section, relptr, symbols)
 /* Perhaps we need to adjust this one; mmo labels (originally) without a
    leading ':' might more appropriately be called local.  */
 #define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define mmo_bfd_is_target_special_symbol  \
+  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
 
 /* Is this one really used or defined by anyone?  */
 #define mmo_get_lineno _bfd_nosymbols_get_lineno
@@ -3236,6 +3184,7 @@ mmo_canonicalize_reloc (abfd, section, relptr, symbols)
 /* 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_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
@@ -3250,6 +3199,8 @@ mmo_canonicalize_reloc (abfd, section, relptr, symbols)
 #define mmo_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
 #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
 
@@ -3258,25 +3209,18 @@ mmo_canonicalize_reloc (abfd, section, relptr, symbols)
 #define mmo_set_arch_mach bfd_default_set_arch_mach
 #define mmo_bfd_relax_section bfd_generic_relax_section
 #define mmo_bfd_merge_sections bfd_generic_merge_sections
+#define mmo_bfd_is_group_section bfd_generic_is_group_section
 #define mmo_bfd_discard_group bfd_generic_discard_group
-
-/* objcopy will be upset if we return -1 from bfd_get_reloc_upper_bound by
-   using BFD_JUMP_TABLE_RELOCS (_bfd_norelocs) rather than 0.  FIXME: Most
-   likely a bug in the _bfd_norelocs definition.
-
-   On the other hand, we smuggle in an mmo object (because setting up ELF
-   is too cumbersome) when linking (from other formats, presumably ELF) to
-   represent the g255 entry.  We need to link that object, so need to say
-   it has no relocs.  Upper bound for the size of the relocation table is
-   the size of a NULL pointer, and we support "canonicalization" for that
-   pointer.  */
-#define mmo_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+#define mmo_section_already_linked \
+  _bfd_generic_section_already_linked
+#define mmo_bfd_define_common_symbol bfd_generic_define_common_symbol
 
 /* We want to copy time of creation, otherwise we'd use
    BFD_JUMP_TABLE_COPY (_bfd_generic).  */
 #define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
 #define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
 #define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#define mmo_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
 #define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
 #define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
 
@@ -3330,9 +3274,7 @@ const bfd_target bfd_mmo_vec =
   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
   BFD_JUMP_TABLE_SYMBOLS (mmo),
-  /* We have to provide a valid method for getting relocs, returning zero,
-     so we can't say BFD_JUMP_TABLE_RELOCS (_bfd_norelocs).  */
-  BFD_JUMP_TABLE_RELOCS (mmo),
+  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
   BFD_JUMP_TABLE_WRITE (mmo),
   BFD_JUMP_TABLE_LINK (mmo),
   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),