]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/elf-m10300.c
Touches most files in bfd/, so likely will be blamed for everything..
[thirdparty/binutils-gdb.git] / bfd / elf-m10300.c
index ac320d67ca63b9468a8480908fcc714bbbba9711..01211ba9d3215db2a58de5e14870d94583a27dec 100644 (file)
@@ -1,5 +1,6 @@
 /* Matsushita 10300 specific support for 32-bit ELF
-   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -23,8 +24,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "elf-bfd.h"
 #include "elf/mn10300.h"
 
-struct elf32_mn10300_link_hash_entry
-{
+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 bfd_link_info *,
+          asection *, int));
+static boolean mn10300_elf_relocate_section
+  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+          Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean mn10300_elf_relax_section
+  PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
+static bfd_byte * mn10300_elf_get_relocated_section_contents
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+          bfd_byte *, boolean, asymbol **));
+static unsigned long elf_mn10300_mach PARAMS ((flagword));
+
+void    _bfd_mn10300_elf_final_write_processing PARAMS ((bfd *, boolean));
+boolean _bfd_mn10300_elf_object_p PARAMS ((bfd *));
+boolean _bfd_mn10300_elf_merge_private_bfd_data PARAMS ((bfd *,bfd *));
+
+struct elf32_mn10300_link_hash_entry {
   /* The basic elf link hash table entry.  */
   struct elf_link_hash_entry root;
 
@@ -62,8 +80,7 @@ struct elf32_mn10300_link_hash_entry
 /* 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;
 
@@ -119,8 +136,7 @@ static void compute_function_info
    does absolutely nothing.  */
 #define USE_RELA
 
-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,
@@ -264,17 +280,14 @@ static reloc_howto_type elf_mn10300_howto_table[] =
         0xffffff,
         0xffffff,
         false),
-
 };
 
-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, },
@@ -459,7 +472,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
     case R_MN10300_24:
       value += addend;
 
-      if ((long)value > 0x7fffff || (long)value < -0x800000)
+      if ((long) value > 0x7fffff || (long) value < -0x800000)
        return bfd_reloc_overflow;
 
       bfd_put_8 (input_bfd, value & 0xff, hit_data);
@@ -470,7 +483,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
     case R_MN10300_16:
       value += addend;
 
-      if ((long)value > 0x7fff || (long)value < -0x8000)
+      if ((long) value > 0x7fff || (long) value < -0x8000)
        return bfd_reloc_overflow;
 
       bfd_put_16 (input_bfd, value, hit_data);
@@ -479,7 +492,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
     case R_MN10300_8:
       value += addend;
 
-      if ((long)value > 0x7f || (long)value < -0x80)
+      if ((long) value > 0x7f || (long) value < -0x80)
        return bfd_reloc_overflow;
 
       bfd_put_8 (input_bfd, value, hit_data);
@@ -491,7 +504,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
       value -= offset;
       value += addend;
 
-      if ((long)value > 0xff || (long)value < -0x100)
+      if ((long) value > 0xff || (long) value < -0x100)
        return bfd_reloc_overflow;
 
       bfd_put_8 (input_bfd, value, hit_data);
@@ -503,7 +516,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
       value -= offset;
       value += addend;
 
-      if ((long)value > 0xffff || (long)value < -0x10000)
+      if ((long) value > 0xffff || (long) value < -0x10000)
        return bfd_reloc_overflow;
 
       bfd_put_16 (input_bfd, value, hit_data);
@@ -526,7 +539,6 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
       return bfd_reloc_notsupported;
     }
 }
-
 \f
 /* Relocate an MN10300 ELF section.  */
 static boolean
