mgorny updated this revision to Diff 401378.
mgorny added a comment.
Herald added a subscriber: fedor.sergeev.
Use `CreateStructForIdentifier()` whenever possible. Describe the remaining
union members.
Open question: do we care for 100% correct SPARC support? Given that it has
different `_sigfault` layout, it adds some complexity while LLDB doesn't seem
to support SPARC at all.
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
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits