* elf32-sparc.c (bfd_elf32_new_section_hook): Define.
[binutils-gdb.git] / bfd / elf64-mmix.c
index 3bda435c987cc9727fc94752bfaf1a6531d9c924..a7b28065f75edfcf3108788f88859a59e0a570f2 100644 (file)
@@ -1,5 +1,5 @@
 /* MMIX-specific support for 64-bit ELF.
-   Copyright 2001, 2002 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Hans-Peter Nilsson <hp@bitrange.com>
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -41,8 +41,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  _bfd_abort (__FILE__, __LINE__,               \
             "bad case for " #x)
 
+struct _mmix_elf_section_data
+{
+  struct bfd_elf_section_data elf;
+  union
+  {
+    struct bpo_reloc_section_info *reloc;
+    struct bpo_greg_section_info *greg;
+  } bpo;
+};
+
+#define mmix_elf_section_data(sec) \
+  ((struct _mmix_elf_section_data *) (sec)->used_by_bfd)
+
 /* For each section containing a base-plus-offset (BPO) reloc, we attach
-   this struct as elf_section_data (section)->tdata, which is otherwise
+   this struct as mmix_elf_section_data (section)->bpo, which is otherwise
    NULL.  */
 struct bpo_reloc_section_info
   {
@@ -78,12 +91,12 @@ struct bpo_reloc_request
     size_t bpo_reloc_no;
 
     /* Set when the value is computed.  Better than coding "guard values"
-       into the other members.  Is false only for BPO relocs in a GC:ed
+       into the other members.  Is FALSE only for BPO relocs in a GC:ed
        section.  */
-    boolean valid;
+    bfd_boolean valid;
   };
 
