2009-02-23 Christophe Lyon <christophe.lyon@st.com>
authorDaniel Jacobowitz <drow@false.org>
Mon, 23 Feb 2009 21:48:53 +0000 (21:48 +0000)
committerDaniel Jacobowitz <drow@false.org>
Mon, 23 Feb 2009 21:48:53 +0000 (21:48 +0000)
bfd/
* elf32-arm.c (stub_insn_type): New type.
(stub_reloc_type): Likewise.
(insn_sequence): Likewise.
(elf32_arm_stub_long_branch_any_any): Encode using insn_sequence.
(elf32_arm_stub_long_branch_v4t_arm_thumb): Likewise.
(elf32_arm_stub_long_branch_thumb_only): Likewise.
(elf32_arm_stub_long_branch_v4t_thumb_arm): Likewise.
(elf32_arm_stub_short_branch_v4t_thumb_arm): Likewise.
(elf32_arm_stub_long_branch_any_any_pic): Likewise.
(elf32_arm_stub_hash_entry): Add new helper fields.
(stub_hash_newfunc): Initialize these new fields.
(arm_build_one_stub): Encode Arm and Thumb instructions separately
to take endianness into account.
(arm_size_one_stub): Compute size of stubs using insn_sequence.
(arm_map_one_stub): Code is now more generic, thanks to
insn_sequence.

ld/testsuite/
* ld-arm/arm-elf.exp: Add new farcall-thumb-arm-be8 test.
* ld-arm/farcall-thumb-arm-be8.d: New expected result.
* ld-arm/farcall-arm-arm-be8.d: Replace wildcards by instructions.

bfd/ChangeLog
bfd/elf32-arm.c
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/farcall-arm-arm-be8.d
ld/testsuite/ld-arm/farcall-thumb-arm-be8.d [new file with mode: 0644]

index 1c4717f14eed93eb52e22dbf89cb4232a858f280..dbf1d0c24174bc2bac5f9d0accd7b3648aef1ced 100644 (file)
@@ -1,3 +1,22 @@
+2009-02-20  Christophe Lyon  <christophe.lyon@st.com>
+
+       * elf32-arm.c (stub_insn_type): New type.
+       (stub_reloc_type): Likewise.
+       (insn_sequence): Likewise.
+       (elf32_arm_stub_long_branch_any_any): Encode using insn_sequence.
+       (elf32_arm_stub_long_branch_v4t_arm_thumb): Likewise.
+       (elf32_arm_stub_long_branch_thumb_only): Likewise.
+       (elf32_arm_stub_long_branch_v4t_thumb_arm): Likewise.
+       (elf32_arm_stub_short_branch_v4t_thumb_arm): Likewise.
+       (elf32_arm_stub_long_branch_any_any_pic): Likewise.
+       (elf32_arm_stub_hash_entry): Add new helper fields.
+       (stub_hash_newfunc): Initialize these new fields.
+       (arm_build_one_stub): Encode Arm and Thumb instructions separately
+       to take endianness into account.
+       (arm_size_one_stub): Compute size of stubs using insn_sequence.
+       (arm_map_one_stub): Code is now more generic, thanks to
+       insn_sequence.
+
 2009-02-23  Christophe Lyon  <christophe.lyon@st.com>
 
        * elf32-arm.c (elf32_arm_stub_long_branch_thumb_only): Fix stub
index 6cf3322419f072aaf64a5c26f7274a5e33188965..919d4585396522a4b99ba7057644cde1fd9767f1 100644 (file)
@@ -2010,63 +2010,92 @@ static const bfd_vma elf32_arm_symbian_plt_entry [] =
 #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)
 #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)
 
