//===--------------------------- DwarfParser.hpp --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
//  Parses DWARF CFIs (FDEs and CIEs).
//
//===----------------------------------------------------------------------===//

#ifndef __DWARF_PARSER_HPP__
#define __DWARF_PARSER_HPP__

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include "libunwind.h"
#include "dwarf2.h"
#include "Registers.hpp"

#include "config.h"

namespace libunwind {

/// CFI_Parser does basic parsing of a CFI (Call Frame Information) records.
/// See DWARF Spec for details:
///    http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
///
template <typename A>
class CFI_Parser {
public:
  typedef typename A::pint_t pint_t;

  /// Information encoded in a CIE (Common Information Entry)
  struct CIE_Info {
    pint_t    cieStart;
    pint_t    cieLength;
    pint_t    cieInstructions;
    uint8_t   pointerEncoding;
    uint8_t   lsdaEncoding;
    uint8_t   personalityEncoding;
    uint8_t   personalityOffsetInCIE;
    pint_t    personality;
    uint32_t  codeAlignFactor;
    int       dataAlignFactor;
    bool      isSignalFrame;
    bool      fdesHaveAugmentationData;
    uint8_t   returnAddressRegister;
#if defined(_LIBUNWIND_TARGET_AARCH64)
    bool      addressesSignedWithBKey;
#endif
  };

  /// Information about an FDE (Frame Description Entry)
  struct FDE_Info {
    pint_t  fdeStart;
    pint_t  fdeLength;
    pint_t  fdeInstructions;
    pint_t  pcStart;
    pint_t  pcEnd;
    pint_t  lsda;
  };

  enum {
    kMaxRegisterNumber = _LIBUNWIND_HIGHEST_DWARF_REGISTER
  };
  enum RegisterSavedWhere {
    kRegisterUnused,
    kRegisterInCFA,
    kRegisterOffsetFromCFA,
    kRegisterInRegister,
    kRegisterAtExpression,
    kRegisterIsExpression
  };
  struct RegisterLocation {
    RegisterSavedWhere location;
    bool initialStateSaved;
    int64_t value;
  };
  /// Information about a frame layout and registers saved determined
  /// by "running" the DWARF FDE "instructions"
  struct PrologInfo {
    uint32_t          cfaRegister;
    int32_t           cfaRegisterOffset;  // CFA = (cfaRegister)+cfaRegisterOffset
    int64_t           cfaExpression;      // CFA = expression
    uint32_t          spExtraArgSize;
    uint32_t          codeOffsetAtStackDecrement;
    bool              registersInOtherRegisters;
    bool              sameValueUsed;
    RegisterLocation  savedRegisters[kMaxRegisterNumber + 1];
    enum class InitializeTime { kLazy, kNormal };

    // When saving registers, this data structure is lazily initialized.
    PrologInfo(InitializeTime IT = InitializeTime::kNormal) {
      if (IT == InitializeTime::kNormal)
        memset(this, 0, sizeof(*this));
    }
    void checkSaveRegister(uint64_t reg, PrologInfo &initialState) {
      if (!savedRegisters[reg].initialStateSaved) {
        initialState.savedRegisters[reg] = savedRegisters[reg];
        savedRegisters[reg].initialStateSaved = true;
      }
    }
    void setRegister(uint64_t reg, RegisterSavedWhere newLocation,
                     int64_t newValue, PrologInfo &initialState) {
      checkSaveRegister(reg, initialState);
      savedRegisters[reg].location = newLocation;
      savedRegisters[reg].value = newValue;
    }
    void setRegisterLocation(uint64_t reg, RegisterSavedWhere newLocation,
                             PrologInfo &initialState) {
      checkSaveRegister(reg, initialState);
      savedRegisters[reg].location = newLocation;
    }
    void setRegisterValue(uint64_t reg, int64_t newValue,
                          PrologInfo &initialState) {
      checkSaveRegister(reg, initialState);
      savedRegisters[reg].value = newValue;
    }
    void restoreRegisterToInitialState(uint64_t reg, PrologInfo &initialState) {
      if (savedRegisters[reg].initialStateSaved)
        savedRegisters[reg] = initialState.savedRegisters[reg];
      // else the register still holds its initial state
    }
  };

