bool FIRCLSDwarfUnwindSetRegisterValue()

in Crashlytics/Crashlytics/Unwind/FIRCLSUnwind_arm.c [193:308]


bool FIRCLSDwarfUnwindSetRegisterValue(FIRCLSThreadContext* registers,
                                       uint64_t num,
                                       uintptr_t value) {
  switch (num) {
    case CLS_DWARF_ARM64_X0:
      registers->__ss.__x[0] = value;
      return true;
    case CLS_DWARF_ARM64_X1:
      registers->__ss.__x[1] = value;
      return true;
    case CLS_DWARF_ARM64_X2:
      registers->__ss.__x[2] = value;
      return true;
    case CLS_DWARF_ARM64_X3:
      registers->__ss.__x[3] = value;
      return true;
    case CLS_DWARF_ARM64_X4:
      registers->__ss.__x[4] = value;
      return true;
    case CLS_DWARF_ARM64_X5:
      registers->__ss.__x[5] = value;
      return true;
    case CLS_DWARF_ARM64_X6:
      registers->__ss.__x[6] = value;
      return true;
    case CLS_DWARF_ARM64_X7:
      registers->__ss.__x[7] = value;
      return true;
    case CLS_DWARF_ARM64_X8:
      registers->__ss.__x[8] = value;
      return true;
    case CLS_DWARF_ARM64_X9:
      registers->__ss.__x[9] = value;
      return true;
    case CLS_DWARF_ARM64_X10:
      registers->__ss.__x[10] = value;
      return true;
    case CLS_DWARF_ARM64_X11:
      registers->__ss.__x[11] = value;
      return true;
    case CLS_DWARF_ARM64_X12:
      registers->__ss.__x[12] = value;
      return true;
    case CLS_DWARF_ARM64_X13:
      registers->__ss.__x[13] = value;
      return true;
    case CLS_DWARF_ARM64_X14:
      registers->__ss.__x[14] = value;
      return true;
    case CLS_DWARF_ARM64_X15:
      registers->__ss.__x[15] = value;
      return true;
    case CLS_DWARF_ARM64_X16:
      registers->__ss.__x[16] = value;
      return true;
    case CLS_DWARF_ARM64_X17:
      registers->__ss.__x[17] = value;
      return true;
    case CLS_DWARF_ARM64_X18:
      registers->__ss.__x[18] = value;
      return true;
    case CLS_DWARF_ARM64_X19:
      registers->__ss.__x[19] = value;
      return true;
    case CLS_DWARF_ARM64_X20:
      registers->__ss.__x[20] = value;
      return true;
    case CLS_DWARF_ARM64_X21:
      registers->__ss.__x[21] = value;
      return true;
    case CLS_DWARF_ARM64_X22:
      registers->__ss.__x[22] = value;
      return true;
    case CLS_DWARF_ARM64_X23:
      registers->__ss.__x[23] = value;
      return true;
    case CLS_DWARF_ARM64_X24:
      registers->__ss.__x[24] = value;
      return true;
    case CLS_DWARF_ARM64_X25:
      registers->__ss.__x[25] = value;
      return true;
    case CLS_DWARF_ARM64_X26:
      registers->__ss.__x[26] = value;
      return true;
    case CLS_DWARF_ARM64_X27:
      registers->__ss.__x[27] = value;
      return true;
    case CLS_DWARF_ARM64_X28:
      registers->__ss.__x[28] = value;
      return true;
    case CLS_DWARF_ARM64_FP:
      FIRCLSThreadContextSetFramePointer(registers, value);
      return true;
    case CLS_DWARF_ARM64_SP:
      FIRCLSThreadContextSetStackPointer(registers, value);
      return true;
    case CLS_DWARF_ARM64_LR:
      // Here's what's going on. For x86, the "return register" is virtual. The architecture
      // doesn't actually have one, but DWARF does have the concept. So, when the system
      // tries to set the return register, we set the PC. You can see this behavior
      // in the FIRCLSDwarfUnwindSetRegisterValue implemenation for that architecture. In the
      // case of ARM64, the register is real. So, we have to be extra careful to make sure
      // we update the PC here. Otherwise, when a DWARF unwind completes, it won't have
      // changed the PC to the right value.
      FIRCLSThreadContextSetLinkRegister(registers, value);
      FIRCLSThreadContextSetPC(registers, value);
      return true;
    default:
      break;
  }

  FIRCLSSDKLog("Unrecognized set register number %llu\n", num);

  return false;
}