mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 09:14:14 +08:00
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:
@ -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>
|
2020-01-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* configure.tgt: Add sparc-*-freebsd case.
|
* configure.tgt: Add sparc-*-freebsd case.
|
||||||
|
@ -275,21 +275,21 @@ target_is_430xv2 (void)
|
|||||||
return selected_isa == MSP_ISA_430Xv2;
|
return selected_isa == MSP_ISA_430Xv2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate an absolute 16-bit relocation.
|
/* Generate an absolute 16-bit relocation, for 430 (!extended_op) instructions
|
||||||
For the 430X we generate a relocation without linker range checking
|
only.
|
||||||
if the value is being used in an extended (ie 20-bit) instruction,
|
For the 430X we generate a 430 relocation only for the case where part of an
|
||||||
otherwise if have a shifted expression we use a HI reloc.
|
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
|
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
|
#undef CHECK_RELOC_MSP430
|
||||||
#define CHECK_RELOC_MSP430(OP) \
|
#define CHECK_RELOC_MSP430(OP) \
|
||||||
(target_is_430x () \
|
(target_is_430x () \
|
||||||
? (extended_op \
|
? ((OP).expp == MSP_EXPP_ALL \
|
||||||
? BFD_RELOC_16 \
|
? BFD_RELOC_MSP430X_ABS16 \
|
||||||
: ((OP).vshift == 1) \
|
: ((OP).vshift == 1 \
|
||||||
? BFD_RELOC_MSP430_ABS_HI16 \
|
? BFD_RELOC_MSP430_ABS_HI16 : BFD_RELOC_16)) \
|
||||||
: BFD_RELOC_MSP430X_ABS16) \
|
|
||||||
: ((imm_op || byte_op) \
|
: ((imm_op || byte_op) \
|
||||||
? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
|
? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
|
||||||
|
|
||||||
@ -1909,13 +1909,15 @@ msp430_srcoperand (struct msp430_operand_s * op,
|
|||||||
char *h = l;
|
char *h = l;
|
||||||
int vshift = -1;
|
int vshift = -1;
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
/* Use all parts of the constant expression by default. */
|
||||||
|
enum msp430_expp_e expp = MSP_EXPP_ALL;
|
||||||
|
|
||||||
/* Check if there is:
|
/* Check if there is:
|
||||||
llo(x) - least significant 16 bits, x &= 0xffff
|
llo(x) - least significant 16 bits, x &= 0xffff
|
||||||
lhi(x) - x = (x >> 16) & 0xffff,
|
lhi(x) - x = (x >> 16) & 0xffff,
|
||||||
hlo(x) - x = (x >> 32) & 0xffff,
|
hlo(x) - x = (x >> 32) & 0xffff,
|
||||||
hhi(x) - x = (x >> 48) & 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;
|
*imm_op = TRUE;
|
||||||
|
|
||||||
@ -1923,31 +1925,37 @@ msp430_srcoperand (struct msp430_operand_s * op,
|
|||||||
{
|
{
|
||||||
vshift = 0;
|
vshift = 0;
|
||||||
rval = 3;
|
rval = 3;
|
||||||
|
expp = MSP_EXPP_LLO;
|
||||||
}
|
}
|
||||||
else if (strncasecmp (h, "#lhi(", 5) == 0)
|
else if (strncasecmp (h, "#lhi(", 5) == 0)
|
||||||
{
|
{
|
||||||
vshift = 1;
|
vshift = 1;
|
||||||
rval = 3;
|
rval = 3;
|
||||||
|
expp = MSP_EXPP_LHI;
|
||||||
}
|
}
|
||||||
else if (strncasecmp (h, "#hlo(", 5) == 0)
|
else if (strncasecmp (h, "#hlo(", 5) == 0)
|
||||||
{
|
{
|
||||||
vshift = 2;
|
vshift = 2;
|
||||||
rval = 3;
|
rval = 3;
|
||||||
|
expp = MSP_EXPP_HLO;
|
||||||
}
|
}
|
||||||
else if (strncasecmp (h, "#hhi(", 5) == 0)
|
else if (strncasecmp (h, "#hhi(", 5) == 0)
|
||||||
{
|
{
|
||||||
vshift = 3;
|
vshift = 3;
|
||||||
rval = 3;
|
rval = 3;
|
||||||
|
expp = MSP_EXPP_HHI;
|
||||||
}
|
}
|
||||||
else if (strncasecmp (h, "#lo(", 4) == 0)
|
else if (strncasecmp (h, "#lo(", 4) == 0)
|
||||||
{
|
{
|
||||||
vshift = 0;
|
vshift = 0;
|
||||||
rval = 2;
|
rval = 2;
|
||||||
|
expp = MSP_EXPP_LO;
|
||||||
}
|
}
|
||||||
else if (strncasecmp (h, "#hi(", 4) == 0)
|
else if (strncasecmp (h, "#hi(", 4) == 0)
|
||||||
{
|
{
|
||||||
vshift = 1;
|
vshift = 1;
|
||||||
rval = 2;
|
rval = 2;
|
||||||
|
expp = MSP_EXPP_HI;
|
||||||
}
|
}
|
||||||
|
|
||||||
op->reg = 0; /* Reg PC. */
|
op->reg = 0; /* Reg PC. */
|
||||||
@ -1956,6 +1964,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
|
|||||||
__tl = h + 1 + rval;
|
__tl = h + 1 + rval;
|
||||||
op->mode = OP_EXP;
|
op->mode = OP_EXP;
|
||||||
op->vshift = vshift;
|
op->vshift = vshift;
|
||||||
|
op->expp = expp;
|
||||||
|
|
||||||
end = parse_exp (__tl, &(op->exp));
|
end = parse_exp (__tl, &(op->exp));
|
||||||
if (end != NULL && *end != 0 && *end != ')' )
|
if (end != NULL && *end != 0 && *end != ')' )
|
||||||
@ -2167,6 +2176,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
|
|||||||
}
|
}
|
||||||
op->mode = OP_EXP;
|
op->mode = OP_EXP;
|
||||||
op->vshift = 0;
|
op->vshift = 0;
|
||||||
|
op->expp = MSP_EXPP_ALL;
|
||||||
if (op->exp.X_op == O_constant)
|
if (op->exp.X_op == O_constant)
|
||||||
{
|
{
|
||||||
int x = op->exp.X_add_number;
|
int x = op->exp.X_add_number;
|
||||||
@ -2275,6 +2285,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
|
|||||||
*h = 0;
|
*h = 0;
|
||||||
op->mode = OP_EXP;
|
op->mode = OP_EXP;
|
||||||
op->vshift = 0;
|
op->vshift = 0;
|
||||||
|
op->expp = MSP_EXPP_ALL;
|
||||||
end = parse_exp (__tl, &(op->exp));
|
end = parse_exp (__tl, &(op->exp));
|
||||||
if (end != NULL && *end != 0)
|
if (end != NULL && *end != 0)
|
||||||
{
|
{
|
||||||
@ -2348,6 +2359,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
|
|||||||
op->am = (*l == '-' ? 3 : 1);
|
op->am = (*l == '-' ? 3 : 1);
|
||||||
op->ol = 1;
|
op->ol = 1;
|
||||||
op->vshift = 0;
|
op->vshift = 0;
|
||||||
|
op->expp = MSP_EXPP_ALL;
|
||||||
__tl = l;
|
__tl = l;
|
||||||
end = parse_exp (__tl, &(op->exp));
|
end = parse_exp (__tl, &(op->exp));
|
||||||
if (end != NULL && * end != 0)
|
if (end != NULL && * end != 0)
|
||||||
@ -2382,6 +2394,7 @@ msp430_dstoperand (struct msp430_operand_s * op,
|
|||||||
op->am = 1;
|
op->am = 1;
|
||||||
op->ol = 1;
|
op->ol = 1;
|
||||||
op->vshift = 0;
|
op->vshift = 0;
|
||||||
|
op->expp = MSP_EXPP_ALL;
|
||||||
(void) parse_exp (__tl, &(op->exp));
|
(void) parse_exp (__tl, &(op->exp));
|
||||||
|
|
||||||
if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
|
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-lower-good"
|
||||||
run_dump_test "attr-430x-large-any-bad"
|
run_dump_test "attr-430x-large-any-bad"
|
||||||
run_dump_test "attr-430x-large-any-good"
|
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>
|
2020-01-13 Claudiu Zissulescu <claziss@gmail.com>
|
||||||
|
|
||||||
* elf/arc-cpu.def: Update ARC cpu list.
|
* elf/arc-cpu.def: Update ARC cpu list.
|
||||||
|
@ -21,6 +21,18 @@
|
|||||||
#ifndef __MSP430_H_
|
#ifndef __MSP430_H_
|
||||||
#define __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
|
struct msp430_operand_s
|
||||||
{
|
{
|
||||||
int ol; /* Operand length words. */
|
int ol; /* Operand length words. */
|
||||||
@ -28,6 +40,9 @@ struct msp430_operand_s
|
|||||||
int reg; /* Register. */
|
int reg; /* Register. */
|
||||||
int mode; /* Operand mode. */
|
int mode; /* Operand mode. */
|
||||||
int vshift; /* Number of bytes to shift operand down. */
|
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_REG 0
|
||||||
#define OP_EXP 1
|
#define OP_EXP 1
|
||||||
#ifndef DASM_SECTION
|
#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>
|
2020-01-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* testsuite/ld-powerpc/ambiguousv1b.d: Adjust expected output.
|
* testsuite/ld-powerpc/ambiguousv1b.d: Adjust expected output.
|
||||||
|
@ -174,6 +174,8 @@ run_ld_link_tests $msp430eithershuffletests
|
|||||||
run_ld_link_tests $msp430warntests
|
run_ld_link_tests $msp430warntests
|
||||||
|
|
||||||
run_dump_test valid-map
|
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
|
# Don't run data region tests if a data region is specified
|
||||||
if {[string match "*-mdata-region*" [board_info [target_info name] multilib_flags]]} {
|
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
|
Reference in New Issue
Block a user