-/* We attach this as elf_section_data (sec)->tdata in the linker-allocated
+/* We attach this as mmix_elf_section_data (sec)->bpo in the linker-allocated
    greg contents section (MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME),
    which is linked into the register contents section
    (MMIX_REG_CONTENTS_SECTION_NAME).  This section is created by the
@@ -120,7 +133,7 @@ struct bpo_greg_section_info
     struct bpo_reloc_request *reloc_request;
   };
 
-static boolean mmix_elf_link_output_symbol_hook
+static bfd_boolean mmix_elf_link_output_symbol_hook
   PARAMS ((bfd *, struct bfd_link_info *, const char *,
           Elf_Internal_Sym *, asection *));
 
@@ -131,27 +144,30 @@ static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
 
 static void mmix_info_to_howto_rela
-  PARAMS ((bfd *, arelent *, Elf64_Internal_Rela *));
+  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
 
 static int mmix_elf_sort_relocs PARAMS ((const PTR, const PTR));
 
-static boolean mmix_elf_check_relocs
+static bfd_boolean mmix_elf_new_section_hook
+  PARAMS ((bfd *, asection *));
+
+static bfd_boolean mmix_elf_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
           const Elf_Internal_Rela *));
 
-static boolean mmix_elf_check_common_relocs
+static bfd_boolean mmix_elf_check_common_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
           const Elf_Internal_Rela *));
 
-static boolean mmix_elf_relocate_section
+static bfd_boolean mmix_elf_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
 
 static asection * mmix_elf_gc_mark_hook
-  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
           struct elf_link_hash_entry *, Elf_Internal_Sym *));
 
-static boolean mmix_elf_gc_sweep_hook
+static bfd_boolean mmix_elf_gc_sweep_hook
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
           const Elf_Internal_Rela *));
 
@@ -162,23 +178,23 @@ static bfd_reloc_status_type mmix_final_link_relocate
 static bfd_reloc_status_type mmix_elf_perform_relocation
   PARAMS ((asection *, reloc_howto_type *, PTR, bfd_vma, bfd_vma));
 
-static boolean mmix_elf_section_from_bfd_section
+static bfd_boolean mmix_elf_section_from_bfd_section
   PARAMS ((bfd *, asection *, int *));
 
-static boolean mmix_elf_add_symbol_hook
+static bfd_boolean mmix_elf_add_symbol_hook
   PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
           const char **, flagword *, asection **, bfd_vma *));
 
-static boolean mmix_elf_is_local_label_name
+static bfd_boolean mmix_elf_is_local_label_name
   PARAMS ((bfd *, const char *));
 
 static int bpo_reloc_request_sort_fn PARAMS ((const PTR, const PTR));
 
-static boolean mmix_elf_relax_section
+static bfd_boolean mmix_elf_relax_section
   PARAMS ((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
-          boolean *again));
+          bfd_boolean *again));
 
-extern boolean mmix_elf_final_link PARAMS ((bfd *, struct bfd_link_info *));
+extern bfd_boolean mmix_elf_final_link PARAMS ((bfd *, struct bfd_link_info *));
 
 extern void mmix_elf_symbol_processing PARAMS ((bfd *, asymbol *));
 
@@ -195,195 +211,195 @@ static reloc_howto_type elf_mmix_howto_table[] =
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_NONE",         /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* An 8 bit absolute relocation.  */
   HOWTO (R_MMIX_8,             /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_8",            /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xff,                  /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* An 16 bit absolute relocation.  */
   HOWTO (R_MMIX_16,            /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_16",           /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffff,                /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* An 24 bit absolute relocation.  */
   HOWTO (R_MMIX_24,            /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_24",           /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0xffffff,             /* src_mask */
         0xffffff,              /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* A 32 bit absolute relocation.  */
   HOWTO (R_MMIX_32,            /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_32",           /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* 64 bit relocation.  */
   HOWTO (R_MMIX_64,            /* type */
         0,                     /* rightshift */
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
         64,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_64",           /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         MINUS_ONE,             /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* An 8 bit PC-relative relocation.  */
   HOWTO (R_MMIX_PC_8,          /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_PC_8",         /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xff,                  /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* An 16 bit PC-relative relocation.  */
   HOWTO (R_MMIX_PC_16,         /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_PC_16",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffff,                /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* An 24 bit PC-relative relocation.  */
   HOWTO (R_MMIX_PC_24,         /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_PC_24",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0xffffff,             /* src_mask */
         0xffffff,              /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* A 32 bit absolute PC-relative relocation.  */
   HOWTO (R_MMIX_PC_32,         /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_PC_32",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* 64 bit PC-relative relocation.  */
   HOWTO (R_MMIX_PC_64,         /* type */
         0,                     /* rightshift */
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
         64,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MMIX_PC_64",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         MINUS_ONE,             /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* GNU extension to record C++ vtable hierarchy.  */
   HOWTO (R_MMIX_GNU_VTINHERIT, /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         NULL,                  /* special_function */
         "R_MMIX_GNU_VTINHERIT", /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* GNU extension to record C++ vtable member usage.  */
   HOWTO (R_MMIX_GNU_VTENTRY,   /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
         "R_MMIX_GNU_VTENTRY", /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* The GETA relocation is supposed to get any address that could
      possibly be reached by the GETA instruction.  It can silently expand
@@ -393,57 +409,57 @@ static reloc_howto_type elf_mmix_howto_table[] =
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_GETA",         /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_GETA_1,                /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_GETA_1",               /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_GETA_2,                /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_GETA_2",               /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_GETA_3,                /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_GETA_3",               /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* The conditional branches are supposed to reach any (code) address.
      It can silently expand to a 64-bit operand, but will emit an error if
@@ -453,71 +469,71 @@ static reloc_howto_type elf_mmix_howto_table[] =
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_CBRANCH",      /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_CBRANCH_J,     /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_CBRANCH_J",    /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_CBRANCH_1,     /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_CBRANCH_1",    /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_CBRANCH_2,     /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_CBRANCH_2",    /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_CBRANCH_3,     /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_CBRANCH_3",    /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* The PUSHJ instruction can reach any (code) address, as long as it's
      the beginning of a function (no usable restriction).  It can silently
@@ -528,57 +544,57 @@ static reloc_howto_type elf_mmix_howto_table[] =
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_PUSHJ",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_PUSHJ_1,       /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_PUSHJ_1",      /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_PUSHJ_2,       /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_PUSHJ_2",      /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_PUSHJ_3,       /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_PUSHJ_3",      /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* A JMP is supposed to reach any (code) address.  By itself, it can
      reach +-64M; the expansion can reach all 64 bits.  Note that the 64M
@@ -588,57 +604,57 @@ static reloc_howto_type elf_mmix_howto_table[] =
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         27,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_JMP",          /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x1ffffff,            /* src_mask */
         0x1ffffff,             /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_JMP_1,         /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         27,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_JMP_1",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x1ffffff,            /* src_mask */
         0x1ffffff,             /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_JMP_2,         /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         27,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_JMP_2",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x1ffffff,            /* src_mask */
         0x1ffffff,             /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   HOWTO (R_MMIX_JMP_3,         /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         27,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_JMP_3",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x1ffffff,            /* src_mask */
         0x1ffffff,             /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* When we don't emit link-time-relaxable code from the assembler, or
      when relaxation has done all it can do, these relocs are used.  For
@@ -647,30 +663,30 @@ static reloc_howto_type elf_mmix_howto_table[] =
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_ADDR19",       /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x0100ffff,           /* src_mask */
         0x0100ffff,            /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* For JMP.  */
   HOWTO (R_MMIX_ADDR27,                /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         27,                    /* bitsize */
-        true,                  /* pc_relative */
+        TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_ADDR27",       /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         ~0x1ffffff,            /* src_mask */
         0x1ffffff,             /* dst_mask */
-        true),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* A general register or the value 0..255.  If a value, then the
      instruction (offset -3) needs adjusting.  */
@@ -678,30 +694,30 @@ static reloc_howto_type elf_mmix_howto_table[] =
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_REG_OR_BYTE",  /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xff,                  /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* A general register.  */
   HOWTO (R_MMIX_REG,           /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_REG",          /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xff,                  /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* A register plus an index, corresponding to the relocation expression.
      The sizes must correspond to the valid range of the expression, while
@@ -710,15 +726,15 @@ static reloc_howto_type elf_mmix_howto_table[] =
         0,                     /* rightshift */
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
         64,                    /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_BASE_PLUS_OFFSET", /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffff,                /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* A "magic" relocation for a LOCAL expression, asserting that the
      expression is less than the number of global registers.  No actual
@@ -729,15 +745,15 @@ static reloc_howto_type elf_mmix_howto_table[] =
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        false,                 /* pc_relative */
+        FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         mmix_elf_reloc,        /* special_function */
         "R_MMIX_LOCAL",        /* name */
-        false,                 /* partial_inplace */
+        FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        false),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
  };
 
 
@@ -795,6 +811,22 @@ bfd_elf64_bfd_reloc_type_lookup (abfd, code)
   return NULL;
 }
 
+static bfd_boolean
+mmix_elf_new_section_hook (abfd, sec)
+     bfd *abfd;
+     asection *sec;
+{
+  struct _mmix_elf_section_data *sdata;
+  bfd_size_type amt = sizeof (*sdata);
+
+  sdata = (struct _mmix_elf_section_data *) bfd_zalloc (abfd, amt);
+  if (sdata == NULL)
+    return FALSE;
+  sec->used_by_bfd = (PTR) sdata;
+
+  return _bfd_elf_new_section_hook (abfd, sec);
+}
+
 
 /* This function performs the actual bitfiddling and sanity check for a
    final relocation.  Each relocation gets its *worst*-case expansion
@@ -943,7 +975,7 @@ mmix_elf_perform_relocation (isec, howto, datap, addr, value)
          value += addr;
          break;
        }
-      /* FALLTHROUGH. */
+      /* FALLTHROUGH.  */
     case R_MMIX_ADDR19:
     case R_MMIX_ADDR27:
       /* These must be in range, or else we emit an error.  */
@@ -983,13 +1015,11 @@ mmix_elf_perform_relocation (isec, howto, datap, addr, value)
     case R_MMIX_BASE_PLUS_OFFSET:
       {
        struct bpo_reloc_section_info *bpodata
-         = (struct bpo_reloc_section_info *)
-         elf_section_data (isec)->tdata;
+         = mmix_elf_section_data (isec)->bpo.reloc;
        asection *bpo_greg_section
          = bpodata->bpo_greg_section;
        struct bpo_greg_section_info *gregdata
-         = (struct bpo_greg_section_info *)
-         elf_section_data (bpo_greg_section)->tdata;
+         = mmix_elf_section_data (bpo_greg_section)->bpo.greg;
        size_t bpo_index
          = gregdata->bpo_reloc_indexes[bpodata->bpo_index++];
 
@@ -1063,7 +1093,7 @@ static void
 mmix_info_to_howto_rela (abfd, cache_ptr, dst)
      bfd *abfd ATTRIBUTE_UNUSED;
      arelent *cache_ptr;
-     Elf64_Internal_Rela *dst;
+     Elf_Internal_Rela *dst;
 {
   unsigned int r_type;
 
@@ -1157,7 +1187,7 @@ mmix_elf_reloc (abfd, reloc_entry, symbol, data, input_section,
 /* Relocate an MMIX ELF section.  Modified from elf32-fr30.c; look to it
    for guidance if you're thinking of copying this.  */
 
-static boolean
+static bfd_boolean
 mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                           contents, relocs, local_syms, local_sections)
      bfd *output_bfd ATTRIBUTE_UNUSED;
@@ -1189,7 +1219,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       bfd_reloc_status_type r;
       const char *name = NULL;
       int r_type;
-      boolean undefined_signalled = false;
+      bfd_boolean undefined_signalled = FALSE;
 
       r_type = ELF64_R_TYPE (rel->r_info);
 
@@ -1265,9 +1295,9 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              if (! undefined_signalled
                  && ! ((*info->callbacks->undefined_symbol)
                        (info, h->root.root.string, input_bfd,
-                        input_section, rel->r_offset, true)))
-               return false;
-             undefined_signalled = true;
+                        input_section, rel->r_offset, TRUE)))
+               return FALSE;
+             undefined_signalled = TRUE;
              relocation = 0;
            }
        }
@@ -1278,7 +1308,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
       if (r != bfd_reloc_ok)
        {
-         boolean check_ok = true;
+         bfd_boolean check_ok = TRUE;
          const char * msg = (const char *) NULL;
 
          switch (r)
@@ -1294,8 +1324,8 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              if (! undefined_signalled)
                check_ok = info->callbacks->undefined_symbol
                  (info, name, input_bfd, input_section, rel->r_offset,
-                  true);
-             undefined_signalled = true;
+                  TRUE);
+             undefined_signalled = TRUE;
              break;
 
            case bfd_reloc_outofrange:
@@ -1320,11 +1350,11 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              (info, msg, name, input_bfd, input_section, rel->r_offset);
 
          if (! check_ok)
-           return false;
+           return FALSE;
        }
     }
 
-  return true;
+  return TRUE;
 }
 \f
 /* Perform a single relocation.  By default we use the standard BFD
@@ -1524,8 +1554,8 @@ mmix_final_link_relocate (howto, input_section, contents,
    relocation.  */
 
 static asection *
-mmix_elf_gc_mark_hook (abfd, info, rel, h, sym)
-     bfd *abfd;
+mmix_elf_gc_mark_hook (sec, info, rel, h, sym)
+     asection *sec;
      struct bfd_link_info *info ATTRIBUTE_UNUSED;
      Elf_Internal_Rela *rel;
      struct elf_link_hash_entry *h;
@@ -1555,9 +1585,7 @@ mmix_elf_gc_mark_hook (abfd, info, rel, h, sym)
        }
     }
   else
-    {
-      return bfd_section_from_elf_index (abfd, sym->st_shndx);
-    }
+    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
 
   return NULL;
 }
@@ -1567,7 +1595,7 @@ mmix_elf_gc_mark_hook (abfd, info, rel, h, sym)
    GC (or section merge) and the point when all input sections must be
    present.  Better to waste some memory and (perhaps) a little time.  */
 
-static boolean
+static bfd_boolean
 mmix_elf_gc_sweep_hook (abfd, info, sec, relocs)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info ATTRIBUTE_UNUSED;
@@ -1575,22 +1603,19 @@ mmix_elf_gc_sweep_hook (abfd, info, sec, relocs)
      const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
 {
   struct bpo_reloc_section_info *bpodata
-    = (struct bpo_reloc_section_info *)
-    elf_section_data (sec)->tdata;
+    = mmix_elf_section_data (sec)->bpo.reloc;
   asection *allocated_gregs_section;
 
   /* If no bpodata here, we have nothing to do.  */
   if (bpodata == NULL)
-    return true;
+    return TRUE;
 
   allocated_gregs_section = bpodata->bpo_greg_section;
 
-  ((struct bpo_greg_section_info *)
-   elf_section_data (allocated_gregs_section)->tdata)
-    ->n_bpo_relocs
+  mmix_elf_section_data (allocated_gregs_section)->bpo.greg->n_bpo_relocs
     -= bpodata->n_bpo_relocs_this_section;
 
-  return true;
+  return TRUE;
 }
 \f
 /* Sort register relocs to come before expanding relocs.  */
@@ -1630,7 +1655,7 @@ mmix_elf_sort_relocs (p1, p2)
 
 /* Subset of mmix_elf_check_relocs, common to ELF and mmo linking.  */
 
-static boolean
+static bfd_boolean
 mmix_elf_check_common_relocs  (abfd, info, sec, relocs)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -1645,7 +1670,7 @@ mmix_elf_check_common_relocs  (abfd, info, sec, relocs)
   const Elf_Internal_Rela *rel_end;
 
   if (info->relocateable)
-    return true;
+    return TRUE;
 
   /* We currently have to abuse this COFF-specific member, since there's
      no target-machine-dedicated member.  There's no alternative outside
@@ -1694,16 +1719,18 @@ mmix_elf_check_common_relocs  (abfd, info, sec, relocs)
                  || !bfd_set_section_alignment (bpo_greg_owner,
                                                 allocated_gregs_section,
                                                 3))
-               return false;
+               return FALSE;
 
              gregdata = (struct bpo_greg_section_info *)
                bfd_zalloc (bpo_greg_owner, sizeof (struct bpo_greg_section_info));
              if (gregdata == NULL)
-               return false;
-             elf_section_data (allocated_gregs_section)->tdata = gregdata;
+               return FALSE;
+             mmix_elf_section_data (allocated_gregs_section)->bpo.greg
+               = gregdata;
            }
          else if (gregdata == NULL)
-           gregdata = elf_section_data (allocated_gregs_section)->tdata;
+           gregdata
+             = mmix_elf_section_data (allocated_gregs_section)->bpo.greg;
 
          /* Get ourselves some auxiliary info for the BPO-relocs.  */
          if (bpodata == NULL)
@@ -1715,8 +1742,8 @@ mmix_elf_check_common_relocs  (abfd, info, sec, relocs)
                           sizeof (struct bpo_reloc_section_info)
                           * (sec->reloc_count + 1));
              if (bpodata == NULL)
-               return false;
-             elf_section_data (sec)->tdata = bpodata;
+               return FALSE;
+             mmix_elf_section_data (sec)->bpo.reloc = bpodata;
              bpodata->first_base_plus_offset_reloc
                = bpodata->bpo_index
                = gregdata->n_max_bpo_relocs;
@@ -1736,12 +1763,12 @@ mmix_elf_check_common_relocs  (abfd, info, sec, relocs)
        }
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Look through the relocs for a section during the first phase.  */
 
