* gdbarch.sh: Remove "macro" column of input table. Remove handling
[deliverable/binutils-gdb.git] / bfd / elf-m10300.c
index 81c5db026ee98cba1011bae3bc9156840217ca94..9aedc06b044edc916c41ce37d687d03317b4eb6f 100644 (file)
@@ -1,50 +1,30 @@
 /* Matsushita 10300 specific support for 32-bit ELF
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   2006, 2007 Free Software Foundation, Inc.
 
-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., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/mn10300.h"
-
-static bfd_reloc_status_type mn10300_elf_final_link_relocate
-  PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,
-          bfd_vma, bfd_vma, bfd_vma,
-          struct elf_link_hash_entry *, unsigned long, struct bfd_link_info *,
-          asection *, int));
-static bfd_boolean mn10300_elf_relocate_section
-  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-          Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
-static bfd_boolean mn10300_elf_relax_section
-  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
-static bfd_byte * mn10300_elf_get_relocated_section_contents
-  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
-          bfd_byte *, bfd_boolean, asymbol **));
-static unsigned long elf_mn10300_mach
-  PARAMS ((flagword));
-void _bfd_mn10300_elf_final_write_processing
-  PARAMS ((bfd *, bfd_boolean));
-bfd_boolean _bfd_mn10300_elf_object_p
-  PARAMS ((bfd *));
-bfd_boolean _bfd_mn10300_elf_merge_private_bfd_data
-  PARAMS ((bfd *,bfd *));
+#include "libiberty.h"
 
 /* The mn10300 linker needs to keep track of the number of relocs that
    it decides to copy in check_relocs for each symbol.  This is so
@@ -52,7 +32,8 @@ bfd_boolean _bfd_mn10300_elf_merge_private_bfd_data
    linking with -Bsymbolic.  We store the information in a field
    extending the regular ELF linker hash table.  */
 