  struct PrologInfoStackEntry {
    PrologInfoStackEntry(PrologInfoStackEntry *n, const PrologInfo &i)
        : next(n), info(i) {}
    PrologInfoStackEntry *next;
    PrologInfo info;
  };

  static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
                      uint32_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo,
                      CIE_Info *cieInfo);
  static const char *decodeFDE(A &addressSpace, pint_t fdeStart,
                               FDE_Info *fdeInfo, CIE_Info *cieInfo);
  static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo,
                                   const CIE_Info &cieInfo, pint_t upToPC,
                                   int arch, PrologInfo *results);

  static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo);

private:
  static bool parseInstructions(A &addressSpace, pint_t instructions,
                                pint_t instructionsEnd, const CIE_Info &cieInfo,
                                pint_t pcoffset,
                                PrologInfoStackEntry *&rememberStack, int arch,
                                PrologInfo *results);
};

/// Parse a FDE into a CIE_Info and an FDE_Info
template <typename A>
const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart,
                                     FDE_Info *fdeInfo, CIE_Info *cieInfo) {
  pint_t p = fdeStart;
  pint_t cfiLength = (pint_t)addressSpace.get32(p);
  p += 4;
  if (cfiLength == 0xffffffff) {
    // 0xffffffff means length is really next 8 bytes
    cfiLength = (pint_t)addressSpace.get64(p);
    p += 8;
  }
  if (cfiLength == 0)
    return "FDE has zero length"; // end marker
  uint32_t ciePointer = addressSpace.get32(p);
  if (ciePointer == 0)
    return "FDE is really a CIE"; // this is a CIE not an FDE
  pint_t nextCFI = p + cfiLength;
  pint_t cieStart = p - ciePointer;
  const char *err = parseCIE(addressSpace, cieStart, cieInfo);
  if (err != NULL)
    return err;
  p += 4;
  // Parse pc begin and range.
  pint_t pcStart =
      addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding);
  pint_t pcRange =
      addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F);
  // Parse rest of info.
  fdeInfo->lsda = 0;
  // Check for augmentation length.
  if (cieInfo->fdesHaveAugmentationData) {
    pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI);
    pint_t endOfAug = p + augLen;
    if (cieInfo->lsdaEncoding != DW_EH_PE_omit) {
      // Peek at value (without indirection).  Zero means no LSDA.
      pint_t lsdaStart = p;
      if (addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F) !=
          0) {
        // Reset pointer and re-parse LSDA address.
        p = lsdaStart;
        fdeInfo->lsda =
            addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding);
      }
    }
    p = endOfAug;
  }
  fdeInfo->fdeStart = fdeStart;
  fdeInfo->fdeLength = nextCFI - fdeStart;
  fdeInfo->fdeInstructions = p;
  fdeInfo->pcStart = pcStart;
  fdeInfo->pcEnd = pcStart + pcRange;
  return NULL; // success
}

