ronantakizawa/codereview-bench huggingface dataset:
Repository: llvm/llvm-project
File: llvm/include/llvm/Transforms/Vectorize/VPlanTestPass.h (C/C++)

Code before:
//===- VPlanTestPass.h - Test VPlan transforms ----------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This pass is a lightweight testing harness for VPlan transforms. It builds
// VPlan0 for loops and runs specified transforms.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANTESTPASS_H
#define LLVM_TRANSFORMS_VECTORIZE_VPLANTESTPASS_H

#include "llvm/IR/PassManager.h"

namespace llvm {

class VPlanTestPass : public PassInfoMixin<VPlanTestPass> {
  std::string TransformPipeline;

public:
  VPlanTestPass(std::string Pipeline = "")
      : TransformPipeline(std::move(Pipeline)) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);

  void printPipeline(raw_ostream &OS,
                     function_ref<StringRef(StringRef)> MapClassName2PassName);
};

} // end namespace llvm

#endif // LLVM_TRANSFORMS_VECTORIZE_VPLANTESTPASS_H


Review comment (suggestion):
```suggestion
  VPlanTestPass(StringRefPipeline = "")
      : TransformPipeline(Pipeline) {}
```

The StringMap keeps StringRefs anyway.

Code after:
//===- VPlanTestPass.h - Test VPlan transforms ----------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This pass is a lightweight testing harness for VPlan transforms. It builds
// VPlan0 for loops and runs specified transforms.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANTESTPASS_H
#define LLVM_TRANSFORMS_VECTORIZE_VPLANTESTPASS_H

#include "llvm/IR/PassManager.h"

namespace llvm {

class VPlanTestPass : public PassInfoMixin<VPlanTestPass> {
  StringRef TransformPipeline;

public:
  VPlanTestPass(StringRef Pipeline = "") : TransformPipeline(Pipeline) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);

  void printPipeline(raw_ostream &OS,
                     function_ref<StringRef(StringRef)> MapClassName2PassName);
};

} // end namespace llvm

#endif // LLVM_TRANSFORMS_VECTORIZE_VPLANTESTPASS_H
Repository: llvm/llvm-project
File: clang/test/DebugInfo/CXX/ptrauth-member-function-pointer-debuglocs.cpp (C++)

Code before:
// RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics \
// RUN:     -emit-llvm -std=c++11 -O1 -disable-llvm-passes \
// RUN:     -debug-info-kind=limited %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
// RUN:     -emit-llvm -std=c++11 -O1 -disable-llvm-passes \
// RUN:     -debug-info-kind=limited %s -o - | FileCheck %s

// Check that compiler-generated *_vfpthunk_ function has a !dbg location
// attached to the call instruction.

// CHECK:      define {{.*}}@_ZN1A2f0Ev_vfpthunk_{{.*}} !dbg
// CHECK-NOT:  define
// CHECK:        musttail call void %{{[0-9]+}}(ptr
// CHECK-SAME:     [ "ptrauth"(i32 0, i64 %{{[0-9]+}}) ]
// CHECK-SAME:     !dbg

volatile long T;

struct A {
  virtual void f0() {
    T = 0;
  }
};
typedef void (A::*MFP)();

void caller() {
  A a;

  MFP x = &A::f0;
  (a.*x)();
}


Review comment (bug):
include the debug info index and the required debug identities so we can record that the pseudo address correctly ties to the thunk scope

e.g.
```llvm
musttail .... !dbg [[DEBUG_INDEX:![0-9]+]]
[[SCOPE_INDEX:![0-9]+]] = distinct !DISubprogram(linkageName: "_ZN1A2f0Ev_vfpthunk_",
[[DEBUG_INDEX]] = !DILocation(line: 0, scope: [[SCOPE_INDEX]])
```


Code after:
// RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics \
// RUN:     -emit-llvm -std=c++11 -O1 -disable-llvm-passes \
// RUN:     -debug-info-kind=limited %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
// RUN:     -emit-llvm -std=c++11 -O1 -disable-llvm-passes \
// RUN:     -debug-info-kind=limited %s -o - | FileCheck %s

// Check that compiler-generated *_vfpthunk_ function has a !dbg location
// attached to the call instruction.

// CHECK:      define {{.*}}@_ZN1A2f0Ev_vfpthunk_({{.*}})
// CHECK-SAME:     !dbg ![[SCOPE_INDEX:[0-9]+]]
// CHECK-NOT:  define
// CHECK:        %[[DISCR:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %{{[0-9]+}}, i64 9385)
// CHECK-NOT:  define
// CHECK:        musttail call void %{{[0-9]+}}(ptr
// CHECK-SAME:     [ "ptrauth"(i32 0, i64 %[[DISCR]]) ]
// CHECK-SAME:     !dbg ![[LOCATION_INDEX:[0-9]+]]