-struct elf32_mn10300_link_hash_entry {
+struct elf32_mn10300_link_hash_entry
+{
   /* The basic elf link hash table entry.  */
   struct elf_link_hash_entry root;
 
@@ -85,12 +66,16 @@ struct elf32_mn10300_link_hash_entry {
    prologue deleted.  */
 #define MN10300_DELETED_PROLOGUE_BYTES 0x2
   unsigned char flags;
+
+  /* Calculated value.  */
+  bfd_vma value;
 };
 
 /* We derive a hash table from the main elf linker hash table so
    we can store state variables and a secondary hash table without
    resorting to global variables.  */
-struct elf32_mn10300_link_hash_table {
+struct elf32_mn10300_link_hash_table
+{
   /* The main hash table.  */
   struct elf_link_hash_table root;
 
@@ -104,6 +89,10 @@ struct elf32_mn10300_link_hash_table {
   char flags;
 };
 
+#ifndef streq
+#define streq(a, b) (strcmp ((a),(b)) == 0)
+#endif
+
 /* For MN10300 linker hash table.  */
 
 /* Get the MN10300 ELF linker hash table from a link_info structure.  */
@@ -114,51 +103,11 @@ struct elf32_mn10300_link_hash_table {
 #define elf32_mn10300_link_hash_traverse(table, func, info)            \
   (elf_link_hash_traverse                                              \
    (&(table)->root,                                                    \
-    (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),   \
     (info)))
 
-static struct bfd_hash_entry *elf32_mn10300_link_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static struct bfd_link_hash_table *elf32_mn10300_link_hash_table_create
-  PARAMS ((bfd *));
-static void elf32_mn10300_link_hash_table_free
-  PARAMS ((struct bfd_link_hash_table *));
-
-static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
-  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-static void mn10300_info_to_howto
-  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
-static bfd_boolean mn10300_elf_check_relocs
-  PARAMS ((bfd *, struct bfd_link_info *, asection *,
-          const Elf_Internal_Rela *));
-static asection *mn10300_elf_gc_mark_hook
-  PARAMS ((asection *, struct bfd_link_info *info, Elf_Internal_Rela *,
-          struct elf_link_hash_entry *, Elf_Internal_Sym *));
-static bfd_boolean mn10300_elf_relax_delete_bytes
-  PARAMS ((bfd *, asection *, bfd_vma, int));
-static bfd_boolean mn10300_elf_symbol_address_p
-  PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
-static bfd_boolean elf32_mn10300_finish_hash_table_entry
-  PARAMS ((struct bfd_hash_entry *, PTR));
-static void compute_function_info
-  PARAMS ((bfd *, struct elf32_mn10300_link_hash_entry *,
-          bfd_vma, unsigned char *));
-
-static bfd_boolean _bfd_mn10300_elf_create_got_section
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean _bfd_mn10300_elf_create_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean _bfd_mn10300_elf_adjust_dynamic_symbol
-  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static bfd_boolean _bfd_mn10300_elf_size_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean _bfd_mn10300_elf_finish_dynamic_symbol
-  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
-          Elf_Internal_Sym *));
-static bfd_boolean _bfd_mn10300_elf_finish_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-
-static reloc_howto_type elf_mn10300_howto_table[] = {
+static reloc_howto_type elf_mn10300_howto_table[] =
+{
   /* Dummy relocation.  Does nothing.  */
   HOWTO (R_MN10300_NONE,
         0,
@@ -258,7 +207,7 @@ static reloc_howto_type elf_mn10300_howto_table[] = {
         0xff,
         TRUE),
 
-  /* GNU extension to record C++ vtable hierarchy */
+  /* GNU extension to record C++ vtable hierarchy */
   HOWTO (R_MN10300_GNU_VTINHERIT, /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -497,15 +446,16 @@ static reloc_howto_type elf_mn10300_howto_table[] = {
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
-
 };
 
-struct mn10300_reloc_map {
+struct mn10300_reloc_map
+{
   bfd_reloc_code_real_type bfd_reloc_val;
   unsigned char elf_reloc_val;
 };
 
-static const struct mn10300_reloc_map mn10300_reloc_map[] = {
+static const struct mn10300_reloc_map mn10300_reloc_map[] =
+{
   { BFD_RELOC_NONE, R_MN10300_NONE, },
   { BFD_RELOC_32, R_MN10300_32, },
   { BFD_RELOC_16, R_MN10300_16, },
@@ -535,9 +485,8 @@ static const struct mn10300_reloc_map mn10300_reloc_map[] = {
 /* Create the GOT section.  */
 
 static bfd_boolean
-_bfd_mn10300_elf_create_got_section (abfd, info)
-     bfd * abfd;
-     struct bfd_link_info * info;
+_bfd_mn10300_elf_create_got_section (bfd * abfd,
+                                    struct bfd_link_info * info)
 {
   flagword   flags;
   flagword   pltflags;
@@ -620,19 +569,28 @@ _bfd_mn10300_elf_create_got_section (abfd, info)
 }
 
 static reloc_howto_type *
-bfd_elf32_bfd_reloc_type_lookup (abfd, code)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     bfd_reloc_code_real_type code;
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                bfd_reloc_code_real_type code)
 {
   unsigned int i;
 
-  for (i = 0;
-       i < sizeof (mn10300_reloc_map) / sizeof (struct mn10300_reloc_map);
-       i++)
-    {
-      if (mn10300_reloc_map[i].bfd_reloc_val == code)
-       return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val];
-    }
+  for (i = ARRAY_SIZE (mn10300_reloc_map); i--;)
+    if (mn10300_reloc_map[i].bfd_reloc_val == code)
+      return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val];
+
+  return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                const char *r_name)
+{
+  unsigned int i;
+
+  for (i = ARRAY_SIZE (elf_mn10300_howto_table); i--;)
+    if (elf_mn10300_howto_table[i].name != NULL
+       && strcasecmp (elf_mn10300_howto_table[i].name, r_name) == 0)
+      return elf_mn10300_howto_table + i;
 
   return NULL;
 }
@@ -640,16 +598,15 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
 /* Set the howto pointer for an MN10300 ELF reloc.  */
 
 static void
-mn10300_info_to_howto (abfd, cache_ptr, dst)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *cache_ptr;
-     Elf_Internal_Rela *dst;
+mn10300_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+                      arelent *cache_ptr,
+                      Elf_Internal_Rela *dst)
 {
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
   BFD_ASSERT (r_type < (unsigned int) R_MN10300_MAX);
-  cache_ptr->howto = &elf_mn10300_howto_table[r_type];
+  cache_ptr->howto = elf_mn10300_howto_table + r_type;
 }
 
 /* Look through the relocs for a section during the first phase.
@@ -657,14 +614,13 @@ mn10300_info_to_howto (abfd, cache_ptr, dst)
    virtual table relocs for gc.  */
 
 static bfd_boolean
-mn10300_elf_check_relocs (abfd, info, sec, relocs)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *sec;
-     const Elf_Internal_Rela *relocs;
+mn10300_elf_check_relocs (bfd *abfd,
+                         struct bfd_link_info *info,
+                         asection *sec,
+                         const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   bfd *      dynobj;
@@ -682,13 +638,11 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
-  if (!elf_bad_symtab (abfd))
-    sym_hashes_end -= symtab_hdr->sh_info;
 
   dynobj = elf_hash_table (info)->dynobj;
   local_got_offsets = elf_local_got_offsets (abfd);
   rel_end = relocs + sec->reloc_count;
+
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
@@ -740,7 +694,9 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
        /* This relocation describes which C++ vtable entries are actually
           used.  Record for later use during GC.  */
        case R_MN10300_GNU_VTENTRY:
-         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         BFD_ASSERT (h != NULL);
+         if (h != NULL
+             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
        case R_MN10300_GOT32:
@@ -801,7 +757,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
                  unsigned int i;
 
                  size = symtab_hdr->sh_info * sizeof (bfd_vma);
-                 local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+                 local_got_offsets = bfd_alloc (abfd, size);
 
                  if (local_got_offsets == NULL)
                    return FALSE;
@@ -825,7 +781,6 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
            }
 
          sgot->size += 4;
-
          break;
 
        case R_MN10300_PLT32:
@@ -847,7 +802,6 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
            break;
 
          h->needs_plt = 1;
-
          break;
 
        case R_MN10300_24:
@@ -883,9 +837,8 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
                  if (name == NULL)
                    return FALSE;
 
-                 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
-                             && strcmp (bfd_get_section_name (abfd, sec),
-                                        name + 5) == 0);
+                 BFD_ASSERT (CONST_STRNEQ (name, ".rela")
+                             && streq (bfd_get_section_name (abfd, sec), name + 5));
 
                  sreloc = bfd_get_section_by_name (dynobj, name);
                  if (sreloc == NULL)
@@ -896,9 +849,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
                               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
                      if ((sec->flags & SEC_ALLOC) != 0)
                        flags |= SEC_ALLOC | SEC_LOAD;
-                     sreloc = bfd_make_section_with_flags (dynobj,
-                                                           name,
-                                                           flags);
+                     sreloc = bfd_make_section_with_flags (dynobj, name, flags);
                      if (sreloc == NULL
                          || ! bfd_set_section_alignment (dynobj, sreloc, 2))
                        return FALSE;
@@ -919,63 +870,42 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
    relocation.  */
 
 static asection *
-mn10300_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;
-     Elf_Internal_Sym *sym;
+mn10300_elf_gc_mark_hook (asection *sec,
+                         struct bfd_link_info *info,
+                         Elf_Internal_Rela *rel,
+                         struct elf_link_hash_entry *h,
+                         Elf_Internal_Sym *sym)
 {
   if (h != NULL)
-    {
-      switch (ELF32_R_TYPE (rel->r_info))
-       {
-       case R_MN10300_GNU_VTINHERIT:
-       case R_MN10300_GNU_VTENTRY:
-         break;
-
-       default:
-         switch (h->root.type)
-           {
-           case bfd_link_hash_defined:
-           case bfd_link_hash_defweak:
-             return h->root.u.def.section;
-
-           case bfd_link_hash_common:
-             return h->root.u.c.p->section;
-
-           default:
-             break;
-           }
-       }
-    }
-  else
-    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+    switch (ELF32_R_TYPE (rel->r_info))
+      {
+      case R_MN10300_GNU_VTINHERIT:
+      case R_MN10300_GNU_VTENTRY:
+       return NULL;
+      }
 
-  return NULL;
+  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
 /* Perform a relocation as part of a final link.  */
+
 static bfd_reloc_status_type
-mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
-                                input_section, contents, offset, value,
-                                addend, h, symndx, info, sym_sec, is_local)
-     reloc_howto_type *howto;
-     bfd *input_bfd;
-     bfd *output_bfd ATTRIBUTE_UNUSED;
-     asection *input_section;
-     bfd_byte *contents;
-     bfd_vma offset;
-     bfd_vma value;
-     bfd_vma addend;
-     struct elf_link_hash_entry * h;
-     unsigned long symndx;
-     struct bfd_link_info *info;
-     asection *sym_sec ATTRIBUTE_UNUSED;
-     int is_local ATTRIBUTE_UNUSED;
+mn10300_elf_final_link_relocate (reloc_howto_type *howto,
+                                bfd *input_bfd,
+                                bfd *output_bfd ATTRIBUTE_UNUSED,
+                                asection *input_section,
+                                bfd_byte *contents,
+                                bfd_vma offset,
+                                bfd_vma value,
+                                bfd_vma addend,
+                                struct elf_link_hash_entry * h,
+                                unsigned long symndx,
+                                struct bfd_link_info *info,
+                                asection *sym_sec ATTRIBUTE_UNUSED,
+                                int is_local ATTRIBUTE_UNUSED)
 {
   unsigned long r_type = howto->type;
-  bfd_byte *hit_data = contents + offset;
+  bfd_byte * hit_data = contents + offset;
   bfd *      dynobj;
   bfd_vma *  local_got_offsets;
   asection * sgot;
@@ -1033,10 +963,10 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
              if (name == NULL)
                return FALSE;
 
-             BFD_ASSERT (strncmp (name, ".rela", 5) == 0
-                         && strcmp (bfd_get_section_name (input_bfd,
-                                                          input_section),
-                                    name + 5) == 0);
+             BFD_ASSERT (CONST_STRNEQ (name, ".rela")
+                         && streq (bfd_get_section_name (input_bfd,
+                                                         input_section),
+                                   name + 5));
 
              sreloc = bfd_get_section_by_name (dynobj, name);
              BFD_ASSERT (sreloc != NULL);
@@ -1161,7 +1091,6 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
 
     case R_MN10300_GOTPC32:
       /* Use global offset table as symbol value.  */
-
       value = bfd_get_section_by_name (dynobj,
                                       ".got")->output_section->vma;
       value -= (input_section->output_section->vma
@@ -1174,7 +1103,6 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
 
     case R_MN10300_GOTPC16:
       /* Use global offset table as symbol value.  */
-
       value = bfd_get_section_by_name (dynobj,
                                       ".got")->output_section->vma;
       value -= (input_section->output_section->vma
@@ -1365,25 +1293,21 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
 }
 \f
 /* Relocate an MN10300 ELF section.  */
+
 static bfd_boolean
-mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
-                             contents, relocs, local_syms, local_sections)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     bfd *input_bfd;
-     asection *input_section;
-     bfd_byte *contents;
-     Elf_Internal_Rela *relocs;
-     Elf_Internal_Sym *local_syms;
-     asection **local_sections;
+mn10300_elf_relocate_section (bfd *output_bfd,
+                             struct bfd_link_info *info,
+                             bfd *input_bfd,
+                             asection *input_section,
+                             bfd_byte *contents,
+                             Elf_Internal_Rela *relocs,
+                             Elf_Internal_Sym *local_syms,
+                             asection **local_sections)
 {
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -1459,7 +1383,7 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
               obscure cases sec->output_section will be NULL.  */
            relocation = 0;
 
-         else if (unresolved_reloc)
+         else if (!info->relocatable && unresolved_reloc)
            (*_bfd_error_handler)
              (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
               input_bfd,
@@ -1469,18 +1393,32 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
               h->root.root.root.string);
        }
 
+      if (sec != NULL && elf_discarded_section (sec))
+       {
+         /* For relocs against symbols from removed linkonce sections,
+            or sections discarded by a linker script, we just want the
+            section contents zeroed.  Avoid any special processing.  */
+         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+         rel->r_info = 0;
+         rel->r_addend = 0;
+         continue;
+       }
+
+      if (info->relocatable)
+       continue;
+
       r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
                                           input_section,
                                           contents, rel->r_offset,
                                           relocation, rel->r_addend,
-                                          (struct elf_link_hash_entry *)h,
+                                          (struct elf_link_hash_entry *) h,
                                           r_symndx,
                                           info, sec, h == NULL);
 
       if (r != bfd_reloc_ok)
        {
          const char *name;
-         const char *msg = (const char *) 0;
+         const char *msg = NULL;
 
          if (h != NULL)
            name = h->root.root.root.string;
@@ -1518,12 +1456,17 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              goto common_error;
 
            case bfd_reloc_dangerous:
-             msg = _("internal error: dangerous error");
+             if (r_type == R_MN10300_PCREL32)
+               msg = _("error: inappropriate relocation type for shared"
+                       " library (did you forget -fpic?)");
+             else
+               msg = _("internal error: suspicious relocation type used"
+                       " in shared library");
              goto common_error;
 
            default:
              msg = _("internal error: unknown error");
-             /* fall through */
+             /* Fall through.  */
 
            common_error:
              if (!((*info->callbacks->warning)
@@ -1539,13 +1482,13 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 }
 
 /* Finish initializing one hash table entry.  */
+
 static bfd_boolean
-elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
-     struct bfd_hash_entry *gen_entry;
-     PTR in_args;
+elf32_mn10300_finish_hash_table_entry (struct bfd_hash_entry *gen_entry,
+                                      void * in_args)
 {
   struct elf32_mn10300_link_hash_entry *entry;
-  struct bfd_link_info *link_info = (struct bfd_link_info *)in_args;
+  struct bfd_link_info *link_info = (struct bfd_link_info *) in_args;
   unsigned int byte_count = 0;
 
   entry = (struct elf32_mn10300_link_hash_entry *) gen_entry;
@@ -1593,13 +1536,270 @@ elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
        byte_count += 4;
     }
 
-  /* If using "call" will result in larger code, then turn all
-     the associated "call" instructions into "calls" instructions.  */
-  if (byte_count < entry->direct_calls)
-    entry->flags |= MN10300_CONVERT_CALL_TO_CALLS;
-
-  /* This routine never fails.  */
-  return TRUE;
+  /* If using "call" will result in larger code, then turn all
+     the associated "call" instructions into "calls" instructions.  */
+  if (byte_count < entry->direct_calls)
+    entry->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+
+  /* This routine never fails.  */
+  return TRUE;
+}
+
+/* Used to count hash table entries.  */
+
+static bfd_boolean
+elf32_mn10300_count_hash_table_entries (struct bfd_hash_entry *gen_entry ATTRIBUTE_UNUSED,
+                                       void * in_args)
+{
+  int *count = (int *)in_args;
+
+  (*count) ++;
+  return TRUE;
+}
+
+/* Used to enumerate hash table entries into a linear array.  */
+
+static bfd_boolean
+elf32_mn10300_list_hash_table_entries (struct bfd_hash_entry *gen_entry,
+                                      void * in_args)
+{
+  struct bfd_hash_entry ***ptr = (struct bfd_hash_entry ***) in_args;
+
+  **ptr = gen_entry;
+  (*ptr) ++;
+  return TRUE;
+}
+
+/* Used to sort the array created by the above.  */
+
+static int
+sort_by_value (const void *va, const void *vb)
+{
+  struct elf32_mn10300_link_hash_entry *a
+    = *(struct elf32_mn10300_link_hash_entry **)va;
+  struct elf32_mn10300_link_hash_entry *b
+    = *(struct elf32_mn10300_link_hash_entry **)vb;
+
+  return a->value - b->value;
+}
+
+/* Compute the stack size and movm arguments for the function
+   referred to by HASH at address ADDR in section with
+   contents CONTENTS, store the information in the hash table.  */
+
+static void
+compute_function_info (bfd *abfd,
+                      struct elf32_mn10300_link_hash_entry *hash,
+                      bfd_vma addr,
+                      unsigned char *contents)
+{
+  unsigned char byte1, byte2;
+  /* We only care about a very small subset of the possible prologue
+     sequences here.  Basically we look for:
+
+     movm [d2,d3,a2,a3],sp (optional)
+     add <size>,sp (optional, and only for sizes which fit in an unsigned
+                   8 bit number)
+
+     If we find anything else, we quit.  */
+
+  /* Look for movm [regs],sp.  */
+  byte1 = bfd_get_8 (abfd, contents + addr);
+  byte2 = bfd_get_8 (abfd, contents + addr + 1);
+
+  if (byte1 == 0xcf)
+    {
+      hash->movm_args = byte2;
+      addr += 2;
+      byte1 = bfd_get_8 (abfd, contents + addr);
+      byte2 = bfd_get_8 (abfd, contents + addr + 1);
+    }
+
+  /* Now figure out how much stack space will be allocated by the movm
+     instruction.  We need this kept separate from the function's normal
+     stack space.  */
+  if (hash->movm_args)
+    {
+      /* Space for d2.  */
+      if (hash->movm_args & 0x80)
+       hash->movm_stack_size += 4;
+
+      /* Space for d3.  */
+      if (hash->movm_args & 0x40)
+       hash->movm_stack_size += 4;
+
+      /* Space for a2.  */
+      if (hash->movm_args & 0x20)
+       hash->movm_stack_size += 4;
+
+      /* Space for a3.  */
+      if (hash->movm_args & 0x10)
+       hash->movm_stack_size += 4;
+
+      /* "other" space.  d0, d1, a0, a1, mdr, lir, lar, 4 byte pad.  */
+      if (hash->movm_args & 0x08)
+       hash->movm_stack_size += 8 * 4;
+
+      if (bfd_get_mach (abfd) == bfd_mach_am33
+         || bfd_get_mach (abfd) == bfd_mach_am33_2)
+       {
+         /* "exother" space.  e0, e1, mdrq, mcrh, mcrl, mcvf */
+         if (hash->movm_args & 0x1)
+           hash->movm_stack_size += 6 * 4;
+
+         /* exreg1 space.  e4, e5, e6, e7 */
+         if (hash->movm_args & 0x2)
+           hash->movm_stack_size += 4 * 4;
+
+         /* exreg0 space.  e2, e3  */
+         if (hash->movm_args & 0x4)
+           hash->movm_stack_size += 2 * 4;
+       }
+    }
+
+  /* Now look for the two stack adjustment variants.  */
+  if (byte1 == 0xf8 && byte2 == 0xfe)
+    {
+      int temp = bfd_get_8 (abfd, contents + addr + 2);
+      temp = ((temp & 0xff) ^ (~0x7f)) + 0x80;
+
+      hash->stack_size = -temp;
+    }
+  else if (byte1 == 0xfa && byte2 == 0xfe)
+    {
+      int temp = bfd_get_16 (abfd, contents + addr + 2);
+      temp = ((temp & 0xffff) ^ (~0x7fff)) + 0x8000;
+      temp = -temp;
+
+      if (temp < 255)
+       hash->stack_size = temp;
+    }
+
+  /* If the total stack to be allocated by the call instruction is more
+     than 255 bytes, then we can't remove the stack adjustment by using
+     "call" (we might still be able to remove the "movm" instruction.  */
+  if (hash->stack_size + hash->movm_stack_size > 255)
+    hash->stack_size = 0;
+}
+
+/* Delete some bytes from a section while relaxing.  */
+
+static bfd_boolean
+mn10300_elf_relax_delete_bytes (bfd *abfd,
+                               asection *sec,
+                               bfd_vma addr,
+                               int count)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  unsigned int sec_shndx;
+  bfd_byte *contents;
+  Elf_Internal_Rela *irel, *irelend;
+  Elf_Internal_Rela *irelalign;
+  bfd_vma toaddr;
+  Elf_Internal_Sym *isym, *isymend;
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_link_hash_entry **end_hashes;
+  unsigned int symcount;
+
+  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+  contents = elf_section_data (sec)->this_hdr.contents;
+
+  /* The deletion must stop at the next ALIGN reloc for an aligment
+     power larger than the number of bytes we are deleting.  */
+
+  irelalign = NULL;
+  toaddr = sec->size;
+
+  irel = elf_section_data (sec)->relocs;
+  irelend = irel + sec->reloc_count;
+
+  /* Actually delete the bytes.  */
+  memmove (contents + addr, contents + addr + count,
+          (size_t) (toaddr - addr - count));
+  sec->size -= count;
+
+  /* Adjust all the relocs.  */
+  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+    {
+      /* Get the new reloc address.  */
+      if ((irel->r_offset > addr
+          && irel->r_offset < toaddr))
+       irel->r_offset -= count;
+    }
+
+  /* Adjust the local symbols defined in this section.  */
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+    {
+      if (isym->st_shndx == sec_shndx
+         && isym->st_value > addr
+         && isym->st_value < toaddr)
+       isym->st_value -= count;
+    }
+
+  /* Now adjust the global symbols defined in this section.  */
+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+             - symtab_hdr->sh_info);
+  sym_hashes = elf_sym_hashes (abfd);
+  end_hashes = sym_hashes + symcount;
+  for (; sym_hashes < end_hashes; sym_hashes++)
+    {
+      struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+      if ((sym_hash->root.type == bfd_link_hash_defined
+          || sym_hash->root.type == bfd_link_hash_defweak)
+         && sym_hash->root.u.def.section == sec
+         && sym_hash->root.u.def.value > addr
+         && sym_hash->root.u.def.value < toaddr)
+       sym_hash->root.u.def.value -= count;
+    }
+
+  return TRUE;
+}
+
+/* Return TRUE if a symbol exists at the given address, else return
+   FALSE.  */
+
+static bfd_boolean
+mn10300_elf_symbol_address_p (bfd *abfd,
+                             asection *sec,
+                             Elf_Internal_Sym *isym,
+                             bfd_vma addr)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  unsigned int sec_shndx;
+  Elf_Internal_Sym *isymend;
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_link_hash_entry **end_hashes;
+  unsigned int symcount;
+
+  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+  /* Examine all the symbols.  */
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+    if (isym->st_shndx == sec_shndx
+       && isym->st_value == addr)
+      return TRUE;
+
+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+             - symtab_hdr->sh_info);
+  sym_hashes = elf_sym_hashes (abfd);
+  end_hashes = sym_hashes + symcount;
+  for (; sym_hashes < end_hashes; sym_hashes++)
+    {
+      struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+      if ((sym_hash->root.type == bfd_link_hash_defined
+          || sym_hash->root.type == bfd_link_hash_defweak)
+         && sym_hash->root.u.def.section == sec
+         && sym_hash->root.u.def.value == addr)
+       return TRUE;
+    }
+
+  return FALSE;
 }
 
 /* This function handles relaxing for the mn10300.
@@ -1642,11 +1842,10 @@ elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
        and somewhat more difficult to support.  */
 
 static bfd_boolean
-mn10300_elf_relax_section (abfd, sec, link_info, again)
-     bfd *abfd;
-     asection *sec;
-     struct bfd_link_info *link_info;
-     bfd_boolean *again;
+mn10300_elf_relax_section (bfd *abfd,
+                          asection *sec,
+                          struct bfd_link_info *link_info,
+                          bfd_boolean *again)
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Rela *internal_relocs = NULL;
@@ -1697,9 +1896,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
              char *new_name;
 
              /* If there's nothing to do in this section, skip it.  */
-             if (! (((section->flags & SEC_RELOC) != 0
-                     && section->reloc_count != 0)
-                    || (section->flags & SEC_CODE) != 0))
+             if (! ((section->flags & SEC_RELOC) != 0
+                    && section->reloc_count != 0))
+               continue;
+             if ((section->flags & SEC_ALLOC) == 0)
                continue;
 
              /* Get cached copy of section contents if it exists.  */
@@ -1719,12 +1919,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
              if ((section->flags & SEC_RELOC) != 0
                  && section->reloc_count != 0)
                {
-
                  /* Get a copy of the native relocations.  */
-                 internal_relocs = (_bfd_elf_link_read_relocs
-                                    (input_bfd, section, (PTR) NULL,
-                                     (Elf_Internal_Rela *) NULL,
-                                     link_info->keep_memory));
+                 internal_relocs = _bfd_elf_link_read_relocs (input_bfd, section,
+                                                              NULL, NULL,
+                                                              link_info->keep_memory);
                  if (internal_relocs == NULL)
                    goto error_return;
 
@@ -1802,13 +2000,17 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                                   elf_sym_hashes (input_bfd)[r_index];
                        }
 
-                     /* If this is not a "call" instruction, then we
-                        should convert "call" instructions to "calls"
-                        instructions.  */
-                     code = bfd_get_8 (input_bfd,
-                                       contents + irel->r_offset - 1);
-                     if (code != 0xdd && code != 0xcd)
-                       hash->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+                     sym_name = hash->root.root.root.string;
+                     if ((section->flags & SEC_CODE) != 0)
+                       {
+                         /* If this is not a "call" instruction, then we
+                            should convert "call" instructions to "calls"
+                            instructions.  */
+                         code = bfd_get_8 (input_bfd,
+                                           contents + irel->r_offset - 1);
+                         if (code != 0xdd && code != 0xcd)
+                           hash->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+                       }
 
                      /* If this is a jump/call, then bump the
                         direct_calls counter.  Else force "call" to
@@ -1901,6 +2103,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                          free (new_name);
                          compute_function_info (input_bfd, hash,
                                                 isym->st_value, contents);
+                         hash->value = isym->st_value;
                        }
                    }
 
@@ -1962,6 +2165,46 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                                        elf32_mn10300_finish_hash_table_entry,
                                        link_info);
 
+      {
+       /* This section of code collects all our local symbols, sorts
+          them by value, and looks for multiple symbols referring to
+          the same address.  For those symbols, the flags are merged.
+          At this point, the only flag that can be set is
+          MN10300_CONVERT_CALL_TO_CALLS, so we simply OR the flags
+          together.  */
+       int static_count = 0, i;
+       struct elf32_mn10300_link_hash_entry **entries;
+       struct elf32_mn10300_link_hash_entry **ptr;
+
+       elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
+                                         elf32_mn10300_count_hash_table_entries,
+                                         &static_count);
+
+       entries = bfd_malloc (static_count * sizeof (* ptr));
+
+       ptr = entries;
+       elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
+                                         elf32_mn10300_list_hash_table_entries,
+                                         & ptr);
+
+       qsort (entries, static_count, sizeof (entries[0]), sort_by_value);
+
+       for (i = 0; i < static_count - 1; i++)
+         if (entries[i]->value && entries[i]->value == entries[i+1]->value)
+           {
+             int v = entries[i]->flags;
+             int j;
+
+             for (j = i + 1; j < static_count && entries[j]->value == entries[i]->value; j++)
+               v |= entries[j]->flags;
+
+             for (j = i; j < static_count && entries[j]->value == entries[i]->value; j++)
+               entries[j]->flags = v;
+
+             i = j - 1;
+           }
+      }
+
       /* All entries in the hash table are fully initialized.  */
       hash_table->flags |= MN10300_HASH_ENTRIES_INITIALIZED;
 
@@ -2004,10 +2247,9 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
              if (section->reloc_count != 0)
                {
                  /* Get a copy of the native relocations.  */
-                 internal_relocs = (_bfd_elf_link_read_relocs
-                                    (input_bfd, section, (PTR) NULL,
-                                     (Elf_Internal_Rela *) NULL,
-                                     link_info->keep_memory));
+                 internal_relocs = _bfd_elf_link_read_relocs (input_bfd, section,
+                                                              NULL, NULL,
+                                                              link_info->keep_memory);
                  if (internal_relocs == NULL)
                    goto error_return;
                }
@@ -2065,10 +2307,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                  sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
                  sym_name = new_name;
 
-                 elftab = &hash_table->static_hash_table->root;
-                 sym_hash = ((struct elf32_mn10300_link_hash_entry *)
-                             elf_link_hash_lookup (elftab, sym_name,
-                                                   FALSE, FALSE, FALSE));
+                 elftab = & hash_table->static_hash_table->root;
+                 sym_hash = (struct elf32_mn10300_link_hash_entry *)
+                   elf_link_hash_lookup (elftab, sym_name,
+                                         FALSE, FALSE, FALSE);
 
                  free (new_name);
                  if (sym_hash == NULL)
@@ -2181,10 +2423,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                  if (! link_info->keep_memory)
                    free (contents);
                  else
-                   {
-                     /* Cache the section contents for elf_link_input_bfd.  */
-                     elf_section_data (section)->this_hdr.contents = contents;
-                   }
+                   /* Cache the section contents for elf_link_input_bfd.  */
+                   elf_section_data (section)->this_hdr.contents = contents;
                }
              contents = NULL;
            }
