summaryrefslogtreecommitdiffstats
path: root/tools/toolchain-patches/binutils-2.20.1-ld-thumb-interwork-long-call.diff
diff options
context:
space:
mode:
Diffstat (limited to 'tools/toolchain-patches/binutils-2.20.1-ld-thumb-interwork-long-call.diff')
-rw-r--r--tools/toolchain-patches/binutils-2.20.1-ld-thumb-interwork-long-call.diff569
1 files changed, 0 insertions, 569 deletions
diff --git a/tools/toolchain-patches/binutils-2.20.1-ld-thumb-interwork-long-call.diff b/tools/toolchain-patches/binutils-2.20.1-ld-thumb-interwork-long-call.diff
deleted file mode 100644
index 5eb5debfbf..0000000000
--- a/tools/toolchain-patches/binutils-2.20.1-ld-thumb-interwork-long-call.diff
+++ /dev/null
@@ -1,569 +0,0 @@
-http://sourceware.org/ml/binutils/2010-02/msg00460.html
-
-Drop this patch when binutils 2.21 is out
-diff -ur binutils-2.20.1.orig/bfd/elf32-arm.c binutils-2.20.1/bfd/elf32-arm.c
---- binutils-2.20.1.orig/bfd/elf32-arm.c 2010-06-11 18:48:06.000000000 +0200
-+++ binutils-2.20.1/bfd/elf32-arm.c 2010-06-11 18:51:00.000000000 +0200
-@@ -2401,6 +2401,7 @@
- unsigned long orig_insn;
- char *stub_name;
- enum elf32_arm_stub_type stub_type;
-+ int st_type;
- };
-
- /* A table of relocs applied to branches which might trigger Cortex-A8
-@@ -2647,6 +2648,9 @@
- asection *stub_sec;
- } *stub_group;
-
-+ /* Number of elements in stub_group. */
-+ int top_id;
-+
- /* Assorted information used by elf32_arm_size_stubs. */
- unsigned int bfd_count;
- int top_index;
-@@ -2933,6 +2937,7 @@
- ret->add_stub_section = NULL;
- ret->layout_sections_again = NULL;
- ret->stub_group = NULL;
-+ ret->top_id = 0;
- ret->bfd_count = 0;
- ret->top_index = 0;
- ret->input_list = NULL;
-@@ -3033,7 +3038,7 @@
- arm_type_of_stub (struct bfd_link_info *info,
- asection *input_sec,
- const Elf_Internal_Rela *rel,
-- unsigned char st_type,
-+ int *actual_st_type,
- struct elf32_arm_link_hash_entry *hash,
- bfd_vma destination,
- asection *sym_sec,
-@@ -3048,6 +3053,7 @@
- int thumb_only;
- enum elf32_arm_stub_type stub_type = arm_stub_none;
- int use_plt = 0;
-+ int st_type = *actual_st_type;
-
- /* We don't know the actual type of destination in case it is of
- type STT_SECTION: give up. */
-@@ -3065,14 +3071,15 @@
- + input_sec->output_section->vma
- + rel->r_offset);
-
-- branch_offset = (bfd_signed_vma)(destination - location);
--
- r_type = ELF32_R_TYPE (rel->r_info);
-
- /* Keep a simpler condition, for the sake of clarity. */
-- if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1)
-+ if (globals->splt != NULL
-+ && hash != NULL
-+ && hash->root.plt.offset != (bfd_vma) -1)
- {
- use_plt = 1;
-+
- /* Note when dealing with PLT entries: the main PLT stub is in
- ARM mode, so if the branch is in Thumb mode, another
- Thumb->ARM stub will be inserted later just before the ARM
-@@ -3081,8 +3088,15 @@
- Thumb->Arm one and branch directly to the ARM PLT entry
- because it avoids spreading offset corrections in several
- places. */
-+
-+ destination = (globals->splt->output_section->vma
-+ + globals->splt->output_offset
-+ + hash->root.plt.offset);
-+ st_type = STT_FUNC;
- }
-
-+ branch_offset = (bfd_signed_vma)(destination - location);
-+
- if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
- {
- /* Handle cases where:
-@@ -3176,7 +3190,9 @@
- }
- }
- }
-- else if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32)
-+ else if (r_type == R_ARM_CALL
-+ || r_type == R_ARM_JUMP24
-+ || r_type == R_ARM_PLT32)
- {
- if (st_type == STT_ARM_TFUNC)
- {
-@@ -3231,6 +3247,12 @@
- }
- }
-
-+ /* If a stub is needed, record the actual destination type. */
-+ if (stub_type != arm_stub_none)
-+ {
-+ *actual_st_type = st_type;
-+ }
-+
- return stub_type;
- }
-
-@@ -3240,31 +3262,35 @@
- elf32_arm_stub_name (const asection *input_section,
- const asection *sym_sec,
- const struct elf32_arm_link_hash_entry *hash,
-- const Elf_Internal_Rela *rel)
-+ const Elf_Internal_Rela *rel,
-+ enum elf32_arm_stub_type stub_type)
-+
- {
- char *stub_name;
- bfd_size_type len;
-
- if (hash)
- {
-- len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1;
-+ len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1 + 2 + 1;
- stub_name = bfd_malloc (len);
- if (stub_name != NULL)
-- sprintf (stub_name, "%08x_%s+%x",
-+ sprintf (stub_name, "%08x_%s+%x_%d",
- input_section->id & 0xffffffff,
- hash->root.root.root.string,
-- (int) rel->r_addend & 0xffffffff);
-+ (int) rel->r_addend & 0xffffffff,
-+ (int) stub_type);
- }
- else
- {
-- len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
-+ len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1 + 2 + 1;
- stub_name = bfd_malloc (len);
- if (stub_name != NULL)
-- sprintf (stub_name, "%08x_%x:%x+%x",
-+ sprintf (stub_name, "%08x_%x:%x+%x_%d",
- input_section->id & 0xffffffff,
- sym_sec->id & 0xffffffff,
- (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
-- (int) rel->r_addend & 0xffffffff);
-+ (int) rel->r_addend & 0xffffffff,
-+ (int) stub_type);
- }
-
- return stub_name;
-@@ -3278,7 +3304,8 @@
- const asection *sym_sec,
- struct elf_link_hash_entry *hash,
- const Elf_Internal_Rela *rel,
-- struct elf32_arm_link_hash_table *htab)
-+ struct elf32_arm_link_hash_table *htab,
-+ enum elf32_arm_stub_type stub_type)
- {
- struct elf32_arm_stub_hash_entry *stub_entry;
- struct elf32_arm_link_hash_entry *h = (struct elf32_arm_link_hash_entry *) hash;
-@@ -3296,7 +3323,8 @@
-
- if (h != NULL && h->stub_cache != NULL
- && h->stub_cache->h == h
-- && h->stub_cache->id_sec == id_sec)
-+ && h->stub_cache->id_sec == id_sec
-+ && h->stub_cache->stub_type == stub_type)
- {
- stub_entry = h->stub_cache;
- }
-@@ -3304,7 +3332,7 @@
- {
- char *stub_name;
-
-- stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel);
-+ stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel, stub_type);
- if (stub_name == NULL)
- return NULL;
-
-@@ -3464,7 +3492,7 @@
- /* We have to do the a8 fixes last, as they are less aligned than
- the other veneers. */
- return TRUE;
--
-+
- /* Make a note of the offset within the stubs for this entry. */
- stub_entry->stub_offset = stub_sec->size;
- loc = stub_sec->contents + stub_entry->stub_offset;
-@@ -3499,17 +3527,17 @@
- BFD_ASSERT ((data & 0xff00) == 0xd000);
- data |= ((stub_entry->orig_insn >> 22) & 0xf) << 8;
- }
-- put_thumb_insn (globals, stub_bfd, data, loc + size);
-+ bfd_put_16 (stub_bfd, data, loc + size);
- size += 2;
- }
- break;
-
- case THUMB32_TYPE:
-- put_thumb_insn (globals, stub_bfd,
-- (template_sequence[i].data >> 16) & 0xffff,
-- loc + size);
-- put_thumb_insn (globals, stub_bfd, template_sequence[i].data & 0xffff,
-- loc + size + 2);
-+ bfd_put_16 (stub_bfd,
-+ (template_sequence[i].data >> 16) & 0xffff,
-+ loc + size);
-+ bfd_put_16 (stub_bfd, template_sequence[i].data & 0xffff,
-+ loc + size + 2);
- if (template_sequence[i].r_type != R_ARM_NONE)
- {
- stub_reloc_idx[nrelocs] = i;
-@@ -3519,8 +3547,8 @@
- break;
-
- case ARM_TYPE:
-- put_arm_insn (globals, stub_bfd, template_sequence[i].data,
-- loc + size);
-+ bfd_put_32 (stub_bfd, template_sequence[i].data,
-+ loc + size);
- /* Handle cases where the target is encoded within the
- instruction. */
- if (template_sequence[i].r_type == R_ARM_JUMP24)
-@@ -3599,11 +3627,23 @@
- }
- else
- {
-- _bfd_final_link_relocate (elf32_arm_howto_from_type
-- (template_sequence[stub_reloc_idx[i]].r_type), stub_bfd, stub_sec,
-- stub_sec->contents, stub_entry->stub_offset + stub_reloc_offset[i],
-- sym_value + stub_entry->target_addend,
-- template_sequence[stub_reloc_idx[i]].reloc_addend);
-+ Elf_Internal_Rela rel;
-+ bfd_boolean unresolved_reloc;
-+ char *error_message;
-+ bfd_vma points_to = sym_value + stub_entry->target_addend
-+ + template_sequence[stub_reloc_idx[i]].reloc_addend;
-+
-+ rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i];
-+ rel.r_info = ELF32_R_INFO (0,
-+ template_sequence[stub_reloc_idx[i]].r_type);
-+ rel.r_addend = 0;
-+
-+ elf32_arm_final_link_relocate (elf32_arm_howto_from_type
-+ (template_sequence[stub_reloc_idx[i]].r_type),
-+ stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
-+ points_to, info, stub_entry->target_section, "", stub_entry->st_type,
-+ (struct elf_link_hash_entry *) stub_entry->h, &unresolved_reloc,
-+ &error_message);
- }
-
- return TRUE;
-@@ -3728,6 +3768,7 @@
- htab->stub_group = bfd_zmalloc (amt);
- if (htab->stub_group == NULL)
- return -1;
-+ htab->top_id = top_id;
-
- /* We can't use output_bfd->section_count here to find the top output
- section index as some sections may have been removed, and
-@@ -4009,7 +4050,7 @@
- }
-
- is_32bit_branch = is_b || is_bl || is_blx || is_bcc;
--
-+
- if (((base_vma + i) & 0xfff) == 0xffe
- && insn_32bit
- && is_32bit_branch
-@@ -4178,6 +4219,8 @@
- a8_fixes[num_a8_fixes].orig_insn = insn;
- a8_fixes[num_a8_fixes].stub_name = stub_name;
- a8_fixes[num_a8_fixes].stub_type = stub_type;
-+ a8_fixes[num_a8_fixes].st_type =
-+ is_blx ? STT_FUNC : STT_ARM_TFUNC;
-
- num_a8_fixes++;
- }
-@@ -4193,11 +4236,11 @@
- if (elf_section_data (section)->this_hdr.contents == NULL)
- free (contents);
- }
--
-+
- *a8_fixes_p = a8_fixes;
- *num_a8_fixes_p = num_a8_fixes;
- *a8_fix_table_size_p = a8_fix_table_size;
--
-+
- return FALSE;
- }
-
-@@ -4345,7 +4388,7 @@
- const char *sym_name;
- char *stub_name;
- const asection *id_sec;
-- unsigned char st_type;
-+ int st_type;
- bfd_boolean created_stub = FALSE;
-
- r_type = ELF32_R_TYPE (irela->r_info);
-@@ -4403,7 +4446,7 @@
- /* This is an undefined symbol. It can never
- be resolved. */
- continue;
--
-+
- if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
- sym_value = sym->st_value;
- destination = (sym_value + irela->r_addend
-@@ -4493,7 +4536,7 @@
- {
- /* Determine what (if any) linker stub is needed. */
- stub_type = arm_type_of_stub (info, section, irela,
-- st_type, hash,
-+ &st_type, hash,
- destination, sym_sec,
- input_bfd, sym_name);
- if (stub_type == arm_stub_none)
-@@ -4504,7 +4547,7 @@
-
- /* Get the name of this stub. */
- stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash,
-- irela);
-+ irela, stub_type);
- if (!stub_name)
- goto error_ret_free_internal;
-
-@@ -4703,7 +4746,7 @@
- stub_entry->target_value = a8_fixes[i].offset;
- stub_entry->target_addend = a8_fixes[i].addend;
- stub_entry->orig_insn = a8_fixes[i].orig_insn;
-- stub_entry->st_type = STT_ARM_TFUNC;
-+ stub_entry->st_type = a8_fixes[i].st_type;
-
- size = find_stub_size_and_template (a8_fixes[i].stub_type,
- &template_sequence,
-@@ -6866,6 +6909,7 @@
- ".tls_vars") == 0)
- && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI)
- || !SYMBOL_CALLS_LOCAL (info, h))
-+ && (!strstr (input_section->name, STUB_SUFFIX))
- && (h == NULL
- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- || h->root.type != bfd_link_hash_undefweak)
-@@ -6990,7 +7034,6 @@
- case R_ARM_PC24: /* Arm B/BL instruction. */
- case R_ARM_PLT32:
- {
-- bfd_signed_vma branch_offset;
- struct elf32_arm_stub_hash_entry *stub_entry = NULL;
-
- if (r_type == R_ARM_XPC25)
-@@ -7026,45 +7069,46 @@
- || r_type == R_ARM_JUMP24
- || r_type == R_ARM_PLT32)
- {
-- bfd_vma from;
--
-- /* If the call goes through a PLT entry, make sure to
-- check distance to the right destination address. */
-- if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
-- {
-- value = (splt->output_section->vma
-- + splt->output_offset
-- + h->plt.offset);
-- *unresolved_reloc_p = FALSE;
-- /* The PLT entry is in ARM mode, regardless of the
-- target function. */
-- sym_flags = STT_FUNC;
-- }
-+ enum elf32_arm_stub_type stub_type = arm_stub_none;
-+ struct elf32_arm_link_hash_entry *hash;
-
-- from = (input_section->output_section->vma
-- + input_section->output_offset
-- + rel->r_offset);
-- branch_offset = (bfd_signed_vma)(value - from);
--
-- if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
-- || branch_offset < ARM_MAX_BWD_BRANCH_OFFSET
-- || ((sym_flags == STT_ARM_TFUNC)
-- && (((r_type == R_ARM_CALL) && !globals->use_blx)
-- || (r_type == R_ARM_JUMP24)
-- || (r_type == R_ARM_PLT32) ))
-- )
-+ hash = (struct elf32_arm_link_hash_entry *) h;
-+ stub_type = arm_type_of_stub (info, input_section, rel,
-+ &sym_flags, hash,
-+ value, sym_sec,
-+ input_bfd, sym_name);
-+
-+ if (stub_type != arm_stub_none)
- {
- /* The target is out of reach, so redirect the
- branch to the local stub for this function. */
-
- stub_entry = elf32_arm_get_stub_entry (input_section,
- sym_sec, h,
-- rel, globals);
-+ rel, globals,
-+ stub_type);
- if (stub_entry != NULL)
- value = (stub_entry->stub_offset
- + stub_entry->stub_sec->output_offset
- + stub_entry->stub_sec->output_section->vma);
- }
-+ else
-+ {
-+ /* If the call goes through a PLT entry, make sure to
-+ check distance to the right destination address. */
-+ if (h != NULL
-+ && splt != NULL
-+ && h->plt.offset != (bfd_vma) -1)
-+ {
-+ value = (splt->output_section->vma
-+ + splt->output_offset
-+ + h->plt.offset);
-+ *unresolved_reloc_p = FALSE;
-+ /* The PLT entry is in ARM mode, regardless of the
-+ target function. */
-+ sym_flags = STT_FUNC;
-+ }
-+ }
- }
-
- /* The ARM ELF ABI says that this reloc is computed as: S - P + A
-@@ -7444,58 +7488,29 @@
- }
- }
-
-- /* Handle calls via the PLT. */
-- if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
-- {
-- value = (splt->output_section->vma
-- + splt->output_offset
-- + h->plt.offset);
-- if (globals->use_blx && r_type == R_ARM_THM_CALL)
-- {
-- /* If the Thumb BLX instruction is available, convert the
-- BL to a BLX instruction to call the ARM-mode PLT entry. */
-- lower_insn = (lower_insn & ~0x1000) | 0x0800;
-- sym_flags = STT_FUNC;
-- }
-- else
-- {
-- /* Target the Thumb stub before the ARM PLT entry. */
-- value -= PLT_THUMB_STUB_SIZE;
-- sym_flags = STT_ARM_TFUNC;
-- }
-- *unresolved_reloc_p = FALSE;
-- }
--
-+ enum elf32_arm_stub_type stub_type = arm_stub_none;
- if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
- {
- /* Check if a stub has to be inserted because the destination
- is too far. */
-- bfd_vma from;
-- bfd_signed_vma branch_offset;
-- struct elf32_arm_stub_hash_entry *stub_entry = NULL;
--
-- from = (input_section->output_section->vma
-- + input_section->output_offset
-- + rel->r_offset);
-- branch_offset = (bfd_signed_vma)(value - from);
--
-- if ((!thumb2
-- && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET
-- || (branch_offset < THM_MAX_BWD_BRANCH_OFFSET)))
-- ||
-- (thumb2
-- && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
-- || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
-- || ((sym_flags != STT_ARM_TFUNC)
-- && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
-- || r_type == R_ARM_THM_JUMP24)))
-+ struct elf32_arm_stub_hash_entry *stub_entry;
-+ struct elf32_arm_link_hash_entry *hash;
-+
-+ hash = (struct elf32_arm_link_hash_entry *) h;
-+
-+ stub_type = arm_type_of_stub (info, input_section, rel,
-+ &sym_flags, hash, value, sym_sec,
-+ input_bfd, sym_name);
-+
-+ if (stub_type != arm_stub_none)
- {
- /* The target is out of reach or we are changing modes, so
- redirect the branch to the local stub for this
- function. */
- stub_entry = elf32_arm_get_stub_entry (input_section,
- sym_sec, h,
-- rel, globals);
-+ rel, globals,
-+ stub_type);
- if (stub_entry != NULL)
- value = (stub_entry->stub_offset
- + stub_entry->stub_sec->output_offset
-@@ -7512,6 +7527,33 @@
- }
- }
-
-+ /* Handle calls via the PLT. */
-+ if (stub_type == arm_stub_none
-+ && h != NULL
-+ && splt != NULL
-+ && h->plt.offset != (bfd_vma) -1)
-+ {
-+ value = (splt->output_section->vma
-+ + splt->output_offset
-+ + h->plt.offset);
-+
-+ if (globals->use_blx && r_type == R_ARM_THM_CALL)
-+ {
-+ /* If the Thumb BLX instruction is available, convert
-+ the BL to a BLX instruction to call the ARM-mode
-+ PLT entry. */
-+ lower_insn = (lower_insn & ~0x1000) | 0x0800;
-+ sym_flags = STT_FUNC;
-+ }
-+ else
-+ {
-+ /* Target the Thumb stub before the ARM PLT entry. */
-+ value -= PLT_THUMB_STUB_SIZE;
-+ sym_flags = STT_ARM_TFUNC;
-+ }
-+ *unresolved_reloc_p = FALSE;
-+ }
-+
- relocation = value + signed_addend;
-
- relocation -= (input_section->output_section->vma
-@@ -9298,11 +9340,26 @@
- elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
- {
- struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
-+ asection *sec, *osec;
-
- /* Invoke the regular ELF backend linker to do all the work. */
- if (!bfd_elf_final_link (abfd, info))
- return FALSE;
-
-+ /* Process stub sections (eg BE8 encoding, ...). */
-+ struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
-+ int i;
-+ for(i=0; i<htab->top_id; i++) {
-+ sec = htab->stub_group[i].stub_sec;
-+ if (sec) {
-+ osec = sec->output_section;
-+ elf32_arm_write_section (abfd, info, sec, sec->contents);
-+ if (! bfd_set_section_contents (abfd, osec, sec->contents,
-+ sec->output_offset, sec->size))
-+ return FALSE;
-+ }
-+ }
-+
- /* Write out any glue sections now that we have created all the
- stubs. */
- if (globals->bfd_of_glue_owner != NULL)
-@@ -12875,6 +12932,7 @@
- sym.st_other = 0;
- sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
- sym.st_shndx = osi->sec_shndx;
-+ elf32_arm_section_map_add (osi->sec, names[type][1], offset);
- return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
- }
-