aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.c
diff options
context:
space:
mode:
authorVictor Kamensky <victor.kamensky@linaro.org>2014-10-23 11:53:53 +1030
committerAlan Modra <amodra@gmail.com>2014-10-23 11:53:53 +1030
commit685e70ae51e312f7cbcfa8943fffceb540d46640 (patch)
treeb8d9001930ed10eadc94f010cefd8947961993f5 /bfd/elf32-arm.c
parent65e84d12a068d72c94e96a569dac915386494e7a (diff)
downloadgdb-685e70ae51e312f7cbcfa8943fffceb540d46640.zip
gdb-685e70ae51e312f7cbcfa8943fffceb540d46640.tar.gz
gdb-685e70ae51e312f7cbcfa8943fffceb540d46640.tar.bz2
ARM: plt_size functions need to read instructions in right byte order
elf32_arm_plt0_size and elf32_arm_plt_size read instructions to determine what is size of PLT entry. However it does not read instruction correctly in case of ARM big endian V7 case. In this case instructions are still kept in little endian order (BE8). * elf32-arm.c (read_code32): New function to read 32 bit arm instruction. (read_code16): New function to read 16 bit thumb instrution. (elf32_arm_plt0_size, elf32_arm_plt_size): Use read_code32 and read_code16 to read instructions.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r--bfd/elf32-arm.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 996889d..49d0f65 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -15956,6 +15956,26 @@ const struct elf_size_info elf32_arm_size_info =
bfd_elf32_swap_reloca_out
};
+static bfd_vma
+read_code32 (const bfd *abfd, const bfd_byte *addr)
+{
+ /* V7 BE8 code is always little endian. */
+ if ((elf_elfheader (abfd)->e_flags & EF_ARM_BE8) != 0)
+ return bfd_getl32 (addr);
+
+ return bfd_get_32 (abfd, addr);
+}
+
+static bfd_vma
+read_code16 (const bfd *abfd, const bfd_byte *addr)
+{
+ /* V7 BE8 code is always little endian. */
+ if ((elf_elfheader (abfd)->e_flags & EF_ARM_BE8) != 0)
+ return bfd_getl16 (addr);
+
+ return bfd_get_16 (abfd, addr);
+}
+
/* Return size of plt0 entry starting at ADDR
or (bfd_vma) -1 if size can not be determined. */
@@ -15965,7 +15985,7 @@ elf32_arm_plt0_size (const bfd *abfd, const bfd_byte *addr)
bfd_vma first_word;
bfd_vma plt0_size;
- first_word = H_GET_32 (abfd, addr);
+ first_word = read_code32 (abfd, addr);
if (first_word == elf32_arm_plt0_entry[0])
plt0_size = 4 * ARRAY_SIZE (elf32_arm_plt0_entry);
@@ -15990,17 +16010,17 @@ elf32_arm_plt_size (const bfd *abfd, const bfd_byte *start, bfd_vma offset)
const bfd_byte *addr = start + offset;
/* PLT entry size if fixed on Thumb-only platforms. */
- if (H_GET_32(abfd, start) == elf32_thumb2_plt0_entry[0])
+ if (read_code32 (abfd, start) == elf32_thumb2_plt0_entry[0])
return 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
/* Respect Thumb stub if necessary. */
- if (H_GET_16(abfd, addr) == elf32_arm_plt_thumb_stub[0])
+ if (read_code16 (abfd, addr) == elf32_arm_plt_thumb_stub[0])
{
plt_size += 2 * ARRAY_SIZE(elf32_arm_plt_thumb_stub);
}
/* Strip immediate from first add. */
- first_insn = H_GET_32(abfd, addr + plt_size) & 0xffffff00;
+ first_insn = read_code32 (abfd, addr + plt_size) & 0xffffff00;
#ifdef FOUR_WORD_PLT
if (first_insn == elf32_arm_plt_entry[0])