-static boolean
+static bfd_boolean
 mmix_elf_check_relocs (abfd, info, sec, relocs)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -1754,7 +1781,7 @@ mmix_elf_check_relocs (abfd, info, sec, relocs)
   const Elf_Internal_Rela *rel_end;
 
   if (info->relocateable)
-    return true;
+    return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
@@ -1769,7 +1796,7 @@ mmix_elf_check_relocs (abfd, info, sec, relocs)
 
   /* Do the common part.  */
   if (!mmix_elf_check_common_relocs (abfd, info, sec, relocs))
-    return false;
+    return FALSE;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -1789,25 +1816,25 @@ mmix_elf_check_relocs (abfd, info, sec, relocs)
            Reconstruct it for later use during GC.  */
         case R_MMIX_GNU_VTINHERIT:
           if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-            return false;
+            return FALSE;
           break;
 
         /* This relocation describes which C++ vtable entries are actually
            used.  Record for later use during GC.  */
         case R_MMIX_GNU_VTENTRY:
           if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))
-            return false;
+            return FALSE;
           break;
        }
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Wrapper for mmix_elf_check_common_relocs, called when linking to mmo.
    Copied from elf_link_add_object_symbols.  */
 
-boolean
+bfd_boolean
 _bfd_mmix_check_all_relocs (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -1817,7 +1844,7 @@ _bfd_mmix_check_all_relocs (abfd, info)
   for (o = abfd->sections; o != NULL; o = o->next)
     {
       Elf_Internal_Rela *internal_relocs;
-      boolean ok;
+      bfd_boolean ok;
 
       if ((o->flags & SEC_RELOC) == 0
          || o->reloc_count == 0
@@ -1831,7 +1858,7 @@ _bfd_mmix_check_all_relocs (abfd, info)
                                       (Elf_Internal_Rela *) NULL,
                                       info->keep_memory);
       if (internal_relocs == NULL)
-       return false;
+       return FALSE;
 
       ok = mmix_elf_check_common_relocs (abfd, info, o, internal_relocs);
 
@@ -1839,17 +1866,17 @@ _bfd_mmix_check_all_relocs (abfd, info)
        free (internal_relocs);
 
       if (! ok)
-       return false;
+       return FALSE;
     }
 
-  return true;
+  return TRUE;
 }
 \f
 /* Change symbols relative to the reg contents section to instead be to
    the register section, and scale them down to correspond to the register
    number.  */
 
-static boolean
+static bfd_boolean
 mmix_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info ATTRIBUTE_UNUSED;
@@ -1866,7 +1893,7 @@ mmix_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
       sym->st_shndx = SHN_REGISTER;
     }
 
-  return true;
+  return TRUE;
 }
 
 /* We fake a register section that holds values that are register numbers.
@@ -1915,7 +1942,7 @@ mmix_elf_symbol_processing (abfd, asym)
 /* Given a BFD section, try to locate the corresponding ELF section
    index.  */
 
-static boolean
+static bfd_boolean
 mmix_elf_section_from_bfd_section (abfd, sec, retval)
      bfd *                 abfd ATTRIBUTE_UNUSED;
      asection *            sec;
@@ -1924,9 +1951,9 @@ mmix_elf_section_from_bfd_section (abfd, sec, retval)
   if (strcmp (bfd_get_section_name (abfd, sec), MMIX_REG_SECTION_NAME) == 0)
     *retval = SHN_REGISTER;
   else
-    return false;
+    return FALSE;
 
-  return true;
+  return TRUE;
 }
 
 /* Hook called by the linker routine which adds symbols from an object
@@ -1936,7 +1963,7 @@ mmix_elf_section_from_bfd_section (abfd, sec, retval)
    symbols, since otherwise having two with the same value would cause
    them to be "merged", but with the contents serialized.  */
 
