180814287SRaphael Isemann //===-- PlatformLinux.cpp -------------------------------------------------===// 2e996fd30SGreg Clayton // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e996fd30SGreg Clayton // 7e996fd30SGreg Clayton //===----------------------------------------------------------------------===// 8e996fd30SGreg Clayton 9e996fd30SGreg Clayton #include "PlatformLinux.h" 10b2f1fb29SVirgile Bello #include "lldb/Host/Config.h" 11e996fd30SGreg Clayton 1276e47d48SRaphael Isemann #include <cstdio> 133011d55fSJonas Devlieghere #if LLDB_ENABLE_POSIX 14ecc11474SStephen Wilson #include <sys/utsname.h> 15b2f1fb29SVirgile Bello #endif 16ecc11474SStephen Wilson 179db2541dSDavid Spickett #include "Utility/ARM64_DWARF_Registers.h" 1828041352SGreg Clayton #include "lldb/Core/Debugger.h" 19ecc11474SStephen Wilson #include "lldb/Core/PluginManager.h" 2013b18261SZachary Turner #include "lldb/Host/HostInfo.h" 219db2541dSDavid Spickett #include "lldb/Symbol/UnwindPlan.h" 22e996fd30SGreg Clayton #include "lldb/Target/Process.h" 23b9c1b51eSKate Stone #include "lldb/Target/Target.h" 245713a05bSZachary Turner #include "lldb/Utility/FileSpec.h" 256f9e6901SZachary Turner #include "lldb/Utility/Log.h" 26d821c997SPavel Labath #include "lldb/Utility/State.h" 2797206d57SZachary Turner #include "lldb/Utility/Status.h" 28bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 29e996fd30SGreg Clayton 3005097246SAdrian Prantl // Define these constants from Linux mman.h for use when targeting remote linux 3105097246SAdrian Prantl // systems even when host has different values. 3296ad3de5SRobert Flack #define MAP_PRIVATE 2 3396ad3de5SRobert Flack #define MAP_ANON 0x20 3496ad3de5SRobert Flack 35e996fd30SGreg Clayton using namespace lldb; 36e996fd30SGreg Clayton using namespace lldb_private; 37db264a6dSTamas Berghammer using namespace lldb_private::platform_linux; 38e996fd30SGreg Clayton 39bba9ba8dSJonas Devlieghere LLDB_PLUGIN_DEFINE(PlatformLinux) 40fbb4d1e4SJonas Devlieghere 4128041352SGreg Clayton static uint32_t g_initialize_count = 0; 4228041352SGreg Clayton 43281961a8STodd Fiala 44b9c1b51eSKate Stone PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) { 45*a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Platform); 460e92fbb5SPavel Labath LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force, 470e92fbb5SPavel Labath arch ? arch->GetArchitectureName() : "<null>", 480e92fbb5SPavel Labath arch ? arch->GetTriple().getTriple() : "<null>"); 49015d818bSTodd Fiala 50b3a40ba8SGreg Clayton bool create = force; 51a6682a41SJonas Devlieghere if (!create && arch && arch->IsValid()) { 52b3a40ba8SGreg Clayton const llvm::Triple &triple = arch->GetTriple(); 53b9c1b51eSKate Stone switch (triple.getOS()) { 5470512317SGreg Clayton case llvm::Triple::Linux: 55b1da257aSTed Woodward create = true; 5670512317SGreg Clayton break; 5770512317SGreg Clayton 58dbc6c0bbSGreg Clayton #if defined(__linux__) 5905097246SAdrian Prantl // Only accept "unknown" for the OS if the host is linux and it "unknown" 6005097246SAdrian Prantl // wasn't specified (it was just returned because it was NOT specified) 61015d818bSTodd Fiala case llvm::Triple::OSType::UnknownOS: 6270512317SGreg Clayton create = !arch->TripleOSWasSpecified(); 6370512317SGreg Clayton break; 64dbc6c0bbSGreg Clayton #endif 6570512317SGreg Clayton default: 6670512317SGreg Clayton break; 6770512317SGreg Clayton } 6870512317SGreg Clayton } 69015d818bSTodd Fiala 700e92fbb5SPavel Labath LLDB_LOG(log, "create = {0}", create); 71b9c1b51eSKate Stone if (create) { 72615eb7e6SGreg Clayton return PlatformSP(new PlatformLinux(false)); 73015d818bSTodd Fiala } 74615eb7e6SGreg Clayton return PlatformSP(); 75ecc11474SStephen Wilson } 76ecc11474SStephen Wilson 77a458ef4fSPavel Labath llvm::StringRef PlatformLinux::GetPluginDescriptionStatic(bool is_host) { 7828041352SGreg Clayton if (is_host) 7928041352SGreg Clayton return "Local Linux user platform plug-in."; 8028041352SGreg Clayton return "Remote Linux user platform plug-in."; 81ecc11474SStephen Wilson } 82ecc11474SStephen Wilson 83b9c1b51eSKate Stone void PlatformLinux::Initialize() { 843c4f89d7STamas Berghammer PlatformPOSIX::Initialize(); 853c4f89d7STamas Berghammer 86b9c1b51eSKate Stone if (g_initialize_count++ == 0) { 871c6a1ea9STamas Berghammer #if defined(__linux__) && !defined(__ANDROID__) 8828041352SGreg Clayton PlatformSP default_platform_sp(new PlatformLinux(true)); 8913b18261SZachary Turner default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); 90615eb7e6SGreg Clayton Platform::SetHostPlatform(default_platform_sp); 9128041352SGreg Clayton #endif 92b9c1b51eSKate Stone PluginManager::RegisterPlugin( 93b9c1b51eSKate Stone PlatformLinux::GetPluginNameStatic(false), 9428041352SGreg Clayton PlatformLinux::GetPluginDescriptionStatic(false), 95d65ac229SPavel Labath PlatformLinux::CreateInstance, nullptr); 96ecc11474SStephen Wilson } 97e996fd30SGreg Clayton } 98e996fd30SGreg Clayton 99b9c1b51eSKate Stone void PlatformLinux::Terminate() { 100b9c1b51eSKate Stone if (g_initialize_count > 0) { 101b9c1b51eSKate Stone if (--g_initialize_count == 0) { 10228041352SGreg Clayton PluginManager::UnregisterPlugin(PlatformLinux::CreateInstance); 103e996fd30SGreg Clayton } 10428041352SGreg Clayton } 1053c4f89d7STamas Berghammer 1063c4f89d7STamas Berghammer PlatformPOSIX::Terminate(); 10728041352SGreg Clayton } 108e996fd30SGreg Clayton 109e996fd30SGreg Clayton /// Default Constructor 110b9c1b51eSKate Stone PlatformLinux::PlatformLinux(bool is_host) 111b9c1b51eSKate Stone : PlatformPOSIX(is_host) // This is the local host platform 112669e57ebSPavel Labath { 113669e57ebSPavel Labath if (is_host) { 114e49b8e06SRobert Flack ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 115669e57ebSPavel Labath m_supported_architectures.push_back(hostArch); 116669e57ebSPavel Labath if (hostArch.GetTriple().isArch64Bit()) { 117669e57ebSPavel Labath m_supported_architectures.push_back( 118669e57ebSPavel Labath HostInfo::GetArchitecture(HostInfo::eArchKind32)); 119e49b8e06SRobert Flack } 120b9c1b51eSKate Stone } else { 121669e57ebSPavel Labath m_supported_architectures = CreateArchList( 122669e57ebSPavel Labath {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::arm, 123669e57ebSPavel Labath llvm::Triple::aarch64, llvm::Triple::mips64, llvm::Triple::mips64, 124669e57ebSPavel Labath llvm::Triple::hexagon, llvm::Triple::mips, llvm::Triple::mips64el, 125669e57ebSPavel Labath llvm::Triple::mipsel, llvm::Triple::systemz}, 126669e57ebSPavel Labath llvm::Triple::Linux); 127669e57ebSPavel Labath } 128669e57ebSPavel Labath } 129669e57ebSPavel Labath 130669e57ebSPavel Labath std::vector<ArchSpec> PlatformLinux::GetSupportedArchitectures() { 131e49b8e06SRobert Flack if (m_remote_platform_sp) 132669e57ebSPavel Labath return m_remote_platform_sp->GetSupportedArchitectures(); 133669e57ebSPavel Labath return m_supported_architectures; 134e996fd30SGreg Clayton } 135ecc11474SStephen Wilson 136b9c1b51eSKate Stone void PlatformLinux::GetStatus(Stream &strm) { 1373be69dacSDaniel Malea Platform::GetStatus(strm); 138ecc11474SStephen Wilson 1393011d55fSJonas Devlieghere #if LLDB_ENABLE_POSIX 140b743a803SStephane Sezer // Display local kernel information only when we are running in host mode. 14105097246SAdrian Prantl // Otherwise, we would end up printing non-Linux information (when running on 14205097246SAdrian Prantl // Mac OS for example). 143b9c1b51eSKate Stone if (IsHost()) { 144b2f1fb29SVirgile Bello struct utsname un; 145b2f1fb29SVirgile Bello 1463be69dacSDaniel Malea if (uname(&un)) 1473be69dacSDaniel Malea return; 1483be69dacSDaniel Malea 1493be69dacSDaniel Malea strm.Printf(" Kernel: %s\n", un.sysname); 1503be69dacSDaniel Malea strm.Printf(" Release: %s\n", un.release); 1513be69dacSDaniel Malea strm.Printf(" Version: %s\n", un.version); 152b743a803SStephane Sezer } 153b2f1fb29SVirgile Bello #endif 154ecc11474SStephen Wilson } 155ecc11474SStephen Wilson 15645c3fc97SRaphael Isemann uint32_t 157b9c1b51eSKate Stone PlatformLinux::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) { 15845c3fc97SRaphael Isemann uint32_t resume_count = 0; 15928041352SGreg Clayton 160348fb385STodd Fiala // Always resume past the initial stop when we use eLaunchFlagDebug 161b9c1b51eSKate Stone if (launch_info.GetFlags().Test(eLaunchFlagDebug)) { 162348fb385STodd Fiala // Resume past the stop for the final exec into the true inferior. 163348fb385STodd Fiala ++resume_count; 164348fb385STodd Fiala } 165015d818bSTodd Fiala 166348fb385STodd Fiala // If we're not launching a shell, we're done. 16710687b0eSZachary Turner const FileSpec &shell = launch_info.GetShell(); 16810687b0eSZachary Turner if (!shell) 169348fb385STodd Fiala return resume_count; 170348fb385STodd Fiala 17110687b0eSZachary Turner std::string shell_string = shell.GetPath(); 172348fb385STodd Fiala // We're in a shell, so for sure we have to resume past the shell exec. 173348fb385STodd Fiala ++resume_count; 174348fb385STodd Fiala 175348fb385STodd Fiala // Figure out what shell we're planning on using. 17610687b0eSZachary Turner const char *shell_name = strrchr(shell_string.c_str(), '/'); 177248a1305SKonrad Kleine if (shell_name == nullptr) 17810687b0eSZachary Turner shell_name = shell_string.c_str(); 17928041352SGreg Clayton else 180348fb385STodd Fiala shell_name++; 181348fb385STodd Fiala 182b9c1b51eSKate Stone if (strcmp(shell_name, "csh") == 0 || strcmp(shell_name, "tcsh") == 0 || 183b9c1b51eSKate Stone strcmp(shell_name, "zsh") == 0 || strcmp(shell_name, "sh") == 0) { 184348fb385STodd Fiala // These shells seem to re-exec themselves. Add another resume. 185348fb385STodd Fiala ++resume_count; 186ecc11474SStephen Wilson } 18713e8e1c3SJohnny Chen 188348fb385STodd Fiala return resume_count; 189348fb385STodd Fiala } 190348fb385STodd Fiala 191b9c1b51eSKate Stone bool PlatformLinux::CanDebugProcess() { 192b9c1b51eSKate Stone if (IsHost()) { 193b36f9178SPavel Labath return true; 194b9c1b51eSKate Stone } else { 195015d818bSTodd Fiala // If we're connected, we can debug. 196015d818bSTodd Fiala return IsConnected(); 197015d818bSTodd Fiala } 198348fb385STodd Fiala } 199015d818bSTodd Fiala 200b9c1b51eSKate Stone void PlatformLinux::CalculateTrapHandlerSymbolNames() { 2012094dbf4SJason Molenda m_trap_handlers.push_back(ConstString("_sigtramp")); 2023fd917d8SJoseph Tremoulet m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn")); 2033fd917d8SJoseph Tremoulet m_trap_handlers.push_back(ConstString("__restore_rt")); 2042094dbf4SJason Molenda } 205af245d11STodd Fiala 2069db2541dSDavid Spickett static lldb::UnwindPlanSP GetAArch64TrapHanlderUnwindPlan(ConstString name) { 2079db2541dSDavid Spickett UnwindPlanSP unwind_plan_sp; 2089db2541dSDavid Spickett if (name != "__kernel_rt_sigreturn") 2099db2541dSDavid Spickett return unwind_plan_sp; 2109db2541dSDavid Spickett 2119db2541dSDavid Spickett UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>(); 2129db2541dSDavid Spickett row->SetOffset(0); 2139db2541dSDavid Spickett 2149db2541dSDavid Spickett // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: 2159db2541dSDavid Spickett // - 128-byte siginfo struct 2169db2541dSDavid Spickett // - ucontext struct: 2179db2541dSDavid Spickett // - 8-byte long (uc_flags) 2189db2541dSDavid Spickett // - 8-byte pointer (uc_link) 2199db2541dSDavid Spickett // - 24-byte stack_t 2209db2541dSDavid Spickett // - 128-byte signal set 2219db2541dSDavid Spickett // - 8 bytes of padding because sigcontext has 16-byte alignment 2229db2541dSDavid Spickett // - sigcontext/mcontext_t 2239db2541dSDavid Spickett // [1] 2249db2541dSDavid Spickett // https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c 2259db2541dSDavid Spickett int32_t offset = 128 + 8 + 8 + 24 + 128 + 8; 2269db2541dSDavid Spickett // Then sigcontext[2] is: 2279db2541dSDavid Spickett // - 8 byte fault address 2289db2541dSDavid Spickett // - 31 8 byte registers 2299db2541dSDavid Spickett // - 8 byte sp 2309db2541dSDavid Spickett // - 8 byte pc 2319db2541dSDavid Spickett // [2] 2329db2541dSDavid Spickett // https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/sigcontext.h 2339db2541dSDavid Spickett 2349db2541dSDavid Spickett // Skip fault address 2359db2541dSDavid Spickett offset += 8; 2369db2541dSDavid Spickett row->GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, offset); 2379db2541dSDavid Spickett 2389db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x0, 0 * 8, false); 2399db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x1, 1 * 8, false); 2409db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x2, 2 * 8, false); 2419db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x3, 3 * 8, false); 2429db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x4, 4 * 8, false); 2439db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x5, 5 * 8, false); 2449db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x6, 6 * 8, false); 2459db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x7, 7 * 8, false); 2469db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x8, 8 * 8, false); 2479db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x9, 9 * 8, false); 2489db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x10, 10 * 8, false); 2499db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x11, 11 * 8, false); 2509db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x12, 12 * 8, false); 2519db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x13, 13 * 8, false); 2529db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x14, 14 * 8, false); 2539db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x15, 15 * 8, false); 2549db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x16, 16 * 8, false); 2559db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x17, 17 * 8, false); 2569db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x18, 18 * 8, false); 2579db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x19, 19 * 8, false); 2589db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x20, 20 * 8, false); 2599db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x21, 21 * 8, false); 2609db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x22, 22 * 8, false); 2619db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x23, 23 * 8, false); 2629db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x24, 24 * 8, false); 2639db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x25, 25 * 8, false); 2649db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x26, 26 * 8, false); 2659db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x27, 27 * 8, false); 2669db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x28, 28 * 8, false); 2679db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::fp, 29 * 8, false); 2689db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x30, 30 * 8, false); 2699db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::sp, 31 * 8, false); 2709db2541dSDavid Spickett row->SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::pc, 32 * 8, false); 2719db2541dSDavid Spickett 2729db2541dSDavid Spickett // The sigcontext may also contain floating point and SVE registers. 2739db2541dSDavid Spickett // However this would require a dynamic unwind plan so they are not included 2749db2541dSDavid Spickett // here. 2759db2541dSDavid Spickett 2769db2541dSDavid Spickett unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF); 2779db2541dSDavid Spickett unwind_plan_sp->AppendRow(row); 2789db2541dSDavid Spickett unwind_plan_sp->SetSourceName("AArch64 Linux sigcontext"); 2799db2541dSDavid Spickett unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes); 2809db2541dSDavid Spickett // Because sp is the same throughout the function 2819db2541dSDavid Spickett unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 2829db2541dSDavid Spickett unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes); 2839db2541dSDavid Spickett 2849db2541dSDavid Spickett return unwind_plan_sp; 2859db2541dSDavid Spickett } 2869db2541dSDavid Spickett 2879db2541dSDavid Spickett lldb::UnwindPlanSP 2889db2541dSDavid Spickett PlatformLinux::GetTrapHandlerUnwindPlan(const llvm::Triple &triple, 2899db2541dSDavid Spickett ConstString name) { 2909db2541dSDavid Spickett if (triple.isAArch64()) 2919db2541dSDavid Spickett return GetAArch64TrapHanlderUnwindPlan(name); 2929db2541dSDavid Spickett 2939db2541dSDavid Spickett return {}; 2949db2541dSDavid Spickett } 2959db2541dSDavid Spickett 29637c40af7SEd Maste MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch, 29737c40af7SEd Maste addr_t addr, addr_t length, 29837c40af7SEd Maste unsigned prot, unsigned flags, 29937c40af7SEd Maste addr_t fd, addr_t offset) { 30096ad3de5SRobert Flack uint64_t flags_platform = 0; 301ddb93b63SFangrui Song uint64_t map_anon = arch.IsMIPS() ? 0x800 : MAP_ANON; 302e0d8c422SMohit K. Bhakkad 30396ad3de5SRobert Flack if (flags & eMmapFlagsPrivate) 30496ad3de5SRobert Flack flags_platform |= MAP_PRIVATE; 30596ad3de5SRobert Flack if (flags & eMmapFlagsAnon) 306e0d8c422SMohit K. Bhakkad flags_platform |= map_anon; 30737c40af7SEd Maste 30837c40af7SEd Maste MmapArgList args({addr, length, prot, flags_platform, fd, offset}); 30937c40af7SEd Maste return args; 31096ad3de5SRobert Flack } 3116e25aeeaSEnrico Granata 3123053e143SMichał Górny CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) { 3133053e143SMichał Górny if (!m_type_system_up) 3143053e143SMichał Górny m_type_system_up.reset(new TypeSystemClang("siginfo", triple)); 3153053e143SMichał Górny TypeSystemClang *ast = m_type_system_up.get(); 3163053e143SMichał Górny 3173053e143SMichał Górny bool si_errno_then_code = true; 3183053e143SMichał Górny 3193053e143SMichał Górny switch (triple.getArch()) { 3203053e143SMichał Górny case llvm::Triple::mips: 3213053e143SMichał Górny case llvm::Triple::mipsel: 3223053e143SMichał Górny case llvm::Triple::mips64: 3233053e143SMichał Górny case llvm::Triple::mips64el: 3243053e143SMichał Górny // mips has si_code and si_errno swapped 3253053e143SMichał Górny si_errno_then_code = false; 3263053e143SMichał Górny break; 3273053e143SMichał Górny default: 3283053e143SMichał Górny break; 3293053e143SMichał Górny } 3303053e143SMichał Górny 3313053e143SMichał Górny // generic types 3323053e143SMichał Górny CompilerType int_type = ast->GetBasicType(eBasicTypeInt); 3333053e143SMichał Górny CompilerType uint_type = ast->GetBasicType(eBasicTypeUnsignedInt); 3343053e143SMichał Górny CompilerType short_type = ast->GetBasicType(eBasicTypeShort); 3353053e143SMichał Górny CompilerType long_type = ast->GetBasicType(eBasicTypeLong); 3363053e143SMichał Górny CompilerType voidp_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType(); 3373053e143SMichał Górny 3383053e143SMichał Górny // platform-specific types 3393053e143SMichał Górny CompilerType &pid_type = int_type; 3403053e143SMichał Górny CompilerType &uid_type = uint_type; 3413053e143SMichał Górny CompilerType &clock_type = long_type; 3423053e143SMichał Górny CompilerType &band_type = long_type; 3433053e143SMichał Górny 3443053e143SMichał Górny CompilerType sigval_type = ast->CreateRecordType( 3453053e143SMichał Górny nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t", 3463053e143SMichał Górny clang::TTK_Union, lldb::eLanguageTypeC); 3473053e143SMichał Górny ast->StartTagDeclarationDefinition(sigval_type); 3483053e143SMichał Górny ast->AddFieldToRecordType(sigval_type, "sival_int", int_type, 3493053e143SMichał Górny lldb::eAccessPublic, 0); 3503053e143SMichał Górny ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type, 3513053e143SMichał Górny lldb::eAccessPublic, 0); 3523053e143SMichał Górny ast->CompleteTagDeclarationDefinition(sigval_type); 3533053e143SMichał Górny 3543053e143SMichał Górny CompilerType sigfault_bounds_type = ast->CreateRecordType( 3553053e143SMichał Górny nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "", 3563053e143SMichał Górny clang::TTK_Union, lldb::eLanguageTypeC); 3573053e143SMichał Górny ast->StartTagDeclarationDefinition(sigfault_bounds_type); 3583053e143SMichał Górny ast->AddFieldToRecordType(sigfault_bounds_type, "_addr_bnd", 3593053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 3603053e143SMichał Górny { 3613053e143SMichał Górny {"_lower", voidp_type}, 3623053e143SMichał Górny {"_upper", voidp_type}, 3633053e143SMichał Górny }), 3643053e143SMichał Górny lldb::eAccessPublic, 0); 3653053e143SMichał Górny ast->AddFieldToRecordType(sigfault_bounds_type, "_pkey", uint_type, 3663053e143SMichał Górny lldb::eAccessPublic, 0); 3673053e143SMichał Górny ast->CompleteTagDeclarationDefinition(sigfault_bounds_type); 3683053e143SMichał Górny 3693053e143SMichał Górny // siginfo_t 3703053e143SMichał Górny CompilerType siginfo_type = ast->CreateRecordType( 3713053e143SMichał Górny nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t", 3723053e143SMichał Górny clang::TTK_Struct, lldb::eLanguageTypeC); 3733053e143SMichał Górny ast->StartTagDeclarationDefinition(siginfo_type); 3743053e143SMichał Górny ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type, 3753053e143SMichał Górny lldb::eAccessPublic, 0); 3763053e143SMichał Górny 3773053e143SMichał Górny if (si_errno_then_code) { 3783053e143SMichał Górny ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type, 3793053e143SMichał Górny lldb::eAccessPublic, 0); 3803053e143SMichał Górny ast->AddFieldToRecordType(siginfo_type, "si_code", int_type, 3813053e143SMichał Górny lldb::eAccessPublic, 0); 3823053e143SMichał Górny } else { 3833053e143SMichał Górny ast->AddFieldToRecordType(siginfo_type, "si_code", int_type, 3843053e143SMichał Górny lldb::eAccessPublic, 0); 3853053e143SMichał Górny ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type, 3863053e143SMichał Górny lldb::eAccessPublic, 0); 3873053e143SMichał Górny } 3883053e143SMichał Górny 3893053e143SMichał Górny // the structure is padded on 64-bit arches to fix alignment 3903053e143SMichał Górny if (triple.isArch64Bit()) 3913053e143SMichał Górny ast->AddFieldToRecordType(siginfo_type, "__pad0", int_type, 3923053e143SMichał Górny lldb::eAccessPublic, 0); 3933053e143SMichał Górny 3943053e143SMichał Górny // union used to hold the signal data 3953053e143SMichał Górny CompilerType union_type = ast->CreateRecordType( 3963053e143SMichał Górny nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "", 3973053e143SMichał Górny clang::TTK_Union, lldb::eLanguageTypeC); 3983053e143SMichał Górny ast->StartTagDeclarationDefinition(union_type); 3993053e143SMichał Górny 4003053e143SMichał Górny ast->AddFieldToRecordType( 4013053e143SMichał Górny union_type, "_kill", 4023053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 4033053e143SMichał Górny { 4043053e143SMichał Górny {"si_pid", pid_type}, 4053053e143SMichał Górny {"si_uid", uid_type}, 4063053e143SMichał Górny }), 4073053e143SMichał Górny lldb::eAccessPublic, 0); 4083053e143SMichał Górny 4093053e143SMichał Górny ast->AddFieldToRecordType( 4103053e143SMichał Górny union_type, "_timer", 4113053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 4123053e143SMichał Górny { 4133053e143SMichał Górny {"si_tid", int_type}, 4143053e143SMichał Górny {"si_overrun", int_type}, 4153053e143SMichał Górny {"si_sigval", sigval_type}, 4163053e143SMichał Górny }), 4173053e143SMichał Górny lldb::eAccessPublic, 0); 4183053e143SMichał Górny 4193053e143SMichał Górny ast->AddFieldToRecordType( 4203053e143SMichał Górny union_type, "_rt", 4213053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 4223053e143SMichał Górny { 4233053e143SMichał Górny {"si_pid", pid_type}, 4243053e143SMichał Górny {"si_uid", uid_type}, 4253053e143SMichał Górny {"si_sigval", sigval_type}, 4263053e143SMichał Górny }), 4273053e143SMichał Górny lldb::eAccessPublic, 0); 4283053e143SMichał Górny 4293053e143SMichał Górny ast->AddFieldToRecordType( 4303053e143SMichał Górny union_type, "_sigchld", 4313053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 4323053e143SMichał Górny { 4333053e143SMichał Górny {"si_pid", pid_type}, 4343053e143SMichał Górny {"si_uid", uid_type}, 4353053e143SMichał Górny {"si_status", int_type}, 4363053e143SMichał Górny {"si_utime", clock_type}, 4373053e143SMichał Górny {"si_stime", clock_type}, 4383053e143SMichał Górny }), 4393053e143SMichał Górny lldb::eAccessPublic, 0); 4403053e143SMichał Górny 4413053e143SMichał Górny ast->AddFieldToRecordType( 4423053e143SMichał Górny union_type, "_sigfault", 4433053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 4443053e143SMichał Górny { 4453053e143SMichał Górny {"si_addr", voidp_type}, 4463053e143SMichał Górny {"si_addr_lsb", short_type}, 4473053e143SMichał Górny {"_bounds", sigfault_bounds_type}, 4483053e143SMichał Górny }), 4493053e143SMichał Górny lldb::eAccessPublic, 0); 4503053e143SMichał Górny 4513053e143SMichał Górny ast->AddFieldToRecordType( 4523053e143SMichał Górny union_type, "_sigpoll", 4533053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 4543053e143SMichał Górny { 4553053e143SMichał Górny {"si_band", band_type}, 4563053e143SMichał Górny {"si_fd", int_type}, 4573053e143SMichał Górny }), 4583053e143SMichał Górny lldb::eAccessPublic, 0); 4593053e143SMichał Górny 4603053e143SMichał Górny // NB: SIGSYS is not present on ia64 but we don't seem to support that 4613053e143SMichał Górny ast->AddFieldToRecordType( 4623053e143SMichał Górny union_type, "_sigsys", 4633053e143SMichał Górny ast->CreateStructForIdentifier(ConstString(), 4643053e143SMichał Górny { 4653053e143SMichał Górny {"_call_addr", voidp_type}, 4663053e143SMichał Górny {"_syscall", int_type}, 4673053e143SMichał Górny {"_arch", uint_type}, 4683053e143SMichał Górny }), 4693053e143SMichał Górny lldb::eAccessPublic, 0); 4703053e143SMichał Górny 4713053e143SMichał Górny ast->CompleteTagDeclarationDefinition(union_type); 4723053e143SMichał Górny ast->AddFieldToRecordType(siginfo_type, "_sifields", union_type, 4733053e143SMichał Górny lldb::eAccessPublic, 0); 4743053e143SMichał Górny 4753053e143SMichał Górny ast->CompleteTagDeclarationDefinition(siginfo_type); 4763053e143SMichał Górny return siginfo_type; 4773053e143SMichał Górny } 478