+enum stub_insn_type
+  {
+    THUMB16_TYPE = 1,
+    THUMB32_TYPE,
+    ARM_TYPE,
+    DATA_TYPE
+  };
+
+enum stub_reloc_type
+  {
+    STUB_RELOC_NONE = 0,
+    STUB_RELOC_ABS,
+    STUB_RELOC_PIC,
+  };
+
+#define THUMB16_INSN(X)    {(X), THUMB16_TYPE, R_ARM_NONE, 0}
+#define THUMB32_INSN(X)    {(X), THUMB32_TYPE, R_ARM_NONE, 0}
+#define ARM_INSN(X)        {(X), ARM_TYPE, R_ARM_NONE, 0}
+#define ARM_REL_INSN(X, Z) {(X), ARM_TYPE, R_ARM_JUMP24, (Z)}
+#define DATA_WORD(X,Y,Z)   {(X), DATA_TYPE, (Y), (Z)}
+
+typedef struct
+{
+  bfd_vma data;
+  enum stub_insn_type type;
+  enum stub_reloc_type reloc_type;
+  int reloc_addend;
+}  insn_sequence;
+
 /* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx
    to reach the stub if necessary.  */
-static const bfd_vma elf32_arm_stub_long_branch_any_any[] =
+static const insn_sequence elf32_arm_stub_long_branch_any_any[] =
   {
-    0xe51ff004,         /* ldr   pc, [pc, #-4] */
-    0x00000000,         /* dcd   R_ARM_ABS32(X) */
+    ARM_INSN(0xe51ff004),            /* ldr   pc, [pc, #-4] */
+    DATA_WORD(0, R_ARM_ABS32, 0),    /* dcd   R_ARM_ABS32(X) */
   };
 
 /* V4T Arm -> Thumb long branch stub. Used on V4T where blx is not
    available.  */
-static const bfd_vma elf32_arm_stub_long_branch_v4t_arm_thumb[] =
+static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] =
   {
-    0xe59fc000,         /* ldr   ip, [pc, #0] */
-    0xe12fff1c,         /* bx    ip */
-    0x00000000,         /* dcd   R_ARM_ABS32(X) */
+    ARM_INSN(0xe59fc000),            /* ldr   ip, [pc, #0] */
+    ARM_INSN(0xe12fff1c),            /* bx    ip */
+    DATA_WORD(0, R_ARM_ABS32, 0),    /* dcd   R_ARM_ABS32(X) */
   };
 
 /* Thumb -> Thumb long branch stub. Used on architectures which
    support only this mode, or on V4T where it is expensive to switch
    to ARM.  */
-static const bfd_vma elf32_arm_stub_long_branch_thumb_only[] =
+static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] =
   {
-    0x4802b401,         /* push {r0} */
-                        /* ldr  r0, [pc, #8] */
-    0xbc014684,         /* mov  ip, r0 */
-                        /* pop  {r0} */
-    0xbf004760,         /* bx   ip */
-                        /* nop */
-    0x00000000,         /* dcd  R_ARM_ABS32(X) */
+    THUMB16_INSN(0xb401),             /* push {r0} */
+    THUMB16_INSN(0x4802),             /* ldr  r0, [pc, #8] */
+    THUMB16_INSN(0x4684),             /* mov  ip, r0 */
+    THUMB16_INSN(0xbc01),             /* pop  {r0} */
+    THUMB16_INSN(0x4760),             /* bx   ip */
+    THUMB16_INSN(0xbf00),             /* nop */
+    DATA_WORD(0, R_ARM_ABS32, 0),     /* dcd  R_ARM_ABS32(X) */
   };
 
 /* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not
    available.  */
-static const bfd_vma elf32_arm_stub_long_branch_v4t_thumb_arm[] =
+static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] =
   {
-    0x46c04778,         /* bx   pc */
-                        /* nop   */
-    0xe51ff004,         /* ldr   pc, [pc, #-4] */
-    0x00000000,         /* dcd   R_ARM_ABS32(X) */
+    THUMB16_INSN(0x4778),             /* bx   pc */
+    THUMB16_INSN(0x46c0),             /* nop   */
+    ARM_INSN(0xe51ff004),             /* ldr   pc, [pc, #-4] */
+    DATA_WORD(0, R_ARM_ABS32, 0),     /* dcd   R_ARM_ABS32(X) */
   };
 
 /* V4T Thumb -> ARM short branch stub. Shorter variant of the above
    one, when the destination is close enough.  */