-boolean
+bfd_boolean
 mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
      bfd *abfd;
      struct bfd_link_info *info ATTRIBUTE_UNUSED;
@@ -1953,31 +1980,31 @@ mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
                       strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)) == 0)
     {
       /* See if we have another one.  */
-      struct elf_link_hash_entry *h
-       = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash,
-                                                              *namep,
-                                                              false,
-                                                              false, false);
+      struct bfd_link_hash_entry *h = bfd_link_hash_lookup (info->hash,
+                                                           *namep,
+                                                           FALSE,
+                                                           FALSE,
+                                                           FALSE);
 
-      if (h != NULL && h->root.type != bfd_link_hash_undefined)
+      if (h != NULL && h->type != bfd_link_hash_undefined)
        {
          /* How do we get the asymbol (or really: the filename) from h?
-            h->root.u.def.section->owner is NULL.  */
+            h->u.def.section->owner is NULL.  */
          ((*_bfd_error_handler)
           (_("%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"),
            bfd_get_filename (abfd), *namep,
            *namep + strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)));
           bfd_set_error (bfd_error_bad_value);
-          return false;
+          return FALSE;
        }
     }
 
-  return true;
+  return TRUE;
 }
 
 /* We consider symbols matching "L.*:[0-9]+" to be local symbols.  */
 
-boolean
+bfd_boolean
 mmix_elf_is_local_label_name (abfd, name)
      bfd *abfd;
      const char *name;
@@ -1987,19 +2014,19 @@ mmix_elf_is_local_label_name (abfd, name)
 
   /* Also include the default local-label definition.  */
   if (_bfd_elf_is_local_label_name (abfd, name))
-    return true;
+    return TRUE;
 
   if (*name != 'L')
-    return false;
+    return FALSE;
 
   /* If there's no ":", or more than one, it's not a local symbol.  */
   colpos = strchr (name, ':');
   if (colpos == NULL || strchr (colpos + 1, ':') != NULL)
-    return false;
+    return FALSE;
 
   /* Check that there are remaining characters and that they are digits.  */
   if (colpos[1] == 0)
-    return false;
+    return FALSE;
 
   digits = strspn (colpos + 1, "0123456789");
   return digits != 0 && colpos[1 + digits] == 0;