@@ -605,8 +617,8 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       else
        {
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
+         while (h->root.root.type == bfd_link_hash_indirect
+                || h->root.root.type == bfd_link_hash_warning)
            h = (struct elf32_mn10300_link_hash_entry *) h->root.root.u.i.link;
          if (h->root.root.type == bfd_link_hash_defined
              || h->root.root.type == bfd_link_hash_defweak)
@@ -637,7 +649,7 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       if (r != bfd_reloc_ok)
        {
          const char *name;
-         const char *msg = (const char *)0;
+         const char *msg = (const char *) 0;
 
          if (h != NULL)
            name = h->root.root.root.string;
@@ -703,7 +715,7 @@ elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
   struct elf32_mn10300_link_hash_entry *entry;
   unsigned int byte_count = 0;
 
-  entry = (struct elf32_mn10300_link_hash_entry *)gen_entry;
+  entry = (struct elf32_mn10300_link_hash_entry *) gen_entry;
 
   /* If we already know we want to convert "call" to "calls" for calls
      to this symbol, then return now.  */
@@ -823,22 +835,21 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          /* We're going to need all the symbols for each bfd.  */
          symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
-          /* Get cached copy if it exists.  */
-          if (symtab_hdr->contents != NULL)
-            extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
-          else
-            {
-              /* Go get them off disk.  */
-              extsyms = ((Elf32_External_Sym *)
-                         bfd_malloc (symtab_hdr->sh_size));
-              if (extsyms == NULL)
-                goto error_return;
-              free_extsyms = extsyms;
-              if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
-                  || (bfd_read (extsyms, 1, symtab_hdr->sh_size, input_bfd)
-                      != symtab_hdr->sh_size))
-                goto error_return;
-            }
+         /* Get cached copy if it exists.  */
+         if (symtab_hdr->contents != NULL)
+           extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+         else
+           {
+             bfd_size_type amt = symtab_hdr->sh_size;
+             /* Go get them off disk.  */
+             extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
+             if (extsyms == NULL)
+               goto error_return;
+             free_extsyms = extsyms;
+             if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+                 || bfd_bread (extsyms, amt, input_bfd) != amt)
+               goto error_return;
+           }
 
          /* Iterate over each section in this bfd.  */
          for (section = input_bfd->sections;
@@ -857,7 +868,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
              else if (section->_raw_size != 0)
                {
                  /* Go get them off disk.  */
-                 contents = (bfd_byte *)bfd_malloc (section->_raw_size);
+                 contents = (bfd_byte *) bfd_malloc (section->_raw_size);
                  if (contents == NULL)
                    goto error_return;
                  free_contents = contents;
@@ -900,7 +911,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                      r_type = ELF32_R_TYPE (irel->r_info);
                      r_index = ELF32_R_SYM (irel->r_info);
 
-                     if (r_type < 0 || r_type >= (int)R_MN10300_MAX)
+                     if (r_type < 0 || r_type >= (int) R_MN10300_MAX)
                        goto error_return;
 
                      /* We need the name and hash table entry of the target
@@ -913,6 +924,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                        {
                          /* A local symbol.  */
                          Elf_Internal_Sym isym;
+                         struct elf_link_hash_table *elftab;
+                         bfd_size_type amt;
 
                          bfd_elf32_swap_symbol_in (input_bfd,
                                                    extsyms + r_index, &isym);
@@ -941,17 +954,19 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
                          /* Tack on an ID so we can uniquely identify this
                             local symbol in the global hash table.  */
-                         new_name = bfd_malloc (strlen (sym_name) + 10);
+                         amt = strlen (sym_name) + 10;
+                         new_name = bfd_malloc (amt);
                          if (new_name == 0)
                            goto error_return;
 
-                         sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+                         sprintf (new_name, "%s_%08x",
+                                  sym_name, (int) sym_sec);
                          sym_name = new_name;
 
-                         hash = (struct elf32_mn10300_link_hash_entry *)
-                                  elf_link_hash_lookup (&hash_table->static_hash_table->root,
-                                                        sym_name, true,
-                                                        true, false);
+                         elftab = &hash_table->static_hash_table->root;
+                         hash = ((struct elf32_mn10300_link_hash_entry *)
+                                 elf_link_hash_lookup (elftab, sym_name,
+                                                       true, true, false));
                          free (new_name);
                        }
                      else
@@ -1003,6 +1018,9 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                      if (isym.st_shndx == shndx
                          && ELF_ST_TYPE (isym.st_info) == STT_FUNC)
                        {
+                         struct elf_link_hash_table *elftab;
+                         bfd_size_type amt;
+
                          if (isym.st_shndx == SHN_UNDEF)
                            sym_sec = bfd_und_section_ptr;
                          else if (isym.st_shndx > 0
@@ -1015,26 +1033,28 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                          else if (isym.st_shndx == SHN_COMMON)
                            sym_sec = bfd_com_section_ptr;
 
-                         sym_name = bfd_elf_string_from_elf_section (input_bfd,
-                                                       symtab_hdr->sh_link,
-                                                       isym.st_name);
+                         sym_name = (bfd_elf_string_from_elf_section
+                                     (input_bfd, symtab_hdr->sh_link,
+                                      isym.st_name));
 
                          /* Tack on an ID so we can uniquely identify this
                             local symbol in the global hash table.  */
-                         new_name = bfd_malloc (strlen (sym_name) + 10);
+                         amt = strlen (sym_name) + 10;
+                         new_name = bfd_malloc (amt);
                          if (new_name == 0)
                            goto error_return;
 
-                         sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+                         sprintf (new_name, "%s_%08x",
+                                  sym_name, (int) sym_sec);
                          sym_name = new_name;
 
-                         hash = (struct elf32_mn10300_link_hash_entry *)
-                                   elf_link_hash_lookup (&hash_table->static_hash_table->root,
-                                                         sym_name, true,
-                                                         true, false);
+                         elftab = &hash_table->static_hash_table->root;
+                         hash = ((struct elf32_mn10300_link_hash_entry *)
+                                 elf_link_hash_lookup (elftab, sym_name,
+                                                       true, true, false));
                          free (new_name);
                          compute_function_info (input_bfd, hash,
-                                                isym.st_value, contents);
+                                                isym.st_value, contents);
                        }
                    }
 
