================
@@ -1946,146 +1947,169 @@ size_t 
Platform::ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
   return 0;
 }
 
-size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
-                                                 BreakpointSite *bp_site) {
-  ArchSpec arch = target.GetArchitecture();
-  assert(arch.IsValid());
-  const uint8_t *trap_opcode = nullptr;
-  size_t trap_opcode_size = 0;
+llvm::ArrayRef<uint8_t> Platform::SoftwareTrapOpcodeBytes(const ArchSpec &arch,
+                                                          size_t size_hint) {
+  llvm::ArrayRef<uint8_t> trap_opcode;
 
   switch (arch.GetMachine()) {
   case llvm::Triple::aarch64_32:
   case llvm::Triple::aarch64: {
     static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
-    trap_opcode = g_aarch64_opcode;
-    trap_opcode_size = sizeof(g_aarch64_opcode);
+    trap_opcode =
+        llvm::ArrayRef<uint8_t>(g_aarch64_opcode, sizeof(g_aarch64_opcode));
   } break;
 
   case llvm::Triple::arc: {
-    static const uint8_t g_hex_opcode[] = { 0xff, 0x7f };
-    trap_opcode = g_hex_opcode;
-    trap_opcode_size = sizeof(g_hex_opcode);
+    static const uint8_t g_hex_opcode[] = {0xff, 0x7f};
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_hex_opcode, sizeof(g_hex_opcode));
   } break;
 
-  // TODO: support big-endian arm and thumb trap codes.
   case llvm::Triple::arm: {
-    // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
-    // linux kernel does otherwise.
+    // ARM CPUs have dedicated BKPT instructions: 0xe7fddefe and 0xdefe.
+    // However, the linux kernel recognizes two different sequences based on
+    // undefined instruction encodings (linux/arch/arm/kernel/ptrace.c)
     static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
     static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
 
-    lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetConstituentAtIndex(0));
-    AddressClass addr_class = AddressClass::eUnknown;
-
-    if (bp_loc_sp) {
-      addr_class = bp_loc_sp->GetAddress().GetAddressClass();
-      if (addr_class == AddressClass::eUnknown &&
-          (bp_loc_sp->GetAddress().GetFileAddress() & 1))
-        addr_class = AddressClass::eCodeAlternateISA;
-    }
-
-    if (addr_class == AddressClass::eCodeAlternateISA) {
-      trap_opcode = g_thumb_breakpoint_opcode;
-      trap_opcode_size = sizeof(g_thumb_breakpoint_opcode);
+    if (size_hint == 2) {
+      trap_opcode = llvm::ArrayRef<uint8_t>(g_thumb_breakpoint_opcode,
+                                            sizeof(g_thumb_breakpoint_opcode));
     } else {
-      trap_opcode = g_arm_breakpoint_opcode;
-      trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
+      trap_opcode = llvm::ArrayRef<uint8_t>(g_arm_breakpoint_opcode,
+                                            sizeof(g_arm_breakpoint_opcode));
     }
   } break;
 
   case llvm::Triple::avr: {
     static const uint8_t g_hex_opcode[] = {0x98, 0x95};
-    trap_opcode = g_hex_opcode;
-    trap_opcode_size = sizeof(g_hex_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_hex_opcode, sizeof(g_hex_opcode));
   } break;
 
   case llvm::Triple::mips:
   case llvm::Triple::mips64: {
     static const uint8_t g_hex_opcode[] = {0x00, 0x00, 0x00, 0x0d};
-    trap_opcode = g_hex_opcode;
-    trap_opcode_size = sizeof(g_hex_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_hex_opcode, sizeof(g_hex_opcode));
   } break;
 
   case llvm::Triple::mipsel:
   case llvm::Triple::mips64el: {
     static const uint8_t g_hex_opcode[] = {0x0d, 0x00, 0x00, 0x00};
-    trap_opcode = g_hex_opcode;
-    trap_opcode_size = sizeof(g_hex_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_hex_opcode, sizeof(g_hex_opcode));
   } break;
 
   case llvm::Triple::msp430: {
     static const uint8_t g_msp430_opcode[] = {0x43, 0x43};
-    trap_opcode = g_msp430_opcode;
-    trap_opcode_size = sizeof(g_msp430_opcode);
+    trap_opcode =
+        llvm::ArrayRef<uint8_t>(g_msp430_opcode, sizeof(g_msp430_opcode));
   } break;
 
   case llvm::Triple::systemz: {
     static const uint8_t g_hex_opcode[] = {0x00, 0x01};
-    trap_opcode = g_hex_opcode;
-    trap_opcode_size = sizeof(g_hex_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_hex_opcode, sizeof(g_hex_opcode));
   } break;
 
   case llvm::Triple::hexagon: {
     static const uint8_t g_hex_opcode[] = {0x0c, 0xdb, 0x00, 0x54};
-    trap_opcode = g_hex_opcode;
-    trap_opcode_size = sizeof(g_hex_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_hex_opcode, sizeof(g_hex_opcode));
   } break;
 
   case llvm::Triple::ppc:
   case llvm::Triple::ppc64: {
     static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08};
-    trap_opcode = g_ppc_opcode;
-    trap_opcode_size = sizeof(g_ppc_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_ppc_opcode, sizeof(g_ppc_opcode));
   } break;
 
   case llvm::Triple::ppc64le: {
     static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
-    trap_opcode = g_ppc64le_opcode;
-    trap_opcode_size = sizeof(g_ppc64le_opcode);
+    trap_opcode =
+        llvm::ArrayRef<uint8_t>(g_ppc64le_opcode, sizeof(g_ppc64le_opcode));
   } break;
 
   case llvm::Triple::x86:
   case llvm::Triple::x86_64: {
     static const uint8_t g_i386_opcode[] = {0xCC};
-    trap_opcode = g_i386_opcode;
-    trap_opcode_size = sizeof(g_i386_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_i386_opcode, 
sizeof(g_i386_opcode));
   } break;
 
   case llvm::Triple::riscv32:
   case llvm::Triple::riscv64: {
     static const uint8_t g_riscv_opcode[] = {0x73, 0x00, 0x10, 0x00}; // ebreak
     static const uint8_t g_riscv_opcode_c[] = {0x02, 0x90}; // c.ebreak
-    if (arch.GetFlags() & ArchSpec::eRISCV_rvc) {
+    if (size_hint == 2) {
       trap_opcode = g_riscv_opcode_c;
-      trap_opcode_size = sizeof(g_riscv_opcode_c);
     } else {
-      trap_opcode = g_riscv_opcode;
-      trap_opcode_size = sizeof(g_riscv_opcode);
+      trap_opcode =
+          llvm::ArrayRef<uint8_t>(g_riscv_opcode, sizeof(g_riscv_opcode));
     }
   } break;
 
   case llvm::Triple::loongarch32:
   case llvm::Triple::loongarch64: {
     static const uint8_t g_loongarch_opcode[] = {0x05, 0x00, 0x2a,
                                                  0x00}; // break 0x5
-    trap_opcode = g_loongarch_opcode;
-    trap_opcode_size = sizeof(g_loongarch_opcode);
+    trap_opcode =
+        llvm::ArrayRef<uint8_t>(g_loongarch_opcode, 
sizeof(g_loongarch_opcode));
   } break;
 
+  // Unreachable (0x00) triggers an unconditional trap.
   case llvm::Triple::wasm32: {
-    // Unreachable (0x00) triggers an unconditional trap.
     static const uint8_t g_wasm_opcode[] = {0x00};
-    trap_opcode = g_wasm_opcode;
-    trap_opcode_size = sizeof(g_wasm_opcode);
+    trap_opcode = llvm::ArrayRef<uint8_t>(g_wasm_opcode, 
sizeof(g_wasm_opcode));
   } break;
+  // The default case should not match against anything, so return empty Array
+  default: {
+    trap_opcode = llvm::ArrayRef<uint8_t>{};
+  };
+  }
+  return trap_opcode;
+}
 
