This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Ping [PATCH][MIPS] Fix MIPS symbol difference calculation
- From: Kwok Cheung Yeung <kcy at codesourcery dot com>
- To: <binutils at sourceware dot org>
- Date: Fri, 27 Mar 2015 23:20:29 +0000
- Subject: Ping [PATCH][MIPS] Fix MIPS symbol difference calculation
- Authentication-results: sourceware.org; auth=none
I submitted this patch nearly a year ago, but have had no response since
then.
https://sourceware.org/ml/binutils/2014-05/msg00292.html
The bug is still present in the code. I have updated the patch slightly
to reflect the current state of the source in git. Okay to apply?
Thanks
Kwok
This fixes a problem where the difference between two symbols
may be miscalculated by the assembler when used in a %hi
relocation operator.
gas/
* config/tc-mips.c (fixup_has_matching_lo_p): Also match
`fx_subsy' fixup fields.
(append_insn): Don't put fixups on `mips_hi_fixup_list' that have
non-NULL `fx_subsy' field.
gas/testsuite/
* gas/mips/mips.exp: Add new hilo-diff-subsy tests.
* gas/mips/hilo-diff-subsy.d: New test file.
* gas/mips/hilo-diff-subsy-n32.d: New test file.
* gas/mips/hilo-diff-subsy-n64.d: New test file.
* gas/mips/micromips@hilo-diff-subsy.d: New test file.
* gas/mips/micromips@hilo-diff-subsy-n32.d: New test file.
* gas/mips/micromips@hilo-diff-subsy-n64.d: New test file.
* gas/mips/mips16@hilo-diff-subsy.d: New test file.
* gas/mips/hilo-diff-subsy.s: New test file.
---
gas/config/tc-mips.c | 4 +++-
gas/testsuite/gas/mips/hilo-diff-subsy-n32.d | 5 +++++
gas/testsuite/gas/mips/hilo-diff-subsy-n64.d | 5 +++++
gas/testsuite/gas/mips/hilo-diff-subsy.d | 14 ++++++++++++++
gas/testsuite/gas/mips/hilo-diff-subsy.s | 15
+++++++++++++++
gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n32.d | 5 +++++
gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n64.d | 5 +++++
gas/testsuite/gas/mips/micromips@hilo-diff-subsy.d | 14 ++++++++++++++
gas/testsuite/gas/mips/mips.exp | 7 +++++++
gas/testsuite/gas/mips/mips16@hilo-diff-subsy.d | 14 ++++++++++++++
10 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 gas/testsuite/gas/mips/hilo-diff-subsy-n32.d
create mode 100644 gas/testsuite/gas/mips/hilo-diff-subsy-n64.d
create mode 100644 gas/testsuite/gas/mips/hilo-diff-subsy.d
create mode 100644 gas/testsuite/gas/mips/hilo-diff-subsy.s
create mode 100644 gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n32.d
create mode 100644 gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n64.d
create mode 100644 gas/testsuite/gas/mips/micromips@hilo-diff-subsy.d
create mode 100644 gas/testsuite/gas/mips/mips16@hilo-diff-subsy.d
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index e61bb4d..1a2b240 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -4186,6 +4186,7 @@ fixup_has_matching_lo_p (fixS *fixp)
return (fixp->fx_next != NULL
&& fixp->fx_next->fx_r_type == matching_lo_reloc (fixp->fx_r_type)
&& fixp->fx_addsy == fixp->fx_next->fx_addsy
+ && fixp->fx_subsy == fixp->fx_next->fx_subsy
&& fixp->fx_offset == fixp->fx_next->fx_offset);
}
@@ -7395,7 +7396,8 @@ append_insn (struct mips_cl_insn *ip, expressionS
*address_expr,
if (mips_relax.first_fixup == 0)
mips_relax.first_fixup = ip->fixp[0];
}
- else if (reloc_needs_lo_p (*reloc_type))
+ else if (reloc_needs_lo_p (*reloc_type)
+ && ip->fixp[0]->fx_subsy == NULL)
{
struct mips_hi_fixup *hi_fixup;
diff --git a/gas/testsuite/gas/mips/hilo-diff-subsy-n32.d
b/gas/testsuite/gas/mips/hilo-diff-subsy-n32.d
new file mode 100644
index 0000000..200fa84
--- /dev/null
+++ b/gas/testsuite/gas/mips/hilo-diff-subsy-n32.d
@@ -0,0 +1,5 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS hilo-diff-subsy n32
+#as: -n32
+#source: hilo-diff-subsy.s
+#dump: hilo-diff-subsy.d
diff --git a/gas/testsuite/gas/mips/hilo-diff-subsy-n64.d
b/gas/testsuite/gas/mips/hilo-diff-subsy-n64.d
new file mode 100644
index 0000000..7a0d0e2
--- /dev/null
+++ b/gas/testsuite/gas/mips/hilo-diff-subsy-n64.d
@@ -0,0 +1,5 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS hilo-diff-subsy n64
+#as: -64
+#source: hilo-diff-subsy.s
+#dump: hilo-diff-subsy.d
diff --git a/gas/testsuite/gas/mips/hilo-diff-subsy.d
b/gas/testsuite/gas/mips/hilo-diff-subsy.d
new file mode 100644
index 0000000..ecaf0b9
--- /dev/null
+++ b/gas/testsuite/gas/mips/hilo-diff-subsy.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS hilo-diff-subsy o32
+#as: -32
+#source: hilo-diff-subsy.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 24020000 li v0,0
+[0-9a-f]+ <[^>]*> 24420014 addiu v0,v0,20
+#...
+[0-9a-f]+ <[^>]*> 2402ffff li v0,-1
+[0-9a-f]+ <[^>]*> 24427ff4 addiu v0,v0,32756
+#pass
diff --git a/gas/testsuite/gas/mips/hilo-diff-subsy.s
b/gas/testsuite/gas/mips/hilo-diff-subsy.s
new file mode 100644
index 0000000..8efedbf
--- /dev/null
+++ b/gas/testsuite/gas/mips/hilo-diff-subsy.s
@@ -0,0 +1,15 @@
+ .text
+foo:
+ li $2, %hi(LAB3-LAB1)
+LAB1:
+ addiu $2, %lo(LAB3-LAB1)
+LAB2:
+ nop
+ nop
+ nop
+ nop
+LAB3:
+ .fill 32760
+ li $2, %hi(LAB2-LAB4)
+LAB4:
+ addiu $2, %lo(LAB2-LAB4)
diff --git a/gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n32.d
b/gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n32.d
new file mode 100644
index 0000000..931a68f
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n32.d
@@ -0,0 +1,5 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS hilo-diff-subsy n32
+#as: -n32
+#source: hilo-diff-subsy.s
+#dump: micromips@hilo-diff-subsy.d
diff --git a/gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n64.d
b/gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n64.d
new file mode 100644
index 0000000..dfbcd2d
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@hilo-diff-subsy-n64.d
@@ -0,0 +1,5 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS hilo-diff-subsy n64
+#as: -64
+#source: hilo-diff-subsy.s
+#dump: micromips@hilo-diff-subsy.d
diff --git a/gas/testsuite/gas/mips/micromips@hilo-diff-subsy.d
b/gas/testsuite/gas/mips/micromips@hilo-diff-subsy.d
new file mode 100644
index 0000000..f75de82
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@hilo-diff-subsy.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS hilo-diff-subsy o32
+#as: -32
+#source: hilo-diff-subsy.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 3040 0000 li v0,0
+[0-9a-f]+ <[^>]*> 3042 000b addiu v0,v0,11
+#...
+[0-9a-f]+ <[^>]*> 3040ffff andi zero,v0,0xffff
+[0-9a-f]+ <[^>]*> 3042 7ffc addiu v0,v0,32764
+#pass
diff --git a/gas/testsuite/gas/mips/mips.exp
b/gas/testsuite/gas/mips/mips.exp
index 11c9b05..5842d56 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1203,6 +1203,13 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test_arches "hilo-diff-eb-n64" [mips_arch_list_matching mips3]
run_dump_test_arches "hilo-diff-el-n64" [mips_arch_list_matching mips3]
}
+ run_dump_test_arches "hilo-diff-subsy" [mips_arch_list_all]
+ if $has_newabi {
+ run_dump_test_arches "hilo-diff-subsy-n32" \
+ [mips_arch_list_matching mips3]
+ run_dump_test_arches "hilo-diff-subsy-n64" \
+ [mips_arch_list_matching mips3]
+ }
run_dump_test_arches "lui" [mips_arch_list_matching mips1]
run_list_test_arches "lui-1" "-32" [mips_arch_list_matching mips1]
run_list_test_arches "lui-2" "-32" [mips_arch_list_matching mips1]
diff --git a/gas/testsuite/gas/mips/mips16@hilo-diff-subsy.d
b/gas/testsuite/gas/mips/mips16@hilo-diff-subsy.d
new file mode 100644
index 0000000..54f515a
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips16@hilo-diff-subsy.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS hilo-diff-subsy o32
+#as: -32
+#source: hilo-diff-subsy.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> f000 6a00 li v0,0
+[0-9a-f]+ <[^>]*> f000 4a0b addiu v0,11
+#...
+[0-9a-f]+ <[^>]*> f7ff 6a1f li v0,65535
+[0-9a-f]+ <[^>]*> f7ef 4a1c addiu v0,32764
+#pass
--
2.3.4