@@ -2007,7 +2034,7 @@ mmix_elf_is_local_label_name (abfd, name)
 
 /* We get rid of the register section here.  */
 
-boolean
+bfd_boolean
 mmix_elf_final_link (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -2035,7 +2062,7 @@ mmix_elf_final_link (abfd, info)
     }
 
   if (! bfd_elf64_bfd_final_link (abfd, info))
-    return false;
+    return FALSE;
 
   /* Since this section is marked SEC_LINKER_CREATED, it isn't output by
      the regular linker machinery.  We do it here, like other targets with
@@ -2050,15 +2077,15 @@ mmix_elf_final_link (abfd, info)
                                     greg_section->contents,
                                     (file_ptr) greg_section->output_offset,
                                     greg_section->_cooked_size))
-       return false;
+       return FALSE;
     }
-  return true;
+  return TRUE;
 }
 
 /* Initialize stuff for the linker-generated GREGs to match
    R_MMIX_BASE_PLUS_OFFSET relocs seen by the linker.  */
 
-boolean
+bfd_boolean
 _bfd_mmix_prepare_linker_allocated_gregs (abfd, info)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
@@ -2076,20 +2103,19 @@ _bfd_mmix_prepare_linker_allocated_gregs (abfd, info)
      If there is no such object, there was no R_MMIX_BASE_PLUS_OFFSET.  */
   bpo_greg_owner = (bfd *) info->base_file;
   if (bpo_greg_owner == NULL)
-    return true;
+    return TRUE;
 
   bpo_gregs_section
     = bfd_get_section_by_name (bpo_greg_owner,
                               MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
 
   if (bpo_gregs_section == NULL)
-    return true;
+    return TRUE;
 
   /* We use the target-data handle in the ELF section data.  */
-  gregdata = (struct bpo_greg_section_info *)
-    elf_section_data (bpo_gregs_section)->tdata;
+  gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
   if (gregdata == NULL)
-    return false;
+    return FALSE;
 
   n_gregs = gregdata->n_bpo_relocs;
   gregdata->n_allocated_bpo_gregs = n_gregs;
@@ -2102,7 +2128,7 @@ _bfd_mmix_prepare_linker_allocated_gregs (abfd, info)
   gregs_size = n_gregs * 8;
 
   if (!bfd_set_section_size (bpo_greg_owner, bpo_gregs_section, gregs_size))
-    return false;
+    return FALSE;
 
   /* Allocate and set up the GREG arrays.  They're filled in at relaxation
      time.  Note that we must use the max number ever noted for the array,
@@ -2118,7 +2144,7 @@ _bfd_mmix_prepare_linker_allocated_gregs (abfd, info)
                 gregdata->n_max_bpo_relocs
                 * sizeof (size_t));
   if (bpo_reloc_indexes == NULL)
-    return false;
+    return FALSE;
 
   /* The default order is an identity mapping.  */
   for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
@@ -2127,13 +2153,13 @@ _bfd_mmix_prepare_linker_allocated_gregs (abfd, info)
       gregdata->reloc_request[i].bpo_reloc_no = i;
     }
 
-  return true;
+  return TRUE;
 }
 \f
 /* Fill in contents in the linker allocated gregs.  Everything is
    calculated at this point; we just move the contents into place here.  */
 
-boolean
+bfd_boolean
 _bfd_mmix_finalize_linker_allocated_gregs (abfd, link_info)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *link_info;
@@ -2151,7 +2177,7 @@ _bfd_mmix_finalize_linker_allocated_gregs (abfd, link_info)
      object, there was no R_MMIX_BASE_PLUS_OFFSET.  */
   bpo_greg_owner = (bfd *) link_info->base_file;
   if (bpo_greg_owner == NULL)