-static const bfd_vma elf32_arm_stub_short_branch_v4t_thumb_arm[] =
+static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] =
   {
-    0x46c04778,         /* bx   pc */
-                        /* nop   */
-    0xea000000,         /* b    (X) */
+    THUMB16_INSN(0x4778),             /* bx   pc */
+    THUMB16_INSN(0x46c0),             /* nop   */
+    ARM_REL_INSN(0xea000000, -8),     /* b    (X-8) */
   };
 
 /* ARM/Thumb -> ARM/Thumb long branch stub, PIC. On V5T and above, use
    blx to reach the stub if necessary.  */
-static const bfd_vma elf32_arm_stub_long_branch_any_any_pic[] =
+static const insn_sequence elf32_arm_stub_long_branch_any_any_pic[] =
   {
-    0xe59fc000,         /* ldr   r12, [pc] */
-    0xe08ff00c,         /* add   pc, pc, ip */
-    0x00000000,         /* dcd   R_ARM_REL32(X-4) */
+    ARM_INSN(0xe59fc000),             /* ldr   r12, [pc] */
+    ARM_INSN(0xe08ff00c),             /* add   pc, pc, ip */
+    DATA_WORD(0, R_ARM_REL32, -4),    /* dcd   R_ARM_REL32(X-4) */
   };
 
 /* Section name for stubs is the associated section name plus this
@@ -2100,7 +2129,14 @@ struct elf32_arm_stub_hash_entry
   bfd_vma target_value;
   asection *target_section;
 
+  /* The stub type.  */
   enum elf32_arm_stub_type stub_type;
+  /* Its encoding size in bytes.  */
+  int stub_size;
+  /* Its template.  */
+  const insn_sequence *stub_template;
+  /* The size of the template (number of entries).  */
+  int stub_template_size;
 
   /* The symbol table entry, if any, that this was derived from.  */
   struct elf32_arm_link_hash_entry *h;
@@ -2469,6 +2505,9 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
       eh->target_value = 0;
       eh->target_section = NULL;
       eh->stub_type = arm_stub_none;
+      eh->stub_size = 0;
+      eh->stub_template = NULL;
+      eh->stub_template_size = 0;
       eh->h = NULL;
       eh->id_sec = NULL;
     }
@@ -3108,9 +3147,11 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
   bfd_vma sym_value;
   int template_size;
   int size;
-  const bfd_vma *template;
+  const insn_sequence *template;
   int i;
   struct elf32_arm_link_hash_table * globals;
+  int stub_reloc_idx = -1;
+  int stub_reloc_offset;
 
   /* Massage our args to the form they really have.  */
   stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
@@ -3136,101 +3177,61 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
               + stub_entry->target_section->output_offset
               + stub_entry->target_section->output_section->vma);
 
