#define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)
#define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)
-static const bfd_vma arm_long_branch_stub[] =
+/* 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[] =
{
0xe51ff004, /* ldr pc, [pc, #-4] */
0x00000000, /* dcd R_ARM_ABS32(X) */
};
-static const bfd_vma arm_thumb_v4t_long_branch_stub[] =
+/* 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[] =
{
0xe59fc000, /* ldr ip, [pc, #0] */
0xe12fff1c, /* bx ip */
0x00000000, /* dcd R_ARM_ABS32(X) */
};
-static const bfd_vma arm_thumb_thumb_long_branch_stub[] =
+/* 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[] =
{
0x4e02b540, /* push {r6, lr} */
/* ldr r6, [pc, #8] */
0x00000000, /* dcd R_ARM_ABS32(X) */
};
-static const bfd_vma arm_thumb_arm_v4t_long_branch_stub[] =
+/* 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[] =
{
0x4e03b540, /* push {r6, lr} */
/* ldr r6, [pc, #12] */
0x00000000, /* dcd R_ARM_ABS32(X) */
};
-static const bfd_vma arm_thumb_arm_v4t_short_branch_stub[] =
+/* 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[] =
{
0x46c04778, /* bx pc */
/* nop */
0xea000000, /* b (X) */
};
-static const bfd_vma arm_pic_long_branch_stub[] =
+/* 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[] =
{
0xe59fc000, /* ldr r12, [pc] */
0xe08ff00c, /* add pc, pc, ip */
enum elf32_arm_stub_type
{
arm_stub_none,
- arm_stub_long_branch,
- arm_thumb_v4t_stub_long_branch,
- arm_thumb_thumb_stub_long_branch,
- arm_thumb_arm_v4t_stub_long_branch,
- arm_thumb_arm_v4t_stub_short_branch,
- arm_stub_pic_long_branch,
+ arm_stub_long_branch_any_any,
+ arm_stub_long_branch_v4t_arm_thumb,
+ arm_stub_long_branch_thumb_only,
+ arm_stub_long_branch_v4t_thumb_arm,
+ arm_stub_short_branch_v4t_thumb_arm,
+ arm_stub_long_branch_any_any_pic,
};
struct elf32_arm_stub_hash_entry
{
switch (stub_type)
{
- case arm_thumb_thumb_stub_long_branch:
- case arm_thumb_arm_v4t_stub_long_branch:
- case arm_thumb_arm_v4t_stub_short_branch:
+ case arm_stub_long_branch_thumb_only:
+ case arm_stub_long_branch_v4t_thumb_arm:
+ case arm_stub_short_branch_v4t_thumb_arm:
return TRUE;
case arm_stub_none:
BFD_FAIL ();
{
stub_type = (info->shared | globals->pic_veneer)
? ((globals->use_blx)
- ? arm_stub_pic_long_branch
+ ? arm_stub_long_branch_any_any_pic
: arm_stub_none)
: (globals->use_blx)
- ? arm_stub_long_branch
+ ? arm_stub_long_branch_any_any
: arm_stub_none;
}
else
stub_type = (info->shared | globals->pic_veneer)
? arm_stub_none
: (globals->use_blx)
- ? arm_thumb_thumb_stub_long_branch
+ ? arm_stub_long_branch_thumb_only
: arm_stub_none;
}
}
stub_type = (info->shared | globals->pic_veneer)
? ((globals->use_blx)
- ? arm_stub_pic_long_branch
+ ? arm_stub_long_branch_any_any_pic
: arm_stub_none)
: (globals->use_blx)
- ? arm_stub_long_branch
- : arm_thumb_arm_v4t_stub_long_branch;
+ ? arm_stub_long_branch_any_any
+ : arm_stub_long_branch_v4t_thumb_arm;
/* Handle v4t short branches. */
- if ((stub_type == arm_thumb_arm_v4t_stub_long_branch)
+ if ((stub_type == arm_stub_long_branch_v4t_thumb_arm)
&& (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)
&& (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET))
- stub_type = arm_thumb_arm_v4t_stub_short_branch;
+ stub_type = arm_stub_short_branch_v4t_thumb_arm;
}
}
}
|| !globals->use_blx)
{
stub_type = (info->shared | globals->pic_veneer)
- ? arm_stub_pic_long_branch
+ ? arm_stub_long_branch_any_any_pic
: (globals->use_blx)
- ? arm_stub_long_branch
- : arm_thumb_v4t_stub_long_branch;
+ ? arm_stub_long_branch_any_any
+ : arm_stub_long_branch_v4t_arm_thumb;
}
}
else
|| (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
{
stub_type = (info->shared | globals->pic_veneer)
- ? arm_stub_pic_long_branch
- : arm_stub_long_branch;
+ ? arm_stub_long_branch_any_any_pic
+ : arm_stub_long_branch_any_any;
}
}
}
switch (stub_entry->stub_type)
{
- case arm_stub_long_branch:
- template = arm_long_branch_stub;
- template_size = (sizeof (arm_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_v4t_stub_long_branch:
- template = arm_thumb_v4t_long_branch_stub;
- template_size = (sizeof (arm_thumb_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_thumb_stub_long_branch:
- template = arm_thumb_thumb_long_branch_stub;
- template_size = (sizeof (arm_thumb_thumb_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_arm_v4t_stub_long_branch:
- template = arm_thumb_arm_v4t_long_branch_stub;
- template_size = (sizeof (arm_thumb_arm_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_arm_v4t_stub_short_branch:
- template = arm_thumb_arm_v4t_short_branch_stub;
- template_size = (sizeof(arm_thumb_arm_v4t_short_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_pic_long_branch:
- template = arm_pic_long_branch_stub;
- template_size = (sizeof (arm_pic_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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 ();
switch (stub_entry->stub_type)
{
- case arm_stub_long_branch:
+ 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_thumb_v4t_stub_long_branch:
+ 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_thumb_thumb_stub_long_branch:
+ 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_thumb_arm_v4t_stub_long_branch:
+ 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 + 16, sym_value, 0);
break;
- case arm_thumb_arm_v4t_stub_short_branch:
+ case arm_stub_short_branch_v4t_thumb_arm:
{
long int rel_offset;
static const insn32 t2a3_b_insn = 0xea000000;
}
break;
- case arm_stub_pic_long_branch:
+ 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),
switch (stub_entry->stub_type)
{
- case arm_stub_long_branch:
- template = arm_long_branch_stub;
- template_size = (sizeof (arm_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_v4t_stub_long_branch:
- template = arm_thumb_v4t_long_branch_stub;
- template_size = (sizeof (arm_thumb_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_thumb_stub_long_branch:
- template = arm_thumb_thumb_long_branch_stub;
- template_size = (sizeof (arm_thumb_thumb_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_arm_v4t_stub_long_branch:
- template = arm_thumb_arm_v4t_long_branch_stub;
- template_size = (sizeof (arm_thumb_arm_v4t_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_thumb_arm_v4t_stub_short_branch:
- template = arm_thumb_arm_v4t_short_branch_stub;
- template_size = (sizeof(arm_thumb_arm_v4t_short_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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_pic_long_branch:
- template = arm_pic_long_branch_stub;
- template_size = (sizeof (arm_pic_long_branch_stub) / sizeof (bfd_vma)) * 4;
+ 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 ();
switch (stub_entry->stub_type)
{
- case arm_stub_long_branch:
+ 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))
if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 4))
return FALSE;
break;
- case arm_thumb_v4t_stub_long_branch:
+ 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))
if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
return FALSE;
break;
- case arm_thumb_thumb_stub_long_branch:
+ 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))
if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
return FALSE;
break;
- case arm_thumb_arm_v4t_stub_long_branch:
+ 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))
if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
return FALSE;
break;
- case arm_thumb_arm_v4t_stub_short_branch:
+ 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_ARM, addr + 4))
return FALSE;
break;
- case arm_stub_pic_long_branch:
+ 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))