aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJozef Lawrynowicz <jozef.l@mittosystems.com>2020-01-15 13:17:27 +0000
committerJozef Lawrynowicz <jozef.l@mittosystems.com>2020-01-15 13:23:06 +0000
commit131cb553d6d10412b20cf49bb0e3a5e736a90a36 (patch)
tree3965e30e6016b4b61a6bb11cb7be81bbd57a99ab /gas
parentc24d0e8d4850d4913a1630a53e272c930849406d (diff)
downloadgdb-131cb553d6d10412b20cf49bb0e3a5e736a90a36.zip
gdb-131cb553d6d10412b20cf49bb0e3a5e736a90a36.tar.gz
gdb-131cb553d6d10412b20cf49bb0e3a5e736a90a36.tar.bz2
MSP430: Fix relocation overflow when using #lo(EXP) macro
gas/ChangeLog: 2020-01-15 Jozef Lawrynowicz <jozef.l@mittosystems.com> * config/tc-msp430.c (CHECK_RELOC_MSP430): Always generate 430X relocations when the target is 430X, except when extracting part of an expression. (msp430_srcoperand): Adjust comment. Initialize the expp member of the msp430_operand_s struct as appropriate. (msp430_dstoperand): Likewise. * testsuite/gas/msp430/msp430.exp: Run new test. * testsuite/gas/msp430/reloc-lo-430x.d: New test. * testsuite/gas/msp430/reloc-lo-430x.s: New test. include/ChangeLog: 2020-01-15 Jozef Lawrynowicz <jozef.l@mittosystems.com> * opcode/msp430.h (enum msp430_expp_e): New. (struct msp430_operand_s): Add expp member to struct. ld/ChangeLog: 2020-01-15 Jozef Lawrynowicz <jozef.l@mittosystems.com> * testsuite/ld-msp430-elf/msp430-elf.exp: Run new test. * testsuite/ld-msp430-elf/reloc-lo-430x.s: New test.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/config/tc-msp430.c35
-rw-r--r--gas/testsuite/gas/msp430/msp430.exp1
-rw-r--r--gas/testsuite/gas/msp430/reloc-lo-430x.d5
-rw-r--r--gas/testsuite/gas/msp430/reloc-lo-430x.s22
5 files changed, 65 insertions, 11 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 0555b29..d88d15c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@
+2020-01-15 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/tc-msp430.c (CHECK_RELOC_MSP430): Always generate 430X
+ relocations when the target is 430X, except when extracting part of an
+ expression.
+ (msp430_srcoperand): Adjust comment.
+ Initialize the expp member of the msp430_operand_s struct as
+ appropriate.
+ (msp430_dstoperand): Likewise.
+ * testsuite/gas/msp430/msp430.exp: Run new test.
+ * testsuite/gas/msp430/reloc-lo-430x.d: New test.
+ * testsuite/gas/msp430/reloc-lo-430x.s: New test.
+
2020-01-15 Alan Modra <amodra@gmail.com>
* configure.tgt: Add sparc-*-freebsd case.
diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c
index b627740..5753882 100644
--- a/gas/config/tc-msp430.c
+++ b/gas/config/tc-msp430.c
@@ -275,21 +275,21 @@ target_is_430xv2 (void)
return selected_isa == MSP_ISA_430Xv2;
}
-/* Generate an absolute 16-bit relocation.
- For the 430X we generate a relocation without linker range checking
- if the value is being used in an extended (ie 20-bit) instruction,
- otherwise if have a shifted expression we use a HI reloc.
+/* Generate an absolute 16-bit relocation, for 430 (!extended_op) instructions
+ only.
+ For the 430X we generate a 430 relocation only for the case where part of an
+ expression is being extracted (e.g. #hi(EXP), #lo(EXP). Otherwise generate
+ a 430X relocation.
For the 430 we generate a relocation without assembler range checking
- if we are handling an immediate value or a byte-width instruction. */
+ if we are handling an immediate value or a byte-width instruction. */
#undef CHECK_RELOC_MSP430
#define CHECK_RELOC_MSP430(OP) \
(target_is_430x () \
- ? (extended_op \
- ? BFD_RELOC_16 \
- : ((OP).vshift == 1) \
- ? BFD_RELOC_MSP430_ABS_HI16 \
- : BFD_RELOC_MSP430X_ABS16) \
+ ? ((OP).expp == MSP_EXPP_ALL \
+ ? BFD_RELOC_MSP430X_ABS16 \
+ : ((OP).vshift == 1 \
+ ? BFD_RELOC_MSP430_ABS_HI16 : BFD_RELOC_16)) \
: ((imm_op || byte_op) \
? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
@@ -1909,13 +1909,15 @@ msp430_srcoperand (struct msp430_operand_s * op,
char *h = l;
int vshift = -1;
int rval = 0;
+ /* Use all parts of the constant expression by default. */
+ enum msp430_expp_e expp = MSP_EXPP_ALL;
/* Check if there is:
llo(x) - least significant 16 bits, x &= 0xffff
lhi(x) - x = (x >> 16) & 0xffff,
hlo(x) - x = (x >> 32) & 0xffff,
hhi(x) - x = (x >> 48) & 0xffff
- The value _MUST_ be constant expression: #hlo(1231231231). */
+ The value _MUST_ be an immediate expression: #hlo(1231231231). */
*imm_op = TRUE;
@@ -1923,31 +1925,37 @@ msp430_srcoperand (struct msp430_operand_s * op,
{
vshift = 0;
rval = 3;
+ expp = MSP_EXPP_LLO;
}
else if (strncasecmp (h, "#lhi(", 5) == 0)
{
vshift = 1;
rval = 3;
+ expp = MSP_EXPP_LHI;
}
else if (strncasecmp (h, "#hlo(", 5) == 0)
{
vshift = 2;
rval = 3;
+ expp = MSP_EXPP_HLO;
}
else if (strncasecmp (h, "#hhi(", 5) == 0)
{
vshift = 3;
rval = 3;
+ expp = MSP_EXPP_HHI;
}
else if (strncasecmp (h, "#lo(", 4) == 0)
{
vshift = 0;
rval = 2;
+ expp = MSP_EXPP_LO;
}
else if (strncasecmp (h, "#hi(", 4) == 0)
{
vshift = 1;
rval = 2;
+ expp = MSP_EXPP_HI;
}
op->reg = 0; /* Reg PC. */
@@ -1956,6 +1964,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
__tl = h + 1 + rval;
op->mode = OP_EXP;
op->vshift = vshift;
+ op->expp = expp;
end = parse_exp (__tl, &(op->exp));
if (end != NULL && *end != 0 && *end != ')' )
@@ -2167,6 +2176,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
}
op->mode = OP_EXP;
op->vshift = 0;
+ op->expp = MSP_EXPP_ALL;
if (op->exp.X_op == O_constant)
{
int x = op->exp.X_add_number;
@@ -2275,6 +2285,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
*h = 0;
op->mode = OP_EXP;
op->vshift = 0;
+ op->expp = MSP_EXPP_ALL;
end = parse_exp (__tl, &(op->exp));
if (end != NULL && *end != 0)
{
@@ -2348,6 +2359,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
op->am = (*l == '-' ? 3 : 1);
op->ol = 1;
op->vshift = 0;
+ op->expp = MSP_EXPP_ALL;
__tl = l;
end = parse_exp (__tl, &(op->exp));
if (end != NULL && * end != 0)
@@ -2382,6 +2394,7 @@ msp430_dstoperand (struct msp430_operand_s * op,
op->am = 1;
op->ol = 1;
op->vshift = 0;
+ op->expp = MSP_EXPP_ALL;
(void) parse_exp (__tl, &(op->exp));
if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
diff --git a/gas/testsuite/gas/msp430/msp430.exp b/gas/testsuite/gas/msp430/msp430.exp
index 6eaa659..624867f 100644
--- a/gas/testsuite/gas/msp430/msp430.exp
+++ b/gas/testsuite/gas/msp430/msp430.exp
@@ -52,4 +52,5 @@ if [expr [istarget "msp430-*-*"]] then {
run_dump_test "attr-430x-large-lower-good"
run_dump_test "attr-430x-large-any-bad"
run_dump_test "attr-430x-large-any-good"
+ run_dump_test "reloc-lo-430x"
}
diff --git a/gas/testsuite/gas/msp430/reloc-lo-430x.d b/gas/testsuite/gas/msp430/reloc-lo-430x.d
new file mode 100644
index 0000000..78adb84
--- /dev/null
+++ b/gas/testsuite/gas/msp430/reloc-lo-430x.d
@@ -0,0 +1,5 @@
+#as: -ml
+#readelf: -r
+#...
+.*R_MSP430_ABS16.*P \+ 0
+#...
diff --git a/gas/testsuite/gas/msp430/reloc-lo-430x.s b/gas/testsuite/gas/msp430/reloc-lo-430x.s
new file mode 100644
index 0000000..a593ac4
--- /dev/null
+++ b/gas/testsuite/gas/msp430/reloc-lo-430x.s
@@ -0,0 +1,22 @@
+.text
+ .balign 2
+ .global foo
+ .type foo, @function
+foo:
+ MOV.W #lo (P), R8
+ RETA
+ .size foo, .-foo
+
+ .balign 2
+ .global main
+ .type main, @function
+main:
+ CALLA #foo
+.L4:
+ BRA #.L4
+ .size main, .-main
+ .section .bss,"aw",@nobits
+ .balign 2
+ .global P
+P:
+ .zero 4