From 4dc3c23df4601114765f755fac6867f82844bc4d Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 8 Sep 2009 10:34:27 +0000 Subject: [PATCH] * 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. --- binutils/ChangeLog | 11 +++++++++++ binutils/dwarf.c | 10 ++++++++++ binutils/readelf.c | 47 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index d9c1562f820..1722fe7ee83 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,14 @@ +2009-09-08 Alan Modra + + * 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 * readelf.c (is_none_reloc , is_none_reloc ): diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 46b6929a011..6c9a1a6fa7e 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 09a4b1cef6e..590c70d5a38 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; @@ -8099,6 +8104,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. */ @@ -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)) -- 2.30.2