// CHECK:      ![[SCOPE_INDEX]] = distinct !DISubprogram(
// CHECK-SAME:                        linkageName: "_ZN1A2f0Ev_vfpthunk_"
// CHECK-SAME:                        flags: DIFlagArtificial | DIFlagThunk
// CHECK:      ![[LOCATION_INDEX]] = !DILocation(line: 0, scope: ![[SCOPE_INDEX]])

volatile long T;

struct A {
  virtual void f0() {
    T = 0;
  }
};
typedef void (A::*MFP)();

void caller() {
  A a;

  MFP x = &A::f0;
  (a.*x)();
}
Repository: llvm/llvm-project
File: llvm/tools/llvm-ir2vec/lib/Utils.cpp (C++)

Code before:
  return Result;
}

Expected<InstEmbeddingsMap>
IR2VecTool::getInstEmbeddingsMap(const Function &F, IR2VecKind Kind) const {
  auto Emb = getIR2VecEmbedder(F, Kind);
  if (!Emb)
    return Emb.takeError();

  InstEmbeddingsMap Result;

  for (const Instruction &I : instructions(F))
    Result.try_emplace(&I, (*Emb)->getInstVector(I));

  return Result;
}

void IR2VecTool::writeEmbeddingsToStream(raw_ostream &OS,
                                         EmbeddingLevel Level) const {
  for (const Function &F : M.getFunctionDefs())
    writeEmbeddingsToStream(F, OS, Level);
}

void IR2VecTool::writeEmbeddingsToStream(const Function &F, raw_ostream &OS,
                                         EmbeddingLevel Level) const {
  auto IR2VecEmbedderObj = getIR2VecEmbedder(F, IR2VecEmbeddingKind);
  if (!IR2VecEmbedderObj) {
    WithColor::error(errs(), ToolName)
        << toString(IR2VecEmbedderObj.takeError()) << "\n";
    return;
  }
  auto Emb = std::move(*IR2VecEmbedderObj);

  OS << "Function: " << F.getName() << "\n";

  // Generate embeddings based on the specified level
  switch (Level) {
  case FunctionLevel:
    Emb->getFunctionVector().print(OS);
    break;
  case BasicBlockLevel:
    for (const BasicBlock &BB : F) {
      OS << BB.getName() << ":";
      Emb->getBBVector(BB).print(OS);
    }
    break;
  case InstructionLevel:
    for (const Instruction &I : instructions(F)) {
      OS << I;
      Emb->getInstVector(I).print(OS);
    }

Review comment (suggestion):
Also, we seem to use `IR2VecEmbeddingKind` here and `Kind` at other places.

Code after:
  return Result;
}

Expected<InstEmbeddingsMap>
IR2VecTool::getInstEmbeddingsMap(const Function &F, IR2VecKind Kind) const {
  auto Emb = createIR2VecEmbedder(F, Kind);
  if (!Emb)
    return Emb.takeError();

  InstEmbeddingsMap Result;

  for (const Instruction &I : instructions(F))
    Result.try_emplace(&I, (*Emb)->getInstVector(I));

  return Result;
}

void IR2VecTool::writeEmbeddingsToStream(raw_ostream &OS,
                                         EmbeddingLevel Level) const {
  for (const Function &F : M.getFunctionDefs())
    writeEmbeddingsToStream(F, OS, Level);
}

void IR2VecTool::writeEmbeddingsToStream(const Function &F, raw_ostream &OS,
                                         EmbeddingLevel Level) const {
  auto IR2VecEmbedderObj = createIR2VecEmbedder(F, IR2VecEmbeddingKind);
  if (!IR2VecEmbedderObj) {
    WithColor::error(errs(), ToolName)
        << toString(IR2VecEmbedderObj.takeError()) << "\n";
    return;
  }
  auto Emb = std::move(*IR2VecEmbedderObj);

  OS << "Function: " << F.getName() << "\n";

  // Generate embeddings based on the specified level
  switch (Level) {
  case FunctionLevel:
    Emb->getFunctionVector().print(OS);
    break;
  case BasicBlockLevel:
    for (const BasicBlock &BB : F) {
      OS << BB.getName() << ":";
      Emb->getBBVector(BB).print(OS);
    }
    break;
  case InstructionLevel:
    for (const Instruction &I : instructions(F)) {
      OS << I;
      Emb->getInstVector(I).print(OS);
    }
Repository: llvm/llvm-project
File: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp (C++)

Code before:
      value = pcb13.lr;
      break;
    default:
      return false;
    }
  }
  return true;
}

bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  return false;
}

int64_t RegisterContextFreeBSDKernel_arm64::GetOsreldate() {
  ProcessSP process_sp = m_thread.GetProcess();
  if (!process_sp)
    return 0;

  Target &target = process_sp->GetTarget();

  SymbolContextList sc_list;
  target.GetImages().FindSymbolsWithNameAndType(ConstString("osreldate"),
                                                lldb::eSymbolTypeData, sc_list);

  if (sc_list.GetSize() > 0) {
    SymbolContext sc;
    sc_list.GetContextAtIndex(0, sc);

    if (sc.symbol) {
      lldb::addr_t addr = sc.symbol->GetLoadAddress(&target);
      if (addr != LLDB_INVALID_ADDRESS) {
        Status error;
        int64_t osreldate = 0;
        size_t bytes_read =
            process_sp->ReadMemory(addr, &osreldate, sizeof(osreldate), error);
        if (bytes_read == sizeof(osreldate) && error.Success()) {
          return osreldate;
        }
      }
    }
  }

  return 0;
}


Review comment (suggestion):
Prefer early returns where possible. Here for instance:
```
if (sc_list.GetSize() == 0)
  return 0;
```

Code after:
    case gpr_x27_arm64:
    case gpr_x28_arm64:
    case gpr_fp_arm64:
      static_assert(gpr_fp_arm64 - gpr_x0_arm64 == 29,
                    "nonconsecutive arm64 register numbers");
      value = pcb13.x[reg - gpr_x0_arm64];
      break;
    case gpr_sp_arm64:
      value = pcb13.sp;
      break;
    case gpr_pc_arm64:
      // The pc of crashing thread is stored in lr.
      value = pcb13.lr;
      break;
    default:
      return false;
    }
  }
  return true;
}

bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  return false;
}

std::optional<int> RegisterContextFreeBSDKernel_arm64::GetOsreldate() {
  ProcessSP process_sp = m_thread.GetProcess();
  if (!process_sp)
    return std::nullopt;

  Target &target = process_sp->GetTarget();

  SymbolContextList sc_list;
  target.GetImages().FindSymbolsWithNameAndType(ConstString("osreldate"),
                                                lldb::eSymbolTypeData, sc_list);
  if (sc_list.GetSize() == 0)
    return std::nullopt;

  SymbolContext sc;
  sc_list.GetContextAtIndex(0, sc);
  if (!sc.symbol)
    return std::nullopt;

  lldb::addr_t addr = sc.symbol->GetLoadAddress(&target);
  if (addr == LLDB_INVALID_ADDRESS)
    return std::nullopt;

  Status error;
  int osreldate = 0;
  size_t bytes_read =
Repository: llvm/llvm-project
File: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h (C/C++)

Code before:
//===-- RegisterContextFreeBSDKernel_arm64.h --------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H

#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"

#include "lldb/Target/Target.h"

class RegisterContextFreeBSDKernel_arm64 : public RegisterContextPOSIX_arm64 {
public:
  RegisterContextFreeBSDKernel_arm64(
      lldb_private::Thread &thread,
      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
      lldb::addr_t pcb_addr);

  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
                    lldb_private::RegisterValue &value) override;

  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
                     const lldb_private::RegisterValue &value) override;

protected:
  bool ReadGPR() override;

  bool ReadFPR() override;

  bool WriteGPR() override;

  bool WriteFPR() override;

private:
  lldb::addr_t m_pcb_addr;

Review comment (bug):
You have this in the cpp file too, you can remove this include. Unless it was broken to start with, in which case you can merge a fix for that without approval.

Code after:
//===-- RegisterContextFreeBSDKernel_arm64.h --------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H

#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"

#include <optional>

class RegisterContextFreeBSDKernel_arm64 : public RegisterContextPOSIX_arm64 {
public:
  RegisterContextFreeBSDKernel_arm64(
      lldb_private::Thread &thread,
      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
      lldb::addr_t pcb_addr);

  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
                    lldb_private::RegisterValue &value) override;

  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
                     const lldb_private::RegisterValue &value) override;

protected:
  bool ReadGPR() override;

  bool ReadFPR() override;

  bool WriteGPR() override;

  bool WriteFPR() override;

private:
  lldb::addr_t m_pcb_addr;
