Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //=== X86NaClRewritePAss.cpp - Rewrite instructions for NaCl SFI --*- C++ -*-=// | 1 //=== X86NaClRewritePAss.cpp - Rewrite instructions for NaCl SFI --*- C++ -*-=// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file contains a pass that ensures stores and loads and stack/frame | 10 // This file contains a pass that ensures stores and loads and stack/frame |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 // sandbox base address. | 455 // sandbox base address. |
| 456 unsigned RegTarget; | 456 unsigned RegTarget; |
| 457 if (Is64Bit) { | 457 if (Is64Bit) { |
| 458 RegTarget = (HideSandboxBase ? X86::R11 : X86::RCX); | 458 RegTarget = (HideSandboxBase ? X86::R11 : X86::RCX); |
| 459 BuildMI(MBB, MBBI, DL, TII->get(X86::POP64r), RegTarget); | 459 BuildMI(MBB, MBBI, DL, TII->get(X86::POP64r), RegTarget); |
| 460 if (Opc == X86::RETI) { | 460 if (Opc == X86::RETI) { |
| 461 BuildMI(MBB, MBBI, DL, TII->get(X86::NACL_ASPi32)) | 461 BuildMI(MBB, MBBI, DL, TII->get(X86::NACL_ASPi32)) |
| 462 .addOperand(MI.getOperand(0)) | 462 .addOperand(MI.getOperand(0)) |
| 463 .addReg(FlagUseZeroBasedSandbox ? 0 : X86::R15); | 463 .addReg(FlagUseZeroBasedSandbox ? 0 : X86::R15); |
| 464 } | 464 } |
| 465 | |
| 465 BuildMI(MBB, MBBI, DL, TII->get(X86::NACL_JMP64r)) | 466 BuildMI(MBB, MBBI, DL, TII->get(X86::NACL_JMP64r)) |
| 466 .addReg(RegTarget) | 467 .addReg(getX86SubSuperRegister(RegTarget, MVT::i32, false)) |
| 467 .addReg(FlagUseZeroBasedSandbox ? 0 : X86::R15); | 468 .addReg(FlagUseZeroBasedSandbox ? 0 : X86::R15); |
| 468 } else { | 469 } else { |
| 469 RegTarget = X86::ECX; | 470 RegTarget = X86::ECX; |
| 470 BuildMI(MBB, MBBI, DL, TII->get(X86::POP32r), RegTarget); | 471 BuildMI(MBB, MBBI, DL, TII->get(X86::POP32r), RegTarget); |
| 471 if (Opc == X86::RETI) { | 472 if (Opc == X86::RETI) { |
| 472 BuildMI(MBB, MBBI, DL, TII->get(X86::ADD32ri), X86::ESP) | 473 BuildMI(MBB, MBBI, DL, TII->get(X86::ADD32ri), X86::ESP) |
| 473 .addReg(X86::ESP) | 474 .addReg(X86::ESP) |
| 474 .addOperand(MI.getOperand(0)); | 475 .addOperand(MI.getOperand(0)); |
| 475 } | 476 } |
| 476 BuildMI(MBB, MBBI, DL, TII->get(X86::NACL_JMP32r)) | 477 BuildMI(MBB, MBBI, DL, TII->get(X86::NACL_JMP32r)) |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 568 bool X86NaClRewritePass::ApplyRewrites(MachineBasicBlock &MBB, | 569 bool X86NaClRewritePass::ApplyRewrites(MachineBasicBlock &MBB, |
| 569 MachineBasicBlock::iterator MBBI) { | 570 MachineBasicBlock::iterator MBBI) { |
| 570 MachineInstr &MI = *MBBI; | 571 MachineInstr &MI = *MBBI; |
| 571 DebugLoc DL = MI.getDebugLoc(); | 572 DebugLoc DL = MI.getDebugLoc(); |
| 572 unsigned Opc = MI.getOpcode(); | 573 unsigned Opc = MI.getOpcode(); |
| 573 | 574 |
| 574 // These direct jumps need their opcode rewritten | 575 // These direct jumps need their opcode rewritten |
| 575 // and variable operands removed. | 576 // and variable operands removed. |
| 576 unsigned NewOpc = 0; | 577 unsigned NewOpc = 0; |
| 577 switch (Opc) { | 578 switch (Opc) { |
| 578 case X86::CALLpcrel32 : NewOpc = X86::NACL_CALL32d; break; | 579 // 32-bit direct calls are handled unmodified by the assemblers |
| 580 case X86::CALLpcrel32 : return true; | |
| 579 case X86::TAILJMPd : NewOpc = X86::JMP_4; break; | 581 case X86::TAILJMPd : NewOpc = X86::JMP_4; break; |
| 580 case X86::NACL_CG_TAILJMPd64 : NewOpc = X86::JMP_4; break; | 582 case X86::NACL_CG_TAILJMPd64 : NewOpc = X86::JMP_4; break; |
| 581 case X86::NACL_CG_CALL64pcrel32: NewOpc = X86::NACL_CALL64d; break; | 583 case X86::NACL_CG_CALL64pcrel32: NewOpc = X86::NACL_CALL64d; break; |
| 582 } | 584 } |
| 583 if (NewOpc) { | 585 if (NewOpc) { |
| 584 BuildMI(MBB, MBBI, DL, TII->get(NewOpc)) | 586 BuildMI(MBB, MBBI, DL, TII->get(NewOpc)) |
| 585 .addOperand(MI.getOperand(0)); | 587 .addOperand(MI.getOperand(0)); |
| 586 MI.eraseFromParent(); | 588 MI.eraseFromParent(); |
| 587 return true; | 589 return true; |
| 588 } | 590 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 617 .addExternalSymbol("__tls_get_addr", X86II::MO_PLT); | 619 .addExternalSymbol("__tls_get_addr", X86II::MO_PLT); |
| 618 MI.eraseFromParent(); | 620 MI.eraseFromParent(); |
| 619 return true; | 621 return true; |
| 620 } | 622 } |
| 621 | 623 |
| 622 // Local Exec NaCl TLS Model | 624 // Local Exec NaCl TLS Model |
| 623 if (Opc == X86::NACL_CG_LE_TLS_addr64 || | 625 if (Opc == X86::NACL_CG_LE_TLS_addr64 || |
| 624 Opc == X86::NACL_CG_LE_TLS_addr32) { | 626 Opc == X86::NACL_CG_LE_TLS_addr32) { |
| 625 unsigned CallOpc, LeaOpc, Reg; | 627 unsigned CallOpc, LeaOpc, Reg; |
| 626 // Rewrite to: | 628 // Rewrite to: |
| 627 // naclcall __nacl_read_tp@PLT | 629 // naclcall __nacl_read_tp@PLT |
|
jvoung (off chromium)
2014/10/15 00:38:14
"call __nacl_read_tp" now?
Derek Schuff
2014/10/15 17:14:14
Done.
| |
| 628 // lea $sym@flag(,%reg), %reg | 630 // lea $sym@flag(,%reg), %reg |
| 629 if (Opc == X86::NACL_CG_LE_TLS_addr64) { | 631 if (Opc == X86::NACL_CG_LE_TLS_addr64) { |
| 630 CallOpc = X86::NACL_CALL64d; | 632 CallOpc = X86::NACL_CALL64d; |
| 631 LeaOpc = X86::LEA64r; | 633 LeaOpc = X86::LEA64r; |
| 632 Reg = X86::RAX; | 634 Reg = X86::RAX; |
| 633 } else { | 635 } else { |
| 634 CallOpc = X86::NACL_CALL32d; | 636 CallOpc = X86::CALLpcrel32; |
| 635 LeaOpc = X86::LEA32r; | 637 LeaOpc = X86::LEA32r; |
| 636 Reg = X86::EAX; | 638 Reg = X86::EAX; |
| 637 } | 639 } |
| 638 BuildMI(MBB, MBBI, DL, TII->get(CallOpc)) | 640 BuildMI(MBB, MBBI, DL, TII->get(CallOpc)) |
| 639 .addExternalSymbol("__nacl_read_tp", X86II::MO_PLT); | 641 .addExternalSymbol("__nacl_read_tp", X86II::MO_PLT); |
| 640 BuildMI(MBB, MBBI, DL, TII->get(LeaOpc), Reg) | 642 BuildMI(MBB, MBBI, DL, TII->get(LeaOpc), Reg) |
| 641 .addReg(0) // Base | 643 .addReg(0) // Base |
| 642 .addImm(1) // Scale | 644 .addImm(1) // Scale |
| 643 .addReg(Reg) // Index | 645 .addReg(Reg) // Index |
| 644 .addGlobalAddress(MI.getOperand(3).getGlobal(), 0, | 646 .addGlobalAddress(MI.getOperand(3).getGlobal(), 0, |
| 645 MI.getOperand(3).getTargetFlags()) | 647 MI.getOperand(3).getTargetFlags()) |
| 646 .addReg(0); // Segment | 648 .addReg(0); // Segment |
| 647 MI.eraseFromParent(); | 649 MI.eraseFromParent(); |
| 648 return true; | 650 return true; |
| 649 } | 651 } |
| 650 | 652 |
| 651 // Initial Exec NaCl TLS Model | 653 // Initial Exec NaCl TLS Model |
| 652 if (Opc == X86::NACL_CG_IE_TLS_addr64 || | 654 if (Opc == X86::NACL_CG_IE_TLS_addr64 || |
| 653 Opc == X86::NACL_CG_IE_TLS_addr32) { | 655 Opc == X86::NACL_CG_IE_TLS_addr32) { |
| 654 unsigned CallOpc, AddOpc, Base, Reg; | 656 unsigned CallOpc, AddOpc, Base, Reg; |
| 655 // Rewrite to: | 657 // Rewrite to: |
| 656 // naclcall __nacl_read_tp@PLT | 658 // naclcall __nacl_read_tp@PLT |
|
jvoung (off chromium)
2014/10/15 00:38:14
same
Derek Schuff
2014/10/15 17:14:13
Done.
| |
| 657 // addq sym@flag(%base), %reg | 659 // addq sym@flag(%base), %reg |
| 658 if (Opc == X86::NACL_CG_IE_TLS_addr64) { | 660 if (Opc == X86::NACL_CG_IE_TLS_addr64) { |
| 659 CallOpc = X86::NACL_CALL64d; | 661 CallOpc = X86::NACL_CALL64d; |
| 660 AddOpc = X86::ADD64rm; | 662 AddOpc = X86::ADD64rm; |
| 661 Base = X86::RIP; | 663 Base = X86::RIP; |
| 662 Reg = X86::RAX; | 664 Reg = X86::RAX; |
| 663 } else { | 665 } else { |
| 664 CallOpc = X86::NACL_CALL32d; | 666 CallOpc = X86::CALLpcrel32; |
| 665 AddOpc = X86::ADD32rm; | 667 AddOpc = X86::ADD32rm; |
| 666 Base = MI.getOperand(3).getTargetFlags() == X86II::MO_INDNTPOFF ? | 668 Base = MI.getOperand(3).getTargetFlags() == X86II::MO_INDNTPOFF ? |
| 667 0 : X86::EBX; // EBX for GOTNTPOFF. | 669 0 : X86::EBX; // EBX for GOTNTPOFF. |
| 668 Reg = X86::EAX; | 670 Reg = X86::EAX; |
| 669 } | 671 } |
| 670 BuildMI(MBB, MBBI, DL, TII->get(CallOpc)) | 672 BuildMI(MBB, MBBI, DL, TII->get(CallOpc)) |
| 671 .addExternalSymbol("__nacl_read_tp", X86II::MO_PLT); | 673 .addExternalSymbol("__nacl_read_tp", X86II::MO_PLT); |
| 672 BuildMI(MBB, MBBI, DL, TII->get(AddOpc), Reg) | 674 BuildMI(MBB, MBBI, DL, TII->get(AddOpc), Reg) |
| 673 .addReg(Reg) | 675 .addReg(Reg) |
| 674 .addReg(Base) | 676 .addReg(Base) |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 747 } | 749 } |
| 748 return Modified; | 750 return Modified; |
| 749 } | 751 } |
| 750 | 752 |
| 751 /// createX86NaClRewritePassPass - returns an instance of the pass. | 753 /// createX86NaClRewritePassPass - returns an instance of the pass. |
| 752 namespace llvm { | 754 namespace llvm { |
| 753 FunctionPass* createX86NaClRewritePass() { | 755 FunctionPass* createX86NaClRewritePass() { |
| 754 return new X86NaClRewritePass(); | 756 return new X86NaClRewritePass(); |
| 755 } | 757 } |
| 756 } | 758 } |
| OLD | NEW |