/// Scan an eh_frame section to find an FDE for a pc
template <typename A>
bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
                            uint32_t sectionLength, pint_t fdeHint,
                            FDE_Info *fdeInfo, CIE_Info *cieInfo) {
  //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);
  pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart;
  const pint_t ehSectionEnd = p + sectionLength;
  while (p < ehSectionEnd) {
    pint_t currentCFI = p;
    //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p);
    pint_t cfiLength = addressSpace.get32(p);
    p += 4;
    if (cfiLength == 0xffffffff) {
      // 0xffffffff means length is really next 8 bytes
      cfiLength = (pint_t)addressSpace.get64(p);
      p += 8;
    }
    if (cfiLength == 0)
      return false; // end marker
    uint32_t id = addressSpace.get32(p);
    if (id == 0) {
      // Skip over CIEs.
      p += cfiLength;
    } else {
      // Process FDE to see if it covers pc.
      pint_t nextCFI = p + cfiLength;
      uint32_t ciePointer = addressSpace.get32(p);
      pint_t cieStart = p - ciePointer;
      // Validate pointer to CIE is within section.
      if ((ehSectionStart <= cieStart) && (cieStart < ehSectionEnd)) {
        if (parseCIE(addressSpace, cieStart, cieInfo) == NULL) {
          p += 4;
          // Parse pc begin and range.
          pint_t pcStart =
              addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding);
          pint_t pcRange = addressSpace.getEncodedP(
              p, nextCFI, cieInfo->pointerEncoding & 0x0F);
          // Test if pc is within the function this FDE covers.
          if ((pcStart < pc) && (pc <= pcStart + pcRange)) {
            // parse rest of info
            fdeInfo->lsda = 0;
            // check for augmentation length
            if (cieInfo->fdesHaveAugmentationData) {
              pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI);
              pint_t endOfAug = p + augLen;
              if (cieInfo->lsdaEncoding != DW_EH_PE_omit) {
                // Peek at value (without indirection).  Zero means no LSDA.
                pint_t lsdaStart = p;
                if (addressSpace.getEncodedP(
                        p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != 0) {
                  // Reset pointer and re-parse LSDA address.
                  p = lsdaStart;
                  fdeInfo->lsda = addressSpace
                      .getEncodedP(p, nextCFI, cieInfo->lsdaEncoding);
                }
              }
              p = endOfAug;
            }
            fdeInfo->fdeStart = currentCFI;
            fdeInfo->fdeLength = nextCFI - currentCFI;
            fdeInfo->fdeInstructions = p;
            fdeInfo->pcStart = pcStart;
            fdeInfo->pcEnd = pcStart + pcRange;
            return true;
          } else {
            // pc is not in begin/range, skip this FDE
          }
        } else {
          // Malformed CIE, now augmentation describing pc range encoding.
        }
      } else {
        // malformed FDE.  CIE is bad
      }
      p = nextCFI;
    }
  }
  return false;
}

/// Extract info from a CIE
template <typename A>
const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
                                    CIE_Info *cieInfo) {
  cieInfo->pointerEncoding = 0;
  cieInfo->lsdaEncoding = DW_EH_PE_omit;
  cieInfo->personalityEncoding = 0;
  cieInfo->personalityOffsetInCIE = 0;
  cieInfo->personality = 0;
  cieInfo->codeAlignFactor = 0;
  cieInfo->dataAlignFactor = 0;
  cieInfo->isSignalFrame = false;
  cieInfo->fdesHaveAugmentationData = false;
#if defined(_LIBUNWIND_TARGET_AARCH64)
  cieInfo->addressesSignedWithBKey = false;
#endif
  cieInfo->cieStart = cie;
  pint_t p = cie;
  pint_t cieLength = (pint_t)addressSpace.get32(p);
  p += 4;
  pint_t cieContentEnd = p + cieLength;
  if (cieLength == 0xffffffff) {
    // 0xffffffff means length is really next 8 bytes
    cieLength = (pint_t)addressSpace.get64(p);
    p += 8;
    cieContentEnd = p + cieLength;
  }
  if (cieLength == 0)
    return NULL;
  // CIE ID is always 0
  if (addressSpace.get32(p) != 0)
    return "CIE ID is not zero";
  p += 4;
  // Version is always 1 or 3
  uint8_t version = addressSpace.get8(p);
  if ((version != 1) && (version != 3))
    return "CIE version is not 1 or 3";
  ++p;
  // save start of augmentation string and find end
  pint_t strStart = p;
  while (addressSpace.get8(p) != 0)
    ++p;
  ++p;
  // parse code aligment factor
  cieInfo->codeAlignFactor = (uint32_t)addressSpace.getULEB128(p, cieContentEnd);
  // parse data alignment factor
  cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
  // parse return address register
  uint64_t raReg = addressSpace.getULEB128(p, cieContentEnd);
  assert(raReg < 255 && "return address register too large");
  cieInfo->returnAddressRegister = (uint8_t)raReg;
  // parse augmentation data based on augmentation string
  const char *result = NULL;
  if (addressSpace.get8(strStart) == 'z') {
    // parse augmentation data length
    addressSpace.getULEB128(p, cieContentEnd);
    for (pint_t s = strStart; addressSpace.get8(s) != '\0'; ++s) {
      switch (addressSpace.get8(s)) {
      case 'z':
        cieInfo->fdesHaveAugmentationData = true;
        break;
      case 'P':
        cieInfo->personalityEncoding = addressSpace.get8(p);
        ++p;
        cieInfo->personalityOffsetInCIE = (uint8_t)(p - cie);
        cieInfo->personality = addressSpace
            .getEncodedP(p, cieContentEnd, cieInfo->personalityEncoding);
        break;
      case 'L':
        cieInfo->lsdaEncoding = addressSpace.get8(p);
        ++p;
        break;
      case 'R':
        cieInfo->pointerEncoding = addressSpace.get8(p);
        ++p;
        break;
      case 'S':
        cieInfo->isSignalFrame = true;
        break;
#if defined(_LIBUNWIND_TARGET_AARCH64)
      case 'B':
        cieInfo->addressesSignedWithBKey = true;
        break;
#endif
      default:
        // ignore unknown letters
        break;
      }
    }
  }
  cieInfo->cieLength = cieContentEnd - cieInfo->cieStart;
  cieInfo->cieInstructions = p;
  return result;
}