Repository: llvm/llvm-project
File: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp (C++)

Code before:
    lldb::addr_t pcb_addr)
    : RegisterContextPOSIX_arm64(thread, std::move(register_info_up)),
      m_pcb_addr(pcb_addr) {}

bool RegisterContextFreeBSDKernel_arm64::ReadGPR() { return true; }

bool RegisterContextFreeBSDKernel_arm64::ReadFPR() { return true; }

bool RegisterContextFreeBSDKernel_arm64::WriteGPR() {
  assert(0);
  return false;
}

bool RegisterContextFreeBSDKernel_arm64::WriteFPR() {
  assert(0);
  return false;
}

bool RegisterContextFreeBSDKernel_arm64::ReadRegister(
    const RegisterInfo *reg_info, RegisterValue &value) {
  if (m_pcb_addr == LLDB_INVALID_ADDRESS)
    return false;

  struct {
#define PCB_FP 10
#define PCB_LR 11
    llvm::support::ulittle64_t x[12];
    llvm::support::ulittle64_t sp;
  } pcb;

  struct {
    llvm::support::ulittle64_t x[30];
    llvm::support::ulittle64_t lr;
    llvm::support::ulittle64_t _reserved;
    llvm::support::ulittle64_t sp;
  } pcb13;

  Status error;

  // TODO: LLVM 24: Remove FreeBSD 13 support
  if (GetOsreldate() >= FBSD14) {
    size_t rd =
        m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
    if (rd != sizeof(pcb))
      return false;

    uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
    switch (reg) {
    case gpr_x19_arm64:
    case gpr_x20_arm64:
    case gpr_x21_arm64:

Review comment (suggestion):
Seems like these are only used in the 14+ path. So move them as close as you can to use and declare them as constant variables instead.
```
const uint32_t pcb_fp_index = 10;
...
```

Code after:
      m_pcb_addr(pcb_addr) {}

bool RegisterContextFreeBSDKernel_arm64::ReadGPR() { return true; }

bool RegisterContextFreeBSDKernel_arm64::ReadFPR() { return true; }

bool RegisterContextFreeBSDKernel_arm64::WriteGPR() {
  assert(0);
  return false;
}

bool RegisterContextFreeBSDKernel_arm64::WriteFPR() {
  assert(0);
  return false;
}

bool RegisterContextFreeBSDKernel_arm64::ReadRegister(
    const RegisterInfo *reg_info, RegisterValue &value) {
  if (m_pcb_addr == LLDB_INVALID_ADDRESS)
    return false;

  // https://cgit.freebsd.org/src/tree/sys/arm64/include/pcb.h
  struct {
    llvm::support::ulittle64_t x[12];
    llvm::support::ulittle64_t sp;
  } pcb;

  // https://cgit.freebsd.org/src/tree/sys/arm64/include/pcb.h?h=stable%2F13
  struct {
    llvm::support::ulittle64_t x[30];
    llvm::support::ulittle64_t lr;
    llvm::support::ulittle64_t _reserved;
    llvm::support::ulittle64_t sp;
  } pcb13;

  Status error;
  constexpr int FBSD14 = 1400084;
  int osreldate = FBSD14;

  if (auto osreldate_or_null = GetOsreldate())
    osreldate = *osreldate_or_null;
  else
    LLDB_LOGF(GetLog(LLDBLog::Object),
              "Cannot find osreldate. Defaulting to %d.", FBSD14);

  // TODO: LLVM 24: Remove FreeBSD 13 support
  if (osreldate >= FBSD14) {
    constexpr uint32_t PCB_FP = 10;
    constexpr uint32_t PCB_LR = 11;
    size_t rd =
        m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
Repository: llvm/llvm-project
File: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp (C++)

Code before:
bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  return false;
}

int RegisterContextFreeBSDKernel_arm64::GetOsreldate() {
  ProcessSP process_sp = m_thread.GetProcess();
  if (!process_sp)
    return 0;

  Target &target = process_sp->GetTarget();

  SymbolContextList sc_list;
  target.GetImages().FindSymbolsWithNameAndType(ConstString("osreldate"),
                                                lldb::eSymbolTypeData, sc_list);

  if (sc_list.GetSize() == 0) {
    LLDB_LOGF(GetLog(LLDBLog::Object),
              "Cannot find osreldate. Defaulting to %d.", FBSD14);
    return FBSD14;
  }

  SymbolContext sc;
  sc_list.GetContextAtIndex(0, sc);

  if (sc.symbol) {
    lldb::addr_t addr = sc.symbol->GetLoadAddress(&target);
    if (addr != LLDB_INVALID_ADDRESS) {
      Status error;
      int64_t osreldate = 0;
      size_t bytes_read =
          process_sp->ReadMemory(addr, &osreldate, sizeof(osreldate), error);
      if (bytes_read == sizeof(osreldate) && error.Success()) {
        return osreldate;
      }
    }
  }

  return 0;
}


Review comment (suggestion):
Early return where possible.
```
if (!sc.symbol)
  return 0;
```
And so on.

Code after:
      break;
    default:
      return false;
    }
  }
  return true;
}

bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  return false;
}

