summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-arm.c18
-rw-r--r--include/elf/ChangeLog4
-rw-r--r--include/elf/arm.h3
4 files changed, 24 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 8cd4935eff4..5701e71fd4e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
2011-05-31 Paul Brook <paul@codesourcery.com>
+ * elf32-arm.c (elf32_arm_final_link_relocate): Only do bl conversion
+ for known functions.
+ (elf32_arm_swap_symbol_in): Only set ST_BRANCH_TO_ARM for function
+ symbols.
+
+2011-05-31 Paul Brook <paul@codesourcery.com>
+
* elf32-arm.c (arm_stub_is_thumb): Add
arm_stub_long_branch_v4t_thumb_tls_pic.
(elf32_arm_final_link_relocate): TLS stubs are always ARM.
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 611e08ed142..58bb367780b 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -8304,7 +8304,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
case, mode switching is performed by the stub. */
if (branch_type == ST_BRANCH_TO_THUMB && !stub_entry)
value |= (1 << 28);
- else
+ else if (stub_entry || branch_type != ST_BRANCH_UNKNOWN)
{
value &= ~(bfd_vma)(1 << 28);
value |= (1 << 24);
@@ -15131,12 +15131,16 @@ elf32_arm_swap_symbol_in (bfd * abfd,
/* New EABI objects mark thumb function symbols by setting the low bit of
the address. */
- if ((ELF_ST_TYPE (dst->st_info) == STT_FUNC
- || ELF_ST_TYPE (dst->st_info) == STT_GNU_IFUNC)
- && (dst->st_value & 1))
+ if (ELF_ST_TYPE (dst->st_info) == STT_FUNC
+ || ELF_ST_TYPE (dst->st_info) == STT_GNU_IFUNC)
{
- dst->st_value &= ~(bfd_vma) 1;
- dst->st_target_internal = ST_BRANCH_TO_THUMB;
+ if (dst->st_value & 1)
+ {
+ dst->st_value &= ~(bfd_vma) 1;
+ dst->st_target_internal = ST_BRANCH_TO_THUMB;
+ }
+ else
+ dst->st_target_internal = ST_BRANCH_TO_ARM;
}
else if (ELF_ST_TYPE (dst->st_info) == STT_ARM_TFUNC)
{
@@ -15146,7 +15150,7 @@ elf32_arm_swap_symbol_in (bfd * abfd,
else if (ELF_ST_TYPE (dst->st_info) == STT_SECTION)
dst->st_target_internal = ST_BRANCH_LONG;
else
- dst->st_target_internal = ST_BRANCH_TO_ARM;
+ dst->st_target_internal = ST_BRANCH_UNKNOWN;
return TRUE;
}
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index a43b34d91bc..d0700468bcd 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,7 @@
+2011-05-31 Paul Brook <paul@codesourcery.com>
+
+ * arm.h (arm_st_branch_type): Add ST_BRANCH_UNKNOWN.
+
2011-04-15 Sergio Durigan Junior <sergiodj@redhat.com>
* common.h (NT_STAPSDT): New define.
diff --git a/include/elf/arm.h b/include/elf/arm.h
index 5b01835a74a..860fdf77afb 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -328,7 +328,8 @@ enum
enum arm_st_branch_type {
ST_BRANCH_TO_ARM,
ST_BRANCH_TO_THUMB,
- ST_BRANCH_LONG
+ ST_BRANCH_LONG,
+ ST_BRANCH_UNKNOWN
};
#define ARM_SYM_BRANCH_TYPE(SYM) \