1 //===- bolt/Target/X86/X86MCPlusBuilder.cpp -------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file provides X86-specific MCPlus builder. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/X86BaseInfo.h" 14 #include "MCTargetDesc/X86InstrRelaxTables.h" 15 #include "MCTargetDesc/X86MCTargetDesc.h" 16 #include "X86MCSymbolizer.h" 17 #include "bolt/Core/MCPlus.h" 18 #include "bolt/Core/MCPlusBuilder.h" 19 #include "llvm/BinaryFormat/ELF.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCFixupKindInfo.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCInstBuilder.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCRegister.h" 26 #include "llvm/MC/MCRegisterInfo.h" 27 #include "llvm/Support/CommandLine.h" 28 #include "llvm/Support/DataExtractor.h" 29 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/Errc.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include "llvm/Support/ErrorOr.h" 33 #include <set> 34 35 #define DEBUG_TYPE "mcplus" 36 37 using namespace llvm; 38 using namespace bolt; 39 40 namespace opts { 41 42 extern cl::OptionCategory BoltOptCategory; 43 44 static cl::opt<bool> X86StripRedundantAddressSize( 45 "x86-strip-redundant-address-size", 46 cl::desc("Remove redundant Address-Size override prefix"), cl::init(true), 47 cl::cat(BoltOptCategory)); 48 49 } // namespace opts 50 51 namespace { 52 53 unsigned getShortBranchOpcode(unsigned Opcode) { 54 switch (Opcode) { 55 default: 56 return Opcode; 57 case X86::JMP_2: return X86::JMP_1; 58 case X86::JMP_4: return X86::JMP_1; 59 case X86::JCC_2: return X86::JCC_1; 60 case X86::JCC_4: return X86::JCC_1; 61 } 62 } 63 64 unsigned getShortArithOpcode(unsigned Opcode) { 65 return X86::getShortOpcodeArith(Opcode); 66 } 67 68 bool isMOVSX64rm32(const MCInst &Inst) { 69 return Inst.getOpcode() == X86::MOVSX64rm32; 70 } 71 72 bool isADD64rr(const MCInst &Inst) { return Inst.getOpcode() == X86::ADD64rr; } 73 74 bool isADDri(const MCInst &Inst) { 75 return Inst.getOpcode() == X86::ADD64ri32 || 76 Inst.getOpcode() == X86::ADD64ri8; 77 } 78 79 #define GET_INSTRINFO_OPERAND_TYPES_ENUM 80 #define GET_INSTRINFO_OPERAND_TYPE 81 #define GET_INSTRINFO_MEM_OPERAND_SIZE 82 #include "X86GenInstrInfo.inc" 83 84 class X86MCPlusBuilder : public MCPlusBuilder { 85 public: 86 X86MCPlusBuilder(const MCInstrAnalysis *Analysis, const MCInstrInfo *Info, 87 const MCRegisterInfo *RegInfo) 88 : MCPlusBuilder(Analysis, Info, RegInfo) {} 89 90 std::unique_ptr<MCSymbolizer> 91 createTargetSymbolizer(BinaryFunction &Function) const override { 92 return std::make_unique<X86MCSymbolizer>(Function); 93 } 94 95 bool isBranch(const MCInst &Inst) const override { 96 return Analysis->isBranch(Inst) && !isTailCall(Inst); 97 } 98 99 bool isNoop(const MCInst &Inst) const override { 100 return X86::isNOP(Inst.getOpcode()); 101 } 102 103 unsigned getCondCode(const MCInst &Inst) const override { 104 unsigned Opcode = Inst.getOpcode(); 105 if (X86::isJCC(Opcode)) 106 return Inst.getOperand(Info->get(Opcode).NumOperands - 1).getImm(); 107 return X86::COND_INVALID; 108 } 109 110 unsigned getInvertedCondCode(unsigned CC) const override { 111 switch (CC) { 112 default: return X86::COND_INVALID; 113 case X86::COND_E: return X86::COND_NE; 114 case X86::COND_NE: return X86::COND_E; 115 case X86::COND_L: return X86::COND_GE; 116 case X86::COND_LE: return X86::COND_G; 117 case X86::COND_G: return X86::COND_LE; 118 case X86::COND_GE: return X86::COND_L; 119 case X86::COND_B: return X86::COND_AE; 120 case X86::COND_BE: return X86::COND_A; 121 case X86::COND_A: return X86::COND_BE; 122 case X86::COND_AE: return X86::COND_B; 123 case X86::COND_S: return X86::COND_NS; 124 case X86::COND_NS: return X86::COND_S; 125 case X86::COND_P: return X86::COND_NP; 126 case X86::COND_NP: return X86::COND_P; 127 case X86::COND_O: return X86::COND_NO; 128 case X86::COND_NO: return X86::COND_O; 129 } 130 } 131 132 unsigned getCondCodesLogicalOr(unsigned CC1, unsigned CC2) const override { 133 enum DecodedCondCode : uint8_t { 134 DCC_EQUAL = 0x1, 135 DCC_GREATER = 0x2, 136 DCC_LESSER = 0x4, 137 DCC_GREATER_OR_LESSER = 0x6, 138 DCC_UNSIGNED = 0x8, 139 DCC_SIGNED = 0x10, 140 DCC_INVALID = 0x20, 141 }; 142 143 auto decodeCondCode = [&](unsigned CC) -> uint8_t { 144 switch (CC) { 145 default: return DCC_INVALID; 146 case X86::COND_E: return DCC_EQUAL; 147 case X86::COND_NE: return DCC_GREATER | DCC_LESSER; 148 case X86::COND_L: return DCC_LESSER | DCC_SIGNED; 149 case X86::COND_LE: return DCC_EQUAL | DCC_LESSER | DCC_SIGNED; 150 case X86::COND_G: return DCC_GREATER | DCC_SIGNED; 151 case X86::COND_GE: return DCC_GREATER | DCC_EQUAL | DCC_SIGNED; 152 case X86::COND_B: return DCC_LESSER | DCC_UNSIGNED; 153 case X86::COND_BE: return DCC_EQUAL | DCC_LESSER | DCC_UNSIGNED; 154 case X86::COND_A: return DCC_GREATER | DCC_UNSIGNED; 155 case X86::COND_AE: return DCC_GREATER | DCC_EQUAL | DCC_UNSIGNED; 156 } 157 }; 158 159 uint8_t DCC = decodeCondCode(CC1) | decodeCondCode(CC2); 160 161 if (DCC & DCC_INVALID) 162 return X86::COND_INVALID; 163 164 if (DCC & DCC_SIGNED && DCC & DCC_UNSIGNED) 165 return X86::COND_INVALID; 166 167 switch (DCC) { 168 default: return X86::COND_INVALID; 169 case DCC_EQUAL | DCC_LESSER | DCC_SIGNED: return X86::COND_LE; 170 case DCC_EQUAL | DCC_LESSER | DCC_UNSIGNED: return X86::COND_BE; 171 case DCC_EQUAL | DCC_GREATER | DCC_SIGNED: return X86::COND_GE; 172 case DCC_EQUAL | DCC_GREATER | DCC_UNSIGNED: return X86::COND_AE; 173 case DCC_GREATER | DCC_LESSER | DCC_SIGNED: return X86::COND_NE; 174 case DCC_GREATER | DCC_LESSER | DCC_UNSIGNED: return X86::COND_NE; 175 case DCC_GREATER | DCC_LESSER: return X86::COND_NE; 176 case DCC_EQUAL | DCC_SIGNED: return X86::COND_E; 177 case DCC_EQUAL | DCC_UNSIGNED: return X86::COND_E; 178 case DCC_EQUAL: return X86::COND_E; 179 case DCC_LESSER | DCC_SIGNED: return X86::COND_L; 180 case DCC_LESSER | DCC_UNSIGNED: return X86::COND_B; 181 case DCC_GREATER | DCC_SIGNED: return X86::COND_G; 182 case DCC_GREATER | DCC_UNSIGNED: return X86::COND_A; 183 } 184 } 185 186 bool isValidCondCode(unsigned CC) const override { 187 return (CC != X86::COND_INVALID); 188 } 189 190 bool isBreakpoint(const MCInst &Inst) const override { 191 return Inst.getOpcode() == X86::INT3; 192 } 193 194 bool isPrefix(const MCInst &Inst) const override { 195 const MCInstrDesc &Desc = Info->get(Inst.getOpcode()); 196 return X86II::isPrefix(Desc.TSFlags); 197 } 198 199 bool isRep(const MCInst &Inst) const override { 200 return Inst.getFlags() == X86::IP_HAS_REPEAT; 201 } 202 203 bool deleteREPPrefix(MCInst &Inst) const override { 204 if (Inst.getFlags() == X86::IP_HAS_REPEAT) { 205 Inst.setFlags(0); 206 return true; 207 } 208 return false; 209 } 210 211 // FIXME: For compatibility with old LLVM only! 212 bool isTerminator(const MCInst &Inst) const override { 213 unsigned Opcode = Inst.getOpcode(); 214 return Info->get(Opcode).isTerminator() || X86::isUD1(Opcode) || 215 X86::isUD2(Opcode); 216 } 217 218 bool isIndirectCall(const MCInst &Inst) const override { 219 return isCall(Inst) && 220 ((getMemoryOperandNo(Inst) != -1) || Inst.getOperand(0).isReg()); 221 } 222 223 bool isPop(const MCInst &Inst) const override { 224 return getPopSize(Inst) == 0 ? false : true; 225 } 226 227 bool isTerminateBranch(const MCInst &Inst) const override { 228 return Inst.getOpcode() == X86::ENDBR32 || Inst.getOpcode() == X86::ENDBR64; 229 } 230 231 int getPopSize(const MCInst &Inst) const override { 232 switch (Inst.getOpcode()) { 233 case X86::POP16r: 234 case X86::POP16rmm: 235 case X86::POP16rmr: 236 case X86::POPF16: 237 case X86::POPA16: 238 case X86::POPDS16: 239 case X86::POPES16: 240 case X86::POPFS16: 241 case X86::POPGS16: 242 case X86::POPSS16: 243 return 2; 244 case X86::POP32r: 245 case X86::POP32rmm: 246 case X86::POP32rmr: 247 case X86::POPA32: 248 case X86::POPDS32: 249 case X86::POPES32: 250 case X86::POPF32: 251 case X86::POPFS32: 252 case X86::POPGS32: 253 case X86::POPSS32: 254 return 4; 255 case X86::POP64r: 256 case X86::POP64rmm: 257 case X86::POP64rmr: 258 case X86::POPF64: 259 case X86::POPFS64: 260 case X86::POPGS64: 261 return 8; 262 } 263 return 0; 264 } 265 266 bool isPush(const MCInst &Inst) const override { 267 return getPushSize(Inst) == 0 ? false : true; 268 } 269 270 int getPushSize(const MCInst &Inst) const override { 271 switch (Inst.getOpcode()) { 272 case X86::PUSH16i8: 273 case X86::PUSH16r: 274 case X86::PUSH16rmm: 275 case X86::PUSH16rmr: 276 case X86::PUSHA16: 277 case X86::PUSHCS16: 278 case X86::PUSHDS16: 279 case X86::PUSHES16: 280 case X86::PUSHF16: 281 case X86::PUSHFS16: 282 case X86::PUSHGS16: 283 case X86::PUSHSS16: 284 case X86::PUSHi16: 285 return 2; 286 case X86::PUSH32i8: 287 case X86::PUSH32r: 288 case X86::PUSH32rmm: 289 case X86::PUSH32rmr: 290 case X86::PUSHA32: 291 case X86::PUSHCS32: 292 case X86::PUSHDS32: 293 case X86::PUSHES32: 294 case X86::PUSHF32: 295 case X86::PUSHFS32: 296 case X86::PUSHGS32: 297 case X86::PUSHSS32: 298 case X86::PUSHi32: 299 return 4; 300 case X86::PUSH64i32: 301 case X86::PUSH64i8: 302 case X86::PUSH64r: 303 case X86::PUSH64rmm: 304 case X86::PUSH64rmr: 305 case X86::PUSHF64: 306 case X86::PUSHFS64: 307 case X86::PUSHGS64: 308 return 8; 309 } 310 return 0; 311 } 312 313 bool isSUB(const MCInst &Inst) const override { 314 return X86::isSUB(Inst.getOpcode()); 315 } 316 317 bool isLEA64r(const MCInst &Inst) const override { 318 return Inst.getOpcode() == X86::LEA64r; 319 } 320 321 bool isLeave(const MCInst &Inst) const override { 322 return Inst.getOpcode() == X86::LEAVE || Inst.getOpcode() == X86::LEAVE64; 323 } 324 325 bool isMoveMem2Reg(const MCInst &Inst) const override { 326 switch (Inst.getOpcode()) { 327 case X86::MOV16rm: 328 case X86::MOV32rm: 329 case X86::MOV64rm: 330 return true; 331 } 332 return false; 333 } 334 335 bool isUnsupportedBranch(unsigned Opcode) const override { 336 switch (Opcode) { 337 default: 338 return false; 339 case X86::LOOP: 340 case X86::LOOPE: 341 case X86::LOOPNE: 342 case X86::JECXZ: 343 case X86::JRCXZ: 344 return true; 345 } 346 } 347 348 bool isLoad(const MCInst &Inst) const override { 349 if (isPop(Inst)) 350 return true; 351 352 int MemOpNo = getMemoryOperandNo(Inst); 353 const MCInstrDesc &MCII = Info->get(Inst.getOpcode()); 354 355 if (MemOpNo == -1) 356 return false; 357 358 return MCII.mayLoad(); 359 } 360 361 bool isStore(const MCInst &Inst) const override { 362 if (isPush(Inst)) 363 return true; 364 365 int MemOpNo = getMemoryOperandNo(Inst); 366 const MCInstrDesc &MCII = Info->get(Inst.getOpcode()); 367 368 if (MemOpNo == -1) 369 return false; 370 371 return MCII.mayStore(); 372 } 373 374 bool isCleanRegXOR(const MCInst &Inst) const override { 375 switch (Inst.getOpcode()) { 376 case X86::XOR16rr: 377 case X86::XOR32rr: 378 case X86::XOR64rr: 379 break; 380 default: 381 return false; 382 } 383 return (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()); 384 } 385 386 bool isPacked(const MCInst &Inst) const override { 387 const MCInstrDesc &Desc = Info->get(Inst.getOpcode()); 388 return (Desc.TSFlags & X86II::OpPrefixMask) == X86II::PD; 389 } 390 391 unsigned getTrapFillValue() const override { return 0xCC; } 392 393 struct IndJmpMatcherFrag1 : MCInstMatcher { 394 std::unique_ptr<MCInstMatcher> Base; 395 std::unique_ptr<MCInstMatcher> Scale; 396 std::unique_ptr<MCInstMatcher> Index; 397 std::unique_ptr<MCInstMatcher> Offset; 398 399 IndJmpMatcherFrag1(std::unique_ptr<MCInstMatcher> Base, 400 std::unique_ptr<MCInstMatcher> Scale, 401 std::unique_ptr<MCInstMatcher> Index, 402 std::unique_ptr<MCInstMatcher> Offset) 403 : Base(std::move(Base)), Scale(std::move(Scale)), 404 Index(std::move(Index)), Offset(std::move(Offset)) {} 405 406 bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB, 407 MutableArrayRef<MCInst> InInstrWindow, int OpNum) override { 408 if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum)) 409 return false; 410 411 if (CurInst->getOpcode() != X86::JMP64m) 412 return false; 413 414 int MemOpNo = MIB.getMemoryOperandNo(*CurInst); 415 if (MemOpNo == -1) 416 return false; 417 418 if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg)) 419 return false; 420 if (!Scale->match(MRI, MIB, this->InstrWindow, 421 MemOpNo + X86::AddrScaleAmt)) 422 return false; 423 if (!Index->match(MRI, MIB, this->InstrWindow, 424 MemOpNo + X86::AddrIndexReg)) 425 return false; 426 if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp)) 427 return false; 428 return true; 429 } 430 431 void annotate(MCPlusBuilder &MIB, StringRef Annotation) override { 432 MIB.addAnnotation(*CurInst, Annotation, true); 433 Base->annotate(MIB, Annotation); 434 Scale->annotate(MIB, Annotation); 435 Index->annotate(MIB, Annotation); 436 Offset->annotate(MIB, Annotation); 437 } 438 }; 439 440 std::unique_ptr<MCInstMatcher> 441 matchIndJmp(std::unique_ptr<MCInstMatcher> Base, 442 std::unique_ptr<MCInstMatcher> Scale, 443 std::unique_ptr<MCInstMatcher> Index, 444 std::unique_ptr<MCInstMatcher> Offset) const override { 445 return std::unique_ptr<MCInstMatcher>( 446 new IndJmpMatcherFrag1(std::move(Base), std::move(Scale), 447 std::move(Index), std::move(Offset))); 448 } 449 450 struct IndJmpMatcherFrag2 : MCInstMatcher { 451 std::unique_ptr<MCInstMatcher> Reg; 452 453 IndJmpMatcherFrag2(std::unique_ptr<MCInstMatcher> Reg) 454 : Reg(std::move(Reg)) {} 455 456 bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB, 457 MutableArrayRef<MCInst> InInstrWindow, int OpNum) override { 458 if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum)) 459 return false; 460 461 if (CurInst->getOpcode() != X86::JMP64r) 462 return false; 463 464 return Reg->match(MRI, MIB, this->InstrWindow, 0); 465 } 466 467 void annotate(MCPlusBuilder &MIB, StringRef Annotation) override { 468 MIB.addAnnotation(*CurInst, Annotation, true); 469 Reg->annotate(MIB, Annotation); 470 } 471 }; 472 473 std::unique_ptr<MCInstMatcher> 474 matchIndJmp(std::unique_ptr<MCInstMatcher> Target) const override { 475 return std::unique_ptr<MCInstMatcher>( 476 new IndJmpMatcherFrag2(std::move(Target))); 477 } 478 479 struct LoadMatcherFrag1 : MCInstMatcher { 480 std::unique_ptr<MCInstMatcher> Base; 481 std::unique_ptr<MCInstMatcher> Scale; 482 std::unique_ptr<MCInstMatcher> Index; 483 std::unique_ptr<MCInstMatcher> Offset; 484 485 LoadMatcherFrag1(std::unique_ptr<MCInstMatcher> Base, 486 std::unique_ptr<MCInstMatcher> Scale, 487 std::unique_ptr<MCInstMatcher> Index, 488 std::unique_ptr<MCInstMatcher> Offset) 489 : Base(std::move(Base)), Scale(std::move(Scale)), 490 Index(std::move(Index)), Offset(std::move(Offset)) {} 491 492 bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB, 493 MutableArrayRef<MCInst> InInstrWindow, int OpNum) override { 494 if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum)) 495 return false; 496 497 if (CurInst->getOpcode() != X86::MOV64rm && 498 CurInst->getOpcode() != X86::MOVSX64rm32) 499 return false; 500 501 int MemOpNo = MIB.getMemoryOperandNo(*CurInst); 502 if (MemOpNo == -1) 503 return false; 504 505 if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg)) 506 return false; 507 if (!Scale->match(MRI, MIB, this->InstrWindow, 508 MemOpNo + X86::AddrScaleAmt)) 509 return false; 510 if (!Index->match(MRI, MIB, this->InstrWindow, 511 MemOpNo + X86::AddrIndexReg)) 512 return false; 513 if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp)) 514 return false; 515 return true; 516 } 517 518 void annotate(MCPlusBuilder &MIB, StringRef Annotation) override { 519 MIB.addAnnotation(*CurInst, Annotation, true); 520 Base->annotate(MIB, Annotation); 521 Scale->annotate(MIB, Annotation); 522 Index->annotate(MIB, Annotation); 523 Offset->annotate(MIB, Annotation); 524 } 525 }; 526 527 std::unique_ptr<MCInstMatcher> 528 matchLoad(std::unique_ptr<MCInstMatcher> Base, 529 std::unique_ptr<MCInstMatcher> Scale, 530 std::unique_ptr<MCInstMatcher> Index, 531 std::unique_ptr<MCInstMatcher> Offset) const override { 532 return std::unique_ptr<MCInstMatcher>( 533 new LoadMatcherFrag1(std::move(Base), std::move(Scale), 534 std::move(Index), std::move(Offset))); 535 } 536 537 struct AddMatcher : MCInstMatcher { 538 std::unique_ptr<MCInstMatcher> A; 539 std::unique_ptr<MCInstMatcher> B; 540 541 AddMatcher(std::unique_ptr<MCInstMatcher> A, 542 std::unique_ptr<MCInstMatcher> B) 543 : A(std::move(A)), B(std::move(B)) {} 544 545 bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB, 546 MutableArrayRef<MCInst> InInstrWindow, int OpNum) override { 547 if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum)) 548 return false; 549 550 if (CurInst->getOpcode() == X86::ADD64rr || 551 CurInst->getOpcode() == X86::ADD64rr_DB || 552 CurInst->getOpcode() == X86::ADD64rr_REV) { 553 if (!A->match(MRI, MIB, this->InstrWindow, 1)) { 554 if (!B->match(MRI, MIB, this->InstrWindow, 1)) 555 return false; 556 return A->match(MRI, MIB, this->InstrWindow, 2); 557 } 558 559 if (B->match(MRI, MIB, this->InstrWindow, 2)) 560 return true; 561 562 if (!B->match(MRI, MIB, this->InstrWindow, 1)) 563 return false; 564 return A->match(MRI, MIB, this->InstrWindow, 2); 565 } 566 567 return false; 568 } 569 570 void annotate(MCPlusBuilder &MIB, StringRef Annotation) override { 571 MIB.addAnnotation(*CurInst, Annotation, true); 572 A->annotate(MIB, Annotation); 573 B->annotate(MIB, Annotation); 574 } 575 }; 576 577 std::unique_ptr<MCInstMatcher> 578 matchAdd(std::unique_ptr<MCInstMatcher> A, 579 std::unique_ptr<MCInstMatcher> B) const override { 580 return std::unique_ptr<MCInstMatcher>( 581 new AddMatcher(std::move(A), std::move(B))); 582 } 583 584 struct LEAMatcher : MCInstMatcher { 585 std::unique_ptr<MCInstMatcher> Target; 586 587 LEAMatcher(std::unique_ptr<MCInstMatcher> Target) 588 : Target(std::move(Target)) {} 589 590 bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB, 591 MutableArrayRef<MCInst> InInstrWindow, int OpNum) override { 592 if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum)) 593 return false; 594 595 if (CurInst->getOpcode() != X86::LEA64r) 596 return false; 597 598 if (CurInst->getOperand(1 + X86::AddrScaleAmt).getImm() != 1 || 599 CurInst->getOperand(1 + X86::AddrIndexReg).getReg() != 600 X86::NoRegister || 601 (CurInst->getOperand(1 + X86::AddrBaseReg).getReg() != 602 X86::NoRegister && 603 CurInst->getOperand(1 + X86::AddrBaseReg).getReg() != X86::RIP)) 604 return false; 605 606 return Target->match(MRI, MIB, this->InstrWindow, 1 + X86::AddrDisp); 607 } 608 609 void annotate(MCPlusBuilder &MIB, StringRef Annotation) override { 610 MIB.addAnnotation(*CurInst, Annotation, true); 611 Target->annotate(MIB, Annotation); 612 } 613 }; 614 615 std::unique_ptr<MCInstMatcher> 616 matchLoadAddr(std::unique_ptr<MCInstMatcher> Target) const override { 617 return std::unique_ptr<MCInstMatcher>(new LEAMatcher(std::move(Target))); 618 } 619 620 bool hasPCRelOperand(const MCInst &Inst) const override { 621 for (const MCOperand &Operand : Inst) 622 if (Operand.isReg() && Operand.getReg() == X86::RIP) 623 return true; 624 return false; 625 } 626 627 int getMemoryOperandNo(const MCInst &Inst) const override { 628 unsigned Opcode = Inst.getOpcode(); 629 const MCInstrDesc &Desc = Info->get(Opcode); 630 int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags); 631 if (MemOpNo >= 0) 632 MemOpNo += X86II::getOperandBias(Desc); 633 return MemOpNo; 634 } 635 636 bool hasEVEXEncoding(const MCInst &Inst) const override { 637 const MCInstrDesc &Desc = Info->get(Inst.getOpcode()); 638 return (Desc.TSFlags & X86II::EncodingMask) == X86II::EVEX; 639 } 640 641 bool isMacroOpFusionPair(ArrayRef<MCInst> Insts) const override { 642 const auto *I = Insts.begin(); 643 while (I != Insts.end() && isPrefix(*I)) 644 ++I; 645 if (I == Insts.end()) 646 return false; 647 648 const MCInst &FirstInst = *I; 649 ++I; 650 while (I != Insts.end() && isPrefix(*I)) 651 ++I; 652 if (I == Insts.end()) 653 return false; 654 const MCInst &SecondInst = *I; 655 656 if (!isConditionalBranch(SecondInst)) 657 return false; 658 // Cannot fuse if the first instruction uses RIP-relative memory. 659 if (hasPCRelOperand(FirstInst)) 660 return false; 661 662 const X86::FirstMacroFusionInstKind CmpKind = 663 X86::classifyFirstOpcodeInMacroFusion(FirstInst.getOpcode()); 664 if (CmpKind == X86::FirstMacroFusionInstKind::Invalid) 665 return false; 666 667 X86::CondCode CC = static_cast<X86::CondCode>(getCondCode(SecondInst)); 668 X86::SecondMacroFusionInstKind BranchKind = 669 X86::classifySecondCondCodeInMacroFusion(CC); 670 if (BranchKind == X86::SecondMacroFusionInstKind::Invalid) 671 return false; 672 return X86::isMacroFused(CmpKind, BranchKind); 673 } 674 675 bool 676 evaluateX86MemoryOperand(const MCInst &Inst, unsigned *BaseRegNum, 677 int64_t *ScaleImm, unsigned *IndexRegNum, 678 int64_t *DispImm, unsigned *SegmentRegNum, 679 const MCExpr **DispExpr = nullptr) const override { 680 assert(BaseRegNum && ScaleImm && IndexRegNum && SegmentRegNum && 681 "one of the input pointers is null"); 682 int MemOpNo = getMemoryOperandNo(Inst); 683 if (MemOpNo < 0) 684 return false; 685 unsigned MemOpOffset = static_cast<unsigned>(MemOpNo); 686 687 if (MemOpOffset + X86::AddrSegmentReg >= MCPlus::getNumPrimeOperands(Inst)) 688 return false; 689 690 const MCOperand &Base = Inst.getOperand(MemOpOffset + X86::AddrBaseReg); 691 const MCOperand &Scale = Inst.getOperand(MemOpOffset + X86::AddrScaleAmt); 692 const MCOperand &Index = Inst.getOperand(MemOpOffset + X86::AddrIndexReg); 693 const MCOperand &Disp = Inst.getOperand(MemOpOffset + X86::AddrDisp); 694 const MCOperand &Segment = 695 Inst.getOperand(MemOpOffset + X86::AddrSegmentReg); 696 697 // Make sure it is a well-formed memory operand. 698 if (!Base.isReg() || !Scale.isImm() || !Index.isReg() || 699 (!Disp.isImm() && !Disp.isExpr()) || !Segment.isReg()) 700 return false; 701 702 *BaseRegNum = Base.getReg(); 703 *ScaleImm = Scale.getImm(); 704 *IndexRegNum = Index.getReg(); 705 if (Disp.isImm()) { 706 assert(DispImm && "DispImm needs to be set"); 707 *DispImm = Disp.getImm(); 708 if (DispExpr) 709 *DispExpr = nullptr; 710 } else { 711 assert(DispExpr && "DispExpr needs to be set"); 712 *DispExpr = Disp.getExpr(); 713 if (DispImm) 714 *DispImm = 0; 715 } 716 *SegmentRegNum = Segment.getReg(); 717 return true; 718 } 719 720 bool evaluateMemOperandTarget(const MCInst &Inst, uint64_t &Target, 721 uint64_t Address, 722 uint64_t Size) const override { 723 unsigned BaseRegNum; 724 int64_t ScaleValue; 725 unsigned IndexRegNum; 726 int64_t DispValue; 727 unsigned SegRegNum; 728 const MCExpr *DispExpr = nullptr; 729 if (!evaluateX86MemoryOperand(Inst, &BaseRegNum, &ScaleValue, &IndexRegNum, 730 &DispValue, &SegRegNum, &DispExpr)) 731 return false; 732 733 // Make sure it's a well-formed addressing we can statically evaluate. 734 if ((BaseRegNum != X86::RIP && BaseRegNum != X86::NoRegister) || 735 IndexRegNum != X86::NoRegister || SegRegNum != X86::NoRegister || 736 DispExpr) 737 return false; 738 739 Target = DispValue; 740 if (BaseRegNum == X86::RIP) { 741 assert(Size != 0 && "instruction size required in order to statically " 742 "evaluate RIP-relative address"); 743 Target += Address + Size; 744 } 745 return true; 746 } 747 748 MCInst::iterator getMemOperandDisp(MCInst &Inst) const override { 749 int MemOpNo = getMemoryOperandNo(Inst); 750 if (MemOpNo < 0) 751 return Inst.end(); 752 return Inst.begin() + (MemOpNo + X86::AddrDisp); 753 } 754 755 bool replaceMemOperandDisp(MCInst &Inst, MCOperand Operand) const override { 756 MCOperand *OI = getMemOperandDisp(Inst); 757 if (OI == Inst.end()) 758 return false; 759 *OI = Operand; 760 return true; 761 } 762 763 /// Get the registers used as function parameters. 764 /// This function is specific to the x86_64 abi on Linux. 765 BitVector getRegsUsedAsParams() const override { 766 BitVector Regs = BitVector(RegInfo->getNumRegs(), false); 767 Regs |= getAliases(X86::RSI); 768 Regs |= getAliases(X86::RDI); 769 Regs |= getAliases(X86::RDX); 770 Regs |= getAliases(X86::RCX); 771 Regs |= getAliases(X86::R8); 772 Regs |= getAliases(X86::R9); 773 return Regs; 774 } 775 776 void getCalleeSavedRegs(BitVector &Regs) const override { 777 Regs |= getAliases(X86::RBX); 778 Regs |= getAliases(X86::RBP); 779 Regs |= getAliases(X86::R12); 780 Regs |= getAliases(X86::R13); 781 Regs |= getAliases(X86::R14); 782 Regs |= getAliases(X86::R15); 783 } 784 785 void getDefaultDefIn(BitVector &Regs) const override { 786 assert(Regs.size() >= RegInfo->getNumRegs() && 787 "The size of BitVector is less than RegInfo->getNumRegs()."); 788 Regs.set(X86::RAX); 789 Regs.set(X86::RCX); 790 Regs.set(X86::RDX); 791 Regs.set(X86::RSI); 792 Regs.set(X86::RDI); 793 Regs.set(X86::R8); 794 Regs.set(X86::R9); 795 Regs.set(X86::XMM0); 796 Regs.set(X86::XMM1); 797 Regs.set(X86::XMM2); 798 Regs.set(X86::XMM3); 799 Regs.set(X86::XMM4); 800 Regs.set(X86::XMM5); 801 Regs.set(X86::XMM6); 802 Regs.set(X86::XMM7); 803 } 804 805 void getDefaultLiveOut(BitVector &Regs) const override { 806 assert(Regs.size() >= RegInfo->getNumRegs() && 807 "The size of BitVector is less than RegInfo->getNumRegs()."); 808 Regs |= getAliases(X86::RAX); 809 Regs |= getAliases(X86::RDX); 810 Regs |= getAliases(X86::RCX); 811 Regs |= getAliases(X86::XMM0); 812 Regs |= getAliases(X86::XMM1); 813 } 814 815 void getGPRegs(BitVector &Regs, bool IncludeAlias) const override { 816 if (IncludeAlias) { 817 Regs |= getAliases(X86::RAX); 818 Regs |= getAliases(X86::RBX); 819 Regs |= getAliases(X86::RBP); 820 Regs |= getAliases(X86::RSI); 821 Regs |= getAliases(X86::RDI); 822 Regs |= getAliases(X86::RDX); 823 Regs |= getAliases(X86::RCX); 824 Regs |= getAliases(X86::R8); 825 Regs |= getAliases(X86::R9); 826 Regs |= getAliases(X86::R10); 827 Regs |= getAliases(X86::R11); 828 Regs |= getAliases(X86::R12); 829 Regs |= getAliases(X86::R13); 830 Regs |= getAliases(X86::R14); 831 Regs |= getAliases(X86::R15); 832 return; 833 } 834 Regs.set(X86::RAX); 835 Regs.set(X86::RBX); 836 Regs.set(X86::RBP); 837 Regs.set(X86::RSI); 838 Regs.set(X86::RDI); 839 Regs.set(X86::RDX); 840 Regs.set(X86::RCX); 841 Regs.set(X86::R8); 842 Regs.set(X86::R9); 843 Regs.set(X86::R10); 844 Regs.set(X86::R11); 845 Regs.set(X86::R12); 846 Regs.set(X86::R13); 847 Regs.set(X86::R14); 848 Regs.set(X86::R15); 849 } 850 851 void getClassicGPRegs(BitVector &Regs) const override { 852 Regs |= getAliases(X86::RAX); 853 Regs |= getAliases(X86::RBX); 854 Regs |= getAliases(X86::RBP); 855 Regs |= getAliases(X86::RSI); 856 Regs |= getAliases(X86::RDI); 857 Regs |= getAliases(X86::RDX); 858 Regs |= getAliases(X86::RCX); 859 } 860 861 void getRepRegs(BitVector &Regs) const override { 862 Regs |= getAliases(X86::RCX); 863 } 864 865 MCPhysReg getAliasSized(MCPhysReg Reg, uint8_t Size) const override { 866 switch (Reg) { 867 case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: case X86::AH: 868 switch (Size) { 869 case 8: return X86::RAX; case 4: return X86::EAX; 870 case 2: return X86::AX; case 1: return X86::AL; 871 default: llvm_unreachable("Unexpected size"); 872 } 873 case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: case X86::BH: 874 switch (Size) { 875 case 8: return X86::RBX; case 4: return X86::EBX; 876 case 2: return X86::BX; case 1: return X86::BL; 877 default: llvm_unreachable("Unexpected size"); 878 } 879 case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: case X86::DH: 880 switch (Size) { 881 case 8: return X86::RDX; case 4: return X86::EDX; 882 case 2: return X86::DX; case 1: return X86::DL; 883 default: llvm_unreachable("Unexpected size"); 884 } 885 case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: 886 switch (Size) { 887 case 8: return X86::RDI; case 4: return X86::EDI; 888 case 2: return X86::DI; case 1: return X86::DIL; 889 default: llvm_unreachable("Unexpected size"); 890 } 891 case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: 892 switch (Size) { 893 case 8: return X86::RSI; case 4: return X86::ESI; 894 case 2: return X86::SI; case 1: return X86::SIL; 895 default: llvm_unreachable("Unexpected size"); 896 } 897 case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: case X86::CH: 898 switch (Size) { 899 case 8: return X86::RCX; case 4: return X86::ECX; 900 case 2: return X86::CX; case 1: return X86::CL; 901 default: llvm_unreachable("Unexpected size"); 902 } 903 case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: 904 switch (Size) { 905 case 8: return X86::RSP; case 4: return X86::ESP; 906 case 2: return X86::SP; case 1: return X86::SPL; 907 default: llvm_unreachable("Unexpected size"); 908 } 909 case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: 910 switch (Size) { 911 case 8: return X86::RBP; case 4: return X86::EBP; 912 case 2: return X86::BP; case 1: return X86::BPL; 913 default: llvm_unreachable("Unexpected size"); 914 } 915 case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B: 916 switch (Size) { 917 case 8: return X86::R8; case 4: return X86::R8D; 918 case 2: return X86::R8W; case 1: return X86::R8B; 919 default: llvm_unreachable("Unexpected size"); 920 } 921 case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B: 922 switch (Size) { 923 case 8: return X86::R9; case 4: return X86::R9D; 924 case 2: return X86::R9W; case 1: return X86::R9B; 925 default: llvm_unreachable("Unexpected size"); 926 } 927 case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B: 928 switch (Size) { 929 case 8: return X86::R10; case 4: return X86::R10D; 930 case 2: return X86::R10W; case 1: return X86::R10B; 931 default: llvm_unreachable("Unexpected size"); 932 } 933 case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B: 934 switch (Size) { 935 case 8: return X86::R11; case 4: return X86::R11D; 936 case 2: return X86::R11W; case 1: return X86::R11B; 937 default: llvm_unreachable("Unexpected size"); 938 } 939 case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B: 940 switch (Size) { 941 case 8: return X86::R12; case 4: return X86::R12D; 942 case 2: return X86::R12W; case 1: return X86::R12B; 943 default: llvm_unreachable("Unexpected size"); 944 } 945 case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B: 946 switch (Size) { 947 case 8: return X86::R13; case 4: return X86::R13D; 948 case 2: return X86::R13W; case 1: return X86::R13B; 949 default: llvm_unreachable("Unexpected size"); 950 } 951 case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B: 952 switch (Size) { 953 case 8: return X86::R14; case 4: return X86::R14D; 954 case 2: return X86::R14W; case 1: return X86::R14B; 955 default: llvm_unreachable("Unexpected size"); 956 } 957 case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B: 958 switch (Size) { 959 case 8: return X86::R15; case 4: return X86::R15D; 960 case 2: return X86::R15W; case 1: return X86::R15B; 961 default: llvm_unreachable("Unexpected size"); 962 } 963 default: 964 dbgs() << Reg << " (get alias sized)\n"; 965 llvm_unreachable("Unexpected reg number"); 966 break; 967 } 968 } 969 970 bool isUpper8BitReg(MCPhysReg Reg) const override { 971 switch (Reg) { 972 case X86::AH: 973 case X86::BH: 974 case X86::CH: 975 case X86::DH: 976 return true; 977 default: 978 return false; 979 } 980 } 981 982 bool cannotUseREX(const MCInst &Inst) const override { 983 switch (Inst.getOpcode()) { 984 case X86::MOV8mr_NOREX: 985 case X86::MOV8rm_NOREX: 986 case X86::MOV8rr_NOREX: 987 case X86::MOVSX32rm8_NOREX: 988 case X86::MOVSX32rr8_NOREX: 989 case X86::MOVZX32rm8_NOREX: 990 case X86::MOVZX32rr8_NOREX: 991 case X86::MOV8mr: 992 case X86::MOV8rm: 993 case X86::MOV8rr: 994 case X86::MOVSX32rm8: 995 case X86::MOVSX32rr8: 996 case X86::MOVZX32rm8: 997 case X86::MOVZX32rr8: 998 case X86::TEST8ri: 999 for (const MCOperand &Operand : MCPlus::primeOperands(Inst)) { 1000 if (!Operand.isReg()) 1001 continue; 1002 if (isUpper8BitReg(Operand.getReg())) 1003 return true; 1004 } 1005 [[fallthrough]]; 1006 default: 1007 return false; 1008 } 1009 } 1010 1011 static uint8_t getMemDataSize(const MCInst &Inst, int MemOpNo) { 1012 using namespace llvm::X86; 1013 int OpType = getOperandType(Inst.getOpcode(), MemOpNo); 1014 return getMemOperandSize(OpType) / 8; 1015 } 1016 1017 /// Classifying a stack access as *not* "SIMPLE" here means we don't know how 1018 /// to change this instruction memory access. It will disable any changes to 1019 /// the stack layout, so we can't do the most aggressive form of shrink 1020 /// wrapping. We must do so in a way that keeps the original stack layout. 1021 /// Otherwise you need to adjust the offset of all instructions accessing the 1022 /// stack: we can't do that anymore because there is one instruction that is 1023 /// not simple. There are other implications as well. We have heuristics to 1024 /// detect when a register is callee-saved and thus eligible for shrink 1025 /// wrapping. If you are restoring a register using a non-simple stack access, 1026 /// then it is classified as NOT callee-saved, and it disables shrink wrapping 1027 /// for *that* register (but not for others). 1028 /// 1029 /// Classifying a stack access as "size 0" or detecting an indexed memory 1030 /// access (to address a vector, for example) here means we know there is a 1031 /// stack access, but we can't quite understand how wide is the access in 1032 /// bytes. This is very serious because we can't understand how memory 1033 /// accesses alias with each other for this function. This will essentially 1034 /// disable not only shrink wrapping but all frame analysis, it will fail it 1035 /// as "we don't understand this function and we give up on it". 1036 bool isStackAccess(const MCInst &Inst, bool &IsLoad, bool &IsStore, 1037 bool &IsStoreFromReg, MCPhysReg &Reg, int32_t &SrcImm, 1038 uint16_t &StackPtrReg, int64_t &StackOffset, uint8_t &Size, 1039 bool &IsSimple, bool &IsIndexed) const override { 1040 // Detect simple push/pop cases first 1041 if (int Sz = getPushSize(Inst)) { 1042 IsLoad = false; 1043 IsStore = true; 1044 IsStoreFromReg = true; 1045 StackPtrReg = X86::RSP; 1046 StackOffset = -Sz; 1047 Size = Sz; 1048 IsSimple = true; 1049 if (Inst.getOperand(0).isImm()) 1050 SrcImm = Inst.getOperand(0).getImm(); 1051 else if (Inst.getOperand(0).isReg()) 1052 Reg = Inst.getOperand(0).getReg(); 1053 else 1054 IsSimple = false; 1055 1056 return true; 1057 } 1058 if (int Sz = getPopSize(Inst)) { 1059 IsLoad = true; 1060 IsStore = false; 1061 if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isReg()) { 1062 IsSimple = false; 1063 } else { 1064 Reg = Inst.getOperand(0).getReg(); 1065 IsSimple = true; 1066 } 1067 StackPtrReg = X86::RSP; 1068 StackOffset = 0; 1069 Size = Sz; 1070 return true; 1071 } 1072 1073 struct InstInfo { 1074 // Size in bytes that Inst loads from memory. 1075 uint8_t DataSize; 1076 bool IsLoad; 1077 bool IsStore; 1078 bool StoreFromReg; 1079 bool Simple; 1080 }; 1081 1082 InstInfo I; 1083 int MemOpNo = getMemoryOperandNo(Inst); 1084 const MCInstrDesc &MCII = Info->get(Inst.getOpcode()); 1085 // If it is not dealing with a memory operand, we discard it 1086 if (MemOpNo == -1 || MCII.isCall()) 1087 return false; 1088 1089 switch (Inst.getOpcode()) { 1090 default: { 1091 bool IsLoad = MCII.mayLoad(); 1092 bool IsStore = MCII.mayStore(); 1093 // Is it LEA? (deals with memory but is not loading nor storing) 1094 if (!IsLoad && !IsStore) { 1095 I = {0, IsLoad, IsStore, false, false}; 1096 break; 1097 } 1098 uint8_t Sz = getMemDataSize(Inst, MemOpNo); 1099 I = {Sz, IsLoad, IsStore, false, false}; 1100 break; 1101 } 1102 // Report simple stack accesses 1103 case X86::MOV8rm: I = {1, true, false, false, true}; break; 1104 case X86::MOV16rm: I = {2, true, false, false, true}; break; 1105 case X86::MOV32rm: I = {4, true, false, false, true}; break; 1106 case X86::MOV64rm: I = {8, true, false, false, true}; break; 1107 case X86::MOV8mr: I = {1, false, true, true, true}; break; 1108 case X86::MOV16mr: I = {2, false, true, true, true}; break; 1109 case X86::MOV32mr: I = {4, false, true, true, true}; break; 1110 case X86::MOV64mr: I = {8, false, true, true, true}; break; 1111 case X86::MOV8mi: I = {1, false, true, false, true}; break; 1112 case X86::MOV16mi: I = {2, false, true, false, true}; break; 1113 case X86::MOV32mi: I = {4, false, true, false, true}; break; 1114 } // end switch (Inst.getOpcode()) 1115 1116 unsigned BaseRegNum; 1117 int64_t ScaleValue; 1118 unsigned IndexRegNum; 1119 int64_t DispValue; 1120 unsigned SegRegNum; 1121 const MCExpr *DispExpr; 1122 if (!evaluateX86MemoryOperand(Inst, &BaseRegNum, &ScaleValue, &IndexRegNum, 1123 &DispValue, &SegRegNum, &DispExpr)) { 1124 LLVM_DEBUG(dbgs() << "Evaluate failed on "); 1125 LLVM_DEBUG(Inst.dump()); 1126 return false; 1127 } 1128 1129 // Make sure it's a stack access 1130 if (BaseRegNum != X86::RBP && BaseRegNum != X86::RSP) 1131 return false; 1132 1133 IsLoad = I.IsLoad; 1134 IsStore = I.IsStore; 1135 IsStoreFromReg = I.StoreFromReg; 1136 Size = I.DataSize; 1137 IsSimple = I.Simple; 1138 StackPtrReg = BaseRegNum; 1139 StackOffset = DispValue; 1140 IsIndexed = IndexRegNum != X86::NoRegister || SegRegNum != X86::NoRegister; 1141 1142 if (!I.Simple) 1143 return true; 1144 1145 // Retrieve related register in simple MOV from/to stack operations. 1146 unsigned MemOpOffset = static_cast<unsigned>(MemOpNo); 1147 if (I.IsLoad) { 1148 MCOperand RegOpnd = Inst.getOperand(0); 1149 assert(RegOpnd.isReg() && "unexpected destination operand"); 1150 Reg = RegOpnd.getReg(); 1151 } else if (I.IsStore) { 1152 MCOperand SrcOpnd = 1153 Inst.getOperand(MemOpOffset + X86::AddrSegmentReg + 1); 1154 if (I.StoreFromReg) { 1155 assert(SrcOpnd.isReg() && "unexpected source operand"); 1156 Reg = SrcOpnd.getReg(); 1157 } else { 1158 assert(SrcOpnd.isImm() && "unexpected source operand"); 1159 SrcImm = SrcOpnd.getImm(); 1160 } 1161 } 1162 1163 return true; 1164 } 1165 1166 void changeToPushOrPop(MCInst &Inst) const override { 1167 assert(!isPush(Inst) && !isPop(Inst)); 1168 1169 struct InstInfo { 1170 // Size in bytes that Inst loads from memory. 1171 uint8_t DataSize; 1172 bool IsLoad; 1173 bool StoreFromReg; 1174 }; 1175 1176 InstInfo I; 1177 switch (Inst.getOpcode()) { 1178 default: { 1179 llvm_unreachable("Unhandled opcode"); 1180 return; 1181 } 1182 case X86::MOV16rm: I = {2, true, false}; break; 1183 case X86::MOV32rm: I = {4, true, false}; break; 1184 case X86::MOV64rm: I = {8, true, false}; break; 1185 case X86::MOV16mr: I = {2, false, true}; break; 1186 case X86::MOV32mr: I = {4, false, true}; break; 1187 case X86::MOV64mr: I = {8, false, true}; break; 1188 case X86::MOV16mi: I = {2, false, false}; break; 1189 case X86::MOV32mi: I = {4, false, false}; break; 1190 } // end switch (Inst.getOpcode()) 1191 1192 unsigned BaseRegNum; 1193 int64_t ScaleValue; 1194 unsigned IndexRegNum; 1195 int64_t DispValue; 1196 unsigned SegRegNum; 1197 const MCExpr *DispExpr; 1198 if (!evaluateX86MemoryOperand(Inst, &BaseRegNum, &ScaleValue, &IndexRegNum, 1199 &DispValue, &SegRegNum, &DispExpr)) { 1200 llvm_unreachable("Evaluate failed"); 1201 return; 1202 } 1203 // Make sure it's a stack access 1204 if (BaseRegNum != X86::RBP && BaseRegNum != X86::RSP) { 1205 llvm_unreachable("Not a stack access"); 1206 return; 1207 } 1208 1209 unsigned MemOpOffset = getMemoryOperandNo(Inst); 1210 unsigned NewOpcode = 0; 1211 if (I.IsLoad) { 1212 switch (I.DataSize) { 1213 case 2: NewOpcode = X86::POP16r; break; 1214 case 4: NewOpcode = X86::POP32r; break; 1215 case 8: NewOpcode = X86::POP64r; break; 1216 default: 1217 llvm_unreachable("Unexpected size"); 1218 } 1219 unsigned RegOpndNum = Inst.getOperand(0).getReg(); 1220 Inst.clear(); 1221 Inst.setOpcode(NewOpcode); 1222 Inst.addOperand(MCOperand::createReg(RegOpndNum)); 1223 } else { 1224 MCOperand SrcOpnd = 1225 Inst.getOperand(MemOpOffset + X86::AddrSegmentReg + 1); 1226 if (I.StoreFromReg) { 1227 switch (I.DataSize) { 1228 case 2: NewOpcode = X86::PUSH16r; break; 1229 case 4: NewOpcode = X86::PUSH32r; break; 1230 case 8: NewOpcode = X86::PUSH64r; break; 1231 default: 1232 llvm_unreachable("Unexpected size"); 1233 } 1234 assert(SrcOpnd.isReg() && "Unexpected source operand"); 1235 unsigned RegOpndNum = SrcOpnd.getReg(); 1236 Inst.clear(); 1237 Inst.setOpcode(NewOpcode); 1238 Inst.addOperand(MCOperand::createReg(RegOpndNum)); 1239 } else { 1240 switch (I.DataSize) { 1241 case 2: NewOpcode = X86::PUSH16i8; break; 1242 case 4: NewOpcode = X86::PUSH32i8; break; 1243 case 8: NewOpcode = X86::PUSH64i32; break; 1244 default: 1245 llvm_unreachable("Unexpected size"); 1246 } 1247 assert(SrcOpnd.isImm() && "Unexpected source operand"); 1248 int64_t SrcImm = SrcOpnd.getImm(); 1249 Inst.clear(); 1250 Inst.setOpcode(NewOpcode); 1251 Inst.addOperand(MCOperand::createImm(SrcImm)); 1252 } 1253 } 1254 } 1255 1256 bool isStackAdjustment(const MCInst &Inst) const override { 1257 switch (Inst.getOpcode()) { 1258 default: 1259 return false; 1260 case X86::SUB64ri32: 1261 case X86::SUB64ri8: 1262 case X86::ADD64ri32: 1263 case X86::ADD64ri8: 1264 case X86::LEA64r: 1265 break; 1266 } 1267 1268 const MCInstrDesc &MCII = Info->get(Inst.getOpcode()); 1269 for (int I = 0, E = MCII.getNumDefs(); I != E; ++I) { 1270 const MCOperand &Operand = Inst.getOperand(I); 1271 if (Operand.isReg() && Operand.getReg() == X86::RSP) 1272 return true; 1273 } 1274 return false; 1275 } 1276 1277 bool 1278 evaluateStackOffsetExpr(const MCInst &Inst, int64_t &Output, 1279 std::pair<MCPhysReg, int64_t> Input1, 1280 std::pair<MCPhysReg, int64_t> Input2) const override { 1281 1282 auto getOperandVal = [&](MCPhysReg Reg) -> ErrorOr<int64_t> { 1283 if (Reg == Input1.first) 1284 return Input1.second; 1285 if (Reg == Input2.first) 1286 return Input2.second; 1287 return make_error_code(errc::result_out_of_range); 1288 }; 1289 1290 switch (Inst.getOpcode()) { 1291 default: 1292 return false; 1293 1294 case X86::SUB64ri32: 1295 case X86::SUB64ri8: 1296 if (!Inst.getOperand(2).isImm()) 1297 return false; 1298 if (ErrorOr<int64_t> InputVal = 1299 getOperandVal(Inst.getOperand(1).getReg())) 1300 Output = *InputVal - Inst.getOperand(2).getImm(); 1301 else 1302 return false; 1303 break; 1304 case X86::ADD64ri32: 1305 case X86::ADD64ri8: 1306 if (!Inst.getOperand(2).isImm()) 1307 return false; 1308 if (ErrorOr<int64_t> InputVal = 1309 getOperandVal(Inst.getOperand(1).getReg())) 1310 Output = *InputVal + Inst.getOperand(2).getImm(); 1311 else 1312 return false; 1313 break; 1314 case X86::ADD64i32: 1315 if (!Inst.getOperand(0).isImm()) 1316 return false; 1317 if (ErrorOr<int64_t> InputVal = getOperandVal(X86::RAX)) 1318 Output = *InputVal + Inst.getOperand(0).getImm(); 1319 else 1320 return false; 1321 break; 1322 1323 case X86::LEA64r: { 1324 unsigned BaseRegNum; 1325 int64_t ScaleValue; 1326 unsigned IndexRegNum; 1327 int64_t DispValue; 1328 unsigned SegRegNum; 1329 const MCExpr *DispExpr = nullptr; 1330 if (!evaluateX86MemoryOperand(Inst, &BaseRegNum, &ScaleValue, 1331 &IndexRegNum, &DispValue, &SegRegNum, 1332 &DispExpr)) 1333 return false; 1334 1335 if (BaseRegNum == X86::NoRegister || IndexRegNum != X86::NoRegister || 1336 SegRegNum != X86::NoRegister || DispExpr) 1337 return false; 1338 1339 if (ErrorOr<int64_t> InputVal = getOperandVal(BaseRegNum)) 1340 Output = *InputVal + DispValue; 1341 else 1342 return false; 1343 1344 break; 1345 } 1346 } 1347 return true; 1348 } 1349 1350 bool isRegToRegMove(const MCInst &Inst, MCPhysReg &From, 1351 MCPhysReg &To) const override { 1352 switch (Inst.getOpcode()) { 1353 default: 1354 return false; 1355 case X86::LEAVE: 1356 case X86::LEAVE64: 1357 To = getStackPointer(); 1358 From = getFramePointer(); 1359 return true; 1360 case X86::MOV64rr: 1361 To = Inst.getOperand(0).getReg(); 1362 From = Inst.getOperand(1).getReg(); 1363 return true; 1364 } 1365 } 1366 1367 MCPhysReg getStackPointer() const override { return X86::RSP; } 1368 MCPhysReg getFramePointer() const override { return X86::RBP; } 1369 MCPhysReg getFlagsReg() const override { return X86::EFLAGS; } 1370 1371 bool escapesVariable(const MCInst &Inst, 1372 bool HasFramePointer) const override { 1373 int MemOpNo = getMemoryOperandNo(Inst); 1374 const MCInstrDesc &MCII = Info->get(Inst.getOpcode()); 1375 const unsigned NumDefs = MCII.getNumDefs(); 1376 static BitVector SPBPAliases(BitVector(getAliases(X86::RSP)) |= 1377 getAliases(X86::RBP)); 1378 static BitVector SPAliases(getAliases(X86::RSP)); 1379 1380 // FIXME: PUSH can be technically a leak, but let's ignore this for now 1381 // because a lot of harmless prologue code will spill SP to the stack. 1382 // Unless push is clearly pushing an object address to the stack as 1383 // demonstrated by having a MemOp. 1384 bool IsPush = isPush(Inst); 1385 if (IsPush && MemOpNo == -1) 1386 return false; 1387 1388 // We use this to detect LEA (has memop but does not access mem) 1389 bool AccessMem = MCII.mayLoad() || MCII.mayStore(); 1390 bool DoesLeak = false; 1391 for (int I = 0, E = MCPlus::getNumPrimeOperands(Inst); I != E; ++I) { 1392 // Ignore if SP/BP is used to dereference memory -- that's fine 1393 if (MemOpNo != -1 && !IsPush && AccessMem && I >= MemOpNo && 1394 I <= MemOpNo + 5) 1395 continue; 1396 // Ignore if someone is writing to SP/BP 1397 if (I < static_cast<int>(NumDefs)) 1398 continue; 1399 1400 const MCOperand &Operand = Inst.getOperand(I); 1401 if (HasFramePointer && Operand.isReg() && SPBPAliases[Operand.getReg()]) { 1402 DoesLeak = true; 1403 break; 1404 } 1405 if (!HasFramePointer && Operand.isReg() && SPAliases[Operand.getReg()]) { 1406 DoesLeak = true; 1407 break; 1408 } 1409 } 1410 1411 // If potential leak, check if it is not just writing to itself/sp/bp 1412 if (DoesLeak) { 1413 for (int I = 0, E = NumDefs; I != E; ++I) { 1414 const MCOperand &Operand = Inst.getOperand(I); 1415 if (HasFramePointer && Operand.isReg() && 1416 SPBPAliases[Operand.getReg()]) { 1417 DoesLeak = false; 1418 break; 1419 } 1420 if (!HasFramePointer && Operand.isReg() && 1421 SPAliases[Operand.getReg()]) { 1422 DoesLeak = false; 1423 break; 1424 } 1425 } 1426 } 1427 return DoesLeak; 1428 } 1429 1430 bool addToImm(MCInst &Inst, int64_t &Amt, MCContext *Ctx) const override { 1431 unsigned ImmOpNo = -1U; 1432 int MemOpNo = getMemoryOperandNo(Inst); 1433 if (MemOpNo != -1) 1434 ImmOpNo = MemOpNo + X86::AddrDisp; 1435 else 1436 for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst); 1437 ++Index) 1438 if (Inst.getOperand(Index).isImm()) 1439 ImmOpNo = Index; 1440 if (ImmOpNo == -1U) 1441 return false; 1442 1443 MCOperand &Operand = Inst.getOperand(ImmOpNo); 1444 Amt += Operand.getImm(); 1445 Operand.setImm(Amt); 1446 // Check for the need for relaxation 1447 if (int64_t(Amt) == int64_t(int8_t(Amt))) 1448 return true; 1449 1450 // Relax instruction 1451 switch (Inst.getOpcode()) { 1452 case X86::SUB64ri8: 1453 Inst.setOpcode(X86::SUB64ri32); 1454 break; 1455 case X86::ADD64ri8: 1456 Inst.setOpcode(X86::ADD64ri32); 1457 break; 1458 default: 1459 // No need for relaxation 1460 break; 1461 } 1462 return true; 1463 } 1464 1465 /// TODO: this implementation currently works for the most common opcodes that 1466 /// load from memory. It can be extended to work with memory store opcodes as 1467 /// well as more memory load opcodes. 1468 bool replaceMemOperandWithImm(MCInst &Inst, StringRef ConstantData, 1469 uint64_t Offset) const override { 1470 enum CheckSignExt : uint8_t { 1471 NOCHECK = 0, 1472 CHECK8, 1473 CHECK32, 1474 }; 1475 1476 using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>; 1477 struct InstInfo { 1478 // Size in bytes that Inst loads from memory. 1479 uint8_t DataSize; 1480 1481 // True when the target operand has to be duplicated because the opcode 1482 // expects a LHS operand. 1483 bool HasLHS; 1484 1485 // List of checks and corresponding opcodes to be used. We try to use the 1486 // smallest possible immediate value when various sizes are available, 1487 // hence we may need to check whether a larger constant fits in a smaller 1488 // immediate. 1489 CheckList Checks; 1490 }; 1491 1492 InstInfo I; 1493 1494 switch (Inst.getOpcode()) { 1495 default: { 1496 switch (getPopSize(Inst)) { 1497 case 2: I = {2, false, {{NOCHECK, X86::MOV16ri}}}; break; 1498 case 4: I = {4, false, {{NOCHECK, X86::MOV32ri}}}; break; 1499 case 8: I = {8, false, {{CHECK32, X86::MOV64ri32}, 1500 {NOCHECK, X86::MOV64rm}}}; break; 1501 default: return false; 1502 } 1503 break; 1504 } 1505 1506 // MOV 1507 case X86::MOV8rm: I = {1, false, {{NOCHECK, X86::MOV8ri}}}; break; 1508 case X86::MOV16rm: I = {2, false, {{NOCHECK, X86::MOV16ri}}}; break; 1509 case X86::MOV32rm: I = {4, false, {{NOCHECK, X86::MOV32ri}}}; break; 1510 case X86::MOV64rm: I = {8, false, {{CHECK32, X86::MOV64ri32}, 1511 {NOCHECK, X86::MOV64rm}}}; break; 1512 1513 // MOVZX 1514 case X86::MOVZX16rm8: I = {1, false, {{NOCHECK, X86::MOV16ri}}}; break; 1515 case X86::MOVZX32rm8: I = {1, false, {{NOCHECK, X86::MOV32ri}}}; break; 1516 case X86::MOVZX32rm16: I = {2, false, {{NOCHECK, X86::MOV32ri}}}; break; 1517 1518 // CMP 1519 case X86::CMP8rm: I = {1, false, {{NOCHECK, X86::CMP8ri}}}; break; 1520 case X86::CMP16rm: I = {2, false, {{CHECK8, X86::CMP16ri8}, 1521 {NOCHECK, X86::CMP16ri}}}; break; 1522 case X86::CMP32rm: I = {4, false, {{CHECK8, X86::CMP32ri8}, 1523 {NOCHECK, X86::CMP32ri}}}; break; 1524 case X86::CMP64rm: I = {8, false, {{CHECK8, X86::CMP64ri8}, 1525 {CHECK32, X86::CMP64ri32}, 1526 {NOCHECK, X86::CMP64rm}}}; break; 1527 1528 // TEST 1529 case X86::TEST8mr: I = {1, false, {{NOCHECK, X86::TEST8ri}}}; break; 1530 case X86::TEST16mr: I = {2, false, {{NOCHECK, X86::TEST16ri}}}; break; 1531 case X86::TEST32mr: I = {4, false, {{NOCHECK, X86::TEST32ri}}}; break; 1532 case X86::TEST64mr: I = {8, false, {{CHECK32, X86::TEST64ri32}, 1533 {NOCHECK, X86::TEST64mr}}}; break; 1534 1535 // ADD 1536 case X86::ADD8rm: I = {1, true, {{NOCHECK, X86::ADD8ri}}}; break; 1537 case X86::ADD16rm: I = {2, true, {{CHECK8, X86::ADD16ri8}, 1538 {NOCHECK, X86::ADD16ri}}}; break; 1539 case X86::ADD32rm: I = {4, true, {{CHECK8, X86::ADD32ri8}, 1540 {NOCHECK, X86::ADD32ri}}}; break; 1541 case X86::ADD64rm: I = {8, true, {{CHECK8, X86::ADD64ri8}, 1542 {CHECK32, X86::ADD64ri32}, 1543 {NOCHECK, X86::ADD64rm}}}; break; 1544 1545 // SUB 1546 case X86::SUB8rm: I = {1, true, {{NOCHECK, X86::SUB8ri}}}; break; 1547 case X86::SUB16rm: I = {2, true, {{CHECK8, X86::SUB16ri8}, 1548 {NOCHECK, X86::SUB16ri}}}; break; 1549 case X86::SUB32rm: I = {4, true, {{CHECK8, X86::SUB32ri8}, 1550 {NOCHECK, X86::SUB32ri}}}; break; 1551 case X86::SUB64rm: I = {8, true, {{CHECK8, X86::SUB64ri8}, 1552 {CHECK32, X86::SUB64ri32}, 1553 {NOCHECK, X86::SUB64rm}}}; break; 1554 1555 // AND 1556 case X86::AND8rm: I = {1, true, {{NOCHECK, X86::AND8ri}}}; break; 1557 case X86::AND16rm: I = {2, true, {{CHECK8, X86::AND16ri8}, 1558 {NOCHECK, X86::AND16ri}}}; break; 1559 case X86::AND32rm: I = {4, true, {{CHECK8, X86::AND32ri8}, 1560 {NOCHECK, X86::AND32ri}}}; break; 1561 case X86::AND64rm: I = {8, true, {{CHECK8, X86::AND64ri8}, 1562 {CHECK32, X86::AND64ri32}, 1563 {NOCHECK, X86::AND64rm}}}; break; 1564 1565 // OR 1566 case X86::OR8rm: I = {1, true, {{NOCHECK, X86::OR8ri}}}; break; 1567 case X86::OR16rm: I = {2, true, {{CHECK8, X86::OR16ri8}, 1568 {NOCHECK, X86::OR16ri}}}; break; 1569 case X86::OR32rm: I = {4, true, {{CHECK8, X86::OR32ri8}, 1570 {NOCHECK, X86::OR32ri}}}; break; 1571 case X86::OR64rm: I = {8, true, {{CHECK8, X86::OR64ri8}, 1572 {CHECK32, X86::OR64ri32}, 1573 {NOCHECK, X86::OR64rm}}}; break; 1574 1575 // XOR 1576 case X86::XOR8rm: I = {1, true, {{NOCHECK, X86::XOR8ri}}}; break; 1577 case X86::XOR16rm: I = {2, true, {{CHECK8, X86::XOR16ri8}, 1578 {NOCHECK, X86::XOR16ri}}}; break; 1579 case X86::XOR32rm: I = {4, true, {{CHECK8, X86::XOR32ri8}, 1580 {NOCHECK, X86::XOR32ri}}}; break; 1581 case X86::XOR64rm: I = {8, true, {{CHECK8, X86::XOR64ri8}, 1582 {CHECK32, X86::XOR64ri32}, 1583 {NOCHECK, X86::XOR64rm}}}; break; 1584 } 1585 1586 // Compute the immediate value. 1587 assert(Offset + I.DataSize <= ConstantData.size() && 1588 "invalid offset for given constant data"); 1589 int64_t ImmVal = 1590 DataExtractor(ConstantData, true, 8).getSigned(&Offset, I.DataSize); 1591 1592 // Compute the new opcode. 1593 unsigned NewOpcode = 0; 1594 for (const std::pair<CheckSignExt, unsigned> &Check : I.Checks) { 1595 NewOpcode = Check.second; 1596 if (Check.first == NOCHECK) 1597 break; 1598 if (Check.first == CHECK8 && isInt<8>(ImmVal)) 1599 break; 1600 if (Check.first == CHECK32 && isInt<32>(ImmVal)) 1601 break; 1602 } 1603 if (NewOpcode == Inst.getOpcode()) 1604 return false; 1605 1606 // Modify the instruction. 1607 MCOperand ImmOp = MCOperand::createImm(ImmVal); 1608 uint32_t TargetOpNum = 0; 1609 // Test instruction does not follow the regular pattern of putting the 1610 // memory reference of a load (5 MCOperands) last in the list of operands. 1611 // Since it is not modifying the register operand, it is not treated as 1612 // a destination operand and it is not the first operand as it is in the 1613 // other instructions we treat here. 1614 if (NewOpcode == X86::TEST8ri || NewOpcode == X86::TEST16ri || 1615 NewOpcode == X86::TEST32ri || NewOpcode == X86::TEST64ri32) 1616 TargetOpNum = getMemoryOperandNo(Inst) + X86::AddrNumOperands; 1617 1618 MCOperand TargetOp = Inst.getOperand(TargetOpNum); 1619 Inst.clear(); 1620 Inst.setOpcode(NewOpcode); 1621 Inst.addOperand(TargetOp); 1622 if (I.HasLHS) 1623 Inst.addOperand(TargetOp); 1624 Inst.addOperand(ImmOp); 1625 1626 return true; 1627 } 1628 1629 /// TODO: this implementation currently works for the most common opcodes that 1630 /// load from memory. It can be extended to work with memory store opcodes as 1631 /// well as more memory load opcodes. 1632 bool replaceMemOperandWithReg(MCInst &Inst, MCPhysReg RegNum) const override { 1633 unsigned NewOpcode; 1634 1635 switch (Inst.getOpcode()) { 1636 default: { 1637 switch (getPopSize(Inst)) { 1638 case 2: NewOpcode = X86::MOV16rr; break; 1639 case 4: NewOpcode = X86::MOV32rr; break; 1640 case 8: NewOpcode = X86::MOV64rr; break; 1641 default: return false; 1642 } 1643 break; 1644 } 1645 1646 // MOV 1647 case X86::MOV8rm: NewOpcode = X86::MOV8rr; break; 1648 case X86::MOV16rm: NewOpcode = X86::MOV16rr; break; 1649 case X86::MOV32rm: NewOpcode = X86::MOV32rr; break; 1650 case X86::MOV64rm: NewOpcode = X86::MOV64rr; break; 1651 } 1652 1653 // Modify the instruction. 1654 MCOperand RegOp = MCOperand::createReg(RegNum); 1655 MCOperand TargetOp = Inst.getOperand(0); 1656 Inst.clear(); 1657 Inst.setOpcode(NewOpcode); 1658 Inst.addOperand(TargetOp); 1659 Inst.addOperand(RegOp); 1660 1661 return true; 1662 } 1663 1664 bool isRedundantMove(const MCInst &Inst) const override { 1665 switch (Inst.getOpcode()) { 1666 default: 1667 return false; 1668 1669 // MOV 1670 case X86::MOV8rr: 1671 case X86::MOV16rr: 1672 case X86::MOV32rr: 1673 case X86::MOV64rr: 1674 break; 1675 } 1676 1677 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg()); 1678 return Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg(); 1679 } 1680 1681 bool requiresAlignedAddress(const MCInst &Inst) const override { 1682 const MCInstrDesc &Desc = Info->get(Inst.getOpcode()); 1683 for (unsigned int I = 0; I < Desc.getNumOperands(); ++I) { 1684 const MCOperandInfo &Op = Desc.operands()[I]; 1685 if (Op.OperandType != MCOI::OPERAND_REGISTER) 1686 continue; 1687 if (Op.RegClass == X86::VR128RegClassID) 1688 return true; 1689 } 1690 return false; 1691 } 1692 1693 bool convertJmpToTailCall(MCInst &Inst) override { 1694 if (isTailCall(Inst)) 1695 return false; 1696 1697 int NewOpcode; 1698 switch (Inst.getOpcode()) { 1699 default: 1700 return false; 1701 case X86::JMP_1: 1702 case X86::JMP_2: 1703 case X86::JMP_4: 1704 NewOpcode = X86::JMP_4; 1705 break; 1706 case X86::JMP16m: 1707 case X86::JMP32m: 1708 case X86::JMP64m: 1709 NewOpcode = X86::JMP32m; 1710 break; 1711 case X86::JMP16r: 1712 case X86::JMP32r: 1713 case X86::JMP64r: 1714 NewOpcode = X86::JMP32r; 1715 break; 1716 } 1717 1718 Inst.setOpcode(NewOpcode); 1719 setTailCall(Inst); 1720 return true; 1721 } 1722 1723 bool convertTailCallToJmp(MCInst &Inst) override { 1724 int NewOpcode; 1725 switch (Inst.getOpcode()) { 1726 default: 1727 return false; 1728 case X86::JMP_4: 1729 NewOpcode = X86::JMP_1; 1730 break; 1731 case X86::JMP32m: 1732 NewOpcode = X86::JMP64m; 1733 break; 1734 case X86::JMP32r: 1735 NewOpcode = X86::JMP64r; 1736 break; 1737 } 1738 1739 Inst.setOpcode(NewOpcode); 1740 removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall); 1741 clearOffset(Inst); 1742 return true; 1743 } 1744 1745 bool convertTailCallToCall(MCInst &Inst) override { 1746 int NewOpcode; 1747 switch (Inst.getOpcode()) { 1748 default: 1749 return false; 1750 case X86::JMP_4: 1751 NewOpcode = X86::CALL64pcrel32; 1752 break; 1753 case X86::JMP32m: 1754 NewOpcode = X86::CALL64m; 1755 break; 1756 case X86::JMP32r: 1757 NewOpcode = X86::CALL64r; 1758 break; 1759 } 1760 1761 Inst.setOpcode(NewOpcode); 1762 removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall); 1763 return true; 1764 } 1765 1766 bool convertCallToIndirectCall(MCInst &Inst, const MCSymbol *TargetLocation, 1767 MCContext *Ctx) override { 1768 assert((Inst.getOpcode() == X86::CALL64pcrel32 || 1769 (Inst.getOpcode() == X86::JMP_4 && isTailCall(Inst))) && 1770 "64-bit direct (tail) call instruction expected"); 1771 const auto NewOpcode = 1772 (Inst.getOpcode() == X86::CALL64pcrel32) ? X86::CALL64m : X86::JMP32m; 1773 Inst.setOpcode(NewOpcode); 1774 1775 // Replace the first operand and preserve auxiliary operands of 1776 // the instruction. 1777 Inst.erase(Inst.begin()); 1778 Inst.insert(Inst.begin(), 1779 MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 1780 Inst.insert(Inst.begin(), 1781 MCOperand::createExpr( // Displacement 1782 MCSymbolRefExpr::create(TargetLocation, 1783 MCSymbolRefExpr::VK_None, *Ctx))); 1784 Inst.insert(Inst.begin(), 1785 MCOperand::createReg(X86::NoRegister)); // IndexReg 1786 Inst.insert(Inst.begin(), 1787 MCOperand::createImm(1)); // ScaleAmt 1788 Inst.insert(Inst.begin(), 1789 MCOperand::createReg(X86::RIP)); // BaseReg 1790 1791 return true; 1792 } 1793 1794 void convertIndirectCallToLoad(MCInst &Inst, MCPhysReg Reg) override { 1795 bool IsTailCall = isTailCall(Inst); 1796 if (IsTailCall) 1797 removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall); 1798 if (Inst.getOpcode() == X86::CALL64m || 1799 (Inst.getOpcode() == X86::JMP32m && IsTailCall)) { 1800 Inst.setOpcode(X86::MOV64rm); 1801 Inst.insert(Inst.begin(), MCOperand::createReg(Reg)); 1802 return; 1803 } 1804 if (Inst.getOpcode() == X86::CALL64r || 1805 (Inst.getOpcode() == X86::JMP32r && IsTailCall)) { 1806 Inst.setOpcode(X86::MOV64rr); 1807 Inst.insert(Inst.begin(), MCOperand::createReg(Reg)); 1808 return; 1809 } 1810 LLVM_DEBUG(Inst.dump()); 1811 llvm_unreachable("not implemented"); 1812 } 1813 1814 bool shortenInstruction(MCInst &Inst, 1815 const MCSubtargetInfo &STI) const override { 1816 unsigned OldOpcode = Inst.getOpcode(); 1817 unsigned NewOpcode = OldOpcode; 1818 1819 int MemOpNo = getMemoryOperandNo(Inst); 1820 1821 // Check and remove redundant Address-Size override prefix. 1822 if (opts::X86StripRedundantAddressSize) { 1823 uint64_t TSFlags = Info->get(OldOpcode).TSFlags; 1824 unsigned Flags = Inst.getFlags(); 1825 1826 if (!X86_MC::needsAddressSizeOverride(Inst, STI, MemOpNo, TSFlags) && 1827 Flags & X86::IP_HAS_AD_SIZE) 1828 Inst.setFlags(Flags ^ X86::IP_HAS_AD_SIZE); 1829 } 1830 1831 // Check and remove EIZ/RIZ. These cases represent ambiguous cases where 1832 // SIB byte is present, but no index is used and modrm alone should have 1833 // been enough. Converting to NoRegister effectively removes the SIB byte. 1834 if (MemOpNo >= 0) { 1835 MCOperand &IndexOp = 1836 Inst.getOperand(static_cast<unsigned>(MemOpNo) + X86::AddrIndexReg); 1837 if (IndexOp.getReg() == X86::EIZ || IndexOp.getReg() == X86::RIZ) 1838 IndexOp = MCOperand::createReg(X86::NoRegister); 1839 } 1840 1841 if (isBranch(Inst)) { 1842 NewOpcode = getShortBranchOpcode(OldOpcode); 1843 } else if (OldOpcode == X86::MOV64ri) { 1844 if (Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).isImm()) { 1845 const int64_t Imm = 1846 Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).getImm(); 1847 if (int64_t(Imm) == int64_t(int32_t(Imm))) 1848 NewOpcode = X86::MOV64ri32; 1849 } 1850 } else { 1851 // If it's arithmetic instruction check if signed operand fits in 1 byte. 1852 const unsigned ShortOpcode = getShortArithOpcode(OldOpcode); 1853 if (ShortOpcode != OldOpcode && 1854 Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).isImm()) { 1855 int64_t Imm = 1856 Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).getImm(); 1857 if (int64_t(Imm) == int64_t(int8_t(Imm))) 1858 NewOpcode = ShortOpcode; 1859 } 1860 } 1861 1862 if (NewOpcode == OldOpcode) 1863 return false; 1864 1865 Inst.setOpcode(NewOpcode); 1866 return true; 1867 } 1868 1869 bool 1870 convertMoveToConditionalMove(MCInst &Inst, unsigned CC, bool AllowStackMemOp, 1871 bool AllowBasePtrStackMemOp) const override { 1872 // - Register-register moves are OK 1873 // - Stores are filtered out by opcode (no store CMOV) 1874 // - Non-stack loads are prohibited (generally unsafe) 1875 // - Stack loads are OK if AllowStackMemOp is true 1876 // - Stack loads with RBP are OK if AllowBasePtrStackMemOp is true 1877 if (isLoad(Inst)) { 1878 // If stack memory operands are not allowed, no loads are allowed 1879 if (!AllowStackMemOp) 1880 return false; 1881 1882 // If stack memory operands are allowed, check if it's a load from stack 1883 bool IsLoad, IsStore, IsStoreFromReg, IsSimple, IsIndexed; 1884 MCPhysReg Reg; 1885 int32_t SrcImm; 1886 uint16_t StackPtrReg; 1887 int64_t StackOffset; 1888 uint8_t Size; 1889 bool IsStackAccess = 1890 isStackAccess(Inst, IsLoad, IsStore, IsStoreFromReg, Reg, SrcImm, 1891 StackPtrReg, StackOffset, Size, IsSimple, IsIndexed); 1892 // Prohibit non-stack-based loads 1893 if (!IsStackAccess) 1894 return false; 1895 // If stack memory operands are allowed, check if it's RBP-based 1896 if (!AllowBasePtrStackMemOp && 1897 RegInfo->isSubRegisterEq(X86::RBP, StackPtrReg)) 1898 return false; 1899 } 1900 1901 unsigned NewOpcode = 0; 1902 switch (Inst.getOpcode()) { 1903 case X86::MOV16rr: 1904 NewOpcode = X86::CMOV16rr; 1905 break; 1906 case X86::MOV16rm: 1907 NewOpcode = X86::CMOV16rm; 1908 break; 1909 case X86::MOV32rr: 1910 NewOpcode = X86::CMOV32rr; 1911 break; 1912 case X86::MOV32rm: 1913 NewOpcode = X86::CMOV32rm; 1914 break; 1915 case X86::MOV64rr: 1916 NewOpcode = X86::CMOV64rr; 1917 break; 1918 case X86::MOV64rm: 1919 NewOpcode = X86::CMOV64rm; 1920 break; 1921 default: 1922 return false; 1923 } 1924 Inst.setOpcode(NewOpcode); 1925 // Insert CC at the end of prime operands, before annotations 1926 Inst.insert(Inst.begin() + MCPlus::getNumPrimeOperands(Inst), 1927 MCOperand::createImm(CC)); 1928 // CMOV is a 3-operand MCInst, so duplicate the destination as src1 1929 Inst.insert(Inst.begin(), Inst.getOperand(0)); 1930 return true; 1931 } 1932 1933 bool lowerTailCall(MCInst &Inst) override { 1934 if (Inst.getOpcode() == X86::JMP_4 && isTailCall(Inst)) { 1935 Inst.setOpcode(X86::JMP_1); 1936 removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall); 1937 return true; 1938 } 1939 return false; 1940 } 1941 1942 const MCSymbol *getTargetSymbol(const MCInst &Inst, 1943 unsigned OpNum = 0) const override { 1944 if (OpNum >= MCPlus::getNumPrimeOperands(Inst)) 1945 return nullptr; 1946 1947 const MCOperand &Op = Inst.getOperand(OpNum); 1948 if (!Op.isExpr()) 1949 return nullptr; 1950 1951 auto *SymExpr = dyn_cast<MCSymbolRefExpr>(Op.getExpr()); 1952 if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_None) 1953 return nullptr; 1954 1955 return &SymExpr->getSymbol(); 1956 } 1957 1958 // This is the same as the base class, but since we are overriding one of 1959 // getTargetSymbol's signatures above, we need to override all of them. 1960 const MCSymbol *getTargetSymbol(const MCExpr *Expr) const override { 1961 return &cast<const MCSymbolRefExpr>(Expr)->getSymbol(); 1962 } 1963 1964 bool analyzeBranch(InstructionIterator Begin, InstructionIterator End, 1965 const MCSymbol *&TBB, const MCSymbol *&FBB, 1966 MCInst *&CondBranch, 1967 MCInst *&UncondBranch) const override { 1968 auto I = End; 1969 1970 // Bottom-up analysis 1971 while (I != Begin) { 1972 --I; 1973 1974 // Ignore nops and CFIs 1975 if (isPseudo(*I)) 1976 continue; 1977 1978 // Stop when we find the first non-terminator 1979 if (!isTerminator(*I)) 1980 break; 1981 1982 if (!isBranch(*I)) 1983 break; 1984 1985 // Handle unconditional branches. 1986 if ((I->getOpcode() == X86::JMP_1 || I->getOpcode() == X86::JMP_2 || 1987 I->getOpcode() == X86::JMP_4) && 1988 !isTailCall(*I)) { 1989 // If any code was seen after this unconditional branch, we've seen 1990 // unreachable code. Ignore them. 1991 CondBranch = nullptr; 1992 UncondBranch = &*I; 1993 const MCSymbol *Sym = getTargetSymbol(*I); 1994 assert(Sym != nullptr && 1995 "Couldn't extract BB symbol from jump operand"); 1996 TBB = Sym; 1997 continue; 1998 } 1999 2000 // Handle conditional branches and ignore indirect branches 2001 if (!isUnsupportedBranch(I->getOpcode()) && 2002 getCondCode(*I) == X86::COND_INVALID) { 2003 // Indirect branch 2004 return false; 2005 } 2006 2007 if (CondBranch == nullptr) { 2008 const MCSymbol *TargetBB = getTargetSymbol(*I); 2009 if (TargetBB == nullptr) { 2010 // Unrecognized branch target 2011 return false; 2012 } 2013 FBB = TBB; 2014 TBB = TargetBB; 2015 CondBranch = &*I; 2016 continue; 2017 } 2018 2019 llvm_unreachable("multiple conditional branches in one BB"); 2020 } 2021 return true; 2022 } 2023 2024 template <typename Itr> 2025 std::pair<IndirectBranchType, MCInst *> 2026 analyzePICJumpTable(Itr II, Itr IE, MCPhysReg R1, MCPhysReg R2) const { 2027 // Analyze PIC-style jump table code template: 2028 // 2029 // lea PIC_JUMP_TABLE(%rip), {%r1|%r2} <- MemLocInstr 2030 // mov ({%r1|%r2}, %index, 4), {%r2|%r1} 2031 // add %r2, %r1 2032 // jmp *%r1 2033 // 2034 // (with any irrelevant instructions in-between) 2035 // 2036 // When we call this helper we've already determined %r1 and %r2, and 2037 // reverse instruction iterator \p II is pointing to the ADD instruction. 2038 // 2039 // PIC jump table looks like following: 2040 // 2041 // JT: ---------- 2042 // E1:| L1 - JT | 2043 // |----------| 2044 // E2:| L2 - JT | 2045 // |----------| 2046 // | | 2047 // ...... 2048 // En:| Ln - JT | 2049 // ---------- 2050 // 2051 // Where L1, L2, ..., Ln represent labels in the function. 2052 // 2053 // The actual relocations in the table will be of the form: 2054 // 2055 // Ln - JT 2056 // = (Ln - En) + (En - JT) 2057 // = R_X86_64_PC32(Ln) + En - JT 2058 // = R_X86_64_PC32(Ln + offsetof(En)) 2059 // 2060 LLVM_DEBUG(dbgs() << "Checking for PIC jump table\n"); 2061 MCInst *MemLocInstr = nullptr; 2062 const MCInst *MovInstr = nullptr; 2063 while (++II != IE) { 2064 MCInst &Instr = *II; 2065 const MCInstrDesc &InstrDesc = Info->get(Instr.getOpcode()); 2066 if (!InstrDesc.hasDefOfPhysReg(Instr, R1, *RegInfo) && 2067 !InstrDesc.hasDefOfPhysReg(Instr, R2, *RegInfo)) { 2068 // Ignore instructions that don't affect R1, R2 registers. 2069 continue; 2070 } 2071 if (!MovInstr) { 2072 // Expect to see MOV instruction. 2073 if (!isMOVSX64rm32(Instr)) { 2074 LLVM_DEBUG(dbgs() << "MOV instruction expected.\n"); 2075 break; 2076 } 2077 2078 // Check if it's setting %r1 or %r2. In canonical form it sets %r2. 2079 // If it sets %r1 - rename the registers so we have to only check 2080 // a single form. 2081 unsigned MovDestReg = Instr.getOperand(0).getReg(); 2082 if (MovDestReg != R2) 2083 std::swap(R1, R2); 2084 if (MovDestReg != R2) { 2085 LLVM_DEBUG(dbgs() << "MOV instruction expected to set %r2\n"); 2086 break; 2087 } 2088 2089 // Verify operands for MOV. 2090 unsigned BaseRegNum; 2091 int64_t ScaleValue; 2092 unsigned IndexRegNum; 2093 int64_t DispValue; 2094 unsigned SegRegNum; 2095 if (!evaluateX86MemoryOperand(Instr, &BaseRegNum, &ScaleValue, 2096 &IndexRegNum, &DispValue, &SegRegNum)) 2097 break; 2098 if (BaseRegNum != R1 || ScaleValue != 4 || 2099 IndexRegNum == X86::NoRegister || DispValue != 0 || 2100 SegRegNum != X86::NoRegister) 2101 break; 2102 MovInstr = &Instr; 2103 } else { 2104 if (!InstrDesc.hasDefOfPhysReg(Instr, R1, *RegInfo)) 2105 continue; 2106 if (!isLEA64r(Instr)) { 2107 LLVM_DEBUG(dbgs() << "LEA instruction expected\n"); 2108 break; 2109 } 2110 if (Instr.getOperand(0).getReg() != R1) { 2111 LLVM_DEBUG(dbgs() << "LEA instruction expected to set %r1\n"); 2112 break; 2113 } 2114 2115 // Verify operands for LEA. 2116 unsigned BaseRegNum; 2117 int64_t ScaleValue; 2118 unsigned IndexRegNum; 2119 const MCExpr *DispExpr = nullptr; 2120 int64_t DispValue; 2121 unsigned SegRegNum; 2122 if (!evaluateX86MemoryOperand(Instr, &BaseRegNum, &ScaleValue, 2123 &IndexRegNum, &DispValue, &SegRegNum, 2124 &DispExpr)) 2125 break; 2126 if (BaseRegNum != RegInfo->getProgramCounter() || 2127 IndexRegNum != X86::NoRegister || SegRegNum != X86::NoRegister || 2128 DispExpr == nullptr) 2129 break; 2130 MemLocInstr = &Instr; 2131 break; 2132 } 2133 } 2134 2135 if (!MemLocInstr) 2136 return std::make_pair(IndirectBranchType::UNKNOWN, nullptr); 2137 2138 LLVM_DEBUG(dbgs() << "checking potential PIC jump table\n"); 2139 return std::make_pair(IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE, 2140 MemLocInstr); 2141 } 2142 2143 IndirectBranchType analyzeIndirectBranch( 2144 MCInst &Instruction, InstructionIterator Begin, InstructionIterator End, 2145 const unsigned PtrSize, MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut, 2146 unsigned &IndexRegNumOut, int64_t &DispValueOut, 2147 const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut) const override { 2148 // Try to find a (base) memory location from where the address for 2149 // the indirect branch is loaded. For X86-64 the memory will be specified 2150 // in the following format: 2151 // 2152 // {%rip}/{%basereg} + Imm + IndexReg * Scale 2153 // 2154 // We are interested in the cases where Scale == sizeof(uintptr_t) and 2155 // the contents of the memory are presumably an array of pointers to code. 2156 // 2157 // Normal jump table: 2158 // 2159 // jmp *(JUMP_TABLE, %index, Scale) <- MemLocInstr 2160 // 2161 // or 2162 // 2163 // mov (JUMP_TABLE, %index, Scale), %r1 <- MemLocInstr 2164 // ... 2165 // jmp %r1 2166 // 2167 // We handle PIC-style jump tables separately. 2168 // 2169 MemLocInstrOut = nullptr; 2170 BaseRegNumOut = X86::NoRegister; 2171 IndexRegNumOut = X86::NoRegister; 2172 DispValueOut = 0; 2173 DispExprOut = nullptr; 2174 2175 std::reverse_iterator<InstructionIterator> II(End); 2176 std::reverse_iterator<InstructionIterator> IE(Begin); 2177 2178 IndirectBranchType Type = IndirectBranchType::UNKNOWN; 2179 2180 // An instruction referencing memory used by jump instruction (directly or 2181 // via register). This location could be an array of function pointers 2182 // in case of indirect tail call, or a jump table. 2183 MCInst *MemLocInstr = nullptr; 2184 2185 if (MCPlus::getNumPrimeOperands(Instruction) == 1) { 2186 // If the indirect jump is on register - try to detect if the 2187 // register value is loaded from a memory location. 2188 assert(Instruction.getOperand(0).isReg() && "register operand expected"); 2189 const unsigned R1 = Instruction.getOperand(0).getReg(); 2190 // Check if one of the previous instructions defines the jump-on register. 2191 for (auto PrevII = II; PrevII != IE; ++PrevII) { 2192 MCInst &PrevInstr = *PrevII; 2193 const MCInstrDesc &PrevInstrDesc = Info->get(PrevInstr.getOpcode()); 2194 2195 if (!PrevInstrDesc.hasDefOfPhysReg(PrevInstr, R1, *RegInfo)) 2196 continue; 2197 2198 if (isMoveMem2Reg(PrevInstr)) { 2199 MemLocInstr = &PrevInstr; 2200 break; 2201 } 2202 if (isADD64rr(PrevInstr)) { 2203 unsigned R2 = PrevInstr.getOperand(2).getReg(); 2204 if (R1 == R2) 2205 return IndirectBranchType::UNKNOWN; 2206 std::tie(Type, MemLocInstr) = analyzePICJumpTable(PrevII, IE, R1, R2); 2207 break; 2208 } 2209 return IndirectBranchType::UNKNOWN; 2210 } 2211 if (!MemLocInstr) { 2212 // No definition seen for the register in this function so far. Could be 2213 // an input parameter - which means it is an external code reference. 2214 // It also could be that the definition happens to be in the code that 2215 // we haven't processed yet. Since we have to be conservative, return 2216 // as UNKNOWN case. 2217 return IndirectBranchType::UNKNOWN; 2218 } 2219 } else { 2220 MemLocInstr = &Instruction; 2221 } 2222 2223 const MCRegister RIPRegister = RegInfo->getProgramCounter(); 2224 2225 // Analyze the memory location. 2226 unsigned BaseRegNum, IndexRegNum, SegRegNum; 2227 int64_t ScaleValue, DispValue; 2228 const MCExpr *DispExpr; 2229 2230 if (!evaluateX86MemoryOperand(*MemLocInstr, &BaseRegNum, &ScaleValue, 2231 &IndexRegNum, &DispValue, &SegRegNum, 2232 &DispExpr)) 2233 return IndirectBranchType::UNKNOWN; 2234 2235 BaseRegNumOut = BaseRegNum; 2236 IndexRegNumOut = IndexRegNum; 2237 DispValueOut = DispValue; 2238 DispExprOut = DispExpr; 2239 2240 if ((BaseRegNum != X86::NoRegister && BaseRegNum != RIPRegister) || 2241 SegRegNum != X86::NoRegister) 2242 return IndirectBranchType::UNKNOWN; 2243 2244 if (MemLocInstr == &Instruction && 2245 (!ScaleValue || IndexRegNum == X86::NoRegister)) { 2246 MemLocInstrOut = MemLocInstr; 2247 return IndirectBranchType::POSSIBLE_FIXED_BRANCH; 2248 } 2249 2250 if (Type == IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE && 2251 (ScaleValue != 1 || BaseRegNum != RIPRegister)) 2252 return IndirectBranchType::UNKNOWN; 2253 2254 if (Type != IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE && 2255 ScaleValue != PtrSize) 2256 return IndirectBranchType::UNKNOWN; 2257 2258 MemLocInstrOut = MemLocInstr; 2259 2260 return Type; 2261 } 2262 2263 /// Analyze a callsite to see if it could be a virtual method call. This only 2264 /// checks to see if the overall pattern is satisfied, it does not guarantee 2265 /// that the callsite is a true virtual method call. 2266 /// The format of virtual method calls that are recognized is one of the 2267 /// following: 2268 /// 2269 /// Form 1: (found in debug code) 2270 /// add METHOD_OFFSET, %VtableReg 2271 /// mov (%VtableReg), %MethodReg 2272 /// ... 2273 /// call or jmp *%MethodReg 2274 /// 2275 /// Form 2: 2276 /// mov METHOD_OFFSET(%VtableReg), %MethodReg 2277 /// ... 2278 /// call or jmp *%MethodReg 2279 /// 2280 /// Form 3: 2281 /// ... 2282 /// call or jmp *METHOD_OFFSET(%VtableReg) 2283 /// 2284 bool analyzeVirtualMethodCall(InstructionIterator ForwardBegin, 2285 InstructionIterator ForwardEnd, 2286 std::vector<MCInst *> &MethodFetchInsns, 2287 unsigned &VtableRegNum, unsigned &MethodRegNum, 2288 uint64_t &MethodOffset) const override { 2289 VtableRegNum = X86::NoRegister; 2290 MethodRegNum = X86::NoRegister; 2291 MethodOffset = 0; 2292 2293 std::reverse_iterator<InstructionIterator> Itr(ForwardEnd); 2294 std::reverse_iterator<InstructionIterator> End(ForwardBegin); 2295 2296 MCInst &CallInst = *Itr++; 2297 assert(isIndirectBranch(CallInst) || isCall(CallInst)); 2298 2299 unsigned BaseReg, IndexReg, SegmentReg; 2300 int64_t Scale, Disp; 2301 const MCExpr *DispExpr; 2302 2303 // The call can just be jmp offset(reg) 2304 if (evaluateX86MemoryOperand(CallInst, &BaseReg, &Scale, &IndexReg, &Disp, 2305 &SegmentReg, &DispExpr)) { 2306 if (!DispExpr && BaseReg != X86::RIP && BaseReg != X86::RBP && 2307 BaseReg != X86::NoRegister) { 2308 MethodRegNum = BaseReg; 2309 if (Scale == 1 && IndexReg == X86::NoRegister && 2310 SegmentReg == X86::NoRegister) { 2311 VtableRegNum = MethodRegNum; 2312 MethodOffset = Disp; 2313 MethodFetchInsns.push_back(&CallInst); 2314 return true; 2315 } 2316 } 2317 return false; 2318 } 2319 if (CallInst.getOperand(0).isReg()) 2320 MethodRegNum = CallInst.getOperand(0).getReg(); 2321 else 2322 return false; 2323 2324 if (MethodRegNum == X86::RIP || MethodRegNum == X86::RBP) { 2325 VtableRegNum = X86::NoRegister; 2326 MethodRegNum = X86::NoRegister; 2327 return false; 2328 } 2329 2330 // find load from vtable, this may or may not include the method offset 2331 while (Itr != End) { 2332 MCInst &CurInst = *Itr++; 2333 const MCInstrDesc &Desc = Info->get(CurInst.getOpcode()); 2334 if (Desc.hasDefOfPhysReg(CurInst, MethodRegNum, *RegInfo)) { 2335 if (isLoad(CurInst) && 2336 evaluateX86MemoryOperand(CurInst, &BaseReg, &Scale, &IndexReg, 2337 &Disp, &SegmentReg, &DispExpr)) { 2338 if (!DispExpr && Scale == 1 && BaseReg != X86::RIP && 2339 BaseReg != X86::RBP && BaseReg != X86::NoRegister && 2340 IndexReg == X86::NoRegister && SegmentReg == X86::NoRegister && 2341 BaseReg != X86::RIP) { 2342 VtableRegNum = BaseReg; 2343 MethodOffset = Disp; 2344 MethodFetchInsns.push_back(&CurInst); 2345 if (MethodOffset != 0) 2346 return true; 2347 break; 2348 } 2349 } 2350 return false; 2351 } 2352 } 2353 2354 if (!VtableRegNum) 2355 return false; 2356 2357 // look for any adds affecting the method register. 2358 while (Itr != End) { 2359 MCInst &CurInst = *Itr++; 2360 const MCInstrDesc &Desc = Info->get(CurInst.getOpcode()); 2361 if (Desc.hasDefOfPhysReg(CurInst, VtableRegNum, *RegInfo)) { 2362 if (isADDri(CurInst)) { 2363 assert(!MethodOffset); 2364 MethodOffset = CurInst.getOperand(2).getImm(); 2365 MethodFetchInsns.insert(MethodFetchInsns.begin(), &CurInst); 2366 break; 2367 } 2368 } 2369 } 2370 2371 return true; 2372 } 2373 2374 bool createStackPointerIncrement(MCInst &Inst, int Size, 2375 bool NoFlagsClobber) const override { 2376 if (NoFlagsClobber) { 2377 Inst.setOpcode(X86::LEA64r); 2378 Inst.clear(); 2379 Inst.addOperand(MCOperand::createReg(X86::RSP)); 2380 Inst.addOperand(MCOperand::createReg(X86::RSP)); // BaseReg 2381 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 2382 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 2383 Inst.addOperand(MCOperand::createImm(-Size)); // Displacement 2384 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 2385 return true; 2386 } 2387 Inst.setOpcode(X86::SUB64ri8); 2388 Inst.clear(); 2389 Inst.addOperand(MCOperand::createReg(X86::RSP)); 2390 Inst.addOperand(MCOperand::createReg(X86::RSP)); 2391 Inst.addOperand(MCOperand::createImm(Size)); 2392 return true; 2393 } 2394 2395 bool createStackPointerDecrement(MCInst &Inst, int Size, 2396 bool NoFlagsClobber) const override { 2397 if (NoFlagsClobber) { 2398 Inst.setOpcode(X86::LEA64r); 2399 Inst.clear(); 2400 Inst.addOperand(MCOperand::createReg(X86::RSP)); 2401 Inst.addOperand(MCOperand::createReg(X86::RSP)); // BaseReg 2402 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 2403 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 2404 Inst.addOperand(MCOperand::createImm(Size)); // Displacement 2405 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 2406 return true; 2407 } 2408 Inst.setOpcode(X86::ADD64ri8); 2409 Inst.clear(); 2410 Inst.addOperand(MCOperand::createReg(X86::RSP)); 2411 Inst.addOperand(MCOperand::createReg(X86::RSP)); 2412 Inst.addOperand(MCOperand::createImm(Size)); 2413 return true; 2414 } 2415 2416 bool createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset, 2417 const MCPhysReg &SrcReg, int Size) const override { 2418 unsigned NewOpcode; 2419 switch (Size) { 2420 default: 2421 return false; 2422 case 2: NewOpcode = X86::MOV16mr; break; 2423 case 4: NewOpcode = X86::MOV32mr; break; 2424 case 8: NewOpcode = X86::MOV64mr; break; 2425 } 2426 Inst.setOpcode(NewOpcode); 2427 Inst.clear(); 2428 Inst.addOperand(MCOperand::createReg(StackReg)); // BaseReg 2429 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 2430 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 2431 Inst.addOperand(MCOperand::createImm(Offset)); // Displacement 2432 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 2433 Inst.addOperand(MCOperand::createReg(SrcReg)); 2434 return true; 2435 } 2436 2437 bool createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg, 2438 int Offset, const MCPhysReg &DstReg, 2439 int Size) const override { 2440 return createLoad(Inst, StackReg, /*Scale=*/1, /*IndexReg=*/X86::NoRegister, 2441 Offset, nullptr, /*AddrSegmentReg=*/X86::NoRegister, 2442 DstReg, Size); 2443 } 2444 2445 bool createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale, 2446 const MCPhysReg &IndexReg, int64_t Offset, 2447 const MCExpr *OffsetExpr, const MCPhysReg &AddrSegmentReg, 2448 const MCPhysReg &DstReg, int Size) const override { 2449 unsigned NewOpcode; 2450 switch (Size) { 2451 default: 2452 return false; 2453 case 2: NewOpcode = X86::MOV16rm; break; 2454 case 4: NewOpcode = X86::MOV32rm; break; 2455 case 8: NewOpcode = X86::MOV64rm; break; 2456 } 2457 Inst.setOpcode(NewOpcode); 2458 Inst.clear(); 2459 Inst.addOperand(MCOperand::createReg(DstReg)); 2460 Inst.addOperand(MCOperand::createReg(BaseReg)); 2461 Inst.addOperand(MCOperand::createImm(Scale)); 2462 Inst.addOperand(MCOperand::createReg(IndexReg)); 2463 if (OffsetExpr) 2464 Inst.addOperand(MCOperand::createExpr(OffsetExpr)); // Displacement 2465 else 2466 Inst.addOperand(MCOperand::createImm(Offset)); // Displacement 2467 Inst.addOperand(MCOperand::createReg(AddrSegmentReg)); // AddrSegmentReg 2468 return true; 2469 } 2470 2471 void createLoadImmediate(MCInst &Inst, const MCPhysReg Dest, 2472 uint32_t Imm) const override { 2473 Inst.setOpcode(X86::MOV64ri32); 2474 Inst.clear(); 2475 Inst.addOperand(MCOperand::createReg(Dest)); 2476 Inst.addOperand(MCOperand::createImm(Imm)); 2477 } 2478 2479 bool createIncMemory(MCInst &Inst, const MCSymbol *Target, 2480 MCContext *Ctx) const override { 2481 2482 Inst.setOpcode(X86::LOCK_INC64m); 2483 Inst.clear(); 2484 Inst.addOperand(MCOperand::createReg(X86::RIP)); // BaseReg 2485 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 2486 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 2487 2488 Inst.addOperand(MCOperand::createExpr( 2489 MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, 2490 *Ctx))); // Displacement 2491 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 2492 return true; 2493 } 2494 2495 bool createIJmp32Frag(SmallVectorImpl<MCInst> &Insts, 2496 const MCOperand &BaseReg, const MCOperand &Scale, 2497 const MCOperand &IndexReg, const MCOperand &Offset, 2498 const MCOperand &TmpReg) const override { 2499 // The code fragment we emit here is: 2500 // 2501 // mov32 (%base, %index, scale), %tmpreg 2502 // ijmp *(%tmpreg) 2503 // 2504 MCInst IJmp; 2505 IJmp.setOpcode(X86::JMP64r); 2506 IJmp.addOperand(TmpReg); 2507 2508 MCInst Load; 2509 Load.setOpcode(X86::MOV32rm); 2510 Load.addOperand(TmpReg); 2511 Load.addOperand(BaseReg); 2512 Load.addOperand(Scale); 2513 Load.addOperand(IndexReg); 2514 Load.addOperand(Offset); 2515 Load.addOperand(MCOperand::createReg(X86::NoRegister)); 2516 2517 Insts.push_back(Load); 2518 Insts.push_back(IJmp); 2519 return true; 2520 } 2521 2522 bool createNoop(MCInst &Inst) const override { 2523 Inst.setOpcode(X86::NOOP); 2524 return true; 2525 } 2526 2527 bool createReturn(MCInst &Inst) const override { 2528 Inst.setOpcode(X86::RET64); 2529 return true; 2530 } 2531 2532 InstructionListType createInlineMemcpy(bool ReturnEnd) const override { 2533 InstructionListType Code; 2534 if (ReturnEnd) 2535 Code.emplace_back(MCInstBuilder(X86::LEA64r) 2536 .addReg(X86::RAX) 2537 .addReg(X86::RDI) 2538 .addImm(1) 2539 .addReg(X86::RDX) 2540 .addImm(0) 2541 .addReg(X86::NoRegister)); 2542 else 2543 Code.emplace_back(MCInstBuilder(X86::MOV64rr) 2544 .addReg(X86::RAX) 2545 .addReg(X86::RDI)); 2546 2547 Code.emplace_back(MCInstBuilder(X86::MOV32rr) 2548 .addReg(X86::ECX) 2549 .addReg(X86::EDX)); 2550 Code.emplace_back(MCInstBuilder(X86::REP_MOVSB_64)); 2551 2552 return Code; 2553 } 2554 2555 InstructionListType createOneByteMemcpy() const override { 2556 InstructionListType Code; 2557 Code.emplace_back(MCInstBuilder(X86::MOV8rm) 2558 .addReg(X86::CL) 2559 .addReg(X86::RSI) 2560 .addImm(0) 2561 .addReg(X86::NoRegister) 2562 .addImm(0) 2563 .addReg(X86::NoRegister)); 2564 Code.emplace_back(MCInstBuilder(X86::MOV8mr) 2565 .addReg(X86::RDI) 2566 .addImm(0) 2567 .addReg(X86::NoRegister) 2568 .addImm(0) 2569 .addReg(X86::NoRegister) 2570 .addReg(X86::CL)); 2571 Code.emplace_back(MCInstBuilder(X86::MOV64rr) 2572 .addReg(X86::RAX) 2573 .addReg(X86::RDI)); 2574 return Code; 2575 } 2576 2577 InstructionListType createCmpJE(MCPhysReg RegNo, int64_t Imm, 2578 const MCSymbol *Target, 2579 MCContext *Ctx) const override { 2580 InstructionListType Code; 2581 Code.emplace_back(MCInstBuilder(X86::CMP64ri8) 2582 .addReg(RegNo) 2583 .addImm(Imm)); 2584 Code.emplace_back(MCInstBuilder(X86::JCC_1) 2585 .addExpr(MCSymbolRefExpr::create( 2586 Target, MCSymbolRefExpr::VK_None, *Ctx)) 2587 .addImm(X86::COND_E)); 2588 return Code; 2589 } 2590 2591 std::optional<Relocation> 2592 createRelocation(const MCFixup &Fixup, 2593 const MCAsmBackend &MAB) const override { 2594 const MCFixupKindInfo &FKI = MAB.getFixupKindInfo(Fixup.getKind()); 2595 2596 assert(FKI.TargetOffset == 0 && "0-bit relocation offset expected"); 2597 const uint64_t RelOffset = Fixup.getOffset(); 2598 2599 uint64_t RelType; 2600 if (FKI.Flags & MCFixupKindInfo::FKF_IsPCRel) { 2601 switch (FKI.TargetSize) { 2602 default: 2603 return std::nullopt; 2604 case 8: RelType = ELF::R_X86_64_PC8; break; 2605 case 16: RelType = ELF::R_X86_64_PC16; break; 2606 case 32: RelType = ELF::R_X86_64_PC32; break; 2607 case 64: RelType = ELF::R_X86_64_PC64; break; 2608 } 2609 } else { 2610 switch (FKI.TargetSize) { 2611 default: 2612 return std::nullopt; 2613 case 8: RelType = ELF::R_X86_64_8; break; 2614 case 16: RelType = ELF::R_X86_64_16; break; 2615 case 32: RelType = ELF::R_X86_64_32; break; 2616 case 64: RelType = ELF::R_X86_64_64; break; 2617 } 2618 } 2619 2620 // Extract a symbol and an addend out of the fixup value expression. 2621 // 2622 // Only the following limited expression types are supported: 2623 // Symbol + Addend 2624 // Symbol 2625 uint64_t Addend = 0; 2626 MCSymbol *Symbol = nullptr; 2627 const MCExpr *ValueExpr = Fixup.getValue(); 2628 if (ValueExpr->getKind() == MCExpr::Binary) { 2629 const auto *BinaryExpr = cast<MCBinaryExpr>(ValueExpr); 2630 assert(BinaryExpr->getOpcode() == MCBinaryExpr::Add && 2631 "unexpected binary expression"); 2632 const MCExpr *LHS = BinaryExpr->getLHS(); 2633 assert(LHS->getKind() == MCExpr::SymbolRef && "unexpected LHS"); 2634 Symbol = const_cast<MCSymbol *>(this->getTargetSymbol(LHS)); 2635 const MCExpr *RHS = BinaryExpr->getRHS(); 2636 assert(RHS->getKind() == MCExpr::Constant && "unexpected RHS"); 2637 Addend = cast<MCConstantExpr>(RHS)->getValue(); 2638 } else { 2639 assert(ValueExpr->getKind() == MCExpr::SymbolRef && "unexpected value"); 2640 Symbol = const_cast<MCSymbol *>(this->getTargetSymbol(ValueExpr)); 2641 } 2642 2643 return Relocation({RelOffset, Symbol, RelType, Addend, 0}); 2644 } 2645 2646 bool replaceImmWithSymbolRef(MCInst &Inst, const MCSymbol *Symbol, 2647 int64_t Addend, MCContext *Ctx, int64_t &Value, 2648 uint64_t RelType) const override { 2649 unsigned ImmOpNo = -1U; 2650 2651 for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst); 2652 ++Index) { 2653 if (Inst.getOperand(Index).isImm()) { 2654 ImmOpNo = Index; 2655 // TODO: this is a bit hacky. It finds the correct operand by 2656 // searching for a specific immediate value. If no value is 2657 // provided it defaults to the last immediate operand found. 2658 // This could lead to unexpected results if the instruction 2659 // has more than one immediate with the same value. 2660 if (Inst.getOperand(ImmOpNo).getImm() == Value) 2661 break; 2662 } 2663 } 2664 2665 if (ImmOpNo == -1U) 2666 return false; 2667 2668 Value = Inst.getOperand(ImmOpNo).getImm(); 2669 2670 setOperandToSymbolRef(Inst, ImmOpNo, Symbol, Addend, Ctx, RelType); 2671 2672 return true; 2673 } 2674 2675 bool replaceRegWithImm(MCInst &Inst, unsigned Register, 2676 int64_t Imm) const override { 2677 2678 enum CheckSignExt : uint8_t { 2679 NOCHECK = 0, 2680 CHECK8, 2681 CHECK32, 2682 }; 2683 2684 using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>; 2685 struct InstInfo { 2686 // Size in bytes that Inst loads from memory. 2687 uint8_t DataSize; 2688 2689 // True when the target operand has to be duplicated because the opcode 2690 // expects a LHS operand. 2691 bool HasLHS; 2692 2693 // List of checks and corresponding opcodes to be used. We try to use the 2694 // smallest possible immediate value when various sizes are available, 2695 // hence we may need to check whether a larger constant fits in a smaller 2696 // immediate. 2697 CheckList Checks; 2698 }; 2699 2700 InstInfo I; 2701 2702 switch (Inst.getOpcode()) { 2703 default: { 2704 switch (getPushSize(Inst)) { 2705 2706 case 2: I = {2, false, {{CHECK8, X86::PUSH16i8}, {NOCHECK, X86::PUSHi16}}}; break; 2707 case 4: I = {4, false, {{CHECK8, X86::PUSH32i8}, {NOCHECK, X86::PUSHi32}}}; break; 2708 case 8: I = {8, false, {{CHECK8, X86::PUSH64i8}, 2709 {CHECK32, X86::PUSH64i32}, 2710 {NOCHECK, Inst.getOpcode()}}}; break; 2711 default: return false; 2712 } 2713 break; 2714 } 2715 2716 // MOV 2717 case X86::MOV8rr: I = {1, false, {{NOCHECK, X86::MOV8ri}}}; break; 2718 case X86::MOV16rr: I = {2, false, {{NOCHECK, X86::MOV16ri}}}; break; 2719 case X86::MOV32rr: I = {4, false, {{NOCHECK, X86::MOV32ri}}}; break; 2720 case X86::MOV64rr: I = {8, false, {{CHECK32, X86::MOV64ri32}, 2721 {NOCHECK, X86::MOV64ri}}}; break; 2722 2723 case X86::MOV8mr: I = {1, false, {{NOCHECK, X86::MOV8mi}}}; break; 2724 case X86::MOV16mr: I = {2, false, {{NOCHECK, X86::MOV16mi}}}; break; 2725 case X86::MOV32mr: I = {4, false, {{NOCHECK, X86::MOV32mi}}}; break; 2726 case X86::MOV64mr: I = {8, false, {{CHECK32, X86::MOV64mi32}, 2727 {NOCHECK, X86::MOV64mr}}}; break; 2728 2729 // MOVZX 2730 case X86::MOVZX16rr8: I = {1, false, {{NOCHECK, X86::MOV16ri}}}; break; 2731 case X86::MOVZX32rr8: I = {1, false, {{NOCHECK, X86::MOV32ri}}}; break; 2732 case X86::MOVZX32rr16: I = {2, false, {{NOCHECK, X86::MOV32ri}}}; break; 2733 2734 // CMP 2735 case X86::CMP8rr: I = {1, false, {{NOCHECK, X86::CMP8ri}}}; break; 2736 case X86::CMP16rr: I = {2, false, {{CHECK8, X86::CMP16ri8}, 2737 {NOCHECK, X86::CMP16ri}}}; break; 2738 case X86::CMP32rr: I = {4, false, {{CHECK8, X86::CMP32ri8}, 2739 {NOCHECK, X86::CMP32ri}}}; break; 2740 case X86::CMP64rr: I = {8, false, {{CHECK8, X86::CMP64ri8}, 2741 {CHECK32, X86::CMP64ri32}, 2742 {NOCHECK, X86::CMP64rr}}}; break; 2743 2744 // TEST 2745 case X86::TEST8rr: I = {1, false, {{NOCHECK, X86::TEST8ri}}}; break; 2746 case X86::TEST16rr: I = {2, false, {{NOCHECK, X86::TEST16ri}}}; break; 2747 case X86::TEST32rr: I = {4, false, {{NOCHECK, X86::TEST32ri}}}; break; 2748 case X86::TEST64rr: I = {8, false, {{CHECK32, X86::TEST64ri32}, 2749 {NOCHECK, X86::TEST64rr}}}; break; 2750 2751 // ADD 2752 case X86::ADD8rr: I = {1, true, {{NOCHECK, X86::ADD8ri}}}; break; 2753 case X86::ADD16rr: I = {2, true, {{CHECK8, X86::ADD16ri8}, 2754 {NOCHECK, X86::ADD16ri}}}; break; 2755 case X86::ADD32rr: I = {4, true, {{CHECK8, X86::ADD32ri8}, 2756 {NOCHECK, X86::ADD32ri}}}; break; 2757 case X86::ADD64rr: I = {8, true, {{CHECK8, X86::ADD64ri8}, 2758 {CHECK32, X86::ADD64ri32}, 2759 {NOCHECK, X86::ADD64rr}}}; break; 2760 2761 // SUB 2762 case X86::SUB8rr: I = {1, true, {{NOCHECK, X86::SUB8ri}}}; break; 2763 case X86::SUB16rr: I = {2, true, {{CHECK8, X86::SUB16ri8}, 2764 {NOCHECK, X86::SUB16ri}}}; break; 2765 case X86::SUB32rr: I = {4, true, {{CHECK8, X86::SUB32ri8}, 2766 {NOCHECK, X86::SUB32ri}}}; break; 2767 case X86::SUB64rr: I = {8, true, {{CHECK8, X86::SUB64ri8}, 2768 {CHECK32, X86::SUB64ri32}, 2769 {NOCHECK, X86::SUB64rr}}}; break; 2770 2771 // AND 2772 case X86::AND8rr: I = {1, true, {{NOCHECK, X86::AND8ri}}}; break; 2773 case X86::AND16rr: I = {2, true, {{CHECK8, X86::AND16ri8}, 2774 {NOCHECK, X86::AND16ri}}}; break; 2775 case X86::AND32rr: I = {4, true, {{CHECK8, X86::AND32ri8}, 2776 {NOCHECK, X86::AND32ri}}}; break; 2777 case X86::AND64rr: I = {8, true, {{CHECK8, X86::AND64ri8}, 2778 {CHECK32, X86::AND64ri32}, 2779 {NOCHECK, X86::AND64rr}}}; break; 2780 2781 // OR 2782 case X86::OR8rr: I = {1, true, {{NOCHECK, X86::OR8ri}}}; break; 2783 case X86::OR16rr: I = {2, true, {{CHECK8, X86::OR16ri8}, 2784 {NOCHECK, X86::OR16ri}}}; break; 2785 case X86::OR32rr: I = {4, true, {{CHECK8, X86::OR32ri8}, 2786 {NOCHECK, X86::OR32ri}}}; break; 2787 case X86::OR64rr: I = {8, true, {{CHECK8, X86::OR64ri8}, 2788 {CHECK32, X86::OR64ri32}, 2789 {NOCHECK, X86::OR64rr}}}; break; 2790 2791 // XOR 2792 case X86::XOR8rr: I = {1, true, {{NOCHECK, X86::XOR8ri}}}; break; 2793 case X86::XOR16rr: I = {2, true, {{CHECK8, X86::XOR16ri8}, 2794 {NOCHECK, X86::XOR16ri}}}; break; 2795 case X86::XOR32rr: I = {4, true, {{CHECK8, X86::XOR32ri8}, 2796 {NOCHECK, X86::XOR32ri}}}; break; 2797 case X86::XOR64rr: I = {8, true, {{CHECK8, X86::XOR64ri8}, 2798 {CHECK32, X86::XOR64ri32}, 2799 {NOCHECK, X86::XOR64rr}}}; break; 2800 } 2801 2802 // Compute the new opcode. 2803 unsigned NewOpcode = 0; 2804 for (const std::pair<CheckSignExt, unsigned> &Check : I.Checks) { 2805 NewOpcode = Check.second; 2806 if (Check.first == NOCHECK) 2807 break; 2808 if (Check.first == CHECK8 && isInt<8>(Imm)) 2809 break; 2810 if (Check.first == CHECK32 && isInt<32>(Imm)) 2811 break; 2812 } 2813 if (NewOpcode == Inst.getOpcode()) 2814 return false; 2815 2816 const MCInstrDesc &InstDesc = Info->get(Inst.getOpcode()); 2817 2818 unsigned NumFound = 0; 2819 for (unsigned Index = InstDesc.getNumDefs() + (I.HasLHS ? 1 : 0), 2820 E = InstDesc.getNumOperands(); 2821 Index != E; ++Index) 2822 if (Inst.getOperand(Index).isReg() && 2823 Inst.getOperand(Index).getReg() == Register) 2824 NumFound++; 2825 2826 if (NumFound != 1) 2827 return false; 2828 2829 MCOperand TargetOp = Inst.getOperand(0); 2830 Inst.clear(); 2831 Inst.setOpcode(NewOpcode); 2832 Inst.addOperand(TargetOp); 2833 if (I.HasLHS) 2834 Inst.addOperand(TargetOp); 2835 Inst.addOperand(MCOperand::createImm(Imm)); 2836 2837 return true; 2838 } 2839 2840 bool replaceRegWithReg(MCInst &Inst, unsigned ToReplace, 2841 unsigned ReplaceWith) const override { 2842 2843 // Get the HasLHS value so that iteration can be done 2844 bool HasLHS; 2845 if (X86::isAND(Inst.getOpcode()) || X86::isADD(Inst.getOpcode()) || 2846 X86::isSUB(Inst.getOpcode())) { 2847 HasLHS = true; 2848 } else if (isPop(Inst) || isPush(Inst) || X86::isCMP(Inst.getOpcode()) || 2849 X86::isTEST(Inst.getOpcode())) { 2850 HasLHS = false; 2851 } else { 2852 switch (Inst.getOpcode()) { 2853 case X86::MOV8rr: 2854 case X86::MOV8rm: 2855 case X86::MOV8mr: 2856 case X86::MOV8ri: 2857 case X86::MOV16rr: 2858 case X86::MOV16rm: 2859 case X86::MOV16mr: 2860 case X86::MOV16ri: 2861 case X86::MOV32rr: 2862 case X86::MOV32rm: 2863 case X86::MOV32mr: 2864 case X86::MOV32ri: 2865 case X86::MOV64rr: 2866 case X86::MOV64rm: 2867 case X86::MOV64mr: 2868 case X86::MOV64ri: 2869 case X86::MOVZX16rr8: 2870 case X86::MOVZX32rr8: 2871 case X86::MOVZX32rr16: 2872 case X86::MOVSX32rm8: 2873 case X86::MOVSX32rr8: 2874 case X86::MOVSX64rm32: 2875 case X86::LEA64r: 2876 HasLHS = false; 2877 break; 2878 default: 2879 return false; 2880 } 2881 } 2882 2883 const MCInstrDesc &InstDesc = Info->get(Inst.getOpcode()); 2884 2885 bool FoundOne = false; 2886 2887 // Iterate only through src operands that arent also dest operands 2888 for (unsigned Index = InstDesc.getNumDefs() + (HasLHS ? 1 : 0), 2889 E = InstDesc.getNumOperands(); 2890 Index != E; ++Index) { 2891 BitVector RegAliases = getAliases(ToReplace, true); 2892 if (!Inst.getOperand(Index).isReg() || 2893 !RegAliases.test(Inst.getOperand(Index).getReg())) 2894 continue; 2895 // Resize register if needed 2896 unsigned SizedReplaceWith = getAliasSized( 2897 ReplaceWith, getRegSize(Inst.getOperand(Index).getReg())); 2898 MCOperand NewOperand = MCOperand::createReg(SizedReplaceWith); 2899 Inst.getOperand(Index) = NewOperand; 2900 FoundOne = true; 2901 } 2902 2903 // Return true if at least one operand was replaced 2904 return FoundOne; 2905 } 2906 2907 bool createUncondBranch(MCInst &Inst, const MCSymbol *TBB, 2908 MCContext *Ctx) const override { 2909 Inst.setOpcode(X86::JMP_1); 2910 Inst.addOperand(MCOperand::createExpr( 2911 MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx))); 2912 return true; 2913 } 2914 2915 bool createCall(MCInst &Inst, const MCSymbol *Target, 2916 MCContext *Ctx) override { 2917 Inst.setOpcode(X86::CALL64pcrel32); 2918 Inst.addOperand(MCOperand::createExpr( 2919 MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx))); 2920 return true; 2921 } 2922 2923 bool createTailCall(MCInst &Inst, const MCSymbol *Target, 2924 MCContext *Ctx) override { 2925 return createDirectCall(Inst, Target, Ctx, /*IsTailCall*/ true); 2926 } 2927 2928 void createLongTailCall(InstructionListType &Seq, const MCSymbol *Target, 2929 MCContext *Ctx) override { 2930 Seq.clear(); 2931 Seq.emplace_back(); 2932 createDirectCall(Seq.back(), Target, Ctx, /*IsTailCall*/ true); 2933 } 2934 2935 bool createTrap(MCInst &Inst) const override { 2936 Inst.clear(); 2937 Inst.setOpcode(X86::TRAP); 2938 return true; 2939 } 2940 2941 bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, 2942 MCContext *Ctx) const override { 2943 unsigned InvCC = getInvertedCondCode(getCondCode(Inst)); 2944 assert(InvCC != X86::COND_INVALID && "invalid branch instruction"); 2945 Inst.getOperand(Info->get(Inst.getOpcode()).NumOperands - 1).setImm(InvCC); 2946 Inst.getOperand(0) = MCOperand::createExpr( 2947 MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx)); 2948 return true; 2949 } 2950 2951 bool replaceBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx, 2952 unsigned CC) const override { 2953 if (CC == X86::COND_INVALID) 2954 return false; 2955 Inst.getOperand(Info->get(Inst.getOpcode()).NumOperands - 1).setImm(CC); 2956 Inst.getOperand(0) = MCOperand::createExpr( 2957 MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx)); 2958 return true; 2959 } 2960 2961 unsigned getCanonicalBranchCondCode(unsigned CC) const override { 2962 switch (CC) { 2963 default: return X86::COND_INVALID; 2964 2965 case X86::COND_E: return X86::COND_E; 2966 case X86::COND_NE: return X86::COND_E; 2967 2968 case X86::COND_L: return X86::COND_L; 2969 case X86::COND_GE: return X86::COND_L; 2970 2971 case X86::COND_LE: return X86::COND_G; 2972 case X86::COND_G: return X86::COND_G; 2973 2974 case X86::COND_B: return X86::COND_B; 2975 case X86::COND_AE: return X86::COND_B; 2976 2977 case X86::COND_BE: return X86::COND_A; 2978 case X86::COND_A: return X86::COND_A; 2979 2980 case X86::COND_S: return X86::COND_S; 2981 case X86::COND_NS: return X86::COND_S; 2982 2983 case X86::COND_P: return X86::COND_P; 2984 case X86::COND_NP: return X86::COND_P; 2985 2986 case X86::COND_O: return X86::COND_O; 2987 case X86::COND_NO: return X86::COND_O; 2988 } 2989 } 2990 2991 bool replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, 2992 MCContext *Ctx) const override { 2993 assert((isCall(Inst) || isBranch(Inst)) && !isIndirectBranch(Inst) && 2994 "Invalid instruction"); 2995 Inst.getOperand(0) = MCOperand::createExpr( 2996 MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx)); 2997 return true; 2998 } 2999 3000 MCPhysReg getX86R11() const override { return X86::R11; } 3001 3002 MCPhysReg getIntArgRegister(unsigned ArgNo) const override { 3003 // FIXME: this should depend on the calling convention. 3004 switch (ArgNo) { 3005 case 0: return X86::RDI; 3006 case 1: return X86::RSI; 3007 case 2: return X86::RDX; 3008 case 3: return X86::RCX; 3009 case 4: return X86::R8; 3010 case 5: return X86::R9; 3011 default: return getNoRegister(); 3012 } 3013 } 3014 3015 void createPause(MCInst &Inst) const override { 3016 Inst.clear(); 3017 Inst.setOpcode(X86::PAUSE); 3018 } 3019 3020 void createLfence(MCInst &Inst) const override { 3021 Inst.clear(); 3022 Inst.setOpcode(X86::LFENCE); 3023 } 3024 3025 bool createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx, 3026 bool IsTailCall) override { 3027 Inst.clear(); 3028 Inst.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32); 3029 Inst.addOperand(MCOperand::createExpr( 3030 MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx))); 3031 if (IsTailCall) 3032 setTailCall(Inst); 3033 return true; 3034 } 3035 3036 void createShortJmp(InstructionListType &Seq, const MCSymbol *Target, 3037 MCContext *Ctx, bool IsTailCall) override { 3038 Seq.clear(); 3039 MCInst Inst; 3040 Inst.setOpcode(X86::JMP_1); 3041 Inst.addOperand(MCOperand::createExpr( 3042 MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx))); 3043 if (IsTailCall) 3044 setTailCall(Inst); 3045 Seq.emplace_back(Inst); 3046 } 3047 3048 bool isConditionalMove(const MCInst &Inst) const override { 3049 unsigned OpCode = Inst.getOpcode(); 3050 return (OpCode == X86::CMOV16rr || OpCode == X86::CMOV32rr || 3051 OpCode == X86::CMOV64rr); 3052 } 3053 3054 bool isBranchOnMem(const MCInst &Inst) const override { 3055 unsigned OpCode = Inst.getOpcode(); 3056 if (OpCode == X86::CALL64m || (OpCode == X86::JMP32m && isTailCall(Inst)) || 3057 OpCode == X86::JMP64m) 3058 return true; 3059 3060 return false; 3061 } 3062 3063 bool isBranchOnReg(const MCInst &Inst) const override { 3064 unsigned OpCode = Inst.getOpcode(); 3065 if (OpCode == X86::CALL64r || (OpCode == X86::JMP32r && isTailCall(Inst)) || 3066 OpCode == X86::JMP64r) 3067 return true; 3068 3069 return false; 3070 } 3071 3072 void createPushRegister(MCInst &Inst, MCPhysReg Reg, 3073 unsigned Size) const override { 3074 Inst.clear(); 3075 unsigned NewOpcode = 0; 3076 if (Reg == X86::EFLAGS) { 3077 switch (Size) { 3078 case 2: NewOpcode = X86::PUSHF16; break; 3079 case 4: NewOpcode = X86::PUSHF32; break; 3080 case 8: NewOpcode = X86::PUSHF64; break; 3081 default: 3082 llvm_unreachable("Unexpected size"); 3083 } 3084 Inst.setOpcode(NewOpcode); 3085 return; 3086 } 3087 switch (Size) { 3088 case 2: NewOpcode = X86::PUSH16r; break; 3089 case 4: NewOpcode = X86::PUSH32r; break; 3090 case 8: NewOpcode = X86::PUSH64r; break; 3091 default: 3092 llvm_unreachable("Unexpected size"); 3093 } 3094 Inst.setOpcode(NewOpcode); 3095 Inst.addOperand(MCOperand::createReg(Reg)); 3096 } 3097 3098 void createPopRegister(MCInst &Inst, MCPhysReg Reg, 3099 unsigned Size) const override { 3100 Inst.clear(); 3101 unsigned NewOpcode = 0; 3102 if (Reg == X86::EFLAGS) { 3103 switch (Size) { 3104 case 2: NewOpcode = X86::POPF16; break; 3105 case 4: NewOpcode = X86::POPF32; break; 3106 case 8: NewOpcode = X86::POPF64; break; 3107 default: 3108 llvm_unreachable("Unexpected size"); 3109 } 3110 Inst.setOpcode(NewOpcode); 3111 return; 3112 } 3113 switch (Size) { 3114 case 2: NewOpcode = X86::POP16r; break; 3115 case 4: NewOpcode = X86::POP32r; break; 3116 case 8: NewOpcode = X86::POP64r; break; 3117 default: 3118 llvm_unreachable("Unexpected size"); 3119 } 3120 Inst.setOpcode(NewOpcode); 3121 Inst.addOperand(MCOperand::createReg(Reg)); 3122 } 3123 3124 void createPushFlags(MCInst &Inst, unsigned Size) const override { 3125 return createPushRegister(Inst, X86::EFLAGS, Size); 3126 } 3127 3128 void createPopFlags(MCInst &Inst, unsigned Size) const override { 3129 return createPopRegister(Inst, X86::EFLAGS, Size); 3130 } 3131 3132 void createAddRegImm(MCInst &Inst, MCPhysReg Reg, int64_t Value, 3133 unsigned Size) const { 3134 unsigned int Opcode; 3135 switch (Size) { 3136 case 1: Opcode = X86::ADD8ri; break; 3137 case 2: Opcode = X86::ADD16ri; break; 3138 case 4: Opcode = X86::ADD32ri; break; 3139 default: 3140 llvm_unreachable("Unexpected size"); 3141 } 3142 Inst.setOpcode(Opcode); 3143 Inst.clear(); 3144 Inst.addOperand(MCOperand::createReg(Reg)); 3145 Inst.addOperand(MCOperand::createReg(Reg)); 3146 Inst.addOperand(MCOperand::createImm(Value)); 3147 } 3148 3149 void createClearRegWithNoEFlagsUpdate(MCInst &Inst, MCPhysReg Reg, 3150 unsigned Size) const { 3151 unsigned int Opcode; 3152 switch (Size) { 3153 case 1: Opcode = X86::MOV8ri; break; 3154 case 2: Opcode = X86::MOV16ri; break; 3155 case 4: Opcode = X86::MOV32ri; break; 3156 // Writing to a 32-bit register always zeros the upper 32 bits of the 3157 // full-width register 3158 case 8: 3159 Opcode = X86::MOV32ri; 3160 Reg = getAliasSized(Reg, 4); 3161 break; 3162 default: 3163 llvm_unreachable("Unexpected size"); 3164 } 3165 Inst.setOpcode(Opcode); 3166 Inst.clear(); 3167 Inst.addOperand(MCOperand::createReg(Reg)); 3168 Inst.addOperand(MCOperand::createImm(0)); 3169 } 3170 3171 void createX86SaveOVFlagToRegister(MCInst &Inst, MCPhysReg Reg) const { 3172 Inst.setOpcode(X86::SETCCr); 3173 Inst.clear(); 3174 Inst.addOperand(MCOperand::createReg(Reg)); 3175 Inst.addOperand(MCOperand::createImm(X86::COND_O)); 3176 } 3177 3178 void createX86Lahf(MCInst &Inst) const { 3179 Inst.setOpcode(X86::LAHF); 3180 Inst.clear(); 3181 } 3182 3183 void createX86Sahf(MCInst &Inst) const { 3184 Inst.setOpcode(X86::SAHF); 3185 Inst.clear(); 3186 } 3187 3188 void createInstrIncMemory(InstructionListType &Instrs, const MCSymbol *Target, 3189 MCContext *Ctx, bool IsLeaf) const override { 3190 unsigned int I = 0; 3191 3192 Instrs.resize(IsLeaf ? 13 : 11); 3193 // Don't clobber application red zone (ABI dependent) 3194 if (IsLeaf) 3195 createStackPointerIncrement(Instrs[I++], 128, 3196 /*NoFlagsClobber=*/true); 3197 3198 // Performance improvements based on the optimization discussed at 3199 // https://reviews.llvm.org/D6629 3200 // LAHF/SAHF are used instead of PUSHF/POPF 3201 // PUSHF 3202 createPushRegister(Instrs[I++], X86::RAX, 8); 3203 createClearRegWithNoEFlagsUpdate(Instrs[I++], X86::RAX, 8); 3204 createX86Lahf(Instrs[I++]); 3205 createPushRegister(Instrs[I++], X86::RAX, 8); 3206 createClearRegWithNoEFlagsUpdate(Instrs[I++], X86::RAX, 8); 3207 createX86SaveOVFlagToRegister(Instrs[I++], X86::AL); 3208 // LOCK INC 3209 createIncMemory(Instrs[I++], Target, Ctx); 3210 // POPF 3211 createAddRegImm(Instrs[I++], X86::AL, 127, 1); 3212 createPopRegister(Instrs[I++], X86::RAX, 8); 3213 createX86Sahf(Instrs[I++]); 3214 createPopRegister(Instrs[I++], X86::RAX, 8); 3215 3216 if (IsLeaf) 3217 createStackPointerDecrement(Instrs[I], 128, 3218 /*NoFlagsClobber=*/true); 3219 } 3220 3221 void createSwap(MCInst &Inst, MCPhysReg Source, MCPhysReg MemBaseReg, 3222 int64_t Disp) const { 3223 Inst.setOpcode(X86::XCHG64rm); 3224 Inst.addOperand(MCOperand::createReg(Source)); 3225 Inst.addOperand(MCOperand::createReg(Source)); 3226 Inst.addOperand(MCOperand::createReg(MemBaseReg)); // BaseReg 3227 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 3228 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 3229 Inst.addOperand(MCOperand::createImm(Disp)); // Displacement 3230 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 3231 } 3232 3233 void createIndirectBranch(MCInst &Inst, MCPhysReg MemBaseReg, 3234 int64_t Disp) const { 3235 Inst.setOpcode(X86::JMP64m); 3236 Inst.addOperand(MCOperand::createReg(MemBaseReg)); // BaseReg 3237 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 3238 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 3239 Inst.addOperand(MCOperand::createImm(Disp)); // Displacement 3240 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 3241 } 3242 3243 InstructionListType createInstrumentedIndirectCall(const MCInst &CallInst, 3244 bool TailCall, 3245 MCSymbol *HandlerFuncAddr, 3246 int CallSiteID, 3247 MCContext *Ctx) override { 3248 // Check if the target address expression used in the original indirect call 3249 // uses the stack pointer, which we are going to clobber. 3250 static BitVector SPAliases(getAliases(X86::RSP)); 3251 bool UsesSP = false; 3252 // Skip defs. 3253 for (unsigned I = Info->get(CallInst.getOpcode()).getNumDefs(), 3254 E = MCPlus::getNumPrimeOperands(CallInst); 3255 I != E; ++I) { 3256 const MCOperand &Operand = CallInst.getOperand(I); 3257 if (Operand.isReg() && SPAliases[Operand.getReg()]) { 3258 UsesSP = true; 3259 break; 3260 } 3261 } 3262 3263 InstructionListType Insts; 3264 MCPhysReg TempReg = getIntArgRegister(0); 3265 // Code sequence used to enter indirect call instrumentation helper: 3266 // push %rdi 3267 // add $8, %rsp ;; $rsp may be used in target, so fix it to prev val 3268 // movq target, %rdi ;; via convertIndirectCallTargetToLoad 3269 // sub $8, %rsp ;; restore correct stack value 3270 // push %rdi 3271 // movq $CallSiteID, %rdi 3272 // push %rdi 3273 // callq/jmp HandlerFuncAddr 3274 Insts.emplace_back(); 3275 createPushRegister(Insts.back(), TempReg, 8); 3276 if (UsesSP) { // Only adjust SP if we really need to 3277 Insts.emplace_back(); 3278 createStackPointerDecrement(Insts.back(), 8, /*NoFlagsClobber=*/false); 3279 } 3280 Insts.emplace_back(CallInst); 3281 // Insts.back() and CallInst now share the same annotation instruction. 3282 // Strip it from Insts.back(), only preserving tail call annotation. 3283 stripAnnotations(Insts.back(), /*KeepTC=*/true); 3284 convertIndirectCallToLoad(Insts.back(), TempReg); 3285 if (UsesSP) { 3286 Insts.emplace_back(); 3287 createStackPointerIncrement(Insts.back(), 8, /*NoFlagsClobber=*/false); 3288 } 3289 Insts.emplace_back(); 3290 createPushRegister(Insts.back(), TempReg, 8); 3291 Insts.emplace_back(); 3292 createLoadImmediate(Insts.back(), TempReg, CallSiteID); 3293 Insts.emplace_back(); 3294 createPushRegister(Insts.back(), TempReg, 8); 3295 Insts.emplace_back(); 3296 createDirectCall(Insts.back(), HandlerFuncAddr, Ctx, 3297 /*TailCall=*/TailCall); 3298 // Carry over metadata 3299 for (int I = MCPlus::getNumPrimeOperands(CallInst), 3300 E = CallInst.getNumOperands(); 3301 I != E; ++I) 3302 Insts.back().addOperand(CallInst.getOperand(I)); 3303 3304 return Insts; 3305 } 3306 3307 InstructionListType createInstrumentedIndCallHandlerExitBB() const override { 3308 const MCPhysReg TempReg = getIntArgRegister(0); 3309 // We just need to undo the sequence created for every ind call in 3310 // instrumentIndirectTarget(), which can be accomplished minimally with: 3311 // popfq 3312 // pop %rdi 3313 // add $16, %rsp 3314 // xchg (%rsp), %rdi 3315 // jmp *-8(%rsp) 3316 InstructionListType Insts(5); 3317 createPopFlags(Insts[0], 8); 3318 createPopRegister(Insts[1], TempReg, 8); 3319 createStackPointerDecrement(Insts[2], 16, /*NoFlagsClobber=*/false); 3320 createSwap(Insts[3], TempReg, X86::RSP, 0); 3321 createIndirectBranch(Insts[4], X86::RSP, -8); 3322 return Insts; 3323 } 3324 3325 InstructionListType 3326 createInstrumentedIndTailCallHandlerExitBB() const override { 3327 const MCPhysReg TempReg = getIntArgRegister(0); 3328 // Same thing as above, but for tail calls 3329 // popfq 3330 // add $16, %rsp 3331 // pop %rdi 3332 // jmp *-16(%rsp) 3333 InstructionListType Insts(4); 3334 createPopFlags(Insts[0], 8); 3335 createStackPointerDecrement(Insts[1], 16, /*NoFlagsClobber=*/false); 3336 createPopRegister(Insts[2], TempReg, 8); 3337 createIndirectBranch(Insts[3], X86::RSP, -16); 3338 return Insts; 3339 } 3340 3341 InstructionListType 3342 createInstrumentedIndCallHandlerEntryBB(const MCSymbol *InstrTrampoline, 3343 const MCSymbol *IndCallHandler, 3344 MCContext *Ctx) override { 3345 const MCPhysReg TempReg = getIntArgRegister(0); 3346 // Code sequence used to check whether InstrTampoline was initialized 3347 // and call it if so, returns via IndCallHandler. 3348 // pushfq 3349 // mov InstrTrampoline,%rdi 3350 // cmp $0x0,%rdi 3351 // je IndCallHandler 3352 // callq *%rdi 3353 // jmpq IndCallHandler 3354 InstructionListType Insts; 3355 Insts.emplace_back(); 3356 createPushFlags(Insts.back(), 8); 3357 Insts.emplace_back(); 3358 createMove(Insts.back(), InstrTrampoline, TempReg, Ctx); 3359 InstructionListType cmpJmp = createCmpJE(TempReg, 0, IndCallHandler, Ctx); 3360 Insts.insert(Insts.end(), cmpJmp.begin(), cmpJmp.end()); 3361 Insts.emplace_back(); 3362 Insts.back().setOpcode(X86::CALL64r); 3363 Insts.back().addOperand(MCOperand::createReg(TempReg)); 3364 Insts.emplace_back(); 3365 createDirectCall(Insts.back(), IndCallHandler, Ctx, /*IsTailCall*/ true); 3366 return Insts; 3367 } 3368 3369 InstructionListType createNumCountersGetter(MCContext *Ctx) const override { 3370 InstructionListType Insts(2); 3371 MCSymbol *NumLocs = Ctx->getOrCreateSymbol("__bolt_num_counters"); 3372 createMove(Insts[0], NumLocs, X86::EAX, Ctx); 3373 createReturn(Insts[1]); 3374 return Insts; 3375 } 3376 3377 InstructionListType 3378 createInstrLocationsGetter(MCContext *Ctx) const override { 3379 InstructionListType Insts(2); 3380 MCSymbol *Locs = Ctx->getOrCreateSymbol("__bolt_instr_locations"); 3381 createLea(Insts[0], Locs, X86::EAX, Ctx); 3382 createReturn(Insts[1]); 3383 return Insts; 3384 } 3385 3386 InstructionListType createInstrTablesGetter(MCContext *Ctx) const override { 3387 InstructionListType Insts(2); 3388 MCSymbol *Locs = Ctx->getOrCreateSymbol("__bolt_instr_tables"); 3389 createLea(Insts[0], Locs, X86::EAX, Ctx); 3390 createReturn(Insts[1]); 3391 return Insts; 3392 } 3393 3394 InstructionListType createInstrNumFuncsGetter(MCContext *Ctx) const override { 3395 InstructionListType Insts(2); 3396 MCSymbol *NumFuncs = Ctx->getOrCreateSymbol("__bolt_instr_num_funcs"); 3397 createMove(Insts[0], NumFuncs, X86::EAX, Ctx); 3398 createReturn(Insts[1]); 3399 return Insts; 3400 } 3401 3402 InstructionListType createSymbolTrampoline(const MCSymbol *TgtSym, 3403 MCContext *Ctx) const override { 3404 InstructionListType Insts(1); 3405 createUncondBranch(Insts[0], TgtSym, Ctx); 3406 return Insts; 3407 } 3408 3409 InstructionListType createDummyReturnFunction(MCContext *Ctx) const override { 3410 InstructionListType Insts(1); 3411 createReturn(Insts[0]); 3412 return Insts; 3413 } 3414 3415 BlocksVectorTy indirectCallPromotion( 3416 const MCInst &CallInst, 3417 const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets, 3418 const std::vector<std::pair<MCSymbol *, uint64_t>> &VtableSyms, 3419 const std::vector<MCInst *> &MethodFetchInsns, 3420 const bool MinimizeCodeSize, MCContext *Ctx) override { 3421 const bool IsTailCall = isTailCall(CallInst); 3422 const bool IsJumpTable = getJumpTable(CallInst) != 0; 3423 BlocksVectorTy Results; 3424 3425 // Label for the current code block. 3426 MCSymbol *NextTarget = nullptr; 3427 3428 // The join block which contains all the instructions following CallInst. 3429 // MergeBlock remains null if CallInst is a tail call. 3430 MCSymbol *MergeBlock = nullptr; 3431 3432 unsigned FuncAddrReg = X86::R10; 3433 3434 const bool LoadElim = !VtableSyms.empty(); 3435 assert((!LoadElim || VtableSyms.size() == Targets.size()) && 3436 "There must be a vtable entry for every method " 3437 "in the targets vector."); 3438 3439 if (MinimizeCodeSize && !LoadElim) { 3440 std::set<unsigned> UsedRegs; 3441 3442 for (unsigned int I = 0; I < MCPlus::getNumPrimeOperands(CallInst); ++I) { 3443 const MCOperand &Op = CallInst.getOperand(I); 3444 if (Op.isReg()) 3445 UsedRegs.insert(Op.getReg()); 3446 } 3447 3448 if (UsedRegs.count(X86::R10) == 0) 3449 FuncAddrReg = X86::R10; 3450 else if (UsedRegs.count(X86::R11) == 0) 3451 FuncAddrReg = X86::R11; 3452 else 3453 return Results; 3454 } 3455 3456 const auto jumpToMergeBlock = [&](InstructionListType &NewCall) { 3457 assert(MergeBlock); 3458 NewCall.push_back(CallInst); 3459 MCInst &Merge = NewCall.back(); 3460 Merge.clear(); 3461 createUncondBranch(Merge, MergeBlock, Ctx); 3462 }; 3463 3464 for (unsigned int i = 0; i < Targets.size(); ++i) { 3465 Results.emplace_back(NextTarget, InstructionListType()); 3466 InstructionListType *NewCall = &Results.back().second; 3467 3468 if (MinimizeCodeSize && !LoadElim) { 3469 // Load the call target into FuncAddrReg. 3470 NewCall->push_back(CallInst); // Copy CallInst in order to get SMLoc 3471 MCInst &Target = NewCall->back(); 3472 Target.clear(); 3473 Target.setOpcode(X86::MOV64ri32); 3474 Target.addOperand(MCOperand::createReg(FuncAddrReg)); 3475 if (Targets[i].first) { 3476 // Is this OK? 3477 Target.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create( 3478 Targets[i].first, MCSymbolRefExpr::VK_None, *Ctx))); 3479 } else { 3480 const uint64_t Addr = Targets[i].second; 3481 // Immediate address is out of sign extended 32 bit range. 3482 if (int64_t(Addr) != int64_t(int32_t(Addr))) 3483 return BlocksVectorTy(); 3484 3485 Target.addOperand(MCOperand::createImm(Addr)); 3486 } 3487 3488 // Compare current call target to a specific address. 3489 NewCall->push_back(CallInst); 3490 MCInst &Compare = NewCall->back(); 3491 Compare.clear(); 3492 if (isBranchOnReg(CallInst)) 3493 Compare.setOpcode(X86::CMP64rr); 3494 else if (CallInst.getOpcode() == X86::CALL64pcrel32) 3495 Compare.setOpcode(X86::CMP64ri32); 3496 else 3497 Compare.setOpcode(X86::CMP64rm); 3498 3499 Compare.addOperand(MCOperand::createReg(FuncAddrReg)); 3500 3501 // TODO: Would be preferable to only load this value once. 3502 for (unsigned i = 0; 3503 i < Info->get(CallInst.getOpcode()).getNumOperands(); ++i) 3504 if (!CallInst.getOperand(i).isInst()) 3505 Compare.addOperand(CallInst.getOperand(i)); 3506 } else { 3507 // Compare current call target to a specific address. 3508 NewCall->push_back(CallInst); 3509 MCInst &Compare = NewCall->back(); 3510 Compare.clear(); 3511 if (isBranchOnReg(CallInst)) 3512 Compare.setOpcode(X86::CMP64ri32); 3513 else 3514 Compare.setOpcode(X86::CMP64mi32); 3515 3516 // Original call address. 3517 for (unsigned i = 0; 3518 i < Info->get(CallInst.getOpcode()).getNumOperands(); ++i) 3519 if (!CallInst.getOperand(i).isInst()) 3520 Compare.addOperand(CallInst.getOperand(i)); 3521 3522 // Target address. 3523 if (Targets[i].first || LoadElim) { 3524 const MCSymbol *Sym = 3525 LoadElim ? VtableSyms[i].first : Targets[i].first; 3526 const uint64_t Addend = LoadElim ? VtableSyms[i].second : 0; 3527 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, *Ctx); 3528 if (Addend) 3529 Expr = MCBinaryExpr::createAdd( 3530 Expr, MCConstantExpr::create(Addend, *Ctx), *Ctx); 3531 Compare.addOperand(MCOperand::createExpr(Expr)); 3532 } else { 3533 const uint64_t Addr = Targets[i].second; 3534 // Immediate address is out of sign extended 32 bit range. 3535 if (int64_t(Addr) != int64_t(int32_t(Addr))) 3536 return BlocksVectorTy(); 3537 3538 Compare.addOperand(MCOperand::createImm(Addr)); 3539 } 3540 } 3541 3542 // jump to next target compare. 3543 NextTarget = 3544 Ctx->createNamedTempSymbol(); // generate label for the next block 3545 NewCall->push_back(CallInst); 3546 3547 if (IsJumpTable) { 3548 MCInst &Je = NewCall->back(); 3549 3550 // Jump to next compare if target addresses don't match. 3551 Je.clear(); 3552 Je.setOpcode(X86::JCC_1); 3553 if (Targets[i].first) 3554 Je.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create( 3555 Targets[i].first, MCSymbolRefExpr::VK_None, *Ctx))); 3556 else 3557 Je.addOperand(MCOperand::createImm(Targets[i].second)); 3558 3559 Je.addOperand(MCOperand::createImm(X86::COND_E)); 3560 assert(!isInvoke(CallInst)); 3561 } else { 3562 MCInst &Jne = NewCall->back(); 3563 3564 // Jump to next compare if target addresses don't match. 3565 Jne.clear(); 3566 Jne.setOpcode(X86::JCC_1); 3567 Jne.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create( 3568 NextTarget, MCSymbolRefExpr::VK_None, *Ctx))); 3569 Jne.addOperand(MCOperand::createImm(X86::COND_NE)); 3570 3571 // Call specific target directly. 3572 Results.emplace_back(Ctx->createNamedTempSymbol(), 3573 InstructionListType()); 3574 NewCall = &Results.back().second; 3575 NewCall->push_back(CallInst); 3576 MCInst &CallOrJmp = NewCall->back(); 3577 3578 CallOrJmp.clear(); 3579 3580 if (MinimizeCodeSize && !LoadElim) { 3581 CallOrJmp.setOpcode(IsTailCall ? X86::JMP32r : X86::CALL64r); 3582 CallOrJmp.addOperand(MCOperand::createReg(FuncAddrReg)); 3583 } else { 3584 CallOrJmp.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32); 3585 3586 if (Targets[i].first) 3587 CallOrJmp.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create( 3588 Targets[i].first, MCSymbolRefExpr::VK_None, *Ctx))); 3589 else 3590 CallOrJmp.addOperand(MCOperand::createImm(Targets[i].second)); 3591 } 3592 if (IsTailCall) 3593 setTailCall(CallOrJmp); 3594 3595 if (CallOrJmp.getOpcode() == X86::CALL64r || 3596 CallOrJmp.getOpcode() == X86::CALL64pcrel32) { 3597 if (std::optional<uint32_t> Offset = getOffset(CallInst)) 3598 // Annotated as duplicated call 3599 setOffset(CallOrJmp, *Offset); 3600 } 3601 3602 if (isInvoke(CallInst) && !isInvoke(CallOrJmp)) { 3603 // Copy over any EH or GNU args size information from the original 3604 // call. 3605 std::optional<MCPlus::MCLandingPad> EHInfo = getEHInfo(CallInst); 3606 if (EHInfo) 3607 addEHInfo(CallOrJmp, *EHInfo); 3608 int64_t GnuArgsSize = getGnuArgsSize(CallInst); 3609 if (GnuArgsSize >= 0) 3610 addGnuArgsSize(CallOrJmp, GnuArgsSize); 3611 } 3612 3613 if (!IsTailCall) { 3614 // The fallthrough block for the most common target should be 3615 // the merge block. 3616 if (i == 0) { 3617 // Fallthrough to merge block. 3618 MergeBlock = Ctx->createNamedTempSymbol(); 3619 } else { 3620 // Insert jump to the merge block if we are not doing a fallthrough. 3621 jumpToMergeBlock(*NewCall); 3622 } 3623 } 3624 } 3625 } 3626 3627 // Cold call block. 3628 Results.emplace_back(NextTarget, InstructionListType()); 3629 InstructionListType &NewCall = Results.back().second; 3630 for (const MCInst *Inst : MethodFetchInsns) 3631 if (Inst != &CallInst) 3632 NewCall.push_back(*Inst); 3633 NewCall.push_back(CallInst); 3634 3635 // Jump to merge block from cold call block 3636 if (!IsTailCall && !IsJumpTable) { 3637 jumpToMergeBlock(NewCall); 3638 3639 // Record merge block 3640 Results.emplace_back(MergeBlock, InstructionListType()); 3641 } 3642 3643 return Results; 3644 } 3645 3646 BlocksVectorTy jumpTablePromotion( 3647 const MCInst &IJmpInst, 3648 const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets, 3649 const std::vector<MCInst *> &TargetFetchInsns, 3650 MCContext *Ctx) const override { 3651 assert(getJumpTable(IJmpInst) != 0); 3652 uint16_t IndexReg = getAnnotationAs<uint16_t>(IJmpInst, "JTIndexReg"); 3653 if (IndexReg == 0) 3654 return BlocksVectorTy(); 3655 3656 BlocksVectorTy Results; 3657 3658 // Label for the current code block. 3659 MCSymbol *NextTarget = nullptr; 3660 3661 for (unsigned int i = 0; i < Targets.size(); ++i) { 3662 Results.emplace_back(NextTarget, InstructionListType()); 3663 InstructionListType *CurBB = &Results.back().second; 3664 3665 // Compare current index to a specific index. 3666 CurBB->emplace_back(MCInst()); 3667 MCInst &CompareInst = CurBB->back(); 3668 CompareInst.setLoc(IJmpInst.getLoc()); 3669 CompareInst.setOpcode(X86::CMP64ri32); 3670 CompareInst.addOperand(MCOperand::createReg(IndexReg)); 3671 3672 const uint64_t CaseIdx = Targets[i].second; 3673 // Immediate address is out of sign extended 32 bit range. 3674 if (int64_t(CaseIdx) != int64_t(int32_t(CaseIdx))) 3675 return BlocksVectorTy(); 3676 3677 CompareInst.addOperand(MCOperand::createImm(CaseIdx)); 3678 shortenInstruction(CompareInst, *Ctx->getSubtargetInfo()); 3679 3680 // jump to next target compare. 3681 NextTarget = 3682 Ctx->createNamedTempSymbol(); // generate label for the next block 3683 CurBB->push_back(MCInst()); 3684 3685 MCInst &JEInst = CurBB->back(); 3686 JEInst.setLoc(IJmpInst.getLoc()); 3687 3688 // Jump to target if indices match 3689 JEInst.setOpcode(X86::JCC_1); 3690 JEInst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create( 3691 Targets[i].first, MCSymbolRefExpr::VK_None, *Ctx))); 3692 JEInst.addOperand(MCOperand::createImm(X86::COND_E)); 3693 } 3694 3695 // Cold call block. 3696 Results.emplace_back(NextTarget, InstructionListType()); 3697 InstructionListType &CurBB = Results.back().second; 3698 for (const MCInst *Inst : TargetFetchInsns) 3699 if (Inst != &IJmpInst) 3700 CurBB.push_back(*Inst); 3701 3702 CurBB.push_back(IJmpInst); 3703 3704 return Results; 3705 } 3706 3707 private: 3708 bool createMove(MCInst &Inst, const MCSymbol *Src, unsigned Reg, 3709 MCContext *Ctx) const { 3710 Inst.setOpcode(X86::MOV64rm); 3711 Inst.addOperand(MCOperand::createReg(Reg)); 3712 Inst.addOperand(MCOperand::createReg(X86::RIP)); // BaseReg 3713 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 3714 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 3715 Inst.addOperand(MCOperand::createExpr( 3716 MCSymbolRefExpr::create(Src, MCSymbolRefExpr::VK_None, 3717 *Ctx))); // Displacement 3718 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 3719 3720 return true; 3721 } 3722 3723 bool createLea(MCInst &Inst, const MCSymbol *Src, unsigned Reg, 3724 MCContext *Ctx) const { 3725 Inst.setOpcode(X86::LEA64r); 3726 Inst.addOperand(MCOperand::createReg(Reg)); 3727 Inst.addOperand(MCOperand::createReg(X86::RIP)); // BaseReg 3728 Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt 3729 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg 3730 Inst.addOperand(MCOperand::createExpr( 3731 MCSymbolRefExpr::create(Src, MCSymbolRefExpr::VK_None, 3732 *Ctx))); // Displacement 3733 Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg 3734 return true; 3735 } 3736 }; 3737 3738 } // namespace 3739 3740 namespace llvm { 3741 namespace bolt { 3742 3743 MCPlusBuilder *createX86MCPlusBuilder(const MCInstrAnalysis *Analysis, 3744 const MCInstrInfo *Info, 3745 const MCRegisterInfo *RegInfo) { 3746 return new X86MCPlusBuilder(Analysis, Info, RegInfo); 3747 } 3748 3749 } // namespace bolt 3750 } // namespace llvm 3751