std::optional<int> RegisterContextFreeBSDKernel_arm64::GetOsreldate() {
  ProcessSP process_sp = m_thread.GetProcess();
  if (!process_sp)
    return std::nullopt;

  Target &target = process_sp->GetTarget();

  SymbolContextList sc_list;
  target.GetImages().FindSymbolsWithNameAndType(ConstString("osreldate"),
                                                lldb::eSymbolTypeData, sc_list);
  if (sc_list.GetSize() == 0)
    return std::nullopt;

  SymbolContext sc;
  sc_list.GetContextAtIndex(0, sc);
  if (!sc.symbol)
    return std::nullopt;

  lldb::addr_t addr = sc.symbol->GetLoadAddress(&target);
  if (addr == LLDB_INVALID_ADDRESS)
    return std::nullopt;

  Status error;
  int osreldate = 0;
  size_t bytes_read =
      process_sp->ReadMemory(addr, &osreldate, sizeof(osreldate), error);
  if (bytes_read == sizeof(osreldate) && error.Success())
    return osreldate;

  return std::nullopt;
}
Repository: llvm/llvm-project
File: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp (C++)

Code before:
  case gpr_x18_arm64:
  case gpr_x19_arm64:
  case gpr_x20_arm64:
  case gpr_x21_arm64:
  case gpr_x22_arm64:
  case gpr_x23_arm64:
  case gpr_x24_arm64:
  case gpr_x25_arm64:
  case gpr_x26_arm64:
  case gpr_x27_arm64:
  case gpr_x28_arm64:
  case gpr_fp_arm64:
    static_assert(gpr_fp_arm64 - gpr_x0_arm64 == 29,
                  "nonconsecutive arm64 register numbers");
    value = pcb.x[reg - gpr_x0_arm64];
    break;
  case gpr_sp_arm64:
    value = pcb.sp;
    break;
  case gpr_pc_arm64:
    // The pc of crashing thread is stored in lr.
    value = pcb.lr;
    break;
  default:
    return false;
  }
  return true;
}

bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  return false;
}


Review comment (bug):
This does the wrong thing for gpr_pc_arm64, it's one past the end, so reads sp. Presumably this is meant to be always `gpr_lr_arm64 - gpr_x19_arm64`, i.e. PCB_LR?

Code after:
    if (rd != sizeof(pcb))
      return false;

    uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
    switch (reg) {
    case gpr_x19_arm64:
    case gpr_x20_arm64:
    case gpr_x21_arm64:
    case gpr_x22_arm64:
    case gpr_x23_arm64:
    case gpr_x24_arm64:
    case gpr_x25_arm64:
    case gpr_x26_arm64:
    case gpr_x27_arm64:
    case gpr_x28_arm64:
    case gpr_fp_arm64:
      static_assert(gpr_fp_arm64 - gpr_x19_arm64 == PCB_FP,
                    "nonconsecutive arm64 register numbers");
      value = pcb.x[reg - gpr_x19_arm64];
      break;
    case gpr_lr_arm64:
    case gpr_pc_arm64:
      // The pc of crashing thread is stored in lr.
      static_assert(gpr_lr_arm64 - gpr_x19_arm64 == PCB_LR,
                    "nonconsecutive arm64 register numbers");
      value = pcb.x[reg - gpr_x19_arm64];
      break;
    case gpr_sp_arm64:
      value = pcb.sp;
      break;
    default:
      return false;
    }
  } else {
    size_t rd = m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb13,
                                                  sizeof(pcb13), error);
    if (rd != sizeof(pcb13))
      return false;

    uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
    switch (reg) {
    case gpr_x0_arm64:
    case gpr_x1_arm64:
    case gpr_x2_arm64:
    case gpr_x3_arm64:
    case gpr_x4_arm64:
    case gpr_x5_arm64:
    case gpr_x6_arm64:
    case gpr_x7_arm64:
    case gpr_x8_arm64:
    case gpr_x9_arm64: