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:
Jozef Lawrynowicz 2020-01-15 13:17:27 +00:00
parent c24d0e8d48
commit 131cb553d6
10 changed files with 114 additions and 11 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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"
}

View File

@ -0,0 +1,5 @@
#as: -ml
#readelf: -r
#...
.*R_MSP430_ABS16.*P \+ 0
#...

View 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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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]]} {

View 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