@@ -1119,22 +1139,21 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          /* We're going to need all the symbols for each bfd.  */
          symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
-          /* Get cached copy if it exists.  */
-          if (symtab_hdr->contents != NULL)
-            extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
-          else
-            {
-              /* Go get them off disk.  */
-              extsyms = ((Elf32_External_Sym *)
-                         bfd_malloc (symtab_hdr->sh_size));
-              if (extsyms == NULL)
-                goto error_return;
-              free_extsyms = extsyms;
-              if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
-                  || (bfd_read (extsyms, 1, symtab_hdr->sh_size, input_bfd)
-                      != symtab_hdr->sh_size))
-                goto error_return;
-            }
+         /* Get cached copy if it exists.  */
+         if (symtab_hdr->contents != NULL)
+           extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+         else
+           {
+             bfd_size_type amt = symtab_hdr->sh_size;
+             /* Go get them off disk.  */
+             extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
+             if (extsyms == NULL)
+               goto error_return;
+             free_extsyms = extsyms;
+             if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+                 || bfd_bread (extsyms, amt, input_bfd) != amt)
+               goto error_return;
+           }
 
          /* Walk over each section in this bfd.  */
          for (section = input_bfd->sections;
@@ -1151,15 +1170,15 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
              if (section->reloc_count != 0)
                {
-                  /* Get a copy of the native relocations.  */
-                  internal_relocs = (_bfd_elf32_link_read_relocs
-                                     (input_bfd, section, (PTR) NULL,
-                                      (Elf_Internal_Rela *) NULL,
-                                      link_info->keep_memory));
-                  if (internal_relocs == NULL)
-                    goto error_return;
-                  if (! link_info->keep_memory)
-                    free_relocs = internal_relocs;
+                 /* Get a copy of the native relocations.  */
+                 internal_relocs = (_bfd_elf32_link_read_relocs
+                                    (input_bfd, section, (PTR) NULL,
+                                     (Elf_Internal_Rela *) NULL,
+                                     link_info->keep_memory));
+                 if (internal_relocs == NULL)
+                   goto error_return;
+                 if (! link_info->keep_memory)
+                   free_relocs = internal_relocs;
                }
 
              /* Get cached copy of section contents if it exists.  */
@@ -1168,7 +1187,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
              else
                {
                  /* Go get them off disk.  */
-                 contents = (bfd_byte *)bfd_malloc (section->_raw_size);
+                 contents = (bfd_byte *) bfd_malloc (section->_raw_size);
                  if (contents == NULL)
                    goto error_return;
                  free_contents = contents;
@@ -1192,6 +1211,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                  asection *sym_sec = NULL;
                  const char *sym_name;
                  char *new_name;
+                 struct elf_link_hash_table *elftab;
+                 bfd_size_type amt;
 
                  bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);
 
@@ -1216,16 +1237,17 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
                  /* Tack on an ID so we can uniquely identify this
                     local symbol in the global hash table.  */
-                 new_name = bfd_malloc (strlen (sym_name) + 10);
+                 amt = strlen (sym_name) + 10;
+                 new_name = bfd_malloc (amt);
                  if (new_name == 0)
                    goto error_return;
-                 sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+                 sprintf (new_name, "%s_%08x", sym_name, (int) sym_sec);
                  sym_name = new_name;
 
-                 sym_hash = (struct elf32_mn10300_link_hash_entry *)
-                           elf_link_hash_lookup (&hash_table->static_hash_table->root,
-                                                 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)
@@ -1243,7 +1265,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                      elf_section_data (section)->this_hdr.contents = contents;
                      free_contents = NULL;
 
-                     symtab_hdr->contents = (bfd_byte *)extsyms;
+                     symtab_hdr->contents = (bfd_byte *) extsyms;
                      free_extsyms = NULL;
 
                      /* Count how many bytes we're going to delete.  */
@@ -1300,7 +1322,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                      elf_section_data (section)->this_hdr.contents = contents;
                      free_contents = NULL;
 
-                     symtab_hdr->contents = (bfd_byte *)extsyms;
+                     symtab_hdr->contents = (bfd_byte *) extsyms;
                      free_extsyms = NULL;
 
                      /* Count how many bytes we're going to delete.  */
@@ -1441,15 +1463,14 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
            extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
          else
            {
+             bfd_size_type amt = symtab_hdr->sh_size;
              /* Go get them off disk.  */
-             extsyms = ((Elf32_External_Sym *)
-                        bfd_malloc (symtab_hdr->sh_size));
+             extsyms = (Elf32_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_read (extsyms, 1, symtab_hdr->sh_size, abfd)
-                     != symtab_hdr->sh_size))
+                 || bfd_bread (extsyms, amt, abfd) != amt)
                goto error_return;
            }
        }
@@ -1487,10 +1508,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
          /* Tack on an ID so we can uniquely identify this
             local symbol in the global hash table.  */
-         new_name = bfd_malloc (strlen (sym_name) + 10);
+         new_name = bfd_malloc ((bfd_size_type) strlen (sym_name) + 10);
          if (new_name == 0)
            goto error_return;
-         sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+         sprintf (new_name, "%s_%08x", sym_name, (int) sym_sec);
          sym_name = new_name;
 
          h = (struct elf32_mn10300_link_hash_entry *)
@@ -1604,7 +1625,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          /* See if the value will fit in 16 bits, note the high value is
             0x7fff + 2 as the target will be two bytes closer if we are
             able to relax.  */
-         if ((long)value < 0x8001 && (long)value > -0x8000)
+         if ((long) value < 0x8001 && (long) value > -0x8000)
            {
              unsigned char code;
 
@@ -1719,7 +1740,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          /* See if the value will fit in 8 bits, note the high value is
             0x7f + 1 as the target will be one bytes closer if we are
             able to relax.  */
-         if ((long)value < 0x80 && (long)value > -0x80)
+         if ((long) value < 0x80 && (long) value > -0x80)
            {
              unsigned char code;
 
@@ -1838,48 +1859,48 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          /* Reverse the condition of the first branch.  */
          switch (code)
            {
-             case 0xc8:
-               code = 0xc9;
-               break;
-             case 0xc9:
-               code = 0xc8;
-               break;
-             case 0xc0:
-               code = 0xc2;
-               break;
-             case 0xc2:
-               code = 0xc0;
-               break;
-             case 0xc3:
-               code = 0xc1;
-               break;
-             case 0xc1:
-               code = 0xc3;
-               break;
-             case 0xc4:
-               code = 0xc6;
-               break;
-             case 0xc6:
-               code = 0xc4;
-               break;
-             case 0xc7:
-               code = 0xc5;
-               break;
-             case 0xc5:
-               code = 0xc7;
-               break;
-             case 0xe8:
-               code = 0xe9;
-               break;
-             case 0x9d:
-               code = 0xe8;
-               break;
-             case 0xea:
-               code = 0xeb;
-               break;
-             case 0xeb:
-               code = 0xea;
-               break;
+           case 0xc8:
+             code = 0xc9;
+             break;
+           case 0xc9:
+             code = 0xc8;
+             break;
+           case 0xc0:
+             code = 0xc2;
+             break;
+           case 0xc2:
+             code = 0xc0;
+             break;
+           case 0xc3:
+             code = 0xc1;
+             break;
+           case 0xc1:
+             code = 0xc3;
+             break;
+           case 0xc4:
+             code = 0xc6;
+             break;
+           case 0xc6:
+             code = 0xc4;
+             break;
+           case 0xc7:
+             code = 0xc5;
+             break;
+           case 0xc5:
+             code = 0xc7;
+             break;
+           case 0xe8:
+             code = 0xe9;
+             break;
+           case 0x9d:
+             code = 0xe8;
+             break;
+           case 0xea:
+             code = 0xeb;
+             break;
+           case 0xeb:
+             code = 0xea;
+             break;
            }
          bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
 
@@ -1909,7 +1930,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          value += irel->r_addend;
 
          /* See if the value will fit in 8 bits.  */
-         if ((long)value < 0x7f && (long)value > -0x80)
+         if ((long) value < 0x7f && (long) value > -0x80)
            {
              unsigned char code;
 
@@ -1921,8 +1942,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
              if (code == 0xfd)
                {
-                 /* Get the second opcode.  */
-                 code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+                 /* Get the second opcode.  */
+                 code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
 
                  /* We can not relax 0x6b, 0x7b, 0x8b, 0x9b as no 24bit
                     equivalent instructions exists.  */
@@ -1954,9 +1975,9 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                          bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
 
                          /* Fix the relocation's type.  */
-                         irel->r_info
-                           ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-                                                        R_MN10300_8);
+                         irel->r_info =
+                           ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                         R_MN10300_8);
 
                          /* Delete two bytes of data.  */
                          if (!mn10300_elf_relax_delete_bytes (abfd, sec,
@@ -1965,12 +1986,11 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
                          /* That will change things, so, we should relax
                             again.  Note that this is not required, and it
-                             may be slow.  */
+                            may be slow.  */
                          *again = true;
                          break;
                        }
                    }
-
                }
            }
        }