-  switch (stub_entry->stub_type)
-    {
-    case arm_stub_long_branch_any_any:
-      template = elf32_arm_stub_long_branch_any_any;
-      template_size = (sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_stub_long_branch_v4t_arm_thumb:
-      template =  elf32_arm_stub_long_branch_v4t_arm_thumb;
-      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_stub_long_branch_thumb_only:
-      template =  elf32_arm_stub_long_branch_thumb_only;
-      template_size = (sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_stub_long_branch_v4t_thumb_arm:
-      template =  elf32_arm_stub_long_branch_v4t_thumb_arm;
-      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_stub_short_branch_v4t_thumb_arm:
-      template =  elf32_arm_stub_short_branch_v4t_thumb_arm;
-      template_size = (sizeof(elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
-      break;
-    case arm_stub_long_branch_any_any_pic:
-      template = elf32_arm_stub_long_branch_any_any_pic;
-      template_size = (sizeof (elf32_arm_stub_long_branch_any_any_pic) / sizeof (bfd_vma)) * 4;
-      break;
-    default:
-      BFD_FAIL ();
-      return FALSE;
-    }
+  template = stub_entry->stub_template;
+  template_size = stub_entry->stub_template_size;
 
   size = 0;
-  for (i = 0; i < (template_size / 4); i++)
+  for (i = 0; i < template_size; i++)
     {
-      /* A 0 pattern is a placeholder, every other pattern is an
-        instruction.  */
-      if (template[i] != 0)
-       put_arm_insn (globals, stub_bfd, template[i], loc + size);
-      else
-       bfd_put_32 (stub_bfd, template[i], loc + size);
+      switch(template[i].type)
+       {
+       case THUMB16_TYPE:
+         put_thumb_insn (globals, stub_bfd, template[i].data, loc + size);
+         size += 2;
+         break;
 
-      size += 4;
+       case ARM_TYPE:
+         put_arm_insn (globals, stub_bfd, template[i].data, loc + size);
+         /* Handle cases where the target is encoded within the
+            instruction.  */
+         if (template[i].reloc_type == R_ARM_JUMP24)
+           {
+             stub_reloc_idx = i;
+             stub_reloc_offset = size;
+           }
+         size += 4;
+         break;
+
+       case DATA_TYPE:
+         bfd_put_32 (stub_bfd, template[i].data, loc + size);
+         stub_reloc_idx = i;
+         stub_reloc_offset = size;
+         size += 4;
+         break;
+
+       default:
+         BFD_FAIL ();
+         return FALSE;
+       }
     }
+
   stub_sec->size += size;
 
+  /* Stub size has already been computed in arm_size_one_stub. Check
+     consistency.  */
+  BFD_ASSERT (size == stub_entry->stub_size);
+
   /* Destination is Thumb. Force bit 0 to 1 to reflect this.  */
   if (stub_entry->st_type == STT_ARM_TFUNC)
     sym_value |= 1;
 
-  switch (stub_entry->stub_type)
-    {
-    case arm_stub_long_branch_any_any:
-      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents,
-                               stub_entry->stub_offset + 4, sym_value, 0);
-      break;
-    case arm_stub_long_branch_v4t_arm_thumb:
-      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents,
-                               stub_entry->stub_offset + 8, sym_value, 0);
-      break;
-    case arm_stub_long_branch_thumb_only:
-      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents,
-                               stub_entry->stub_offset + 12, sym_value, 0);
-      break;
-    case arm_stub_long_branch_v4t_thumb_arm:
-      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents,
-                               stub_entry->stub_offset + 8, sym_value, 0);
-      break;
-    case arm_stub_short_branch_v4t_thumb_arm:
-      {
-       long int rel_offset;
-       static const insn32 t2a3_b_insn = 0xea000000;
-
-       rel_offset = sym_value - (stub_addr + 8 + 4);
+  /* Assume there is one and only one entry to relocate in each stub.  */
+  BFD_ASSERT (stub_reloc_idx != -1);
 
-       put_arm_insn (globals, stub_bfd,
-                     (bfd_vma) t2a3_b_insn | ((rel_offset >> 2) & 0x00FFFFFF),
-                     loc + 4);
-      }
-      break;
-
-    case arm_stub_long_branch_any_any_pic:
-      /* We want the value relative to the address 8 bytes from the
-        start of the stub.  */
-      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_REL32),
-                               stub_bfd, stub_sec, stub_sec->contents,
-                               stub_entry->stub_offset + 8, sym_value, -4);
-      break;
-    default:
-      BFD_FAIL();
-      break;
-    }
+  _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].reloc_type),
+                           stub_bfd, stub_sec, stub_sec->contents,
+                           stub_entry->stub_offset + stub_reloc_offset,
+                           sym_value, template[stub_reloc_idx].reloc_addend);
 
   return TRUE;
 }