@@ -2196,10 +2436,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
              if (! link_info->keep_memory)
                free (isymbuf);
              else
-               {
-                 /* Cache the symbols for elf_link_input_bfd.  */
-                 symtab_hdr->contents = (unsigned char *) isymbuf;
-               }
+               /* Cache the symbols for elf_link_input_bfd.  */
+               symtab_hdr->contents = (unsigned char *) isymbuf;
            }
          isymbuf = NULL;
        }
@@ -2224,9 +2462,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
   /* Get a copy of the native relocations.  */
-  internal_relocs = (_bfd_elf_link_read_relocs
-                    (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
-                     link_info->keep_memory));
+  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+                                              link_info->keep_memory);
   if (internal_relocs == NULL)
     goto error_return;
 
@@ -2309,6 +2546,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                        + sym_sec->output_section->vma
                        + sym_sec->output_offset);
            }
+
          /* Tack on an ID so we can uniquely identify this
             local symbol in the global hash table.  */
          new_name = bfd_malloc ((bfd_size_type) strlen (sym_name) + 10);
@@ -2333,12 +2571,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          BFD_ASSERT (h != NULL);
          if (h->root.root.type != bfd_link_hash_defined
              && h->root.root.type != bfd_link_hash_defweak)
-           {
-             /* This appears to be a reference to an undefined
-               symbol.  Just ignore it--it will be caught by the
-               regular reloc processing.  */
-             continue;
-           }
+           /* This appears to be a reference to an undefined
+              symbol.  Just ignore it--it will be caught by the
+              regular reloc processing.  */
+           continue;
 
          symval = (h->root.root.u.def.value
                    + h->root.root.u.def.section->output_section->vma
@@ -2795,8 +3031,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
         into a 16bit immediate, displacement or absolute address.  */
       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_32
          || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOT32
-         || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOTOFF32
-         || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOTPC32)
+         || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOTOFF32)
        {
          bfd_vma value = symval;
 
@@ -3311,242 +3546,16 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
   return FALSE;
 }
 
-/* Compute the stack size and movm arguments for the function
-   referred to by HASH at address ADDR in section with
-   contents CONTENTS, store the information in the hash table.  */
-static void
-compute_function_info (abfd, hash, addr, contents)
-     bfd *abfd;
-     struct elf32_mn10300_link_hash_entry *hash;
-     bfd_vma addr;
-     unsigned char *contents;
-{
-  unsigned char byte1, byte2;
-  /* We only care about a very small subset of the possible prologue
-     sequences here.  Basically we look for:
-
-     movm [d2,d3,a2,a3],sp (optional)
-     add <size>,sp (optional, and only for sizes which fit in an unsigned
-                   8 bit number)
-
-     If we find anything else, we quit.  */
-
-  /* Look for movm [regs],sp */
-  byte1 = bfd_get_8 (abfd, contents + addr);
-  byte2 = bfd_get_8 (abfd, contents + addr + 1);
-
-  if (byte1 == 0xcf)
-    {
-      hash->movm_args = byte2;
-      addr += 2;
-      byte1 = bfd_get_8 (abfd, contents + addr);
-      byte2 = bfd_get_8 (abfd, contents + addr + 1);
-    }
-
-  /* Now figure out how much stack space will be allocated by the movm
-     instruction.  We need this kept separate from the function's normal
-     stack space.  */
-  if (hash->movm_args)
-    {
-      /* Space for d2.  */
-      if (hash->movm_args & 0x80)
-       hash->movm_stack_size += 4;
-
-      /* Space for d3.  */
-      if (hash->movm_args & 0x40)
-       hash->movm_stack_size += 4;
-
-      /* Space for a2.  */
-      if (hash->movm_args & 0x20)
-       hash->movm_stack_size += 4;
-
-      /* Space for a3.  */
-      if (hash->movm_args & 0x10)
-       hash->movm_stack_size += 4;
-
-      /* "other" space.  d0, d1, a0, a1, mdr, lir, lar, 4 byte pad.  */
-      if (hash->movm_args & 0x08)
-       hash->movm_stack_size += 8 * 4;
-
-      if (bfd_get_mach (abfd) == bfd_mach_am33
-         || bfd_get_mach (abfd) == bfd_mach_am33_2)
-       {
-         /* "exother" space.  e0, e1, mdrq, mcrh, mcrl, mcvf */
-         if (hash->movm_args & 0x1)
-           hash->movm_stack_size += 6 * 4;
-
-         /* exreg1 space.  e4, e5, e6, e7 */
-         if (hash->movm_args & 0x2)
-           hash->movm_stack_size += 4 * 4;
-
-         /* exreg0 space.  e2, e3  */
-         if (hash->movm_args & 0x4)
-           hash->movm_stack_size += 2 * 4;
-       }
-    }
-
-  /* Now look for the two stack adjustment variants.  */
-  if (byte1 == 0xf8 && byte2 == 0xfe)
-    {
-      int temp = bfd_get_8 (abfd, contents + addr + 2);
-      temp = ((temp & 0xff) ^ (~0x7f)) + 0x80;
-
-      hash->stack_size = -temp;
-    }
-  else if (byte1 == 0xfa && byte2 == 0xfe)
-    {
-      int temp = bfd_get_16 (abfd, contents + addr + 2);
-      temp = ((temp & 0xffff) ^ (~0x7fff)) + 0x8000;
-      temp = -temp;
-
-      if (temp < 255)
-       hash->stack_size = temp;
-    }
-
-  /* If the total stack to be allocated by the call instruction is more
-     than 255 bytes, then we can't remove the stack adjustment by using
-     "call" (we might still be able to remove the "movm" instruction.  */
-  if (hash->stack_size + hash->movm_stack_size > 255)
-    hash->stack_size = 0;
-
-  return;
-}
-
-/* Delete some bytes from a section while relaxing.  */
-
-static bfd_boolean
-mn10300_elf_relax_delete_bytes (abfd, sec, addr, count)
-     bfd *abfd;
-     asection *sec;
-     bfd_vma addr;
-     int count;
-{
-  Elf_Internal_Shdr *symtab_hdr;
-  unsigned int sec_shndx;
-  bfd_byte *contents;
-  Elf_Internal_Rela *irel, *irelend;
-  Elf_Internal_Rela *irelalign;
-  bfd_vma toaddr;
-  Elf_Internal_Sym *isym, *isymend;
-  struct elf_link_hash_entry **sym_hashes;
-  struct elf_link_hash_entry **end_hashes;
-  unsigned int symcount;
-
-  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
-
-  contents = elf_section_data (sec)->this_hdr.contents;
-
-  /* The deletion must stop at the next ALIGN reloc for an aligment
-     power larger than the number of bytes we are deleting.  */
-
-  irelalign = NULL;
-  toaddr = sec->size;
-
-  irel = elf_section_data (sec)->relocs;
-  irelend = irel + sec->reloc_count;
-
-  /* Actually delete the bytes.  */
-  memmove (contents + addr, contents + addr + count,
-          (size_t) (toaddr - addr - count));
-  sec->size -= count;
-
-  /* Adjust all the relocs.  */
-  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
-    {
-      /* Get the new reloc address.  */
-      if ((irel->r_offset > addr
-          && irel->r_offset < toaddr))
-       irel->r_offset -= count;
-    }
-
-  /* Adjust the local symbols defined in this section.  */
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
-  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
-    {
-      if (isym->st_shndx == sec_shndx
-         && isym->st_value > addr
-         && isym->st_value < toaddr)
-       isym->st_value -= count;
-    }
-
-  /* Now adjust the global symbols defined in this section.  */
-  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
-             - symtab_hdr->sh_info);
-  sym_hashes = elf_sym_hashes (abfd);
-  end_hashes = sym_hashes + symcount;
-  for (; sym_hashes < end_hashes; sym_hashes++)
-    {
-      struct elf_link_hash_entry *sym_hash = *sym_hashes;
-      if ((sym_hash->root.type == bfd_link_hash_defined
-          || sym_hash->root.type == bfd_link_hash_defweak)
-         && sym_hash->root.u.def.section == sec
-         && sym_hash->root.u.def.value > addr
-         && sym_hash->root.u.def.value < toaddr)
-       {
-         sym_hash->root.u.def.value -= count;
-       }
-    }
-
-  return TRUE;
-}
-
-/* Return TRUE if a symbol exists at the given address, else return
-   FALSE.  */
-static bfd_boolean
-mn10300_elf_symbol_address_p (abfd, sec, isym, addr)
-     bfd *abfd;
-     asection *sec;
-     Elf_Internal_Sym *isym;
-     bfd_vma addr;
-{
-  Elf_Internal_Shdr *symtab_hdr;
-  unsigned int sec_shndx;
-  Elf_Internal_Sym *isymend;
-  struct elf_link_hash_entry **sym_hashes;
-  struct elf_link_hash_entry **end_hashes;
-  unsigned int symcount;
-
-  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
-
-  /* Examine all the symbols.  */
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
-    {
-      if (isym->st_shndx == sec_shndx
-         && isym->st_value == addr)
-       return TRUE;
-    }
-
-  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
-             - symtab_hdr->sh_info);
-  sym_hashes = elf_sym_hashes (abfd);
-  end_hashes = sym_hashes + symcount;
-  for (; sym_hashes < end_hashes; sym_hashes++)
-    {
-      struct elf_link_hash_entry *sym_hash = *sym_hashes;
-      if ((sym_hash->root.type == bfd_link_hash_defined
-          || sym_hash->root.type == bfd_link_hash_defweak)
-         && sym_hash->root.u.def.section == sec
-         && sym_hash->root.u.def.value == addr)
-       return TRUE;
-    }
-
-  return FALSE;
-}
-
 /* This is a version of bfd_generic_get_relocated_section_contents
    which uses mn10300_elf_relocate_section.  */
 
 static bfd_byte *
-mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
-                                           data, relocatable, symbols)
-     bfd *output_bfd;
-     struct bfd_link_info *link_info;
-     struct bfd_link_order *link_order;
-     bfd_byte *data;
-     bfd_boolean relocatable;
-     asymbol **symbols;
+mn10300_elf_get_relocated_section_contents (bfd *output_bfd,
+                                           struct bfd_link_info *link_info,
+                                           struct bfd_link_order *link_order,
+                                           bfd_byte *data,
+                                           bfd_boolean relocatable,
+                                           asymbol **symbols)
 {
   Elf_Internal_Shdr *symtab_hdr;
   asection *input_section = link_order->u.indirect.section;
@@ -3576,9 +3585,8 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
       Elf_Internal_Sym *isym, *isymend;
       bfd_size_type amt;
 
-      internal_relocs = (_bfd_elf_link_read_relocs
-                        (input_bfd, input_section, (PTR) NULL,
-                         (Elf_Internal_Rela *) NULL, FALSE));
+      internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
+                                                  NULL, NULL, FALSE);
       if (internal_relocs == NULL)
        goto error_return;
 
@@ -3595,7 +3603,7 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
 
       amt = symtab_hdr->sh_info;
       amt *= sizeof (asection *);
-      sections = (asection **) bfd_malloc (amt);
+      sections = bfd_malloc (amt);
       if (sections == NULL && amt != 0)
        goto error_return;
 
@@ -3617,8 +3625,8 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
        }
 
       if (! mn10300_elf_relocate_section (output_bfd, link_info, input_bfd,
-                                    input_section, data, internal_relocs,
-                                    isymbuf, sections))
+                                         input_section, data, internal_relocs,
+                                         isymbuf, sections))
        goto error_return;
 
       if (sections != NULL)
@@ -3649,34 +3657,33 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
 /* Create an entry in an MN10300 ELF linker hash table.  */
 
 static struct bfd_hash_entry *
-elf32_mn10300_link_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+elf32_mn10300_link_hash_newfunc (struct bfd_hash_entry *entry,
+                                struct bfd_hash_table *table,
+                                const char *string)
 {
   struct elf32_mn10300_link_hash_entry *ret =
     (struct elf32_mn10300_link_hash_entry *) entry;
 
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
-  if (ret == (struct elf32_mn10300_link_hash_entry *) NULL)
-    ret = ((struct elf32_mn10300_link_hash_entry *)
-          bfd_hash_allocate (table,
-                             sizeof (struct elf32_mn10300_link_hash_entry)));
-  if (ret == (struct elf32_mn10300_link_hash_entry *) NULL)
+  if (ret == NULL)
+    ret = (struct elf32_mn10300_link_hash_entry *)
+          bfd_hash_allocate (table, sizeof (* ret));
+  if (ret == NULL)
     return (struct bfd_hash_entry *) ret;
 
   /* Call the allocation method of the superclass.  */
-  ret = ((struct elf32_mn10300_link_hash_entry *)
+  ret = (struct elf32_mn10300_link_hash_entry *)
         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
-                                    table, string));
-  if (ret != (struct elf32_mn10300_link_hash_entry *) NULL)
+                                    table, string);
+  if (ret != NULL)
     {
       ret->direct_calls = 0;
       ret->stack_size = 0;
       ret->movm_args = 0;
       ret->movm_stack_size = 0;
       ret->flags = 0;
+      ret->value = 0;
     }
 
   return (struct bfd_hash_entry *) ret;
