From: Max Filippov Date: Tue, 23 Sep 2014 03:23:29 +0000 (+0400) Subject: binutils: fix 'call8: call target out of range' xtensa ld bug X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9849f0052cbd9460888e93ca28b98e43437277f9;p=buildroot.git binutils: fix 'call8: call target out of range' xtensa ld bug This fixes the following linux kernel build errors: LD init/built-in.o net/built-in.o: In function `raw_proc_exit': (.init.text+0xe29): dangerous relocation: call8: call target out of range: udp_proc_register net/built-in.o: In function `udp_table_init': (.init.text+0xf09): dangerous relocation: call8: call target out of range: udp_proc_register net/built-in.o: In function `inet_init': af_inet.c:(.init.text+0x142e): dangerous relocation: call8: call target out of range: udp4_proc_exit net/built-in.o: In function `ip_auto_config': ipconfig.c:(.init.text+0x28aa): dangerous relocation: call8: call target out of range: arp_send Backported from: 331ed1307b93d3ff77d248bdf2f7b79a20851457 Signed-off-by: Max Filippov Signed-off-by: Thomas Petazzoni --- diff --git a/package/binutils/2.22/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch b/package/binutils/2.22/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch new file mode 100644 index 0000000000..dba7620b7e --- /dev/null +++ b/package/binutils/2.22/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch @@ -0,0 +1,79 @@ +From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001 +From: Sterling Augustine +Date: Tue, 25 Jan 2011 13:59:13 -0800 +Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation + bug + +During link-time relaxation distance between cross-section call site and +its target may grow, producing 'call target out of range' error for +relaxed calls. Be more conservative when calculating whether or not a +callx can be converted to a straight call. + +2014-09-23 Sterling Augustine + +bfd/ + * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section + call relaxation use furthermost addresses where call source and + destination can be to check whether it's in the range of a direct + call. + +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++---- + 1 file changed, 37 insertions(+), 4 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 09862e3..e32496a 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd, + || is_reloc_sym_weak (abfd, irel))) + return FALSE; + +- self_address = (sec->output_section->vma +- + sec->output_offset + irel->r_offset + 3); +- dest_address = (target_sec->output_section->vma +- + target_sec->output_offset + target_offset); ++ if (target_sec->output_section != sec->output_section) ++ { ++ /* If the two sections are sufficiently far away that relaxation ++ might take the call out of range, we can't simplify. For ++ example, a positive displacement call into another memory ++ could get moved to a lower address due to literal removal, ++ but the destination won't move, and so the displacment might ++ get larger. ++ ++ If the displacement is negative, assume the destination could ++ move as far back as the start of the output section. The ++ self_address will be at least as far into the output section ++ as it is prior to relaxation. ++ ++ If the displacement is postive, assume the destination will be in ++ it's pre-relaxed location (because relaxation only makes sections ++ smaller). The self_address could go all the way to the beginning ++ of the output section. */ ++ ++ dest_address = target_sec->output_section->vma; ++ self_address = sec->output_section->vma; ++ ++ if (sec->output_section->vma > target_sec->output_section->vma) ++ self_address += sec->output_offset + irel->r_offset + 3; ++ else ++ dest_address += bfd_get_section_limit (abfd, target_sec->output_section); ++ /* Call targets should be four-byte aligned. */ ++ dest_address = (dest_address + 3) & ~3; ++ } ++ else ++ { ++ ++ self_address = (sec->output_section->vma ++ + sec->output_offset + irel->r_offset + 3); ++ dest_address = (target_sec->output_section->vma ++ + target_sec->output_offset + target_offset); ++ } + + *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, + self_address, dest_address); +-- +1.8.1.4 + diff --git a/package/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch b/package/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch new file mode 100644 index 0000000000..dba7620b7e --- /dev/null +++ b/package/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch @@ -0,0 +1,79 @@ +From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001 +From: Sterling Augustine +Date: Tue, 25 Jan 2011 13:59:13 -0800 +Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation + bug + +During link-time relaxation distance between cross-section call site and +its target may grow, producing 'call target out of range' error for +relaxed calls. Be more conservative when calculating whether or not a +callx can be converted to a straight call. + +2014-09-23 Sterling Augustine + +bfd/ + * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section + call relaxation use furthermost addresses where call source and + destination can be to check whether it's in the range of a direct + call. + +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++---- + 1 file changed, 37 insertions(+), 4 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 09862e3..e32496a 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd, + || is_reloc_sym_weak (abfd, irel))) + return FALSE; + +- self_address = (sec->output_section->vma +- + sec->output_offset + irel->r_offset + 3); +- dest_address = (target_sec->output_section->vma +- + target_sec->output_offset + target_offset); ++ if (target_sec->output_section != sec->output_section) ++ { ++ /* If the two sections are sufficiently far away that relaxation ++ might take the call out of range, we can't simplify. For ++ example, a positive displacement call into another memory ++ could get moved to a lower address due to literal removal, ++ but the destination won't move, and so the displacment might ++ get larger. ++ ++ If the displacement is negative, assume the destination could ++ move as far back as the start of the output section. The ++ self_address will be at least as far into the output section ++ as it is prior to relaxation. ++ ++ If the displacement is postive, assume the destination will be in ++ it's pre-relaxed location (because relaxation only makes sections ++ smaller). The self_address could go all the way to the beginning ++ of the output section. */ ++ ++ dest_address = target_sec->output_section->vma; ++ self_address = sec->output_section->vma; ++ ++ if (sec->output_section->vma > target_sec->output_section->vma) ++ self_address += sec->output_offset + irel->r_offset + 3; ++ else ++ dest_address += bfd_get_section_limit (abfd, target_sec->output_section); ++ /* Call targets should be four-byte aligned. */ ++ dest_address = (dest_address + 3) & ~3; ++ } ++ else ++ { ++ ++ self_address = (sec->output_section->vma ++ + sec->output_offset + irel->r_offset + 3); ++ dest_address = (target_sec->output_section->vma ++ + target_sec->output_offset + target_offset); ++ } + + *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, + self_address, dest_address); +-- +1.8.1.4 + diff --git a/package/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch b/package/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch new file mode 100644 index 0000000000..e4c600e542 --- /dev/null +++ b/package/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch @@ -0,0 +1,79 @@ +From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001 +From: Sterling Augustine +Date: Tue, 25 Jan 2011 13:59:13 -0800 +Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation + bug + +During link-time relaxation distance between cross-section call site and +its target may grow, producing 'call target out of range' error for +relaxed calls. Be more conservative when calculating whether or not a +callx can be converted to a straight call. + +2014-09-23 Sterling Augustine + +bfd/ + * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section + call relaxation use furthermost addresses where call source and + destination can be to check whether it's in the range of a direct + call. + +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++---- + 1 file changed, 37 insertions(+), 4 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 09862e3..e32496a 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd, + || is_reloc_sym_weak (abfd, irel))) + return FALSE; + +- self_address = (sec->output_section->vma +- + sec->output_offset + irel->r_offset + 3); +- dest_address = (target_sec->output_section->vma +- + target_sec->output_offset + target_offset); ++ if (target_sec->output_section != sec->output_section) ++ { ++ /* If the two sections are sufficiently far away that relaxation ++ might take the call out of range, we can't simplify. For ++ example, a positive displacement call into another memory ++ could get moved to a lower address due to literal removal, ++ but the destination won't move, and so the displacment might ++ get larger. ++ ++ If the displacement is negative, assume the destination could ++ move as far back as the start of the output section. The ++ self_address will be at least as far into the output section ++ as it is prior to relaxation. ++ ++ If the displacement is postive, assume the destination will be in ++ it's pre-relaxed location (because relaxation only makes sections ++ smaller). The self_address could go all the way to the beginning ++ of the output section. */ ++ ++ dest_address = target_sec->output_section->vma; ++ self_address = sec->output_section->vma; ++ ++ if (sec->output_section->vma > target_sec->output_section->vma) ++ self_address += sec->output_offset + irel->r_offset + 3; ++ else ++ dest_address += bfd_get_section_limit (abfd, target_sec->output_section); ++ /* Call targets should be four-byte aligned. */ ++ dest_address = (dest_address + 3) & ~3; ++ } ++ else ++ { ++ ++ self_address = (sec->output_section->vma ++ + sec->output_offset + irel->r_offset + 3); ++ dest_address = (target_sec->output_section->vma ++ + target_sec->output_offset + target_offset); ++ } + + *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, + self_address, dest_address); +-- +1.8.1.4 +