//===-- ArchSpec.cpp --------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "lldb/Core/ArchSpec.h" #include #include #include using namespace lldb; using namespace lldb_private; #define ARCH_SPEC_SEPARATOR_CHAR '-' #ifndef CPU_TYPE_ARM #define CPU_TYPE_ARM ((cpu_type_t) 12) #endif #ifndef CPU_SUBTYPE_ARM_ALL #define CPU_SUBTYPE_ARM_ALL ((cpu_subtype_t) 0) #endif #ifndef CPU_SUBTYPE_ARM_V4T #define CPU_SUBTYPE_ARM_V4T ((cpu_subtype_t) 5) #endif #ifndef CPU_SUBTYPE_ARM_V6 #define CPU_SUBTYPE_ARM_V6 ((cpu_subtype_t) 6) #endif #ifndef CPU_SUBTYPE_ARM_V5TEJ #define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) #endif #ifndef CPU_SUBTYPE_ARM_XSCALE #define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) #endif #ifndef CPU_SUBTYPE_ARM_V7 #define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) #endif //---------------------------------------------------------------------- // A structure that describes all of the information we want to know // about each architecture. //---------------------------------------------------------------------- struct ArchDefinition { uint32_t cpu; uint32_t sub; const char *name; }; //---------------------------------------------------------------------- // A table that gets searched linearly for matches. This table is used // to convert cpu type and subtypes to architecture names, and to // convert architecture names to cpu types and subtypes. The ordering // is important and allows the precedence to be set when the table is // built. //---------------------------------------------------------------------- static ArchDefinition g_arch_defs[] = { { CPU_TYPE_ANY, CPU_TYPE_ANY , "all" }, { CPU_TYPE_ARM, CPU_TYPE_ANY , "arm" }, { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL , "arm" }, { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V4T , "armv4" }, { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V5TEJ , "armv5" }, { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 , "armv6" }, { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 , "armv7" }, { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE , "xscale" }, { CPU_TYPE_POWERPC, CPU_TYPE_ANY , "ppc" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL , "ppc" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_601 , "ppc601" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_602 , "ppc602" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603 , "ppc603" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603e , "ppc603e" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603ev , "ppc603ev" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604 , "ppc604" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604e , "ppc604e" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_620 , "ppc620" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_750 , "ppc750" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400 , "ppc7400" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7450 , "ppc7450" }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_970 , "ppc970" }, { CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_ALL , "ppc64" }, { CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970 , "ppc970-64" }, { CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL , "i386" }, { CPU_TYPE_I386, CPU_SUBTYPE_486 , "i486" }, { CPU_TYPE_I386, CPU_SUBTYPE_486SX , "i486sx" }, { CPU_TYPE_I386, CPU_TYPE_ANY , "i386" }, { CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL , "x86_64" }, { CPU_TYPE_X86_64, CPU_TYPE_ANY , "x86_64" }, // TODO: when we get a platform that knows more about the host OS we should // let it call some accessor funcitons to set the default system arch for // the default, 32 and 64 bit cases instead of hard coding it in this // table. #if defined (__i386__) || defined(__x86_64__) { CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL , LLDB_ARCH_DEFAULT }, { CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL , LLDB_ARCH_DEFAULT_32BIT }, { CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL , LLDB_ARCH_DEFAULT_64BIT }, #elif defined (__arm__) { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 , LLDB_ARCH_DEFAULT }, { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 , LLDB_ARCH_DEFAULT_32BIT }, #elif defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400 , LLDB_ARCH_DEFAULT }, { CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400 , LLDB_ARCH_DEFAULT_32BIT }, { CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970 , LLDB_ARCH_DEFAULT_64BIT }, #endif }; //---------------------------------------------------------------------- // Figure out how many architecture definitions we have //---------------------------------------------------------------------- const size_t k_num_arch_defs = sizeof(g_arch_defs)/sizeof(ArchDefinition); //---------------------------------------------------------------------- // Default constructor //---------------------------------------------------------------------- ArchSpec::ArchSpec() : m_cpu (LLDB_INVALID_CPUTYPE), m_sub (0) { } //---------------------------------------------------------------------- // Constructor that initializes the object with supplied cpu and // subtypes. //---------------------------------------------------------------------- ArchSpec::ArchSpec(uint32_t cpu, uint32_t sub) : m_cpu (cpu), m_sub (sub) { } //---------------------------------------------------------------------- // Constructor that initializes the object with supplied // architecture name. There are also predefined values in // Defines.h: // liblldb_ARCH_DEFAULT // The arch the current system defaults to when a program is // launched without any extra attributes or settings. // // liblldb_ARCH_DEFAULT_32BIT // The 32 bit arch the current system defaults to (if any) // // liblldb_ARCH_DEFAULT_32BIT // The 64 bit arch the current system defaults to (if any) //---------------------------------------------------------------------- ArchSpec::ArchSpec(const char *arch_name) : m_cpu (LLDB_INVALID_CPUTYPE), m_sub (0) { if (arch_name) SetArch(arch_name); } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- ArchSpec::~ArchSpec() { } //---------------------------------------------------------------------- // Assignment operator //---------------------------------------------------------------------- const ArchSpec& ArchSpec::operator= (const ArchSpec& rhs) { if (this != &rhs) { m_cpu = rhs.m_cpu; m_sub = rhs.m_sub; } return *this; } //---------------------------------------------------------------------- // Get a C string representation of the current architecture //---------------------------------------------------------------------- const char * ArchSpec::AsCString() const { return ArchSpec::AsCString(m_cpu, m_sub); } //---------------------------------------------------------------------- // Class function to get a C string representation given a CPU type // and subtype. //---------------------------------------------------------------------- const char * ArchSpec::AsCString(uint32_t cpu, uint32_t sub) { for (uint32_t i=0; i