================
@@ -480,3 +481,111 @@ CompilerType PlatformLinux::GetSiginfoType(const 
llvm::Triple &triple) {
   ast->CompleteTagDeclarationDefinition(siginfo_type);
   return siginfo_type;
 }
+
+static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp) {
+  if (!siginfo_sp)
+    return "";
+
+  lldb_private::LinuxSignals linux_signals;
+  int code = 
siginfo_sp->GetChildMemberWithName("si_code")->GetValueAsSigned(0);
+  int signo =
+      siginfo_sp->GetChildMemberWithName("si_signo")->GetValueAsSigned(-1);
+  // si_code = 0 is SI_NOINFO, we just want the description with nothing
+  // important
+  if (code == 0)
+    return linux_signals.GetSignalDescription(signo, code);
+
+  auto sifields = siginfo_sp->GetChildMemberWithName("_sifields");
+  if (!sifields)
+    return linux_signals.GetSignalDescription(signo, code);
+
+  // declare everything that we can populate later.
+  std::optional<lldb::addr_t> addr;
+  std::optional<lldb::addr_t> upper;
+  std::optional<lldb::addr_t> lower;
+  std::optional<uint32_t> pid;
+  std::optional<uint32_t> uid;
+
+  // The negative si_codes are special and mean this signal was sent from user
+  // space not the kernel. These take precedence because they break some of the
+  // invariants around kernel sent signals. Such as SIGSEGV won't have an
+  // address.
+  if (code < 0) {
+    auto sikill = sifields->GetChildMemberWithName("_kill");
+    if (sikill) {
+      auto pid_sp = sikill->GetChildMemberWithName("si_pid");
+      if (pid_sp)
+        pid = pid_sp->GetValueAsUnsigned(-1);
+      auto uid_sp = sikill->GetChildMemberWithName("si_uid");
+      if (uid_sp)
+        uid = uid_sp->GetValueAsUnsigned(-1);
+    }
+  } else {
+
+    switch (signo) {
+    case SIGILL:
+    case SIGFPE:
+    case SIGBUS: {
+      auto sigfault = sifields->GetChildMemberWithName("_sigfault");
+      if (!sigfault)
+        break;
+
+      auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
+      if (addr_sp)
+        addr = addr_sp->GetValueAsUnsigned(-1);
+      break;
+    }
+    case SIGSEGV: {
+      auto sigfault = sifields->GetChildMemberWithName("_sigfault");
+      if (!sigfault)
+        break;
+
+      auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
+      if (addr_sp)
+        addr = addr_sp->GetValueAsUnsigned(-1);
+
+      auto bounds_sp = sigfault->GetChildMemberWithName("_bounds");
+      if (!bounds_sp)
+        break;
+
+      auto addr_bnds_sp = bounds_sp->GetChildMemberWithName("_addr_bnd");
+      if (!addr_bnds_sp)
+        break;
+
+      auto lower_sp = addr_bnds_sp->GetChildMemberWithName("_lower");
+      if (lower_sp)
+        lower = lower_sp->GetValueAsUnsigned(-1);
+
+      auto upper_sp = addr_bnds_sp->GetChildMemberWithName("_upper");
+      if (upper_sp)
+        upper = upper_sp->GetValueAsUnsigned(-1);
+
+      break;
+    }
+    default:
+      break;
+    }
+  }
+
+  return linux_signals.GetSignalDescription(signo, code, addr, lower, upper,
+                                            uid, pid);
+}
+
+lldb::StopInfoSP PlatformLinux::GetStopInfoFromSiginfo(Thread &thread) {
+  ValueObjectSP siginfo_sp = thread.GetSiginfoValue();
+  if (!siginfo_sp)
+    return {};
+  auto signo_sp = siginfo_sp->GetChildMemberWithName("si_signo");
+  auto sicode_sp = siginfo_sp->GetChildMemberWithName("si_code");
+  if (!signo_sp || !sicode_sp)
+    return {};
+
+  std::string siginfo_description = GetDescriptionFromSiginfo(siginfo_sp);
+  if (siginfo_description.empty())
+    return StopInfo::CreateStopReasonWithSignal(
+        thread, signo_sp->GetValueAsUnsigned(-1));
+  else
----------------
labath wrote:

https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return

https://github.com/llvm/llvm-project/pull/140150
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to