OSDN Git Service

* dwarf.c (byte_get_little_endian): Handle size of 3.
authorAlan Modra <amodra@bigpond.net.au>
Tue, 8 Sep 2009 10:34:27 +0000 (10:34 +0000)
committerAlan Modra <amodra@bigpond.net.au>
Tue, 8 Sep 2009 10:34:27 +0000 (10:34 +0000)
(byte_get_big_endian): Likewise.
* readelf.c (byte_put_little_endian): Likewise.
(byte_put_big_endian): Likewise.
(is_24bit_abs_reloc): New function.
(is_none_reloc): Formatting.
(apply_relocations): Use is_24bit_abs_reloc.  Handle pj and xtensa
reloc peculiarity.

binutils/ChangeLog
binutils/dwarf.c
binutils/readelf.c

index d9c1562..1722fe7 100644 (file)
@@ -1,3 +1,14 @@
+2009-09-08  Alan Modra  <amodra@bigpond.net.au>
+
+       * dwarf.c (byte_get_little_endian): Handle size of 3.
+       (byte_get_big_endian): Likewise.
+       * readelf.c (byte_put_little_endian): Likewise.
+       (byte_put_big_endian): Likewise.
+       (is_24bit_abs_reloc): New function.
+       (is_none_reloc): Formatting.
+       (apply_relocations): Use is_24bit_abs_reloc.  Handle pj and xtensa
+       reloc peculiarity.
+
 2009-09-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * readelf.c (is_none_reloc <EM_XTENSA_OLD>, is_none_reloc <EM_XTENSA>):
index 46b6929..6c9a1a6 100644 (file)
@@ -72,6 +72,11 @@ byte_get_little_endian (unsigned char *field, int size)
       return  ((unsigned int) (field[0]))
        |    (((unsigned int) (field[1])) << 8);
 
+    case 3:
+      return  ((unsigned long) (field[0]))
+       |    (((unsigned long) (field[1])) << 8)
+       |    (((unsigned long) (field[2])) << 16);
+
     case 4:
       return  ((unsigned long) (field[0]))
        |    (((unsigned long) (field[1])) << 8)
@@ -114,6 +119,11 @@ byte_get_big_endian (unsigned char *field, int size)
     case 2:
       return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
 
+    case 3:
+      return ((unsigned long) (field[2]))
+       |   (((unsigned long) (field[1])) << 8)
+       |   (((unsigned long) (field[0])) << 16);
+
     case 4:
       return ((unsigned long) (field[3]))
        |   (((unsigned long) (field[2])) << 8)
index 09a4b1c..590c70d 100644 (file)
@@ -342,6 +342,8 @@ byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
       /* Fall through.  */
     case 4:
       field[3] = (value >> 24) & 0xff;
+      /* Fall through.  */
+    case 3:
       field[2] = (value >> 16) & 0xff;
       /* Fall through.  */
     case 2:
@@ -505,8 +507,11 @@ byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
       /* Fall through.  */
     case 4:
       field[3] = value & 0xff;
-      field[2] = (value >> 8) & 0xff;
-      value >>= 16;
+      value >>= 8;
+      /* Fall through.  */
+    case 3:
+      field[2] = value & 0xff;
+      value >>= 8;
       /* Fall through.  */
     case 2:
       field[1] = value & 0xff;
@@ -8100,6 +8105,22 @@ is_64bit_pcrel_reloc (unsigned int reloc_type)
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+   a 24-bit absolute RELA relocation used in DWARF debug sections.  */
+
+static bfd_boolean
+is_24bit_abs_reloc (unsigned int reloc_type)
+{
+  switch (elf_header.e_machine)
+    {
+    case EM_CYGNUS_MN10200:
+    case EM_MN10200:
+      return reloc_type == 4; /* R_MN10200_24.  */
+    default:
+      return FALSE;
+    }
+}
+
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 16-bit absolute RELA relocation used in DWARF debug sections.  */
 
 static bfd_boolean
@@ -8165,10 +8186,10 @@ is_none_reloc (unsigned int reloc_type)
       return reloc_type == 0;
     case EM_XTENSA_OLD:
     case EM_XTENSA:
-      return reloc_type == 0      /* R_XTENSA_NONE.  */
-            || reloc_type == 17  /* R_XTENSA_DIFF8.  */
-            || reloc_type == 18  /* R_XTENSA_DIFF16.  */
-            || reloc_type == 19; /* R_XTENSA_DIFF32.  */
+      return (reloc_type == 0      /* R_XTENSA_NONE.  */
+             || reloc_type == 17  /* R_XTENSA_DIFF8.  */
+             || reloc_type == 18  /* R_XTENSA_DIFF16.  */
+             || reloc_type == 19  /* R_XTENSA_DIFF32.  */);
     }
   return FALSE;
 }
@@ -8250,6 +8271,8 @@ apply_relocations (void * file,
          else if (is_64bit_abs_reloc (reloc_type)
                   || is_64bit_pcrel_reloc (reloc_type))
            reloc_size = 8;
+         else if (is_24bit_abs_reloc (reloc_type))
+           reloc_size = 3;
          else if (is_16bit_abs_reloc (reloc_type))
            reloc_size = 2;
          else
@@ -8293,7 +8316,17 @@ apply_relocations (void * file,
              continue;
            }
 
-         addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size);
+         addend = 0;
+         if (is_rela)
+           addend += rp->r_addend;
+         /* R_XTENSA_32 and R_PJ_DATA_DIR32 are partial_inplace.  */
+         if (!is_rela
+             || (elf_header.e_machine == EM_XTENSA
+                 && reloc_type == 1)
+             || ((elf_header.e_machine == EM_PJ
+                  || elf_header.e_machine == EM_PJ_OLD)
+                 && reloc_type == 1))
+           addend += byte_get (loc, reloc_size);
 
          if (is_32bit_pcrel_reloc (reloc_type)
              || is_64bit_pcrel_reloc (reloc_type))