[PATCH][GAS][MSP430] Fix relocation overflow when using #lo(EXP) macro
The following assembly code generates a relocation overflow if P is in
upper memory (at or above address 0x10000).
> MOV.W #lo (P), R8
> as -ml reloc.s -o reloc.o
> ld -m msp430X reloc.o
> reloc.o: in function `foo':
> (.text+0x2): relocation truncated to fit: R_MSP430X_ABS16 against symbol `P'
> defined in .bss section in reloc.o
This code is intended to extract the low 16-bits of the address of P, so it is
valid to use a 430 instruction, even though the address of P might be 20-bits in
size (stored in a 32-bit linker symbol).
However, since an R_MSP430X_ABS16 is generated for this instruction, the
20-bit value overflows when used in the 430 instruction which expects a 16-bit
The MSPABI states the following:
MSP430 instructions allow only a 16-bit field. MSP430 instruction relocations
are not typically checked for overflow. MSP430 instructions can also be used
on MSP430X, but the assembler uses different relocations so that overflow
can be checked.
R_MSP430_ABS16 and R_MSP430_PCR16 are used for MSP430 instructions. With one
exception (R_MSP430_ABS16 for $LO16), neither is used for instructions on
MSP430X. The use of R_MSP430_ABS16 for $LO16 for MSP430X is a special case
intended to be half of a 32-bit immediate load.
This means that a R_MSP430_ABS16 relocation should be used for #lo, even when
assembling for MSP430X. The attached patch fixes that.
Note that the patch also removes the redundant check of "extended_op" from
CHECK_RELOC_MSP430. As stated in the above text from the ABI, 430X relocations
should always be used if the target is 430X (except for #lo/#hi), even if the
instruction is 430. CHECK_RELOC_MSP430 is only actually used for 430
Successfully regtested the binutils and GCC/G++ testsuites for msp430-elf
in default configuration and -mlarge/-mdata-region=upper.