-    return true;
+    return TRUE;
 
   bpo_gregs_section
     = bfd_get_section_by_name (bpo_greg_owner,
@@ -2161,21 +2187,23 @@ _bfd_mmix_finalize_linker_allocated_gregs (abfd, link_info)
      without any R_MMIX_BASE_PLUS_OFFSET seen, there will be no such
      section.  */
   if (bpo_gregs_section == NULL)
-    return true;
+    return TRUE;
 
   /* We use the target-data handle in the ELF section data.  */
 
-  gregdata = (struct bpo_greg_section_info *)
-    elf_section_data (bpo_gregs_section)->tdata;
+  gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
   if (gregdata == NULL)
-    return false;
+    return FALSE;
 
   n_gregs = gregdata->n_allocated_bpo_gregs;
 
+  /* We need to have a _raw_size contents even though there's only
+     _cooked_size worth of data, since the generic relocation machinery
+     will allocate and copy that much temporarily.  */
   bpo_gregs_section->contents
-    = contents = bfd_alloc (bpo_greg_owner, bpo_gregs_section->_cooked_size);
+    = contents = bfd_alloc (bpo_greg_owner, bpo_gregs_section->_raw_size);
   if (contents == NULL)
-    return false;
+    return FALSE;
 
   /* Sanity check: If these numbers mismatch, some relocation has not been
      accounted for and the rest of gregdata is probably inconsistent.
@@ -2189,7 +2217,7 @@ _bfd_mmix_finalize_linker_allocated_gregs (abfd, link_info)
   Please report this bug."),
         gregdata->n_remaining_bpo_relocs_this_relaxation_round,
         gregdata->n_bpo_relocs);
-      return false;
+      return FALSE;
     }
 
   for (lastreg = 255, i = 0, j = 0; j < n_gregs; i++)
@@ -2201,7 +2229,7 @@ _bfd_mmix_finalize_linker_allocated_gregs (abfd, link_info)
        j++;
       }
 
-  return true;
+  return TRUE;
 }
 
 /* Sort valid relocs to come before non-valid relocs, then on increasing
@@ -2226,8 +2254,12 @@ bpo_reloc_request_sort_fn (p1, p2)
   if (r1->value != r2->value)
     return r1->value > r2->value ? 1 : -1;
 
-  /* As a last re-sort, use the address so we get a stable sort.  */
-  return r1 > r2 ? 1 : (r1 < r2 ? -1 : 0);
+  /* As a last re-sort, use the relocation number, so we get a stable
+     sort.  The *addresses* aren't stable since items are swapped during
+     sorting.  It depends on the qsort implementation if this actually
+     happens.  */
+  return r1->bpo_reloc_no > r2->bpo_reloc_no
+    ? 1 : (r1->bpo_reloc_no < r2->bpo_reloc_no ? -1 : 0);
 }
 
 /* For debug use only.  Dumps the global register allocations resulting
@@ -2255,8 +2287,7 @@ mmix_dump_bpo_gregs (link_info, pf)
   if (bpo_gregs_section == NULL)
     return;
 
-  gregdata = (struct bpo_greg_section_info *)
-    elf_section_data (bpo_gregs_section)->tdata;
+  gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
   if (gregdata == NULL)
     return;
 
@@ -2276,8 +2307,8 @@ mmix_dump_bpo_gregs (link_info, pf)
     for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
       (*pf) ("%4u (%4u)/%4u#%u: 0x%08lx%08lx  r: %3u o: %3u\n",
             i,
-            gregdata->bpo_reloc_indexes != NULL
-            ? gregdata->bpo_reloc_indexes[i] : -1,
+            (gregdata->bpo_reloc_indexes != NULL
+             ? gregdata->bpo_reloc_indexes[i] : (size_t) -1),
             gregdata->reloc_request[i].bpo_reloc_no,
             gregdata->reloc_request[i].valid,
 
@@ -2295,31 +2326,26 @@ mmix_dump_bpo_gregs (link_info, pf)
 
    Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
 
-static boolean
+static bfd_boolean
 mmix_elf_relax_section (abfd, sec, link_info, again)
      bfd *abfd;
      asection *sec;
      struct bfd_link_info *link_info;
-     boolean *again;
+     bfd_boolean *again;
 {
   Elf_Internal_Shdr *symtab_hdr;
-  Elf_Internal_Shdr *shndx_hdr;
   Elf_Internal_Rela *internal_relocs;
-  Elf_Internal_Rela *free_relocs = NULL;
   Elf_Internal_Rela *irel, *irelend;
   asection *bpo_gregs_section = NULL;
   struct bpo_greg_section_info *gregdata;
   struct bpo_reloc_section_info *bpodata
-    = (struct bpo_reloc_section_info *)
-    elf_section_data (sec)->tdata;
+    = mmix_elf_section_data (sec)->bpo.reloc;
   size_t bpono;
   bfd *bpo_greg_owner;
-  Elf64_External_Sym *extsyms = NULL;
-  Elf64_External_Sym *free_extsyms = NULL;
-  Elf_External_Sym_Shndx *shndx_buf = NULL;
+  Elf_Internal_Sym *isymbuf = NULL;
 
   /* Assume nothing changes.  */
-  *again = false;
+  *again = FALSE;
 
   /* If this is the first time we have been called for this section,
      initialize the cooked size.  */
@@ -2336,15 +2362,13 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
       || (sec->flags & SEC_LINKER_CREATED) != 0
       /* If no R_MMIX_BASE_PLUS_OFFSET relocs, then nothing to do.  */
       || bpodata == NULL)
-    return true;
+    return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
 
   bpo_greg_owner = (bfd *) link_info->base_file;
   bpo_gregs_section = bpodata->bpo_greg_section;
-  gregdata = (struct bpo_greg_section_info *)
-    elf_section_data (bpo_gregs_section)->tdata;
+  gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
 
   bpono = bpodata->first_base_plus_offset_reloc;
 
@@ -2355,8 +2379,6 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
                                   link_info->keep_memory);
   if (internal_relocs == NULL)
     goto error_return;
-  if (! link_info->keep_memory)
-    free_relocs = internal_relocs;
 
   /* Walk through them looking for relaxing opportunities.  */
   irelend = internal_relocs + sec->reloc_count;
@@ -2367,69 +2389,35 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
       if (ELF64_R_TYPE (irel->r_info) != (int) R_MMIX_BASE_PLUS_OFFSET)
        continue;
 