@@ -1985,7 +2005,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          /* See if the value will fit in 24 bits.
             We allow any 16bit match here.  We prune those we can't
             handle below.  */
-         if ((long)value < 0x7fffff && (long)value > -0x800000)
+         if ((long) value < 0x7fffff && (long) value > -0x800000)
            {
              unsigned char code;
 
@@ -2003,7 +2023,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                  /* All the am33 32 -> 24 relaxing possibilities.  */
                  /* We can not relax 0x6b, 0x7b, 0x8b, 0x9b as no 24bit
                     equivalent instructions exists.  */
-                 if (code != 0x6b && code != 0x7b
+                 if (code != 0x6b && code != 0x7b
                      && code != 0x8b && code != 0x9b
                      && ((code & 0x0f) == 0x09 || (code & 0x0f) == 0x08
                          || (code & 0x0f) == 0x0a || (code & 0x0f) == 0x0b
@@ -2031,9 +2051,9 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                          bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
 
                          /* Fix the relocation's type.  */
-                         irel->r_info
-                           ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-                                                        R_MN10300_24);
+                         irel->r_info =
+                           ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                         R_MN10300_24);
 
                          /* Delete one byte of data.  */
                          if (!mn10300_elf_relax_delete_bytes (abfd, sec,
@@ -2042,19 +2062,18 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
                          /* That will change things, so, we should relax
                             again.  Note that this is not required, and it
-                             may be slow.  */
+                            may be slow.  */
                          *again = true;
                          break;
                        }
                    }
-
                }
            }
 
          /* See if the value will fit in 16 bits.
             We allow any 16bit match here.  We prune those we can't
             handle below.  */
-         if ((long)value < 0x7fff && (long)value > -0x8000)
+         if ((long) value < 0x7fff && (long) value > -0x8000)
            {
              unsigned char code;
 
@@ -2189,6 +2208,11 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                  case 0x91:
                  case 0x92:
                  case 0x93:
+                   /* sp-based offsets are zero-extended.  */
+                   if (code >= 0x90 && code <= 0x93
+                       && (long)value < 0)
+                     continue;
+
                    /* Note that we've changed the relocation contents, etc.  */
                    elf_section_data (sec)->relocs = internal_relocs;
                    free_relocs = NULL;
@@ -2237,6 +2261,11 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                        && (value & 0x8000))
                      continue;
 