/// "run" the DWARF instructions and create the abstact PrologInfo for an FDE
template <typename A>
bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
                                         const FDE_Info &fdeInfo,
                                         const CIE_Info &cieInfo, pint_t upToPC,
                                         int arch, PrologInfo *results) {
  PrologInfoStackEntry *rememberStack = NULL;

  // parse CIE then FDE instructions
  bool returnValue =
      parseInstructions(addressSpace, cieInfo.cieInstructions,
                        cieInfo.cieStart + cieInfo.cieLength, cieInfo,
                        (pint_t)(-1), rememberStack, arch, results) &&
      parseInstructions(addressSpace, fdeInfo.fdeInstructions,
                        fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo,
                        upToPC - fdeInfo.pcStart, rememberStack, arch, results);

  // Clean up rememberStack. Even in the case where every DW_CFA_remember_state
  // is paired with a DW_CFA_restore_state, parseInstructions can skip restore
  // opcodes if it reaches the target PC and stops interpreting, so we have to
  // make sure we don't leak memory.
  while (rememberStack) {
    PrologInfoStackEntry *next = rememberStack->next;
    free(rememberStack);
    rememberStack = next;
  }

  return returnValue;
}

/// "run" the DWARF instructions
template <typename A>
bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
                                      pint_t instructionsEnd,
                                      const CIE_Info &cieInfo, pint_t pcoffset,
                                      PrologInfoStackEntry *&rememberStack,
                                      int arch, PrologInfo *results) {
  pint_t p = instructions;
  pint_t codeOffset = 0;
  // initialState initialized as registers in results are modified. Use
  // PrologInfo accessor functions to avoid reading uninitialized data.
  PrologInfo initialState(PrologInfo::InitializeTime::kLazy);

  _LIBUNWIND_TRACE_DWARF("parseInstructions(instructions=0x%0" PRIx64 ")\n",
                         static_cast<uint64_t>(instructionsEnd));

  // see DWARF Spec, section 6.4.2 for details on unwind opcodes
  while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
    uint64_t reg;
    uint64_t reg2;
    int64_t offset;
    uint64_t length;
    uint8_t opcode = addressSpace.get8(p);
    uint8_t operand;
#if !defined(_LIBUNWIND_NO_HEAP)
    PrologInfoStackEntry *entry;
#endif
    ++p;
    switch (opcode) {
    case DW_CFA_nop:
      _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n");
      break;
    case DW_CFA_set_loc:
      codeOffset =
          addressSpace.getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n");
      break;
    case DW_CFA_advance_loc1:
      codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
      p += 1;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
                             static_cast<uint64_t>(codeOffset));
      break;
    case DW_CFA_advance_loc2:
      codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
      p += 2;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
                             static_cast<uint64_t>(codeOffset));
      break;
    case DW_CFA_advance_loc4:
      codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
      p += 4;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
                             static_cast<uint64_t>(codeOffset));
      break;
    case DW_CFA_offset_extended:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
                                                  * cieInfo.dataAlignFactor;
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_offset_extended DWARF unwind, reg too big");
        return false;
      }
      results->setRegister(reg, kRegisterInCFA, offset, initialState);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "
                             "offset=%" PRId64 ")\n",
                             reg, offset);
      break;
    case DW_CFA_restore_extended:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
            "malformed DW_CFA_restore_extended DWARF unwind, reg too big");
        return false;
      }
      results->restoreRegisterToInitialState(reg, initialState);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg);
      break;
    case DW_CFA_undefined:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_undefined DWARF unwind, reg too big");
        return false;
      }
      results->setRegisterLocation(reg, kRegisterUnused, initialState);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
      break;
    case DW_CFA_same_value:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_same_value DWARF unwind, reg too big");
        return false;
      }
      // <rdar://problem/8456377> DW_CFA_same_value unsupported
      // "same value" means register was stored in frame, but its current
      // value has not changed, so no need to restore from frame.
      // We model this as if the register was never saved.
      results->setRegisterLocation(reg, kRegisterUnused, initialState);
      // set flag to disable conversion to compact unwind
      results->sameValueUsed = true;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
      break;
    case DW_CFA_register:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      reg2 = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_register DWARF unwind, reg too big");
        return false;
      }
      if (reg2 > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_register DWARF unwind, reg2 too big");
        return false;
      }
      results->setRegister(reg, kRegisterInRegister, (int64_t)reg2,
                           initialState);
      // set flag to disable conversion to compact unwind
      results->registersInOtherRegisters = true;
      _LIBUNWIND_TRACE_DWARF(
          "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2);
      break;
#if !defined(_LIBUNWIND_NO_HEAP)
    case DW_CFA_remember_state:
      // avoid operator new, because that would be an upward dependency
      entry = (PrologInfoStackEntry *)malloc(sizeof(PrologInfoStackEntry));
      if (entry != NULL) {
        entry->next = rememberStack;
        entry->info = *results;
        rememberStack = entry;
      } else {
        return false;
      }
      _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n");
      break;
    case DW_CFA_restore_state:
      if (rememberStack != NULL) {
        PrologInfoStackEntry *top = rememberStack;
        *results = top->info;
        rememberStack = top->next;
        free((char *)top);
      } else {
        return false;
      }
      _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n");
      break;
#endif
    case DW_CFA_def_cfa:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0("malformed DW_CFA_def_cfa DWARF unwind, reg too big");
        return false;
      }
      results->cfaRegister = (uint32_t)reg;
      results->cfaRegisterOffset = (int32_t)offset;
      _LIBUNWIND_TRACE_DWARF(
          "DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 ")\n", reg, offset);
      break;
    case DW_CFA_def_cfa_register:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
            "malformed DW_CFA_def_cfa_register DWARF unwind, reg too big");
        return false;
      }
      results->cfaRegister = (uint32_t)reg;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg);
      break;
    case DW_CFA_def_cfa_offset:
      results->cfaRegisterOffset = (int32_t)
                                  addressSpace.getULEB128(p, instructionsEnd);
      results->codeOffsetAtStackDecrement = (uint32_t)codeOffset;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n",
                             results->cfaRegisterOffset);
      break;
    case DW_CFA_def_cfa_expression:
      results->cfaRegister = 0;
      results->cfaExpression = (int64_t)p;
      length = addressSpace.getULEB128(p, instructionsEnd);
      assert(length < static_cast<pint_t>(~0) && "pointer overflow");
      p += static_cast<pint_t>(length);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64
                             ", length=%" PRIu64 ")\n",
                             results->cfaExpression, length);
      break;
    case DW_CFA_expression:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_expression DWARF unwind, reg too big");
        return false;
      }
      results->setRegister(reg, kRegisterAtExpression, (int64_t)p,
                           initialState);
      length = addressSpace.getULEB128(p, instructionsEnd);
      assert(length < static_cast<pint_t>(~0) && "pointer overflow");
      p += static_cast<pint_t>(length);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", "
                             "expression=0x%" PRIx64 ", "
                             "length=%" PRIu64 ")\n",
                             reg, results->savedRegisters[reg].value, length);
      break;
    case DW_CFA_offset_extended_sf:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
            "malformed DW_CFA_offset_extended_sf DWARF unwind, reg too big");
        return false;
      }
      offset =
          addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
      results->setRegister(reg, kRegisterInCFA, offset, initialState);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", "
                             "offset=%" PRId64 ")\n",
                             reg, offset);
      break;
    case DW_CFA_def_cfa_sf:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      offset =
          addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_def_cfa_sf DWARF unwind, reg too big");
        return false;
      }
      results->cfaRegister = (uint32_t)reg;
      results->cfaRegisterOffset = (int32_t)offset;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", "
                             "offset=%" PRId64 ")\n",
                             reg, offset);
      break;
    case DW_CFA_def_cfa_offset_sf:
      results->cfaRegisterOffset = (int32_t)
        (addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor);
      results->codeOffsetAtStackDecrement = (uint32_t)codeOffset;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n",
                             results->cfaRegisterOffset);
      break;
    case DW_CFA_val_offset:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG(
                "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64
                ") out of range\n",
                reg);
        return false;
      }
      offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
                                                    * cieInfo.dataAlignFactor;
      results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", "
                             "offset=%" PRId64 "\n",
                             reg, offset);
      break;
    case DW_CFA_val_offset_sf:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_val_offset_sf DWARF unwind, reg too big");
        return false;
      }
      offset =
          addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
      results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", "
                             "offset=%" PRId64 "\n",
                             reg, offset);
      break;
    case DW_CFA_val_expression:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0(
                "malformed DW_CFA_val_expression DWARF unwind, reg too big");
        return false;
      }
      results->setRegister(reg, kRegisterIsExpression, (int64_t)p,
                           initialState);
      length = addressSpace.getULEB128(p, instructionsEnd);
      assert(length < static_cast<pint_t>(~0) && "pointer overflow");
      p += static_cast<pint_t>(length);
      _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", "
                             "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
                             reg, results->savedRegisters[reg].value, length);
      break;
    case DW_CFA_GNU_args_size:
      length = addressSpace.getULEB128(p, instructionsEnd);
      results->spExtraArgSize = (uint32_t)length;
      _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length);
      break;
    case DW_CFA_GNU_negative_offset_extended:
      reg = addressSpace.getULEB128(p, instructionsEnd);
      if (reg > kMaxRegisterNumber) {
        _LIBUNWIND_LOG0("malformed DW_CFA_GNU_negative_offset_extended DWARF "
                        "unwind, reg too big");
        return false;
      }
      offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
                                                    * cieInfo.dataAlignFactor;
      results->setRegister(reg, kRegisterInCFA, -offset, initialState);
      _LIBUNWIND_TRACE_DWARF(
          "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
      break;

#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC)
    // The same constant is used to represent different instructions on
    // AArch64 (negate_ra_state) and SPARC (window_save).
    static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
                  "uses the same constant");
    case DW_CFA_AARCH64_negate_ra_state:
      switch (arch) {
#if defined(_LIBUNWIND_TARGET_AARCH64)
        case REGISTERS_ARM64: {
          int64_t value =
              results->savedRegisters[UNW_ARM64_RA_SIGN_STATE].value ^ 0x1;
          results->setRegisterValue(UNW_ARM64_RA_SIGN_STATE, value, initialState);
          _LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n");
        } break;
#endif

#if defined(_LIBUNWIND_TARGET_SPARC)
      // case DW_CFA_GNU_window_save:
      case REGISTERS_SPARC:
        _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n");
        for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) {
          results->setRegister(reg, kRegisterInRegister,
                               ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0,
                               initialState);
        }

        for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
          results->setRegister(reg, kRegisterInCFA,
                               ((int64_t)reg - UNW_SPARC_L0) * 4, initialState);
        }
        break;
#endif
      }
      break;
#else
      (void)arch;
#endif

    default:
      operand = opcode & 0x3F;
      switch (opcode & 0xC0) {
      case DW_CFA_offset:
        reg = operand;
        if (reg > kMaxRegisterNumber) {
          _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64
                         ") out of range",
                  reg);
          return false;
        }
        offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
                                                    * cieInfo.dataAlignFactor;
        results->setRegister(reg, kRegisterInCFA, offset, initialState);
        _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
                               operand, offset);
        break;
      case DW_CFA_advance_loc:
        codeOffset += operand * cieInfo.codeAlignFactor;
        _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
                               static_cast<uint64_t>(codeOffset));
        break;
      case DW_CFA_restore:
        reg = operand;
        if (reg > kMaxRegisterNumber) {
          _LIBUNWIND_LOG("malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64
                         ") out of range",
                  reg);
          return false;
        }
        results->restoreRegisterToInitialState(reg, initialState);
        _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n",
                               static_cast<uint64_t>(operand));
        break;
      default:
        _LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode);
        return false;
      }
    }
  }

  return true;
}

} // namespace libunwind

#endif // __DWARF_PARSER_HPP__