-  default:
-    return 0;
+size_t Platform::GetTrapOpcodeSizeHint(Target &target, Address addr,
+                                       llvm::ArrayRef<uint8_t> bytes) {
+  ArchSpec arch = target.GetArchitecture();
+  assert(arch.IsValid());
+  const auto &triple = arch.GetTriple();
+
+  if (bytes.size() && triple.isRISCV()) {
+    // RISC-V instructions have the two LSB as 0b11 if they are four-byte
+    return (bytes[0] & 0b11) == 0b11 ? 4 : 2;
+  }
+
+  if (triple.isARM()) {
+    if (auto addr_class = addr.GetAddressClass();
+        addr_class == AddressClass::eCodeAlternateISA) {
+      return 2;
+    }
+  }
+  return 0;
+}
+
+size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
+                                                 BreakpointSite *bp_site) {
+  ArchSpec arch = target.GetArchitecture();
+  assert(arch.IsValid());
+  AddressClass addr_class = AddressClass::eUnknown;
+  if (bp_site) {
+    // TODO: support big-endian arm and thumb trap codes.
----------------
DavidSpickett wrote:

I suspect this TODO can live here for a few decades until anyone notices it, 
which is not a bad thing.

But could you tell me what would be involved in supporting it?

Istr that for AArch64 even on big endian systems, the instructions still come 
out little endian in some form. But same deal there, we do try to include big 
endian but the user base is narrow enough I've never seen an lldb bug report 
for it (llvm codegen we do get a decent amount).

https://github.com/llvm/llvm-project/pull/174348
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to