diff options
-rw-r--r-- | lld/COFF/Chunks.cpp | 12 | ||||
-rw-r--r-- | lld/test/COFF/broken-arm-reloc.yaml | 92 |
2 files changed, 101 insertions, 3 deletions
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index d7f4f43c8d5..fc5998f3945 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -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 diff --git a/lld/test/COFF/broken-arm-reloc.yaml b/lld/test/COFF/broken-arm-reloc.yaml new file mode 100644 index 00000000000..ad4328bcb14 --- /dev/null +++ b/lld/test/COFF/broken-arm-reloc.yaml @@ -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 +... |