GNU Binutils with patches for OS216
修訂 | 131cb553d6d10412b20cf49bb0e3a5e736a90a36 (tree) |
---|---|
時間 | 2020-01-15 22:23:06 |
作者 | Jozef Lawrynowicz <jozef.l@mitt...> |
Commiter | Jozef Lawrynowicz |
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.
@@ -1,3 +1,16 @@ | ||
1 | +2020-01-15 Jozef Lawrynowicz <jozef.l@mittosystems.com> | |
2 | + | |
3 | + * config/tc-msp430.c (CHECK_RELOC_MSP430): Always generate 430X | |
4 | + relocations when the target is 430X, except when extracting part of an | |
5 | + expression. | |
6 | + (msp430_srcoperand): Adjust comment. | |
7 | + Initialize the expp member of the msp430_operand_s struct as | |
8 | + appropriate. | |
9 | + (msp430_dstoperand): Likewise. | |
10 | + * testsuite/gas/msp430/msp430.exp: Run new test. | |
11 | + * testsuite/gas/msp430/reloc-lo-430x.d: New test. | |
12 | + * testsuite/gas/msp430/reloc-lo-430x.s: New test. | |
13 | + | |
1 | 14 | 2020-01-15 Alan Modra <amodra@gmail.com> |
2 | 15 | |
3 | 16 | * configure.tgt: Add sparc-*-freebsd case. |
@@ -275,21 +275,21 @@ target_is_430xv2 (void) | ||
275 | 275 | return selected_isa == MSP_ISA_430Xv2; |
276 | 276 | } |
277 | 277 | |
278 | -/* Generate an absolute 16-bit relocation. | |
279 | - For the 430X we generate a relocation without linker range checking | |
280 | - if the value is being used in an extended (ie 20-bit) instruction, | |
281 | - otherwise if have a shifted expression we use a HI reloc. | |
278 | +/* Generate an absolute 16-bit relocation, for 430 (!extended_op) instructions | |
279 | + only. | |
280 | + For the 430X we generate a 430 relocation only for the case where part of an | |
281 | + expression is being extracted (e.g. #hi(EXP), #lo(EXP). Otherwise generate | |
282 | + a 430X relocation. | |
282 | 283 | For the 430 we generate a relocation without assembler range checking |
283 | - if we are handling an immediate value or a byte-width instruction. */ | |
284 | + if we are handling an immediate value or a byte-width instruction. */ | |
284 | 285 | |
285 | 286 | #undef CHECK_RELOC_MSP430 |
286 | 287 | #define CHECK_RELOC_MSP430(OP) \ |
287 | 288 | (target_is_430x () \ |
288 | - ? (extended_op \ | |
289 | - ? BFD_RELOC_16 \ | |
290 | - : ((OP).vshift == 1) \ | |
291 | - ? BFD_RELOC_MSP430_ABS_HI16 \ | |
292 | - : BFD_RELOC_MSP430X_ABS16) \ | |
289 | + ? ((OP).expp == MSP_EXPP_ALL \ | |
290 | + ? BFD_RELOC_MSP430X_ABS16 \ | |
291 | + : ((OP).vshift == 1 \ | |
292 | + ? BFD_RELOC_MSP430_ABS_HI16 : BFD_RELOC_16)) \ | |
293 | 293 | : ((imm_op || byte_op) \ |
294 | 294 | ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16)) |
295 | 295 |
@@ -1909,13 +1909,15 @@ msp430_srcoperand (struct msp430_operand_s * op, | ||
1909 | 1909 | char *h = l; |
1910 | 1910 | int vshift = -1; |
1911 | 1911 | int rval = 0; |
1912 | + /* Use all parts of the constant expression by default. */ | |
1913 | + enum msp430_expp_e expp = MSP_EXPP_ALL; | |
1912 | 1914 | |
1913 | 1915 | /* Check if there is: |
1914 | 1916 | llo(x) - least significant 16 bits, x &= 0xffff |
1915 | 1917 | lhi(x) - x = (x >> 16) & 0xffff, |
1916 | 1918 | hlo(x) - x = (x >> 32) & 0xffff, |
1917 | 1919 | hhi(x) - x = (x >> 48) & 0xffff |
1918 | - The value _MUST_ be constant expression: #hlo(1231231231). */ | |
1920 | + The value _MUST_ be an immediate expression: #hlo(1231231231). */ | |
1919 | 1921 | |
1920 | 1922 | *imm_op = TRUE; |
1921 | 1923 |
@@ -1923,31 +1925,37 @@ msp430_srcoperand (struct msp430_operand_s * op, | ||
1923 | 1925 | { |
1924 | 1926 | vshift = 0; |
1925 | 1927 | rval = 3; |
1928 | + expp = MSP_EXPP_LLO; | |
1926 | 1929 | } |
1927 | 1930 | else if (strncasecmp (h, "#lhi(", 5) == 0) |
1928 | 1931 | { |
1929 | 1932 | vshift = 1; |
1930 | 1933 | rval = 3; |
1934 | + expp = MSP_EXPP_LHI; | |
1931 | 1935 | } |
1932 | 1936 | else if (strncasecmp (h, "#hlo(", 5) == 0) |
1933 | 1937 | { |
1934 | 1938 | vshift = 2; |
1935 | 1939 | rval = 3; |
1940 | + expp = MSP_EXPP_HLO; | |
1936 | 1941 | } |
1937 | 1942 | else if (strncasecmp (h, "#hhi(", 5) == 0) |
1938 | 1943 | { |
1939 | 1944 | vshift = 3; |
1940 | 1945 | rval = 3; |
1946 | + expp = MSP_EXPP_HHI; | |
1941 | 1947 | } |
1942 | 1948 | else if (strncasecmp (h, "#lo(", 4) == 0) |
1943 | 1949 | { |
1944 | 1950 | vshift = 0; |
1945 | 1951 | rval = 2; |
1952 | + expp = MSP_EXPP_LO; | |
1946 | 1953 | } |
1947 | 1954 | else if (strncasecmp (h, "#hi(", 4) == 0) |
1948 | 1955 | { |
1949 | 1956 | vshift = 1; |
1950 | 1957 | rval = 2; |
1958 | + expp = MSP_EXPP_HI; | |
1951 | 1959 | } |
1952 | 1960 | |
1953 | 1961 | op->reg = 0; /* Reg PC. */ |
@@ -1956,6 +1964,7 @@ msp430_srcoperand (struct msp430_operand_s * op, | ||
1956 | 1964 | __tl = h + 1 + rval; |
1957 | 1965 | op->mode = OP_EXP; |
1958 | 1966 | op->vshift = vshift; |
1967 | + op->expp = expp; | |
1959 | 1968 | |
1960 | 1969 | end = parse_exp (__tl, &(op->exp)); |
1961 | 1970 | if (end != NULL && *end != 0 && *end != ')' ) |
@@ -2167,6 +2176,7 @@ msp430_srcoperand (struct msp430_operand_s * op, | ||
2167 | 2176 | } |
2168 | 2177 | op->mode = OP_EXP; |
2169 | 2178 | op->vshift = 0; |
2179 | + op->expp = MSP_EXPP_ALL; | |
2170 | 2180 | if (op->exp.X_op == O_constant) |
2171 | 2181 | { |
2172 | 2182 | int x = op->exp.X_add_number; |
@@ -2275,6 +2285,7 @@ msp430_srcoperand (struct msp430_operand_s * op, | ||
2275 | 2285 | *h = 0; |
2276 | 2286 | op->mode = OP_EXP; |
2277 | 2287 | op->vshift = 0; |
2288 | + op->expp = MSP_EXPP_ALL; | |
2278 | 2289 | end = parse_exp (__tl, &(op->exp)); |
2279 | 2290 | if (end != NULL && *end != 0) |
2280 | 2291 | { |
@@ -2348,6 +2359,7 @@ msp430_srcoperand (struct msp430_operand_s * op, | ||
2348 | 2359 | op->am = (*l == '-' ? 3 : 1); |
2349 | 2360 | op->ol = 1; |
2350 | 2361 | op->vshift = 0; |
2362 | + op->expp = MSP_EXPP_ALL; | |
2351 | 2363 | __tl = l; |
2352 | 2364 | end = parse_exp (__tl, &(op->exp)); |
2353 | 2365 | if (end != NULL && * end != 0) |
@@ -2382,6 +2394,7 @@ msp430_dstoperand (struct msp430_operand_s * op, | ||
2382 | 2394 | op->am = 1; |
2383 | 2395 | op->ol = 1; |
2384 | 2396 | op->vshift = 0; |
2397 | + op->expp = MSP_EXPP_ALL; | |
2385 | 2398 | (void) parse_exp (__tl, &(op->exp)); |
2386 | 2399 | |
2387 | 2400 | if (op->exp.X_op != O_constant || op->exp.X_add_number != 0) |
@@ -52,4 +52,5 @@ if [expr [istarget "msp430-*-*"]] then { | ||
52 | 52 | run_dump_test "attr-430x-large-lower-good" |
53 | 53 | run_dump_test "attr-430x-large-any-bad" |
54 | 54 | run_dump_test "attr-430x-large-any-good" |
55 | + run_dump_test "reloc-lo-430x" | |
55 | 56 | } |
@@ -0,0 +1,5 @@ | ||
1 | +#as: -ml | |
2 | +#readelf: -r | |
3 | +#... | |
4 | +.*R_MSP430_ABS16.*P \+ 0 | |
5 | +#... |
@@ -0,0 +1,22 @@ | ||
1 | +.text | |
2 | + .balign 2 | |
3 | + .global foo | |
4 | + .type foo, @function | |
5 | +foo: | |
6 | + MOV.W #lo (P), R8 | |
7 | + RETA | |
8 | + .size foo, .-foo | |
9 | + | |
10 | + .balign 2 | |
11 | + .global main | |
12 | + .type main, @function | |
13 | +main: | |
14 | + CALLA #foo | |
15 | +.L4: | |
16 | + BRA #.L4 | |
17 | + .size main, .-main | |
18 | + .section .bss,"aw",@nobits | |
19 | + .balign 2 | |
20 | + .global P | |
21 | +P: | |
22 | + .zero 4 |
@@ -1,3 +1,8 @@ | ||
1 | +2020-01-15 Jozef Lawrynowicz <jozef.l@mittosystems.com> | |
2 | + | |
3 | + * opcode/msp430.h (enum msp430_expp_e): New. | |
4 | + (struct msp430_operand_s): Add expp member to struct. | |
5 | + | |
1 | 6 | 2020-01-13 Claudiu Zissulescu <claziss@gmail.com> |
2 | 7 | |
3 | 8 | * elf/arc-cpu.def: Update ARC cpu list. |
@@ -21,6 +21,18 @@ | ||
21 | 21 | #ifndef __MSP430_H_ |
22 | 22 | #define __MSP430_H_ |
23 | 23 | |
24 | +enum msp430_expp_e | |
25 | +{ | |
26 | + MSP_EXPP_ALL = 0, /* Use full the value of the expression - default. */ | |
27 | + MSP_EXPP_LO, /* Extract least significant word from expression. */ | |
28 | + MSP_EXPP_HI, /* Extract 2nd word from expression. */ | |
29 | + MSP_EXPP_LLO, /* Extract least significant word from an | |
30 | + immediate value. */ | |
31 | + MSP_EXPP_LHI, /* Extract 2nd word from an immediate value. */ | |
32 | + MSP_EXPP_HLO, /* Extract 3rd word from an immediate value. */ | |
33 | + MSP_EXPP_HHI, /* Extract 4th word from an immediate value. */ | |
34 | +}; | |
35 | + | |
24 | 36 | struct msp430_operand_s |
25 | 37 | { |
26 | 38 | int ol; /* Operand length words. */ |
@@ -28,6 +40,9 @@ struct msp430_operand_s | ||
28 | 40 | int reg; /* Register. */ |
29 | 41 | int mode; /* Operand mode. */ |
30 | 42 | int vshift; /* Number of bytes to shift operand down. */ |
43 | + enum msp430_expp_e expp; /* For when the operand is a constant | |
44 | + expression, the part of the expression to | |
45 | + extract. */ | |
31 | 46 | #define OP_REG 0 |
32 | 47 | #define OP_EXP 1 |
33 | 48 | #ifndef DASM_SECTION |
@@ -1,3 +1,8 @@ | ||
1 | +2020-01-15 Jozef Lawrynowicz <jozef.l@mittosystems.com> | |
2 | + | |
3 | + * testsuite/ld-msp430-elf/msp430-elf.exp: Run new test. | |
4 | + * testsuite/ld-msp430-elf/reloc-lo-430x.s: New test. | |
5 | + | |
1 | 6 | 2020-01-15 Alan Modra <amodra@gmail.com> |
2 | 7 | |
3 | 8 | * testsuite/ld-powerpc/ambiguousv1b.d: Adjust expected output. |
@@ -174,6 +174,8 @@ run_ld_link_tests $msp430eithershuffletests | ||
174 | 174 | run_ld_link_tests $msp430warntests |
175 | 175 | |
176 | 176 | run_dump_test valid-map |
177 | +run_ld_link_tests {{ "Check no reloc overflow with #lo and data in the upper region" | |
178 | + "-m msp430X" "" "" {reloc-lo-430x.s} {} "reloc-lo-430x"}} | |
177 | 179 | |
178 | 180 | # Don't run data region tests if a data region is specified |
179 | 181 | if {[string match "*-mdata-region*" [board_info [target_info name] multilib_flags]]} { |
@@ -0,0 +1,22 @@ | ||
1 | +.text | |
2 | + .balign 2 | |
3 | + .global foo | |
4 | + .type foo, @function | |
5 | +foo: | |
6 | + MOV.W #lo (P), R8 | |
7 | + RETA | |
8 | + .size foo, .-foo | |
9 | + | |
10 | + .balign 2 | |
11 | + .global main | |
12 | + .type main, @function | |
13 | +main: | |
14 | + CALLA #foo | |
15 | +.L4: | |
16 | + BRA #.L4 | |
17 | + .size main, .-main | |
18 | + .section .bss,"aw",@nobits | |
19 | + .balign 2 | |
20 | + .global P | |
21 | +P: | |
22 | + .zero 4 |