+                   /* mov imm16, an zero-extends the immediate.  */
+                   if (code == 0xdc
+                       && (long)value < 0)
+                     continue;
+
                    /* Note that we've changed the relocation contents, etc.  */
                    elf_section_data (sec)->relocs = internal_relocs;
                    free_relocs = NULL;
@@ -2282,18 +2311,18 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                    break;
 
                  /* mov (abs32),an    -> mov (abs16),an
-                    mov (d32,sp),an   -> mov (d32,sp),an
-                    mov (d32,sp),dn   -> mov (d32,sp),dn
-                    movbu (d32,sp),dn -> movbu (d32,sp),dn
-                    movhu (d32,sp),dn -> movhu (d32,sp),dn
+                    mov (d32,sp),an   -> mov (d16,sp),an
+                    mov (d32,sp),dn   -> mov (d16,sp),dn
+                    movbu (d32,sp),dn -> movbu (d16,sp),dn
+                    movhu (d32,sp),dn -> movhu (d16,sp),dn
                     add imm32,dn      -> add imm16,dn
                     cmp imm32,dn      -> cmp imm16,dn
                     add imm32,an      -> add imm16,an
                     cmp imm32,an      -> cmp imm16,an
-                    and imm32,dn      -> and imm32,dn
-                    or imm32,dn       -> or imm32,dn
-                    xor imm32,dn      -> xor imm32,dn
-                    btst imm32,dn     -> btst imm32,dn */
+                    and imm32,dn      -> and imm16,dn
+                    or imm32,dn       -> or imm16,dn
+                    xor imm32,dn      -> xor imm16,dn
+                    btst imm32,dn     -> btst imm16,dn */
 
                  case 0xa0:
                  case 0xb0:
@@ -2309,6 +2338,16 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                  case 0xe1:
                  case 0xe2:
                  case 0xe3:
+                   /* cmp imm16, an zero-extends the immediate.  */
+                   if (code == 0xdc
+                       && (long)value < 0)
+                     continue;
+
+                   /* So do sp-based offsets.  */
+                   if (code >= 0xb0 && code <= 0xb3
+                       && (long)value < 0)
+                     continue;
+
                    /* Note that we've changed the relocation contents, etc.  */
                    elf_section_data (sec)->relocs = internal_relocs;
                    free_relocs = NULL;
@@ -2357,7 +2396,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
 
                  /* Fix the relocation's type.  */
                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-                                                R_MN10300_16);
+                                              R_MN10300_16);
 
                  /* Delete two bytes of data.  */
                  if (!mn10300_elf_relax_delete_bytes (abfd, sec,
@@ -2551,7 +2590,8 @@ mn10300_elf_relax_delete_bytes (abfd, sec, addr, count)
   irelend = irel + sec->reloc_count;
 
   /* Actually delete the bytes.  */
-  memmove (contents + addr, contents + addr + count, toaddr - addr - count);
+  memmove (contents + addr, contents + addr + count,
+          (size_t) (toaddr - addr - count));
   sec->_cooked_size -= count;
 
   /* Adjust all the relocs.  */
@@ -2684,7 +2724,7 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
-         input_section->_raw_size);
+         (size_t) input_section->_raw_size);
 
   if ((input_section->flags & SEC_RELOC) != 0
       && input_section->reloc_count > 0)
@@ -2692,20 +2732,19 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
       Elf_Internal_Sym *isymp;
       asection **secpp;
       Elf32_External_Sym *esym, *esymend;
+      bfd_size_type size;
 
       if (symtab_hdr->contents != NULL)
        external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
       else
        {
-         external_syms = ((Elf32_External_Sym *)
-                          bfd_malloc (symtab_hdr->sh_info
-                                      * sizeof (Elf32_External_Sym)));
-         if (external_syms == NULL && symtab_hdr->sh_info > 0)
+         size = symtab_hdr->sh_info;
+         size *= sizeof (Elf32_External_Sym);
+         external_syms = (Elf32_External_Sym *) bfd_malloc (size);
+         if (external_syms == NULL && size != 0)
            goto error_return;
          if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
-             || (bfd_read (external_syms, sizeof (Elf32_External_Sym),
-                           symtab_hdr->sh_info, input_bfd)
-                 != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))))
+             || bfd_bread (external_syms, size, input_bfd) != size)
            goto error_return;
        }
 
@@ -2715,15 +2754,16 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
       if (internal_relocs == NULL)
        goto error_return;
 
