[COFF] Check the instructions in ARM MOV32T relocations

For this relocation, which applies to two consecutive instructions,
it's plausible that the second instruction might not actually be
the right one.

Differential Revision: https://reviews.llvm.org/D50998

llvm-svn: 340715
This commit is contained in:
Martin Storsjo 2018-08-27 06:04:36 +00:00
parent 266b858705
commit c4b0061c05
2 changed files with 101 additions and 3 deletions

View File

@ -124,16 +124,22 @@ static void applyMOV(uint8_t *Off, uint16_t V) {
write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
}
static uint16_t readMOV(uint8_t *Off) {
static uint16_t readMOV(uint8_t *Off, bool MOVT) {
uint16_t Op1 = read16le(Off);
if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240))
error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
" instruction in MOV32T relocation");
uint16_t Op2 = read16le(Off + 2);
if ((Op2 & 0x8000) != 0)
error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
" instruction in MOV32T relocation");
return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
((Op1 & 0x000f) << 12);
}
void applyMOV32T(uint8_t *Off, uint32_t V) {
uint16_t ImmW = readMOV(Off); // read MOVW operand
uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
uint16_t ImmW = readMOV(Off, false); // read MOVW operand
uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
uint32_t Imm = ImmW | (ImmT << 16);
V += Imm; // add the immediate offset
applyMOV(Off, V); // set MOVW operand

View File

@ -0,0 +1,92 @@
# REQUIRES: arm
# .global main
# .global variable
# .text
# .thumb
#main:
# movw r0, :lower16:variable
# nop
# movt r0, :upper16:variable
# ldr r0, [r0]
# bx lr
# .data
#variable:
# .long 42
# RUN: yaml2obj %s > %t.obj
# RUN: not lld-link -out:%t.exe -entry:main %t.obj 2>&1 | FileCheck %s
# CHECK: error: unexpected instruction in MOVT instruction in MOV32T relocation
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_ARMNT
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: 40F2000000BFC0F2000000687047
Relocations:
- VirtualAddress: 0
SymbolName: variable
Type: IMAGE_REL_ARM_MOV32T
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: 2A000000
- Name: .bss
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 14
NumberOfRelocations: 1
NumberOfLinenumbers: 0
CheckSum: 2762100735
Number: 1
- Name: .data
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 4
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 3482275674
Number: 2
- Name: .bss
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 0
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 3
- Name: main
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: variable
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...