From a07b189732a69a569111a1df77171f728f5511a6 Mon Sep 17 00:00:00 2001 From: Edgar E. Iglesias Date: Sun, 21 Aug 2011 23:10:04 +0200 Subject: [PATCH] PR gas/14640 * config/tc-microblaze.c: md_estimate_size_before_relax check not a weak symbol Resolves PR gas 14640 - check for weak symbols before emitting relocation http://sourceware.org/bugzilla/show_bug.cgi?id=14640 Based on original patch by Vasanth Asokan in Xilinx, resolves situation where gas will generate a jump based on a weak definition, which then potentially falls outside the jump range if overridden by a strong definition. Resultant error resembled; relocation truncated to fit: R_MICROBLAZE_32_PCREL_LO against symbol `test_start' defined in .testsection section in reloc_strongsym.o Add microblaze to gas/testsuite, and include a reloc.exp test for this bug. Signed-off-by: Edgar E. Iglesias Signed-off-by: David Holsgrove --- gas/config/tc-microblaze.c | 3 +- gas/testsuite/gas/microblaze/reloc_strongsym.s | 20 +++++++++ gas/testsuite/gas/microblaze/reloc_sym.d | 45 ++++++++++++++++++++ gas/testsuite/gas/microblaze/reloc_sym.exp | 27 ++++++++++++ gas/testsuite/gas/microblaze/reloc_weaksym.s | 52 ++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 1 deletions(-) create mode 100644 gas/testsuite/gas/microblaze/reloc_strongsym.s create mode 100644 gas/testsuite/gas/microblaze/reloc_sym.d create mode 100644 gas/testsuite/gas/microblaze/reloc_sym.exp create mode 100644 gas/testsuite/gas/microblaze/reloc_weaksym.s diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c index 3ab854f..86ac90b 100644 --- a/gas/config/tc-microblaze.c +++ b/gas/config/tc-microblaze.c @@ -2065,7 +2065,8 @@ md_estimate_size_before_relax (fragS * fragP, as_bad (_("Absolute PC-relative value in relaxation code. Assembler error.....")); abort (); } - else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type)) + else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type && + !S_IS_WEAK (fragP->fr_symbol)) { fragP->fr_subtype = DEFINED_PC_OFFSET; /* Don't know now whether we need an imm instruction. */ diff --git a/gas/testsuite/gas/microblaze/reloc_strongsym.s b/gas/testsuite/gas/microblaze/reloc_strongsym.s new file mode 100644 index 0000000..8f34028 --- /dev/null +++ b/gas/testsuite/gas/microblaze/reloc_strongsym.s @@ -0,0 +1,20 @@ + .section ".testsection" + .align 2 + .globl test_start + .ent test_start + .type test_start, @function +test_start: + .frame r19,8,r15 # vars= 0, regs= 1, args= 0 + .mask 0x00080000 + addik r1,r1,-8 + swi r19,r1,4 + addk r19,r1,r0 + addk r1,r19,r0 + lwi r19,r1,4 + addik r1,r1,8 + rtsd r15,8 + nop # Unfilled delay slot + + .end test_start +$Lfe1: + .size test_start,$Lfe1-test_start diff --git a/gas/testsuite/gas/microblaze/reloc_sym.d b/gas/testsuite/gas/microblaze/reloc_sym.d new file mode 100644 index 0000000..990b9dd --- /dev/null +++ b/gas/testsuite/gas/microblaze/reloc_sym.d @@ -0,0 +1,45 @@ + +reloc_sym.x: file format .* + + +Disassembly of section .text: + +10000054 <__def_start>: +10000054: 3021fff8 addik r1, r1, -8 +10000058: fa610004 swi r19, r1, 4 +1000005c: 12610000 addk r19, r1, r0 +10000060: 10330000 addk r1, r19, r0 +10000064: ea610004 lwi r19, r1, 4 +10000068: 30210008 addik r1, r1, 8 +1000006c: b60f0008 rtsd r15, 8 +10000070: 80000000 or r0, r0, r0 + +10000074
: +10000074: 3021ffe0 addik r1, r1, -32 +10000078: f9e10000 swi r15, r1, 0 +1000007c: fa61001c swi r19, r1, 28 +10000080: 12610000 addk r19, r1, r0 +10000084: b000efff imm -4097 +10000088: b9f4ff7c brlid r15, -132 // 4 +1000008c: 80000000 or r0, r0, r0 +10000090: b9f4ffc4 brlid r15, -60 // 10000054 <__def_start> +10000094: 80000000 or r0, r0, r0 +10000098: 10600000 addk r3, r0, r0 +1000009c: e9e10000 lwi r15, r1, 0 +100000a0: 10330000 addk r1, r19, r0 +100000a4: ea61001c lwi r19, r1, 28 +100000a8: 30210020 addik r1, r1, 32 +100000ac: b60f0008 rtsd r15, 8 +100000b0: 80000000 or r0, r0, r0 + +Disassembly of section .testsection: + +00000004 : + 4: 3021fff8 addik r1, r1, -8 + 8: fa610004 swi r19, r1, 4 + c: 12610000 addk r19, r1, r0 + 10: 10330000 addk r1, r19, r0 + 14: ea610004 lwi r19, r1, 4 + 18: 30210008 addik r1, r1, 8 + 1c: b60f0008 rtsd r15, 8 + 20: 80000000 or r0, r0, r0 diff --git a/gas/testsuite/gas/microblaze/reloc_sym.exp b/gas/testsuite/gas/microblaze/reloc_sym.exp new file mode 100644 index 0000000..c7f7322 --- /dev/null +++ b/gas/testsuite/gas/microblaze/reloc_sym.exp @@ -0,0 +1,27 @@ +# Relocation test. + +proc ld_test { objects ldflags dest test } { + set ld_output [target_link $objects $dest $ldflags] + if [string match "" $ld_output] then { pass $test } else { fail $test } +} + +proc objdump_test { exec flags dest test } { + set objcopy [find_binutils_prog objdump] + verbose -log "$objcopy $flags $exec > $dest" + catch "exec $objcopy $flags $exec > $dest" objdump_output + if [string match "" $objdump_output] then { pass $test } else { fail $test } +} + +proc regexp_test { file1 file2 test } { + if [regexp_diff $file1 $file2] then { fail $test } else { pass $test } +} + + +global srcdir subdir +if [istarget microblaze*-*-*] { + gas_test "reloc_strongsym.s" {-o reloc_strongsym.o} {} {assembling reloc_strongsym} + gas_test "reloc_weaksym.s" {-o reloc_weaksym.o} {} {assembling reloc_weaksym} + ld_test {reloc_strongsym.o reloc_weaksym.o} {-e 0 -section-start .text=0x10000054 -section-start .testsection=0x4} {reloc_sym.x} {linking reloc_sym.x} + objdump_test {reloc_sym.x} {-d --section=.text --section=.testsection} {reloc_sym.dump} {disassembling reloc_sym.x} + regexp_test {reloc_sym.dump} "$srcdir/$subdir/reloc_sym.d" {matching disassembly} +} diff --git a/gas/testsuite/gas/microblaze/reloc_weaksym.s b/gas/testsuite/gas/microblaze/reloc_weaksym.s new file mode 100644 index 0000000..7dd9b98 --- /dev/null +++ b/gas/testsuite/gas/microblaze/reloc_weaksym.s @@ -0,0 +1,52 @@ + .text + .align 2 + .globl __def_start + .ent __def_start + .type __def_start, @function +__def_start: + .frame r19,8,r15 # vars= 0, regs= 1, args= 0 + .mask 0x00080000 + addik r1,r1,-8 + swi r19,r1,4 + addk r19,r1,r0 + addk r1,r19,r0 + lwi r19,r1,4 + addik r1,r1,8 + rtsd r15,8 + nop # Unfilled delay slot + + .end __def_start +$Lfe1: + .size __def_start,$Lfe1-__def_start + .align 2 + .globl main + .ent main + .type main, @function +main: + .frame r19,32,r15 # vars= 0, regs= 1, args= 24 + .mask 0x00088000 + addik r1,r1,-32 + swi r15,r1,0 + swi r19,r1,28 + addk r19,r1,r0 + brlid r15,test_start + nop # Unfilled delay slot + + brlid r15,test_start_strong + nop # Unfilled delay slot + + addk r3,r0,r0 + lwi r15,r1,0 + addk r1,r19,r0 + lwi r19,r1,28 + addik r1,r1,32 + rtsd r15,8 + nop # Unfilled delay slot + + .end main +$Lfe2: + .size main,$Lfe2-main + .weakext test_start + test_start = __def_start + .globl test_start_strong + test_start_strong = __def_start -- 1.7.0.4