-      internal_syms = ((Elf_Internal_Sym *)
-                      bfd_malloc (symtab_hdr->sh_info
-                                  * sizeof (Elf_Internal_Sym)));
-      if (internal_syms == NULL && symtab_hdr->sh_info > 0)
+      size = symtab_hdr->sh_info;
+      size *= sizeof (Elf_Internal_Sym);
+      internal_syms = (Elf_Internal_Sym *) bfd_malloc (size);
+      if (internal_syms == NULL && size != 0)
        goto error_return;
 
-      sections = (asection **) bfd_malloc (symtab_hdr->sh_info
-                                          * sizeof (asection *));
-      if (sections == NULL && symtab_hdr->sh_info > 0)
+      size = symtab_hdr->sh_info;
+      size *= sizeof (asection *);
+      sections = (asection **) bfd_malloc (size);
+      if (sections == NULL && size != 0)
        goto error_return;
 
       isymp = internal_syms;
@@ -2834,9 +2874,9 @@ elf32_mn10300_link_hash_table_create (abfd)
      bfd *abfd;
 {
   struct elf32_mn10300_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct elf32_mn10300_link_hash_table);
 
-  ret = ((struct elf32_mn10300_link_hash_table *)
-        bfd_alloc (abfd, sizeof (struct elf32_mn10300_link_hash_table)));
+  ret = (struct elf32_mn10300_link_hash_table *) bfd_alloc (abfd, amt);
   if (ret == (struct elf32_mn10300_link_hash_table *) NULL)
     return NULL;
 
@@ -2848,9 +2888,9 @@ 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_alloc (abfd, sizeof (struct elf_link_hash_table)));
+    = (struct elf32_mn10300_link_hash_table *) bfd_alloc (abfd, amt);
   if (ret->static_hash_table == NULL)
     {
       bfd_release (abfd, ret);
@@ -2867,18 +2907,18 @@ elf32_mn10300_link_hash_table_create (abfd)
   return &ret->root.root;
 }
 
-static int
+static unsigned long
 elf_mn10300_mach (flags)
      flagword flags;
 {
   switch (flags & EF_MN10300_MACH)
     {
-      case E_MN10300_MACH_MN10300:
-      default:
-        return bfd_mach_mn10300;
+    case E_MN10300_MACH_MN10300:
+    default:
+      return bfd_mach_mn10300;
 
-      case E_MN10300_MACH_AM33:
-        return bfd_mach_am33;
+    case E_MN10300_MACH_AM33:
+      return bfd_mach_am33;
     }
 }
 
@@ -2895,14 +2935,14 @@ _bfd_mn10300_elf_final_write_processing (abfd, linker)
 
   switch (bfd_get_mach (abfd))
     {
-      default:
-      case bfd_mach_mn10300:
-       val = E_MN10300_MACH_MN10300;
-       break;
-
-      case bfd_mach_am33:
-       val = E_MN10300_MACH_AM33;
-       break;
+    default:
+    case bfd_mach_mn10300:
+      val = E_MN10300_MACH_MN10300;
+      break;
+
+    case bfd_mach_am33:
+      val = E_MN10300_MACH_AM33;
+      break;
     }
 
   elf_elfheader (abfd)->e_flags &= ~ (EF_MN10300_MACH);
@@ -2914,7 +2954,7 @@ _bfd_mn10300_elf_object_p (abfd)
      bfd *abfd;
 {
   bfd_default_set_arch_mach (abfd, bfd_arch_mn10300,
-                             elf_mn10300_mach (elf_elfheader (abfd)->e_flags));
+                            elf_mn10300_mach (elf_elfheader (abfd)->e_flags));
   return true;
 }
 
@@ -2944,7 +2984,8 @@ _bfd_mn10300_elf_merge_private_bfd_data (ibfd, obfd)
 #define TARGET_LITTLE_SYM      bfd_elf32_mn10300_vec
 #define TARGET_LITTLE_NAME     "elf32-mn10300"
 #define ELF_ARCH               bfd_arch_mn10300
-#define ELF_MACHINE_CODE       EM_CYGNUS_MN10300
+#define ELF_MACHINE_CODE       EM_MN10300
+#define ELF_MACHINE_ALT1       EM_CYGNUS_MN10300
 #define ELF_MAXPAGESIZE                0x1000
 
 #define elf_info_to_howto              mn10300_info_to_howto