diff options
| author | Martin Storsjo <martin@martin.st> | 2018-08-27 06:04:36 +0000 |
|---|---|---|
| committer | Martin Storsjo <martin@martin.st> | 2018-08-27 06:04:36 +0000 |
| commit | c4b0061c0525ff268947e35c1dc9eefced26c083 (patch) | |
| tree | bc8b094e37c2c3f39edbe84507367463e49f4ec3 /lld/COFF/Chunks.cpp | |
| parent | 266b858705f96b24f16909ab4471b6f1514af1ca (diff) | |
| download | bcm5719-llvm-c4b0061c0525ff268947e35c1dc9eefced26c083.tar.gz bcm5719-llvm-c4b0061c0525ff268947e35c1dc9eefced26c083.zip | |
[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
Diffstat (limited to 'lld/COFF/Chunks.cpp')
| -rw-r--r-- | lld/COFF/Chunks.cpp | 12 |
1 files changed, 9 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 |