@@ -3685,18 +3692,18 @@ elf32_mn10300_link_hash_newfunc (entry, table, string)
 /* Create an mn10300 ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
-elf32_mn10300_link_hash_table_create (abfd)
-     bfd *abfd;
+elf32_mn10300_link_hash_table_create (bfd *abfd)
 {
   struct elf32_mn10300_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf32_mn10300_link_hash_table);
+  bfd_size_type amt = sizeof (* ret);
 
-  ret = (struct elf32_mn10300_link_hash_table *) bfd_malloc (amt);
-  if (ret == (struct elf32_mn10300_link_hash_table *) NULL)
+  ret = bfd_malloc (amt);
+  if (ret == NULL)
     return NULL;
 
-  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
-                                      elf32_mn10300_link_hash_newfunc))
+  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+                                     elf32_mn10300_link_hash_newfunc,
+                                     sizeof (struct elf32_mn10300_link_hash_entry)))
     {
       free (ret);
       return NULL;
@@ -3704,29 +3711,28 @@ elf32_mn10300_link_hash_table_create (abfd)
 
   ret->flags = 0;
   amt = sizeof (struct elf_link_hash_table);
-  ret->static_hash_table
-    = (struct elf32_mn10300_link_hash_table *) bfd_malloc (amt);
+  ret->static_hash_table = bfd_malloc (amt);
   if (ret->static_hash_table == NULL)
     {
       free (ret);
       return NULL;
     }
 
-  if (! _bfd_elf_link_hash_table_init (&ret->static_hash_table->root, abfd,
-                                      elf32_mn10300_link_hash_newfunc))
+  if (!_bfd_elf_link_hash_table_init (&ret->static_hash_table->root, abfd,
+                                     elf32_mn10300_link_hash_newfunc,
+                                     sizeof (struct elf32_mn10300_link_hash_entry)))
     {
       free (ret->static_hash_table);
       free (ret);
       return NULL;
     }
-  return &ret->root.root;
+  return & ret->root.root;
 }
 
 /* Free an mn10300 ELF linker hash table.  */
 
 static void
-elf32_mn10300_link_hash_table_free (hash)
-     struct bfd_link_hash_table *hash;
+elf32_mn10300_link_hash_table_free (struct bfd_link_hash_table *hash)
 {
   struct elf32_mn10300_link_hash_table *ret
     = (struct elf32_mn10300_link_hash_table *) hash;
@@ -3738,8 +3744,7 @@ elf32_mn10300_link_hash_table_free (hash)
 }
 
 static unsigned long
-elf_mn10300_mach (flags)
-     flagword flags;
+elf_mn10300_mach (flagword flags)
 {
   switch (flags & EF_MN10300_MACH)
     {
@@ -3759,10 +3764,9 @@ elf_mn10300_mach (flags)
    file.  This gets the MN10300 architecture right based on the machine
    number.  */
 
-void
-_bfd_mn10300_elf_final_write_processing (abfd, linker)
-     bfd *abfd;
-     bfd_boolean linker ATTRIBUTE_UNUSED;
+static void
+_bfd_mn10300_elf_final_write_processing (bfd *abfd,
+                                        bfd_boolean linker ATTRIBUTE_UNUSED)
 {
   unsigned long val;
 
@@ -3786,9 +3790,8 @@ _bfd_mn10300_elf_final_write_processing (abfd, linker)
   elf_elfheader (abfd)->e_flags |= val;
 }
 
-bfd_boolean
-_bfd_mn10300_elf_object_p (abfd)
-     bfd *abfd;
+static bfd_boolean
+_bfd_mn10300_elf_object_p (bfd *abfd)
 {
   bfd_default_set_arch_mach (abfd, bfd_arch_mn10300,
                             elf_mn10300_mach (elf_elfheader (abfd)->e_flags));
@@ -3798,10 +3801,8 @@ _bfd_mn10300_elf_object_p (abfd)
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
-bfd_boolean
-_bfd_mn10300_elf_merge_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+static bfd_boolean
+_bfd_mn10300_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
@@ -3818,9 +3819,9 @@ _bfd_mn10300_elf_merge_private_bfd_data (ibfd, obfd)
   return TRUE;
 }
 
-#define PLT0_ENTRY_SIZE 15
-#define PLT_ENTRY_SIZE 20
-#define PIC_PLT_ENTRY_SIZE 24
+#define PLT0_ENTRY_SIZE     15
+#define PLT_ENTRY_SIZE      20
+#define PIC_PLT_ENTRY_SIZE  24
 
 static const bfd_byte elf_mn10300_plt0_entry[PLT0_ENTRY_SIZE] =
 {
@@ -3864,7 +3865,7 @@ static const bfd_byte elf_mn10300_pic_plt_entry[PIC_PLT_ENTRY_SIZE] =
 /* Return offset of the GOT id in PLT0 entry.  */
 #define elf_mn10300_plt0_gotid_offset(info) 9
 
-/* Return offset of the temporary in PLT entry */
+/* Return offset of the temporary in PLT entry */
 #define elf_mn10300_plt_temp_offset(info) 8
 
 /* Return offset of the symbol in PLT entry.  */
@@ -3881,9 +3882,7 @@ static const bfd_byte elf_mn10300_pic_plt_entry[PIC_PLT_ENTRY_SIZE] =
 /* Create dynamic sections when linking against a dynamic object.  */
 
 static bfd_boolean
-_bfd_mn10300_elf_create_dynamic_sections (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+_bfd_mn10300_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   flagword   flags;
   asection * s;
@@ -3907,7 +3906,6 @@ _bfd_mn10300_elf_create_dynamic_sections (abfd, info)
 
   /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
      .rel[a].bss sections.  */
-
   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
           | SEC_LINKER_CREATED);
 
@@ -3936,7 +3934,7 @@ _bfd_mn10300_elf_create_dynamic_sections (abfd, info)
          continue;
 
        secname = bfd_get_section_name (abfd, sec);
-       relname = (char *) bfd_malloc (strlen (secname) + 6);
+       relname = bfd_malloc (strlen (secname) + 6);
        strcpy (relname, ".rela");
        strcat (relname, secname);
 
@@ -3994,13 +3992,11 @@ _bfd_mn10300_elf_create_dynamic_sections (abfd, info)
    understand.  */
 
 static bfd_boolean
-_bfd_mn10300_elf_adjust_dynamic_symbol (info, h)
-     struct bfd_link_info * info;
-     struct elf_link_hash_entry * h;
+_bfd_mn10300_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
+                                       struct elf_link_hash_entry * h)
 {
   bfd * dynobj;
   asection * s;
-  unsigned int power_of_two;
 
   dynobj = elf_hash_table (info)->dynobj;
 
@@ -4065,13 +4061,11 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (info, h)
 
       /* We also need to make an entry in the .got.plt section, which
         will be placed in the .got section by the linker script.  */
-
       s = bfd_get_section_by_name (dynobj, ".got.plt");
       BFD_ASSERT (s != NULL);
       s->size += 4;
 
       /* We also need to make an entry in the .rela.plt section.  */
-
       s = bfd_get_section_by_name (dynobj, ".rela.plt");
       BFD_ASSERT (s != NULL);
       s->size += sizeof (Elf32_External_Rela);
@@ -4140,36 +4134,14 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (info, h)
       h->needs_copy = 1;
     }
 
-  /* We need to figure out the alignment required for this symbol.  I
-     have no idea how ELF linkers handle this.  */
-  power_of_two = bfd_log2 (h->size);
-  if (power_of_two > 3)
-    power_of_two = 3;
-
-  /* Apply the required alignment.  */
-  s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
-  if (power_of_two > bfd_get_section_alignment (dynobj, s))
-    {
-      if (! bfd_set_section_alignment (dynobj, s, power_of_two))
-       return FALSE;
-    }
-
-  /* Define the symbol as being at this point in the section.  */
-  h->root.u.def.section = s;
-  h->root.u.def.value = s->size;
-
-  /* Increment the section size to make room for the symbol.  */
-  s->size += h->size;
-
-  return TRUE;
+  return _bfd_elf_adjust_dynamic_copy (h, s);
 }
 
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
-_bfd_mn10300_elf_size_dynamic_sections (output_bfd, info)
-     bfd * output_bfd;
-     struct bfd_link_info * info;
+_bfd_mn10300_elf_size_dynamic_sections (bfd * output_bfd,
+                                       struct bfd_link_info * info)
 {
   bfd * dynobj;
   asection * s;
@@ -4220,12 +4192,12 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info)
         of the dynobj section names depend upon the input files.  */
       name = bfd_get_section_name (dynobj, s);
 
-      if (strcmp (name, ".plt") == 0)
+      if (streq (name, ".plt"))
        {
          /* Remember whether there is a PLT.  */
          plt = s->size != 0;
        }
-      else if (strncmp (name, ".rela", 5) == 0)
+      else if (CONST_STRNEQ (name, ".rela"))
        {
          if (s->size != 0)
            {
@@ -4233,7 +4205,7 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info)
 
              /* Remember whether there are any reloc sections other
                 than .rela.plt.  */
-             if (strcmp (name, ".rela.plt") != 0)
+             if (! streq (name, ".rela.plt"))
                {
                  const char * outname;
 
@@ -4258,8 +4230,8 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info)
              s->reloc_count = 0;
            }
        }
