mgorny updated this revision to Diff 401585.
mgorny added a comment.

Put the common test code into a common init function, add tests for armv7, 
arm64, i386, ppc64le.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117707/new/

https://reviews.llvm.org/D117707

Files:
  lldb/bindings/interface/SBPlatform.i
  lldb/include/lldb/API/SBPlatform.h
  lldb/include/lldb/API/SBType.h
  lldb/include/lldb/Target/Platform.h
  lldb/source/API/SBPlatform.cpp
  lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
  lldb/source/Plugins/Platform/Linux/PlatformLinux.h
  lldb/source/Target/Platform.cpp
  lldb/unittests/Platform/CMakeLists.txt
  lldb/unittests/Platform/PlatformLinuxTest.cpp
  lldb/unittests/Platform/tools/generate_siginfo.c

Index: lldb/unittests/Platform/tools/generate_siginfo.c
===================================================================
--- /dev/null
+++ lldb/unittests/Platform/tools/generate_siginfo.c
@@ -0,0 +1,97 @@
+//===-- generate_siginfo_linux.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
+//
+//===----------------------------------------------------------------------===//
+
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+
+siginfo_t siginfo;
+
+#define S() printf("  ExpectFields(siginfo_type, {\n");
+#define S2(subfield)                                                           \
+  printf("  ExpectStruct(union_type, \"%s\", {\n", #subfield);
+#define S3() printf("  ExpectBounds(union_type,\n");
+
+#define P(member)                                                              \
+  printf("    {\"%s\", %zd, %zd},\n", #member, offsetof(siginfo_t, member),    \
+         sizeof(siginfo.member));
+#define P2(member)                                                             \
+  printf("    {\"%s\", %zd, %zd},\n", #member,                                 \
+         offsetof(siginfo_t, member) - offsetof(siginfo_t, _sifields),         \
+         sizeof(siginfo.member));
+#define P2n(member, name)                                                      \
+  printf("    {\"%s\", %zd, %zd},\n", #name,                                   \
+         offsetof(siginfo_t, member) - offsetof(siginfo_t, _sifields),         \
+         sizeof(siginfo.member));
+#define P3n(member, name)                                                      \
+  printf("    {\"%s\", %zd, %zd},\n", #name,                                   \
+         offsetof(siginfo_t, member) -                                         \
+             offsetof(siginfo_t, _sifields._sigfault._bounds),                 \
+         sizeof(siginfo.member));
+
+#define E() printf("  });\n\n");
+#define E3() printf("  );\n\n");
+
+int main() {
+  S();
+  P(si_signo);
+  P(si_errno);
+  P(si_code);
+  P(_sifields);
+  E();
+
+  S2(_kill);
+  P2(si_pid);
+  P2(si_uid);
+  E();
+
+  S2(_timer);
+  P2n(si_timerid, si_tid);
+  P2(si_overrun);
+  P2n(_sifields._timer.si_sigval, si_sigval);
+  E();
+
+  S2(_rt);
+  P2(si_pid);
+  P2(si_uid);
+  P2n(_sifields._rt.si_sigval, si_sigval);
+  E();
+
+  S2(_sigchld);
+  P2(si_pid);
+  P2(si_uid);
+  P2(si_status);
+  P2(si_utime);
+  P2(si_stime);
+  E();
+
+  S2(_sigfault);
+  P2(si_addr);
+  P2(si_addr_lsb);
+  P2n(_sifields._sigfault._bounds, _bounds);
+  E();
+
+  S3();
+  P3n(_sifields._sigfault._bounds._addr_bnd._lower, _lower);
+  P3n(_sifields._sigfault._bounds._addr_bnd._upper, _upper);
+  P3n(_sifields._sigfault._bounds._pkey, _pkey);
+  E3();
+
+  S2(_sigpoll);
+  P2(si_band);
+  P2(si_fd);
+  E();
+
+  S2(_sigsys);
+  P2n(_sifields._sigsys._call_addr, _call_addr);
+  P2n(_sifields._sigsys._syscall, _syscall);
+  P2n(_sifields._sigsys._arch, _arch);
+  E();
+
+  return 0;
+}
Index: lldb/unittests/Platform/PlatformLinuxTest.cpp
===================================================================
--- /dev/null
+++ lldb/unittests/Platform/PlatformLinuxTest.cpp
@@ -0,0 +1,458 @@
+//===-- PlatformLinuxTest.cpp ---------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include <initializer_list>
+#include <tuple>
+
+#include "Plugins/Platform/Linux/PlatformLinux.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+#include "TestingSupport/SubsystemRAII.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Reproducer.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::repro;
+
+namespace {
+class PlatformLinuxTest : public ::testing::Test {
+  SubsystemRAII<FileSystem, HostInfo, TypeSystemClang> subsystems;
+  PlatformSP platform_sp;
+  DebuggerSP debugger_sp;
+  TargetSP target_sp;
+
+public:
+  CompilerType siginfo_type;
+
+  void SetUp() override {
+    llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None));
+    platform_linux::PlatformLinux::Initialize();
+  }
+
+  void TearDown() override {
+    platform_linux::PlatformLinux::Terminate();
+    Reproducer::Terminate();
+  }
+
+  typedef std::tuple<const char *, uint64_t, uint64_t> field_tuple;
+
+  void ExpectField(const CompilerType &container, field_tuple field) {
+    const char *name;
+    uint64_t offset, size;
+    std::tie(name, offset, size) = field;
+
+    SCOPED_TRACE(name);
+    CompilerType field_type;
+    uint64_t bit_offset;
+    ASSERT_NE(container.GetIndexOfFieldWithName(name, &field_type, &bit_offset),
+              UINT32_MAX);
+    EXPECT_EQ(bit_offset, offset * 8);
+    EXPECT_EQ(field_type.GetByteSize(nullptr), llvm::Optional<uint64_t>(size));
+  }
+
+  void ExpectFields(const CompilerType &container,
+                    std::initializer_list<field_tuple> fields) {
+    for (auto x : fields)
+      ExpectField(container, x);
+  }
+
+  void ExpectStruct(const CompilerType &container, const char *struct_name,
+                    std::initializer_list<field_tuple> fields) {
+    SCOPED_TRACE(llvm::formatv("_sifields.{0}", struct_name));
+    CompilerType struct_type;
+    ASSERT_NE(container.GetIndexOfFieldWithName(struct_name, &struct_type),
+              UINT32_MAX);
+    ExpectFields(struct_type, fields);
+  }
+
+  void ExpectBounds(const CompilerType &container, field_tuple addr_bnd_lower,
+                    field_tuple addr_bnd_upper, field_tuple pkey) {
+    CompilerType sigfault_type, bounds_type, addr_bnd_type;
+
+    SCOPED_TRACE("_sifields._sigfault._bounds");
+    ASSERT_NE(container.GetIndexOfFieldWithName("_sigfault", &sigfault_type),
+              UINT32_MAX);
+    ASSERT_NE(sigfault_type.GetIndexOfFieldWithName("_bounds", &bounds_type),
+              UINT32_MAX);
+    ExpectFields(bounds_type, {pkey});
+
+    SCOPED_TRACE("_addr_bnd");
+    ASSERT_NE(bounds_type.GetIndexOfFieldWithName("_addr_bnd", &addr_bnd_type),
+              UINT32_MAX);
+    ExpectFields(addr_bnd_type, {addr_bnd_lower, addr_bnd_upper});
+  }
+
+  void InitializeSiginfo(const char *triple) {
+    ArchSpec arch(triple);
+
+    platform_sp = platform_linux::PlatformLinux::CreateInstance(true, &arch);
+    Platform::SetHostPlatform(platform_sp);
+
+    debugger_sp = Debugger::CreateInstance();
+    ASSERT_TRUE(debugger_sp);
+
+    debugger_sp->GetTargetList().CreateTarget(
+        *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp);
+    ASSERT_TRUE(target_sp);
+
+    siginfo_type = platform_sp->GetSiginfoType(*target_sp);
+  }
+};
+
+} // namespace
+
+TEST_F(PlatformLinuxTest, TestSiginfoType_x86_64) {
+  InitializeSiginfo("x86_64-pc-linux");
+  ASSERT_TRUE(siginfo_type);
+
+  ExpectFields(siginfo_type, {
+                                 {"si_signo", 0, 4},
+                                 {"si_errno", 4, 4},
+                                 {"si_code", 8, 4},
+                             });
+
+  CompilerType union_type;
+  uint64_t union_bit_offset;
+  ASSERT_NE(siginfo_type.GetIndexOfFieldWithName("_sifields", &union_type,
+                                                 &union_bit_offset),
+            UINT32_MAX);
+  EXPECT_EQ(union_bit_offset, 16U * 8);
+
+  ExpectStruct(union_type, "_kill",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+               });
+
+  ExpectStruct(union_type, "_timer",
+               {
+                   {"si_tid", 0, 4},
+                   {"si_overrun", 4, 4},
+                   {"si_sigval", 8, 8},
+               });
+
+  ExpectStruct(union_type, "_rt",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_sigval", 8, 8},
+               });
+
+  ExpectStruct(union_type, "_sigchld",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_status", 8, 4},
+                   {"si_utime", 16, 8},
+                   {"si_stime", 24, 8},
+               });
+
+  ExpectStruct(union_type, "_sigfault",
+               {
+                   {"si_addr", 0, 8},
+                   {"si_addr_lsb", 8, 2},
+                   {"_bounds", 16, 16},
+               });
+
+  ExpectBounds(union_type, {"_lower", 0, 8}, {"_upper", 8, 8}, {"_pkey", 0, 4});
+
+  ExpectStruct(union_type, "_sigpoll",
+               {
+                   {"si_band", 0, 8},
+                   {"si_fd", 8, 4},
+               });
+
+  ExpectStruct(union_type, "_sigsys",
+               {
+                   {"_call_addr", 0, 8},
+                   {"_syscall", 8, 4},
+                   {"_arch", 12, 4},
+               });
+}
+
+TEST_F(PlatformLinuxTest, TestSiginfoType_i386) {
+  InitializeSiginfo("i386-pc-linux");
+  ASSERT_TRUE(siginfo_type);
+
+  ExpectFields(siginfo_type, {
+                                 {"si_signo", 0, 4},
+                                 {"si_errno", 4, 4},
+                                 {"si_code", 8, 4},
+                             });
+
+  CompilerType union_type;
+  uint64_t union_bit_offset;
+  ASSERT_NE(siginfo_type.GetIndexOfFieldWithName("_sifields", &union_type,
+                                                 &union_bit_offset),
+            UINT32_MAX);
+  EXPECT_EQ(union_bit_offset, 12U * 8);
+
+  ExpectStruct(union_type, "_kill",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+               });
+
+  ExpectStruct(union_type, "_timer",
+               {
+                   {"si_tid", 0, 4},
+                   {"si_overrun", 4, 4},
+                   {"si_sigval", 8, 4},
+               });
+
+  ExpectStruct(union_type, "_rt",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_sigval", 8, 4},
+               });
+
+  ExpectStruct(union_type, "_sigchld",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_status", 8, 4},
+                   {"si_utime", 12, 4},
+                   {"si_stime", 16, 4},
+               });
+
+  ExpectStruct(union_type, "_sigfault",
+               {
+                   {"si_addr", 0, 4},
+                   {"si_addr_lsb", 4, 2},
+                   {"_bounds", 8, 8},
+               });
+
+  ExpectBounds(union_type, {"_lower", 0, 4}, {"_upper", 4, 4}, {"_pkey", 0, 4});
+
+  ExpectStruct(union_type, "_sigpoll",
+               {
+                   {"si_band", 0, 4},
+                   {"si_fd", 4, 4},
+               });
+
+  ExpectStruct(union_type, "_sigsys",
+               {
+                   {"_call_addr", 0, 4},
+                   {"_syscall", 4, 4},
+                   {"_arch", 8, 4},
+               });
+}
+
+TEST_F(PlatformLinuxTest, TestSiginfoType_aarch64) {
+  InitializeSiginfo("aarch64-pc-linux");
+  ASSERT_TRUE(siginfo_type);
+
+  ExpectFields(siginfo_type, {
+                                 {"si_signo", 0, 4},
+                                 {"si_errno", 4, 4},
+                                 {"si_code", 8, 4},
+                             });
+
+  CompilerType union_type;
+  uint64_t union_bit_offset;
+  ASSERT_NE(siginfo_type.GetIndexOfFieldWithName("_sifields", &union_type,
+                                                 &union_bit_offset),
+            UINT32_MAX);
+  EXPECT_EQ(union_bit_offset, 16U * 8);
+
+  ExpectStruct(union_type, "_kill",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+               });
+
+  ExpectStruct(union_type, "_timer",
+               {
+                   {"si_tid", 0, 4},
+                   {"si_overrun", 4, 4},
+                   {"si_sigval", 8, 8},
+               });
+
+  ExpectStruct(union_type, "_rt",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_sigval", 8, 8},
+               });
+
+  ExpectStruct(union_type, "_sigchld",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_status", 8, 4},
+                   {"si_utime", 16, 8},
+                   {"si_stime", 24, 8},
+               });
+
+  ExpectStruct(union_type, "_sigfault",
+               {
+                   {"si_addr", 0, 8},
+                   {"si_addr_lsb", 8, 2},
+                   {"_bounds", 16, 16},
+               });
+
+  ExpectBounds(union_type, {"_lower", 0, 8}, {"_upper", 8, 8}, {"_pkey", 0, 4});
+
+  ExpectStruct(union_type, "_sigpoll",
+               {
+                   {"si_band", 0, 8},
+                   {"si_fd", 8, 4},
+               });
+
+  ExpectStruct(union_type, "_sigsys",
+               {
+                   {"_call_addr", 0, 8},
+                   {"_syscall", 8, 4},
+                   {"_arch", 12, 4},
+               });
+}
+
+TEST_F(PlatformLinuxTest, TestSiginfoType_arm) {
+  InitializeSiginfo("armv7-pc-linux");
+  ASSERT_TRUE(siginfo_type);
+
+  ExpectFields(siginfo_type, {
+                                 {"si_signo", 0, 4},
+                                 {"si_errno", 4, 4},
+                                 {"si_code", 8, 4},
+                             });
+
+  CompilerType union_type;
+  uint64_t union_bit_offset;
+  ASSERT_NE(siginfo_type.GetIndexOfFieldWithName("_sifields", &union_type,
+                                                 &union_bit_offset),
+            UINT32_MAX);
+  EXPECT_EQ(union_bit_offset, 12U * 8);
+
+  ExpectStruct(union_type, "_kill",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+               });
+
+  ExpectStruct(union_type, "_timer",
+               {
+                   {"si_tid", 0, 4},
+                   {"si_overrun", 4, 4},
+                   {"si_sigval", 8, 4},
+               });
+
+  ExpectStruct(union_type, "_rt",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_sigval", 8, 4},
+               });
+
+  ExpectStruct(union_type, "_sigchld",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_status", 8, 4},
+                   {"si_utime", 12, 4},
+                   {"si_stime", 16, 4},
+               });
+
+  ExpectStruct(union_type, "_sigfault",
+               {
+                   {"si_addr", 0, 4},
+                   {"si_addr_lsb", 4, 2},
+                   {"_bounds", 8, 8},
+               });
+
+  ExpectBounds(union_type, {"_lower", 0, 4}, {"_upper", 4, 4}, {"_pkey", 0, 4});
+
+  ExpectStruct(union_type, "_sigpoll",
+               {
+                   {"si_band", 0, 4},
+                   {"si_fd", 4, 4},
+               });
+
+  ExpectStruct(union_type, "_sigsys",
+               {
+                   {"_call_addr", 0, 4},
+                   {"_syscall", 4, 4},
+                   {"_arch", 8, 4},
+               });
+}
+
+TEST_F(PlatformLinuxTest, TestSiginfoType_ppc64le) {
+  InitializeSiginfo("powerpc64le-pc-linux");
+  ASSERT_TRUE(siginfo_type);
+
+  ExpectFields(siginfo_type, {
+                                 {"si_signo", 0, 4},
+                                 {"si_errno", 4, 4},
+                                 {"si_code", 8, 4},
+                             });
+
+  CompilerType union_type;
+  uint64_t union_bit_offset;
+  ASSERT_NE(siginfo_type.GetIndexOfFieldWithName("_sifields", &union_type,
+                                                 &union_bit_offset),
+            UINT32_MAX);
+  EXPECT_EQ(union_bit_offset, 16U * 8);
+
+  ExpectStruct(union_type, "_kill",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+               });
+
+  ExpectStruct(union_type, "_timer",
+               {
+                   {"si_tid", 0, 4},
+                   {"si_overrun", 4, 4},
+                   {"si_sigval", 8, 8},
+               });
+
+  ExpectStruct(union_type, "_rt",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_sigval", 8, 8},
+               });
+
+  ExpectStruct(union_type, "_sigchld",
+               {
+                   {"si_pid", 0, 4},
+                   {"si_uid", 4, 4},
+                   {"si_status", 8, 4},
+                   {"si_utime", 16, 8},
+                   {"si_stime", 24, 8},
+               });
+
+  ExpectStruct(union_type, "_sigfault",
+               {
+                   {"si_addr", 0, 8},
+                   {"si_addr_lsb", 8, 2},
+                   {"_bounds", 16, 16},
+               });
+
+  ExpectBounds(union_type, {"_lower", 0, 8}, {"_upper", 8, 8}, {"_pkey", 0, 4});
+
+  ExpectStruct(union_type, "_sigpoll",
+               {
+                   {"si_band", 0, 8},
+                   {"si_fd", 8, 4},
+               });
+
+  ExpectStruct(union_type, "_sigsys",
+               {
+                   {"_call_addr", 0, 8},
+                   {"_syscall", 8, 4},
+                   {"_arch", 12, 4},
+               });
+}
Index: lldb/unittests/Platform/CMakeLists.txt
===================================================================
--- lldb/unittests/Platform/CMakeLists.txt
+++ lldb/unittests/Platform/CMakeLists.txt
@@ -1,8 +1,10 @@
 add_lldb_unittest(LLDBPlatformTests
   PlatformAppleSimulatorTest.cpp
   PlatformDarwinTest.cpp
+  PlatformLinuxTest.cpp
 
   LINK_LIBS
+    lldbPluginPlatformLinux
     lldbPluginPlatformMacOSX
   LINK_COMPONENTS
     Support
Index: lldb/source/Target/Platform.cpp
===================================================================
--- lldb/source/Target/Platform.cpp
+++ lldb/source/Target/Platform.cpp
@@ -2003,3 +2003,7 @@
 
   return 0;
 }