@@ -3244,7 +3245,7 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry,
 {
   struct elf32_arm_stub_hash_entry *stub_entry;
   struct elf32_arm_link_hash_table *htab;
-  const bfd_vma *template;
+  const insn_sequence *template;
   int template_size;
   int size;
   int i;
@@ -3257,27 +3258,28 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry,
     {
     case arm_stub_long_branch_any_any:
       template =  elf32_arm_stub_long_branch_any_any;
-      template_size = (sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (bfd_vma)) * 4;
+      template_size = sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (insn_sequence);
+
       break;
     case arm_stub_long_branch_v4t_arm_thumb:
       template =  elf32_arm_stub_long_branch_v4t_arm_thumb;
-      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (bfd_vma)) * 4;
+      template_size = sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (insn_sequence);
       break;
     case arm_stub_long_branch_thumb_only:
       template =  elf32_arm_stub_long_branch_thumb_only;
-      template_size = (sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (bfd_vma)) * 4;
+      template_size = sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (insn_sequence);
       break;
     case arm_stub_long_branch_v4t_thumb_arm:
       template =  elf32_arm_stub_long_branch_v4t_thumb_arm;
-      template_size = (sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
+      template_size = sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (insn_sequence);
       break;
     case arm_stub_short_branch_v4t_thumb_arm:
       template =  elf32_arm_stub_short_branch_v4t_thumb_arm;
-      template_size = (sizeof(elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (bfd_vma)) * 4;
+      template_size = sizeof (elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (insn_sequence);
       break;
     case arm_stub_long_branch_any_any_pic:
       template = elf32_arm_stub_long_branch_any_any_pic;
-      template_size = (sizeof (elf32_arm_stub_long_branch_any_any_pic) / sizeof (bfd_vma)) * 4;
+      template_size = sizeof (elf32_arm_stub_long_branch_any_any_pic) / sizeof (insn_sequence);
       break;
     default:
       BFD_FAIL ();
@@ -3286,10 +3288,35 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry,
     }
 
   size = 0;
-  for (i = 0; i < (template_size / 4); i++)
-      size += 4;
+  for (i = 0; i < template_size; i++)
+    {
+      switch(template[i].type)
+       {
+       case THUMB16_TYPE:
+         size += 2;
+         break;
+
+       case ARM_TYPE:
+         size += 4;
+         break;
+
+       case DATA_TYPE:
+         size += 4;
+         break;
+
+       default:
+         BFD_FAIL ();
+         return FALSE;
+       }
+    }
+
+  stub_entry->stub_size = size;
+  stub_entry->stub_template = template;
+  stub_entry->stub_template_size = template_size;
+
   size = (size + 7) & ~7;
   stub_entry->stub_sec->size += size;
+
   return TRUE;
 }
 
@@ -11665,6 +11692,11 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
   bfd_vma addr;
   char *stub_name;
   output_arch_syminfo *osi;
+  const insn_sequence *template;
+  enum stub_insn_type prev_type;
+  int size;
+  int i;
+  enum map_symbol_type sym_type;
 
   /* Massage our args to the form they really have.  */
   stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
@@ -11683,62 +11715,70 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
   addr = (bfd_vma) stub_entry->stub_offset;
   stub_name = stub_entry->output_name;
 
-  switch (stub_entry->stub_type)
+  template = stub_entry->stub_template;
+  switch(template[0].type)
     {
-    case arm_stub_long_branch_any_any:
-      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 8))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 4))
-       return FALSE;
-      break;
-    case arm_stub_long_branch_v4t_arm_thumb:
-      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 12))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
+    case ARM_TYPE:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, stub_entry->stub_size))
        return FALSE;
       break;
-    case arm_stub_long_branch_thumb_only:
-      if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 16))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
-       return FALSE;
-      break;
-    case arm_stub_long_branch_v4t_thumb_arm:
-      if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 20))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 4))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
-       return FALSE;
-      break;
-    case arm_stub_short_branch_v4t_thumb_arm:
-      if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1, 8))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 4))
-       return FALSE;
-      break;
-    case arm_stub_long_branch_any_any_pic:
-      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 12))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
+    case THUMB16_TYPE:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1,
+                                     stub_entry->stub_size))
        return FALSE;
       break;
     default:
       BFD_FAIL ();
     }
 
