mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-23 01:08:50 +08:00
bfd/
* elf32-arm.c (elf32_arm_stub_type): Add arm_stub_a8_veneer_lwm. (arm_build_one_stub): Build a8 veneers as a separate pass. (cortex_a8_erratum_scan): Add prev_num_a8_fixes and stub_changed_p parameters. Use them to check if we create a different a8 fixup than the previous pass. (elf32_arm_size_stubs): Move scope of stub_changed and prev_num_a8_fixes into main loop. (elf32_arm_build_stubs): Build a8 veneers in a second pass. ld/testsuite/ * ld-arm/cortex-a8-far-1.s: New. * ld-arm/cortex-a8-far-2.s: New. * ld-arm/cortex-a8-far.d: New. * ld-arm/arm-elf.exp: Add new test.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2009-08-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
* elf32-arm.c (elf32_arm_stub_type): Add arm_stub_a8_veneer_lwm.
|
||||||
|
(arm_build_one_stub): Build a8 veneers as a separate pass.
|
||||||
|
(cortex_a8_erratum_scan): Add prev_num_a8_fixes and stub_changed_p
|
||||||
|
parameters. Use them to check if we create a different a8 fixup
|
||||||
|
than the previous pass.
|
||||||
|
(elf32_arm_size_stubs): Move scope of stub_changed and
|
||||||
|
prev_num_a8_fixes into main loop.
|
||||||
|
(elf32_arm_build_stubs): Build a8 veneers in a second pass.
|
||||||
|
|
||||||
2009-08-04 Alan Modra <amodra@bigpond.net.au>
|
2009-08-04 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* elf32-ppc.c (ppc_elf_relax_section): Correct conditions under
|
* elf32-ppc.c (ppc_elf_relax_section): Correct conditions under
|
||||||
|
@ -2228,6 +2228,8 @@ static const insn_sequence elf32_arm_stub_a8_veneer_blx[] =
|
|||||||
enum elf32_arm_stub_type {
|
enum elf32_arm_stub_type {
|
||||||
arm_stub_none,
|
arm_stub_none,
|
||||||
DEF_STUBS
|
DEF_STUBS
|
||||||
|
/* Note the first a8_veneer type */
|
||||||
|
arm_stub_a8_veneer_lwm = arm_stub_a8_veneer_b_cond
|
||||||
};
|
};
|
||||||
#undef DEF_STUB
|
#undef DEF_STUB
|
||||||
|
|
||||||
@ -3437,6 +3439,12 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
|
|||||||
htab = elf32_arm_hash_table (info);
|
htab = elf32_arm_hash_table (info);
|
||||||
stub_sec = stub_entry->stub_sec;
|
stub_sec = stub_entry->stub_sec;
|
||||||
|
|
||||||
|
if ((htab->fix_cortex_a8 < 0)
|
||||||
|
!= (stub_entry->stub_type >= arm_stub_a8_veneer_lwm))
|
||||||
|
/* 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. */
|
/* Make a note of the offset within the stubs for this entry. */
|
||||||
stub_entry->stub_offset = stub_sec->size;
|
stub_entry->stub_offset = stub_sec->size;
|
||||||
loc = stub_sec->contents + stub_entry->stub_offset;
|
loc = stub_sec->contents + stub_entry->stub_offset;
|
||||||
@ -3893,7 +3901,9 @@ cortex_a8_erratum_scan (bfd *input_bfd,
|
|||||||
unsigned int *num_a8_fixes_p,
|
unsigned int *num_a8_fixes_p,
|
||||||
unsigned int *a8_fix_table_size_p,
|
unsigned int *a8_fix_table_size_p,
|
||||||
struct a8_erratum_reloc *a8_relocs,
|
struct a8_erratum_reloc *a8_relocs,
|
||||||
unsigned int num_a8_relocs)
|
unsigned int num_a8_relocs,
|
||||||
|
unsigned prev_num_a8_fixes,
|
||||||
|
bfd_boolean *stub_changed_p)
|
||||||
{
|
{
|
||||||
asection *section;
|
asection *section;
|
||||||
struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
|
struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
|
||||||
@ -4105,7 +4115,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
|
|||||||
|
|
||||||
if (((base_vma + i) & ~0xfff) == (target & ~0xfff))
|
if (((base_vma + i) & ~0xfff) == (target & ~0xfff))
|
||||||
{
|
{
|
||||||
char *stub_name;
|
char *stub_name = NULL;
|
||||||
|
|
||||||
if (num_a8_fixes == a8_fix_table_size)
|
if (num_a8_fixes == a8_fix_table_size)
|
||||||
{
|
{
|
||||||
@ -4115,9 +4125,28 @@ cortex_a8_erratum_scan (bfd *input_bfd,
|
|||||||
* a8_fix_table_size);
|
* a8_fix_table_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (num_a8_fixes < prev_num_a8_fixes)
|
||||||
|
{
|
||||||
|
/* If we're doing a subsequent scan,
|
||||||
|
check if we've found the same fix as
|
||||||
|
before, and try and reuse the stub
|
||||||
|
name. */
|
||||||
|
stub_name = a8_fixes[num_a8_fixes].stub_name;
|
||||||
|
if ((a8_fixes[num_a8_fixes].section != section)
|
||||||
|
|| (a8_fixes[num_a8_fixes].offset != i))
|
||||||
|
{
|
||||||
|
free (stub_name);
|
||||||
|
stub_name = NULL;
|
||||||
|
*stub_changed_p = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stub_name)
|
||||||
|
{
|
||||||
stub_name = bfd_malloc (8 + 1 + 8 + 1);
|
stub_name = bfd_malloc (8 + 1 + 8 + 1);
|
||||||
if (stub_name != NULL)
|
if (stub_name != NULL)
|
||||||
sprintf (stub_name, "%x:%x", section->id, i);
|
sprintf (stub_name, "%x:%x", section->id, i);
|
||||||
|
}
|
||||||
|
|
||||||
a8_fixes[num_a8_fixes].input_bfd = input_bfd;
|
a8_fixes[num_a8_fixes].input_bfd = input_bfd;
|
||||||
a8_fixes[num_a8_fixes].section = section;
|
a8_fixes[num_a8_fixes].section = section;
|
||||||
@ -4165,10 +4194,9 @@ elf32_arm_size_stubs (bfd *output_bfd,
|
|||||||
{
|
{
|
||||||
bfd_size_type stub_group_size;
|
bfd_size_type stub_group_size;
|
||||||
bfd_boolean stubs_always_after_branch;
|
bfd_boolean stubs_always_after_branch;
|
||||||
bfd_boolean stub_changed = 0;
|
|
||||||
struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
|
struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
|
||||||
struct a8_erratum_fix *a8_fixes = NULL;
|
struct a8_erratum_fix *a8_fixes = NULL;
|
||||||
unsigned int num_a8_fixes = 0, prev_num_a8_fixes = 0, a8_fix_table_size = 10;
|
unsigned int num_a8_fixes = 0, a8_fix_table_size = 10;
|
||||||
struct a8_erratum_reloc *a8_relocs = NULL;
|
struct a8_erratum_reloc *a8_relocs = NULL;
|
||||||
unsigned int num_a8_relocs = 0, a8_reloc_table_size = 10, i;
|
unsigned int num_a8_relocs = 0, a8_reloc_table_size = 10, i;
|
||||||
|
|
||||||
@ -4223,9 +4251,10 @@ elf32_arm_size_stubs (bfd *output_bfd,
|
|||||||
bfd *input_bfd;
|
bfd *input_bfd;
|
||||||
unsigned int bfd_indx;
|
unsigned int bfd_indx;
|
||||||
asection *stub_sec;
|
asection *stub_sec;
|
||||||
|
bfd_boolean stub_changed = FALSE;
|
||||||
|
unsigned prev_num_a8_fixes = num_a8_fixes;
|
||||||
|
|
||||||
num_a8_fixes = 0;
|
num_a8_fixes = 0;
|
||||||
|
|
||||||
for (input_bfd = info->input_bfds, bfd_indx = 0;
|
for (input_bfd = info->input_bfds, bfd_indx = 0;
|
||||||
input_bfd != NULL;
|
input_bfd != NULL;
|
||||||
input_bfd = input_bfd->link_next, bfd_indx++)
|
input_bfd = input_bfd->link_next, bfd_indx++)
|
||||||
@ -4452,6 +4481,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
|
|||||||
{
|
{
|
||||||
/* The proper stub has already been created. */
|
/* The proper stub has already been created. */
|
||||||
free (stub_name);
|
free (stub_name);
|
||||||
|
stub_entry->target_value = sym_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4548,18 +4578,21 @@ elf32_arm_size_stubs (bfd *output_bfd,
|
|||||||
if (htab->fix_cortex_a8)
|
if (htab->fix_cortex_a8)
|
||||||
{
|
{
|
||||||
/* Sort relocs which might apply to Cortex-A8 erratum. */
|
/* Sort relocs which might apply to Cortex-A8 erratum. */
|
||||||
qsort (a8_relocs, num_a8_relocs, sizeof (struct a8_erratum_reloc),
|
qsort (a8_relocs, num_a8_relocs,
|
||||||
|
sizeof (struct a8_erratum_reloc),
|
||||||
&a8_reloc_compare);
|
&a8_reloc_compare);
|
||||||
|
|
||||||
/* Scan for branches which might trigger Cortex-A8 erratum. */
|
/* Scan for branches which might trigger Cortex-A8 erratum. */
|
||||||
if (cortex_a8_erratum_scan (input_bfd, info, &a8_fixes,
|
if (cortex_a8_erratum_scan (input_bfd, info, &a8_fixes,
|
||||||
&num_a8_fixes, &a8_fix_table_size,
|
&num_a8_fixes, &a8_fix_table_size,
|
||||||
a8_relocs, num_a8_relocs) != 0)
|
a8_relocs, num_a8_relocs,
|
||||||
|
prev_num_a8_fixes, &stub_changed)
|
||||||
|
!= 0)
|
||||||
goto error_ret_free_local;
|
goto error_ret_free_local;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htab->fix_cortex_a8 && num_a8_fixes != prev_num_a8_fixes)
|
if (prev_num_a8_fixes != num_a8_fixes)
|
||||||
stub_changed = TRUE;
|
stub_changed = TRUE;
|
||||||
|
|
||||||
if (!stub_changed)
|
if (!stub_changed)
|
||||||
@ -4598,8 +4631,6 @@ elf32_arm_size_stubs (bfd *output_bfd,
|
|||||||
|
|
||||||
/* Ask the linker to do its stuff. */
|
/* Ask the linker to do its stuff. */
|
||||||
(*htab->layout_sections_again) ();
|
(*htab->layout_sections_again) ();
|
||||||
stub_changed = FALSE;
|
|
||||||
prev_num_a8_fixes = num_a8_fixes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add stubs for Cortex-A8 erratum fixes now. */
|
/* Add stubs for Cortex-A8 erratum fixes now. */
|
||||||
@ -4696,6 +4727,12 @@ elf32_arm_build_stubs (struct bfd_link_info *info)
|
|||||||
/* Build the stubs as directed by the stub hash table. */
|
/* Build the stubs as directed by the stub hash table. */
|
||||||
table = &htab->stub_hash_table;
|
table = &htab->stub_hash_table;
|
||||||
bfd_hash_traverse (table, arm_build_one_stub, info);
|
bfd_hash_traverse (table, arm_build_one_stub, info);
|
||||||
|
if (htab->fix_cortex_a8)
|
||||||
|
{
|
||||||
|
/* Place the cortex a8 stubs last. */
|
||||||
|
htab->fix_cortex_a8 = -1;
|
||||||
|
bfd_hash_traverse (table, arm_build_one_stub, info);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2009-08-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
* ld-arm/cortex-a8-far-1.s: New.
|
||||||
|
* ld-arm/cortex-a8-far-2.s: New.
|
||||||
|
* ld-arm/cortex-a8-far.d: New.
|
||||||
|
* ld-arm/arm-elf.exp: Add new test.
|
||||||
|
|
||||||
2009-08-02 H.J. Lu <hongjiu.lu@intel.com>
|
2009-08-02 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR ld/6443
|
PR ld/6443
|
||||||
|
@ -205,6 +205,10 @@ set armelftests {
|
|||||||
"-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-thumb-target.s cortex-a8-fix-blx-rel.s}
|
"-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-thumb-target.s cortex-a8-fix-blx-rel.s}
|
||||||
{{objdump -dr cortex-a8-fix-blx-rel-thumb.d}}
|
{{objdump -dr cortex-a8-fix-blx-rel-thumb.d}}
|
||||||
"cortex-a8-fix-blx-rel-thumb"}
|
"cortex-a8-fix-blx-rel-thumb"}
|
||||||
|
{"Cortex-A8 erratum fix, relocate bl.w and far call"
|
||||||
|
"-EL -Ttext=0x00 --fix-cortex-a8 --defsym far_fn1=0x80000000 --defsym far_fn2=0x80000004 --defsym far_fn=0x7fff0000 --defsym _start=0" "-EL" {cortex-a8-far-1.s cortex-a8-far-2.s}
|
||||||
|
{{objdump -dr cortex-a8-far.d}}
|
||||||
|
"cortex-a8-far"}
|
||||||
{"Unwinding and -gc-sections" "-gc-sections" "" {gc-unwind.s}
|
{"Unwinding and -gc-sections" "-gc-sections" "" {gc-unwind.s}
|
||||||
{{objdump -sj.data gc-unwind.d}}
|
{{objdump -sj.data gc-unwind.d}}
|
||||||
"gc-unwind"}
|
"gc-unwind"}
|
||||||
|
8
ld/testsuite/ld-arm/cortex-a8-far-1.s
Normal file
8
ld/testsuite/ld-arm/cortex-a8-far-1.s
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
.globl two
|
||||||
|
two:
|
||||||
|
bl far_fn
|
||||||
|
.rept 0x200000
|
||||||
|
.long 0
|
||||||
|
.endr
|
20
ld/testsuite/ld-arm/cortex-a8-far-2.s
Normal file
20
ld/testsuite/ld-arm/cortex-a8-far-2.s
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
three:
|
||||||
|
bl far_fn1
|
||||||
|
bl far_fn2
|
||||||
|
.rept 1016
|
||||||
|
.long 0
|
||||||
|
.endr
|
||||||
|
nop
|
||||||
|
label1:
|
||||||
|
eor.w r0, r1, r2
|
||||||
|
beq.w label1
|
||||||
|
|
||||||
|
eor.w r0, r1, r2
|
||||||
|
|
||||||
|
eor.w r0, r1, r2
|
||||||
|
b.w label1
|
||||||
|
|
||||||
|
eor.w r0, r1, r2
|
||||||
|
eor.w r0, r1, r2
|
40
ld/testsuite/ld-arm/cortex-a8-far.d
Normal file
40
ld/testsuite/ld-arm/cortex-a8-far.d
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
.*: file format .*
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section \.text:
|
||||||
|
|
||||||
|
00000000 <two>:
|
||||||
|
0: f000 c802 blx 800008 <__far_fn_from_thumb>
|
||||||
|
...
|
||||||
|
#...
|
||||||
|
00800008 <__far_fn_from_thumb>:
|
||||||
|
800008: e51ff004 ldr pc, \[pc, #-4\] ; 80000c <__far_fn_from_thumb\+0x4>
|
||||||
|
80000c: 7fff0000 .word 0x7fff0000
|
||||||
|
|
||||||
|
00800010 <three>:
|
||||||
|
800010: f001 e806 blx 801020 <__far_fn1_from_thumb>
|
||||||
|
800014: f001 e800 blx 801018 <__far_fn2_from_thumb>
|
||||||
|
...
|
||||||
|
800ff8: bf00 nop
|
||||||
|
|
||||||
|
00800ffa <label1>:
|
||||||
|
800ffa: ea81 0002 eor.w r0, r1, r2
|
||||||
|
800ffe: f000 b813 b.w 801028 <__far_fn1_from_thumb\+0x8>
|
||||||
|
801002: ea81 0002 eor.w r0, r1, r2
|
||||||
|
801006: ea81 0002 eor.w r0, r1, r2
|
||||||
|
80100a: f7ff bff6 b.w 800ffa <label1>
|
||||||
|
80100e: ea81 0002 eor.w r0, r1, r2
|
||||||
|
801012: ea81 0002 eor.w r0, r1, r2
|
||||||
|
...
|
||||||
|
|
||||||
|
00801018 <__far_fn2_from_thumb>:
|
||||||
|
801018: e51ff004 ldr pc, \[pc, #-4\] ; 80101c <__far_fn2_from_thumb\+0x4>
|
||||||
|
80101c: 80000004 .word 0x80000004
|
||||||
|
|
||||||
|
00801020 <__far_fn1_from_thumb>:
|
||||||
|
801020: e51ff004 ldr pc, \[pc, #-4\] ; 801024 <__far_fn1_from_thumb\+0x4>
|
||||||
|
801024: 80000000 .word 0x80000000
|
||||||
|
801028: d001 beq.n 80102e <__far_fn1_from_thumb\+0xe>
|
||||||
|
80102a: f7ff bfea b.w 801002 <label1\+0x8>
|
||||||
|
80102e: f7ff bfe4 b.w 800ffa <label1>
|
Reference in New Issue
Block a user