aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2009-09-08 10:34:27 +0000
committerAlan Modra <amodra@gmail.com>2009-09-08 10:34:27 +0000
commit4dc3c23df4601114765f755fac6867f82844bc4d (patch)
tree93aaef4b9c22529c46d3fe9fde14a2756c5814be
parent8a7e4aa01276c840311b72c0b5c45bd703d3a1a2 (diff)
downloadgdb-4dc3c23df4601114765f755fac6867f82844bc4d.zip
gdb-4dc3c23df4601114765f755fac6867f82844bc4d.tar.gz
gdb-4dc3c23df4601114765f755fac6867f82844bc4d.tar.bz2
* 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.
-rw-r--r--binutils/ChangeLog11
-rw-r--r--binutils/dwarf.c10
-rw-r--r--binutils/readelf.c47
3 files changed, 61 insertions, 7 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index d9c1562..1722fe7 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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>):
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 46b6929..6c9a1a6 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -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)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 09a4b1c..590c70d 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -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))