-      else if (strncmp (name, ".got", 4) != 0
-              && strcmp (name, ".dynbss") != 0)
+      else if (! CONST_STRNEQ (name, ".got")
+              && ! streq (name, ".dynbss"))
        /* It's not one of our sections, so don't allocate space.  */
        continue;
 
@@ -4286,7 +4258,7 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info)
         section's contents are written out.  This should not happen,
         but this way if it does, we get a R_MN10300_NONE reloc
         instead of garbage.  */
-      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+      s->contents = bfd_zalloc (dynobj, s->size);
       if (s->contents == NULL)
        return FALSE;
     }
@@ -4336,11 +4308,10 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info)
    dynamic sections here.  */
 
 static bfd_boolean
-_bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
-     bfd * output_bfd;
-     struct bfd_link_info * info;
-     struct elf_link_hash_entry * h;
-     Elf_Internal_Sym * sym;
+_bfd_mn10300_elf_finish_dynamic_symbol (bfd * output_bfd,
+                                       struct bfd_link_info * info,
+                                       struct elf_link_hash_entry * h,
+                                       Elf_Internal_Sym * sym)
 {
   bfd * dynobj;
 
@@ -4439,14 +4410,13 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       Elf_Internal_Rela rel;
 
       /* This symbol has an entry in the global offset table.  Set it up.  */
-
       sgot = bfd_get_section_by_name (dynobj, ".got");
       srel = bfd_get_section_by_name (dynobj, ".rela.got");
       BFD_ASSERT (sgot != NULL && srel != NULL);
 
       rel.r_offset = (sgot->output_section->vma
                      + sgot->output_offset
-                     + (h->got.offset &1));
+                     + (h->got.offset & ~1));
 
       /* If this is a -Bsymbolic link, and the symbol is defined
         locally, we just want to emit a RELATIVE reloc.  Likewise if
@@ -4494,14 +4464,14 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
                      + h->root.u.def.section->output_offset);
       rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_COPY);
       rel.r_addend = 0;
-      bfd_elf32_swap_reloca_out (output_bfd, &rel,
+      bfd_elf32_swap_reloca_out (output_bfd, & rel,
                                 (bfd_byte *) ((Elf32_External_Rela *) s->contents
                                               + s->reloc_count));
       ++ s->reloc_count;
     }
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
-  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+  if (streq (h->root.root.string, "_DYNAMIC")
       || h == elf_hash_table (info)->hgot)
     sym->st_shndx = SHN_ABS;
 
@@ -4511,9 +4481,8 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
 /* Finish up the dynamic sections.  */
 
 static bfd_boolean
-_bfd_mn10300_elf_finish_dynamic_sections (output_bfd, info)
-     bfd * output_bfd;
-     struct bfd_link_info * info;
+_bfd_mn10300_elf_finish_dynamic_sections (bfd * output_bfd,
+                                         struct bfd_link_info * info)
 {
   bfd *      dynobj;
   asection * sgot;
@@ -4639,14 +4608,10 @@ _bfd_mn10300_elf_reloc_type_class (const Elf_Internal_Rela *rela)
 {
   switch ((int) ELF32_R_TYPE (rela->r_info))
     {
-    case R_MN10300_RELATIVE:
-      return reloc_class_relative;
-    case R_MN10300_JMP_SLOT:
-      return reloc_class_plt;
-    case R_MN10300_COPY:
-      return reloc_class_copy;
-    default:
-      return reloc_class_normal;
+    case R_MN10300_RELATIVE:   return reloc_class_relative;
+    case R_MN10300_JMP_SLOT:   return reloc_class_plt;
+    case R_MN10300_COPY:       return reloc_class_copy;
+    default:                   return reloc_class_normal;
     }
 }
 
@@ -4693,6 +4658,8 @@ _bfd_mn10300_elf_reloc_type_class (const Elf_Internal_Rela *rela)
   _bfd_mn10300_elf_adjust_dynamic_symbol
 #define elf_backend_size_dynamic_sections \
   _bfd_mn10300_elf_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
 #define elf_backend_finish_dynamic_symbol \
   _bfd_mn10300_elf_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections \
This page took 0.043431 seconds and 4 git commands to generate.