-      /* Read this BFD's symbols if we haven't done so already.  */
-      if (extsyms == NULL)
-       {
-         /* Get cached copy if it exists.  */
-         if (symtab_hdr->contents != NULL)
-           extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
-         else
-           {
-             /* Go get them off disk.  */
-             bfd_size_type amt;
-
-             amt = symtab_hdr->sh_info;
-             amt *= sizeof (Elf64_External_Sym);
-             extsyms = (Elf64_External_Sym *) bfd_malloc (amt);
-             if (extsyms == NULL)
-               goto error_return;
-             free_extsyms = extsyms;
-             if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
-                 || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
-               goto error_return;
-             symtab_hdr->contents = (bfd_byte *) extsyms;
-           }
-
-         /* If >64k sections, this presumable happens.  No test-case.  */
-         if (shndx_hdr->sh_size != 0)
-           {
-             bfd_size_type amt;
-
-             amt = symtab_hdr->sh_info;
-             amt *= sizeof (Elf_External_Sym_Shndx);
-             shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
-             if (shndx_buf == NULL)
-               goto error_return;
-             if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
-                 || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
-               goto error_return;
-             shndx_hdr->contents = (bfd_byte *) shndx_buf;
-           }
-       }
-
       /* Get the value of the symbol referred to by the reloc.  */
       if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
        {
          /* A local symbol.  */
-         Elf64_External_Sym *esym;
-         Elf_External_Sym_Shndx *shndx;
-         Elf_Internal_Sym isym;
+         Elf_Internal_Sym *isym;
          asection *sym_sec;
 
-         esym = extsyms + ELF64_R_SYM (irel->r_info);
-         shndx = shndx_buf + (shndx_buf
-                              ? ELF64_R_SYM (irel->r_info) : 0);
-         bfd_elf64_swap_symbol_in (abfd, esym, shndx, &isym);
+         /* Read this BFD's local symbols if we haven't already.  */
+         if (isymbuf == NULL)
+           {
+             isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+             if (isymbuf == NULL)
+               isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+                                               symtab_hdr->sh_info, 0,
+                                               NULL, NULL, NULL);
+             if (isymbuf == 0)
+               goto error_return;
+           }
 
-         if (isym.st_shndx == SHN_UNDEF)
+         isym = isymbuf + ELF64_R_SYM (irel->r_info);
+         if (isym->st_shndx == SHN_UNDEF)
            sym_sec = bfd_und_section_ptr;
-         else if (isym.st_shndx == SHN_ABS)
+         else if (isym->st_shndx == SHN_ABS)
            sym_sec = bfd_abs_section_ptr;
-         else if (isym.st_shndx == SHN_COMMON)
+         else if (isym->st_shndx == SHN_COMMON)
            sym_sec = bfd_com_section_ptr;
          else
-           sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
-         symval = (isym.st_value
+           sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+         symval = (isym->st_value
                    + sym_sec->output_section->vma
                    + sym_sec->output_offset);
        }
@@ -2461,7 +2449,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
 
       gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono]].value
        = symval + irel->r_addend;
-      gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono++]].valid = true;
+      gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono++]].valid = TRUE;
       gregdata->n_remaining_bpo_relocs_this_relaxation_round--;
     }
 
@@ -2494,7 +2482,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
          {
            gregdata->bpo_reloc_indexes[gregdata->reloc_request[i].bpo_reloc_no]
              = i;
-           *again = true;
+           *again = TRUE;
          }
 
       /* Allocate register numbers (indexing from 0).  Stop at the first
@@ -2520,47 +2508,36 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
       if (gregdata->n_allocated_bpo_gregs != regindex + 1)
        {
          gregdata->n_allocated_bpo_gregs = regindex + 1;
-         *again = true;
+         *again = TRUE;
        }
 
       bpo_gregs_section->_cooked_size = (regindex + 1) * 8;
     }
 
-  if (free_relocs != NULL)
-    free (free_relocs);
-
-  if (shndx_buf != NULL)
-    {
-      shndx_hdr->contents = NULL;
-      free (shndx_buf);
-    }
-
-  if (free_extsyms != NULL)
+  if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
     {
       if (! link_info->keep_memory)
+       free (isymbuf);
+      else
        {
-         symtab_hdr->contents = NULL;
-         free (free_extsyms);
+         /* Cache the symbols for elf_link_input_bfd.  */
+         symtab_hdr->contents = (unsigned char *) isymbuf;
        }
     }
 
-  return true;
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
 
- error_return:
-  if (free_relocs != NULL)
-    free (free_relocs);
-  if (shndx_buf != NULL)
-    {
-      shndx_hdr->contents = NULL;
-      free (shndx_buf);
-    }
-  if (free_extsyms != NULL)
-    {
-      symtab_hdr->contents = NULL;
-      free (free_extsyms);
-    }
+  return TRUE;
 
-  return false;
+ error_return:
+  if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+    free (isymbuf);
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
+  return FALSE;
 }
 \f
 #define ELF_ARCH               bfd_arch_mmix
@@ -2607,6 +2584,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
 #define elf_backend_section_from_bfd_section \
        mmix_elf_section_from_bfd_section
 
+#define bfd_elf64_new_section_hook     mmix_elf_new_section_hook
 #define bfd_elf64_bfd_final_link       mmix_elf_final_link
 #define bfd_elf64_bfd_relax_section    mmix_elf_relax_section