+  prev_type = DATA_TYPE;
+  size = 0;
+  for (i = 0; i < stub_entry->stub_template_size; i++)
+    {
+      switch(template[i].type)
+       {
+       case ARM_TYPE:
+         sym_type = ARM_MAP_ARM;
+         break;
+
+       case THUMB16_TYPE:
+         sym_type = ARM_MAP_THUMB;
+         break;
+
+       case DATA_TYPE:
+         sym_type = ARM_MAP_DATA;
+         break;
+
+       default:
+         BFD_FAIL ();
+       }
+
+      if (template[i].type != prev_type)
+       {
+         prev_type = template[i].type;
+         if (!elf32_arm_output_map_sym (osi, sym_type, addr + size))
+           return FALSE;
+       }
+
+      switch(template[i].type)
+       {
+       case ARM_TYPE:
+         size += 4;
+         break;
+
+       case THUMB16_TYPE:
+         size += 2;
+         break;
+
+       case DATA_TYPE:
+         size += 4;
+         break;
+
+       default:
+         BFD_FAIL ();
+       }
+    }
+
   return TRUE;
 }
 
index a8286531f4dd1a2f8c6cde2177d4fa6867ad3455..e6024c31139e07c269072cdb332aac24b137d9fb 100644 (file)
@@ -1,4 +1,11 @@
 2009-02-23  Christophe Lyon  <christophe.lyon@st.com>
+
+       * ld-arm/arm-elf.exp: Add new farcall-thumb-arm-be8 test.
+       * ld-arm/farcall-thumb-arm-be8.d: New expected result.
+       * ld-arm/farcall-arm-arm-be8.d: Replace wildcards by instructions.
+
+2009-02-23  Christophe Lyon  <christophe.lyon@st.com>
+
        * ld-arm/arm-elf.exp: Rewrite non-EABI variants of
        thumb2-bl-as-thumb1-bad and thumb2-bl-bad tests, which now
        pass. farcall-thumb-thumb now passes in EABI mode.
index f850f741bdd5bd121886d6c04e29aee3f07dc243..43b6f80a6f0345d7fa75a40b6e09784c8fd4d02e 100644 (file)
@@ -297,6 +297,9 @@ set armeabitests {
     {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
      "farcall-thumb-arm"}
+    {"Thumb-ARM farcall (BE8)" "-Ttext 0x1000 --section-start .foo=0x2001014 -EB --be8" "-W -EB" {farcall-thumb-arm.s}
+     {{objdump -d farcall-thumb-arm-be8.d}}
+     "farcall-thumb-arm"}
     {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s}
      {{objdump -d farcall-thumb-arm-short.d}}
      "farcall-thumb-arm-short"}
index 524ce6a8cf49ba46af49e4307f25ec50fff2acc1..72bbff8d0aeed7487962e78d31ad3df78aeb8c86 100644 (file)
@@ -3,12 +3,12 @@
 Disassembly of section .text:
 
 00001000 <__bar_veneer>:
-    1000:      04f01fe5        .*
+    1000:      04f01fe5        ldr     pc, \[pc, #-4\] ; 1004 <__bar_veneer\+0x4>
     1004:      02001020        .word   0x02001020
 
 00001008 <_start>:
-    1008:      fcffffeb        .*
+    1008:      fcffffeb        bl      1000 <__bar_veneer>
 Disassembly of section .foo:
 
 02001020 <bar>:
- 2001020:      1eff2fe1        .*
+ 2001020:      1eff2fe1        bx      lr
diff --git a/ld/testsuite/ld-arm/farcall-thumb-arm-be8.d b/ld/testsuite/ld-arm/farcall-thumb-arm-be8.d
new file mode 100644 (file)
index 0000000..8aeb805
--- /dev/null
@@ -0,0 +1,17 @@
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <__bar_from_thumb>:
+    1000:      7847            bx      pc
+    1002:      c046            nop.*
+    1004:      04f01fe5        ldr     pc, \[pc, #-4\] ; 1008 <__bar_from_thumb\+0x8>
+    1008:      02001014        .word   0x02001014
+    100c:      00000000        .word   0x00000000
+
+00001010 <_start>:
+    1010:      fff7 f6ff       bl      1000 <__bar_from_thumb>
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:      1eff2fe1        bx      lr