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.
This commit is contained in:
parent
c24d0e8d48
commit
131cb553d6
10 changed files with 114 additions and 11 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
5
gas/testsuite/gas/msp430/reloc-lo-430x.d
Normal file
5
gas/testsuite/gas/msp430/reloc-lo-430x.d
Normal file
|
@ -0,0 +1,5 @@
|
|||
#as: -ml
|
||||
#readelf: -r
|
||||
#...
|
||||
.*R_MSP430_ABS16.*P \+ 0
|
||||
#...
|
22
gas/testsuite/gas/msp430/reloc-lo-430x.s
Normal file
22
gas/testsuite/gas/msp430/reloc-lo-430x.s
Normal file
|
@ -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
|
|
@ -1,3 +1,8 @@
|
|||
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.
|
||||
|
||||
2020-01-13 Claudiu Zissulescu <claziss@gmail.com>
|
||||
|
||||
* elf/arc-cpu.def: Update ARC cpu list.
|
||||
|
|
|
@ -21,6 +21,18 @@
|
|||
#ifndef __MSP430_H_
|
||||
#define __MSP430_H_
|
||||
|
||||
enum msp430_expp_e
|
||||
{
|
||||
MSP_EXPP_ALL = 0, /* Use full the value of the expression - default. */
|
||||
MSP_EXPP_LO, /* Extract least significant word from expression. */
|
||||
MSP_EXPP_HI, /* Extract 2nd word from expression. */
|
||||
MSP_EXPP_LLO, /* Extract least significant word from an
|
||||
immediate value. */
|
||||
MSP_EXPP_LHI, /* Extract 2nd word from an immediate value. */
|
||||
MSP_EXPP_HLO, /* Extract 3rd word from an immediate value. */
|
||||
MSP_EXPP_HHI, /* Extract 4th word from an immediate value. */
|
||||
};
|
||||
|
||||
struct msp430_operand_s
|
||||
{
|
||||
int ol; /* Operand length words. */
|
||||
|
@ -28,6 +40,9 @@ struct msp430_operand_s
|
|||
int reg; /* Register. */
|
||||
int mode; /* Operand mode. */
|
||||
int vshift; /* Number of bytes to shift operand down. */
|
||||
enum msp430_expp_e expp; /* For when the operand is a constant
|
||||
expression, the part of the expression to
|
||||
extract. */
|
||||
#define OP_REG 0
|
||||
#define OP_EXP 1
|
||||
#ifndef DASM_SECTION
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
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.
|
||||
|
||||
2020-01-15 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/ld-powerpc/ambiguousv1b.d: Adjust expected output.
|
||||
|
|
|
@ -174,6 +174,8 @@ run_ld_link_tests $msp430eithershuffletests
|
|||
run_ld_link_tests $msp430warntests
|
||||
|
||||
run_dump_test valid-map
|
||||
run_ld_link_tests {{ "Check no reloc overflow with #lo and data in the upper region"
|
||||
"-m msp430X" "" "" {reloc-lo-430x.s} {} "reloc-lo-430x"}}
|
||||
|
||||
# Don't run data region tests if a data region is specified
|
||||
if {[string match "*-mdata-region*" [board_info [target_info name] multilib_flags]]} {
|
||||
|
|
22
ld/testsuite/ld-msp430-elf/reloc-lo-430x.s
Normal file
22
ld/testsuite/ld-msp430-elf/reloc-lo-430x.s
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue