コード例 #1
0
int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
                                           pint_t fdeStart, R &registers) {
  FDE_Info fdeInfo;
  CIE_Info cieInfo;
  if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart,
                                                  &fdeInfo, &cieInfo) == NULL) {
    PrologInfo prolog;
    if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc,
                                                                     &prolog)) {
      // get pointer to cfa (architecture specific)
      pint_t cfa = getCFA(addressSpace, prolog, registers);

       // restore registers that dwarf says were saved
      R newRegisters = registers;
      pint_t returnAddress = 0;
      const int lastReg = R::lastDwarfRegNum();
      assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg
                                                && "register range too large");
      assert(lastReg <= (int)cieInfo.returnAddressRegister
                 && "register range does not contain return address register");
      for (int i = 0; i <= lastReg; ++i) {
         if (prolog.savedRegisters[i].location !=
             CFI_Parser<A>::kRegisterUnused) {
           if (registers.validFloatRegister(i))
            newRegisters.setFloatRegister(
                i, getSavedFloatRegister(addressSpace, registers, cfa,
                                         prolog.savedRegisters[i]));
          else if (registers.validVectorRegister(i))
            newRegisters.setVectorRegister(
                i, getSavedVectorRegister(addressSpace, registers, cfa,
                                          prolog.savedRegisters[i]));
          else if (i == (int)cieInfo.returnAddressRegister)
            returnAddress = getSavedRegister(addressSpace, registers, cfa,
                                             prolog.savedRegisters[i]);
          else if (registers.validRegister(i))
            newRegisters.setRegister(
                i, getSavedRegister(addressSpace, registers, cfa,
                                    prolog.savedRegisters[i]));
          else
            return UNW_EBADREG;
        }
      }

      // By definition, the CFA is the stack pointer at the call site, so
      // restoring SP means setting it to CFA.
      newRegisters.setSP(cfa);

      // Return address is address after call site instruction, so setting IP to
      // that does simualates a return.
      newRegisters.setIP(returnAddress);

      // Simulate the step by replacing the register set with the new ones.
      registers = newRegisters;

      return UNW_STEP_SUCCESS;
    }
  }
  return UNW_EBADFRAME;
}
コード例 #2
0
step_result DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
                                                   pint_t fdeStart,
                                                   R &registers,
                                                   unw_proc_info_t *ctx) {
  typename CFI_Parser<A, R>::FDE_Info fdeInfo;
  typename CFI_Parser<A, R>::CIE_Info cieInfo;
  if (!CFI_Parser<A, R>::decodeFDE(addressSpace, fdeStart, &fdeInfo, &cieInfo,
                                   ctx))
    return UNW_STEP_FAILED;

  typename CFI_Parser<A, R>::PrologInfo prolog;
  if (!CFI_Parser<A, R>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo,
                                              pc, &prolog, ctx))
    return UNW_STEP_FAILED;

  // Create working copy of the register set.
  R newRegisters = registers;

  // Get pointer to CFA by the architecture-specific code.
  pint_t cfa = getCFA(addressSpace, prolog, registers);

  // Restore registers according to DWARF instructions
  pint_t returnAddress = 0;
  for (int i = 0; i <= lastRestoreReg(newRegisters); ++i) {
    if (prolog.savedRegisters[i].location == CFI_Parser<A, R>::kRegisterUnused)
      continue;
    if (i == (int)cieInfo.returnAddressRegister)
      returnAddress = getSavedRegister(addressSpace, registers, cfa,
                                       prolog.savedRegisters[i]);
    else if (registers.validRegister(i))
      newRegisters.setRegister(i, getSavedRegister(addressSpace, registers, cfa,
                                                   prolog.savedRegisters[i]));
    else if (registers.validFloatVectorRegister(i))
      newRegisters.copyFloatVectorRegister(
          i, computeRegisterLocation(addressSpace, registers, cfa,
                                     prolog.savedRegisters[i]));
    else
      return UNW_STEP_FAILED;
  }

  // The CFA is defined as the stack pointer at the call site.
  // Therefore the SP is restored by setting it to the CFA.
  newRegisters.setSP(cfa);
  newRegisters.setIP(returnAddress + R::RETURN_OFFSET);
  returnAddress += R::RETURN_OFFSET;
  returnAddress &= ~R::RETURN_MASK;
  newRegisters.setIP(returnAddress);

  // Now replace register set with the working copy.
  registers = newRegisters;

  return UNW_STEP_SUCCESS;
}