+
+CompilerType Platform::GetSiginfoType(lldb_private::Target &target) {
+  return CompilerType();
+}
Index: lldb/source/Plugins/Platform/Linux/PlatformLinux.h
===================================================================
--- lldb/source/Plugins/Platform/Linux/PlatformLinux.h
+++ lldb/source/Plugins/Platform/Linux/PlatformLinux.h
@@ -58,6 +58,8 @@
                                   unsigned flags, lldb::addr_t fd,
                                   lldb::addr_t offset) override;
 
+  CompilerType GetSiginfoType(lldb_private::Target &target) override;
+
   std::vector<ArchSpec> m_supported_architectures;
 };
 
Index: lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
===================================================================
--- lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -14,6 +14,7 @@
 #include <sys/utsname.h>
 #endif
 
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "Utility/ARM64_DWARF_Registers.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/PluginManager.h"
@@ -309,3 +310,183 @@
   return args;
 }
 
+CompilerType PlatformLinux::GetSiginfoType(lldb_private::Target &target) {
+  CompilerType type;
+  TypeSystemClang *ast = ScratchTypeSystemClang::GetForTarget(target);
+  if (!ast)
+    return type;
+
+  const ArchSpec &arch = target.GetArchitecture();
+  bool is_64bit = arch.GetAddressByteSize() == 8;
+  bool si_errno_then_code = true;
+  bool si_band_type_is_int = false;
+
+  // TODO: do we actually care about sparc here? lldb doesn't seem to have
+  // any sparc support
+  switch (arch.GetMachine()) {
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+  case llvm::Triple::mips64:
+  case llvm::Triple::mips64el:
+    // mips has si_code and si_errno swapped
+    si_errno_then_code = false;
+    break;
+  case llvm::Triple::sparc:
+  case llvm::Triple::sparcel:
+  case llvm::Triple::sparcv9:
+    // sparc64 uses int for __SI_BAND_TYPE
+    if (is_64bit)
+      si_band_type_is_int = true;
+    break;
+  default:
+    break;
+  }
+
+  // generic types
+  CompilerType int_type = ast->GetBasicType(eBasicTypeInt);
+  CompilerType uint_type = ast->GetBasicType(eBasicTypeUnsignedInt);
+  CompilerType short_type = ast->GetBasicType(eBasicTypeShort);
+  CompilerType long_type = ast->GetBasicType(eBasicTypeLong);
+  CompilerType voidp_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+  // platform-specific types
+  CompilerType &pid_type = int_type;
+  CompilerType &uid_type = uint_type;
+  CompilerType &clock_type = long_type;
+  CompilerType &band_type = si_band_type_is_int ? int_type : long_type;
+
+  CompilerType sigval_type = ast->CreateRecordType(
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
+      clang::TTK_Union, lldb::eLanguageTypeC);
+  ast->StartTagDeclarationDefinition(sigval_type);
+  ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
+                            lldb::eAccessPublic, 0);
+  ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type,
+                            lldb::eAccessPublic, 0);
+  ast->CompleteTagDeclarationDefinition(sigval_type);
+
+  CompilerType sigfault_bounds_type = ast->CreateRecordType(
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
+      clang::TTK_Union, lldb::eLanguageTypeC);
+  ast->StartTagDeclarationDefinition(sigfault_bounds_type);
+  ast->AddFieldToRecordType(sigfault_bounds_type, "_addr_bnd",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"_lower", voidp_type},
+                                         {"_upper", voidp_type},
+                                     }),
+                            lldb::eAccessPublic, 0);
+  ast->AddFieldToRecordType(sigfault_bounds_type, "_pkey", uint_type,
+                            lldb::eAccessPublic, 0);
+  ast->CompleteTagDeclarationDefinition(sigfault_bounds_type);
+
+  // siginfo_t
+  CompilerType siginfo_type = ast->CreateRecordType(
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
+      clang::TTK_Struct, lldb::eLanguageTypeC);
+  ast->StartTagDeclarationDefinition(siginfo_type);
+  ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type,
+                            lldb::eAccessPublic, 0);
+
+  if (si_errno_then_code) {
+    ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type,
+                              lldb::eAccessPublic, 0);
+    ast->AddFieldToRecordType(siginfo_type, "si_code", int_type,
+                              lldb::eAccessPublic, 0);
+  } else {
+    ast->AddFieldToRecordType(siginfo_type, "si_code", int_type,
+                              lldb::eAccessPublic, 0);
+    ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type,
+                              lldb::eAccessPublic, 0);
+  }
+
+  // the structure is padded on 64-bit arches to fix alignment
+  if (is_64bit)
+    ast->AddFieldToRecordType(siginfo_type, "__pad0", int_type,
+                              lldb::eAccessPublic, 0);
+
+  // union used to hold the signal data
+  CompilerType union_type = ast->CreateRecordType(
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
+      clang::TTK_Union, lldb::eLanguageTypeC);
+  ast->StartTagDeclarationDefinition(union_type);
+
+  ast->AddFieldToRecordType(
+      union_type, "_kill",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"si_pid", pid_type},
+                                         {"si_uid", uid_type},
+                                     }),
+      lldb::eAccessPublic, 0);
+
+  ast->AddFieldToRecordType(
+      union_type, "_timer",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"si_tid", int_type},
+                                         {"si_overrun", int_type},
+                                         {"si_sigval", sigval_type},
+                                     }),
+      lldb::eAccessPublic, 0);
+
+  ast->AddFieldToRecordType(
+      union_type, "_rt",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"si_pid", pid_type},
+                                         {"si_uid", uid_type},
+                                         {"si_sigval", sigval_type},
+                                     }),
+      lldb::eAccessPublic, 0);
+
+  ast->AddFieldToRecordType(
+      union_type, "_sigchld",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"si_pid", pid_type},
+                                         {"si_uid", uid_type},
+                                         {"si_status", int_type},
+                                         {"si_utime", clock_type},
+                                         {"si_stime", clock_type},
+                                     }),
+      lldb::eAccessPublic, 0);
+
+  ast->AddFieldToRecordType(
+      union_type, "_sigfault",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"si_addr", voidp_type},
+                                         // NB: sparc has extra _si_trapno here
+                                         {"si_addr_lsb", short_type},
+                                         {"_bounds", sigfault_bounds_type},
+                                     }),
+      lldb::eAccessPublic, 0);
+
+  ast->AddFieldToRecordType(
+      union_type, "_sigpoll",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"si_band", band_type},
+                                         {"si_fd", int_type},
+                                     }),
+      lldb::eAccessPublic, 0);
+
+  // NB: SIGSYS is not present on ia64 but we don't seem to support that
+  ast->AddFieldToRecordType(
+      union_type, "_sigsys",
+      ast->CreateStructForIdentifier(ConstString(),
+                                     {
+                                         {"_call_addr", voidp_type},
+                                         {"_syscall", int_type},
+                                         {"_arch", uint_type},
+                                     }),
+      lldb::eAccessPublic, 0);
+
+  ast->CompleteTagDeclarationDefinition(union_type);
+  ast->AddFieldToRecordType(siginfo_type, "_sifields", union_type,
+                            lldb::eAccessPublic, 0);
+
+  ast->CompleteTagDeclarationDefinition(siginfo_type);
+  return siginfo_type;
+}
Index: lldb/source/API/SBPlatform.cpp
===================================================================
--- lldb/source/API/SBPlatform.cpp
+++ lldb/source/API/SBPlatform.cpp
@@ -13,6 +13,8 @@
 #include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBLaunchInfo.h"
 #include "lldb/API/SBPlatform.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBType.h"
 #include "lldb/API/SBUnixSignals.h"
 #include "lldb/Host/File.h"
 #include "lldb/Target/Platform.h"
@@ -691,3 +693,17 @@
 
   return SBEnvironment();
 }
+
+SBType SBPlatform::GetSiginfoType(const lldb::SBTarget &target) {
+  LLDB_RECORD_METHOD(lldb::SBType, SBPlatform, GetSiginfoType,
+                     (lldb::Target &), target);
+
+  PlatformSP platform_sp(GetSP());
+  TargetSP target_sp(target.GetSP());
+
+  if (platform_sp && target_sp)
+    return SBType(platform_sp->GetSiginfoType(*target_sp));
+
+  assert(target_sp);
+  return SBType();
+}
Index: lldb/include/lldb/Target/Platform.h
===================================================================
--- lldb/include/lldb/Target/Platform.h
+++ lldb/include/lldb/Target/Platform.h
@@ -863,6 +863,8 @@
     return nullptr;
   }
 
+  virtual CompilerType GetSiginfoType(lldb_private::Target &target);
+
 protected:
   /// Create a list of ArchSpecs with the given OS and a architectures. The
   /// vendor field is left as an "unspecified unknown".
Index: lldb/include/lldb/API/SBType.h
===================================================================
--- lldb/include/lldb/API/SBType.h
+++ lldb/include/lldb/API/SBType.h
@@ -224,6 +224,7 @@
 
   friend class SBFunction;
   friend class SBModule;
+  friend class SBPlatform;
   friend class SBTarget;
   friend class SBTypeEnumMember;
   friend class SBTypeEnumMemberList;
Index: lldb/include/lldb/API/SBPlatform.h
===================================================================
--- lldb/include/lldb/API/SBPlatform.h
+++ lldb/include/lldb/API/SBPlatform.h
@@ -169,6 +169,8 @@
   ///     environment.
   SBEnvironment GetEnvironment();
 
+  SBType GetSiginfoType(const lldb::SBTarget &target);
+
 protected:
   friend class SBDebugger;
   friend class SBTarget;
Index: lldb/bindings/interface/SBPlatform.i
===================================================================
--- lldb/bindings/interface/SBPlatform.i
+++ lldb/bindings/interface/SBPlatform.i
@@ -213,6 +213,9 @@
     lldb::SBEnvironment
     GetEnvironment();
 
+    lldb::SBType
+    GetSiginfoType(lldb::SBTarget &target);
+
 };
 
 } // namespace lldb
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to