示例#1
0
unsigned Disassembler::decodeInstruction(unsigned Address,
  MachineBasicBlock *Block) {
  // Disassemble instruction
  const MCDisassembler *DA = MC->getMCDisassembler();
  uint64_t InstSize;
  MCInst *Inst = new MCInst();
  StringRef Bytes;

  if (!(DA->getInstruction(*Inst, InstSize, *CurSectionMemory, Address,
        nulls(), nulls()))) {
    printError("Unknown instruction encountered, instruction decode failed!");
    return 1;
    // Instructions[Address] = NULL;
    // Block->push_back(NULL);	
    // TODO: Replace with default size for each target.
    // return 1;
    // outs() << format("%8" PRIx64 ":\t", SectAddr + Index);
    // Dism->rawBytesToString(StringRef(Bytes.data() + Index, Size));
    // outs() << "   unkn\n";
  }
  Instructions[Address] = Inst;

  // Recover Instruction information
  const MCInstrInfo *MII = MC->getMCInstrInfo();
  MCInstrDesc *MCID = new MCInstrDesc(MII->get(Inst->getOpcode()));
  MCID->Size = InstSize;

  // Check if the instruction can load to program counter and mark it as a Ret
  // FIXME: Better analysis would be to see if the PC value references memory
  // sent as a parameter or set locally in the function, but that would need to
  // happen after decompilation. In either case, this is definitely a BB
  // terminator or branch!
  if (MCID->mayLoad()
    && MCID->mayAffectControlFlow(*Inst, *MC->getMCRegisterInfo())) {
    MCID->Flags |= (1 << MCID::Return);
    MCID->Flags |= (1 << MCID::Terminator);
  }


  // Recover MachineInstr representation
  DebugLoc *Location = setDebugLoc(Address);
  MachineInstrBuilder MIB = BuildMI(Block, *Location, *MCID);
  unsigned int numDefs = MCID->getNumDefs();
  for (unsigned int i = 0; i < Inst->getNumOperands(); i++) {
    MCOperand MCO = Inst->getOperand(i);
    // FIXME: This hack is a workaround for the assert in MachineInstr.cpp:653,
    // where OpNo >= MCID->getNumOperands()...
    if (i >= MCID->getNumOperands() && !(MCID->isVariadic()))
      break;

    if (MCO.isReg()) {
      unsigned flags = 0;
      // Defs always start at the beginning of the operands list,
      // unfortunately BuildMI doesn't set default define flags so we have
      // to do it manually here.
      // NOTE: This should always be true, but might not be if operands list
      //       is not populated correctly by the MC Backend for the target.
      if (i < numDefs) {
        flags |= RegState::Define;
      }

      // NOTE: No need to worry about imp defs and uses, as these are already
      //       specificed in the MCID attached to the MachineInst object.
      MIB.addReg(MCO.getReg(), flags);
      continue;
    }
    if (MCO.isImm()) {
      MIB.addImm(MCO.getImm());
        continue;
    }
    //else if (MCO.isFPImm()) MIB.addFPImm(MCO.getFPImm());
    if (MCO.isExpr()) {
      MCOperandInfo MCOpInfo = MCID->OpInfo[i];
      switch (MCOpInfo.OperandType) {
        case MCOI::OPERAND_MEMORY:
        case MCOI::OPERAND_PCREL:
        case MCOI::OPERAND_UNKNOWN:
        default:
          printError("Unknown how to handle this Expression at this time.");
      }
    }
    printError("Unknown how to handle Operand!");
  }

  // NOTE: I tried MCOpInfo here, and it appearst o be NULL
  // ... at least for ARM.
  unsigned flags = 0;
  if (MCID->mayLoad())
  	flags |= MachineMemOperand::MOLoad;
  if (MCID->mayStore())
  	flags |= MachineMemOperand::MOStore;
  if (flags != 0) {
  	// Constant* cInt = ConstantInt::get(Type::getInt64Ty(ctx), MCO.getImm());
  	// Value *Val = ConstantExpr::getIntToPtr(cInt,
  	// PointerType::getUnqual(Type::getInt32Ty(ctx)));
  	// FIXME: note size of 4 is known to be bad for
  	// some targets

  	//Copy & paste set getImm to zero
  	MachineMemOperand* MMO = new MachineMemOperand(
  			MachinePointerInfo(), flags, 4, 0);	//MCO.getImm()
		 	 MIB.addMemOperand(MMO);
		 	 //outs() << "Name: " << MII->getName(Inst->getOpcode()) << " Flags: " << flags << "\n";
	 }

  // Note: I don't know why they decided instruction size needed to be 64 bits,
  // but the following conversion shouldn't be an issue.
  return ((unsigned)InstSize);
}
示例#2
0
static inline bool mayAccessMemory(const MCInstrDesc &TID) {
  return TID.mayLoad() || TID.mayStore() || TID.isCall();
}