//===-- 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 "llvm/Support/ELF.h" #include "llvm/Support/MachO.h" using namespace lldb; using namespace lldb_private; #define ARCH_SPEC_SEPARATOR_CHAR '-' //---------------------------------------------------------------------- // 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; }; static const char *g_arch_type_strings[] = { "invalid", "mach-o", "elf" }; #define CPU_ANY (UINT32_MAX) //---------------------------------------------------------------------- // 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_mach_arch_defs[] = { { CPU_ANY, CPU_ANY , "all" }, { llvm::MachO::CPUTypeARM, CPU_ANY , "arm" }, { llvm::MachO::CPUTypeARM, 0 , "arm" }, { llvm::MachO::CPUTypeARM, 5 , "armv4" }, { llvm::MachO::CPUTypeARM, 6 , "armv6" }, { llvm::MachO::CPUTypeARM, 7 , "armv5" }, { llvm::MachO::CPUTypeARM, 8 , "xscale" }, { llvm::MachO::CPUTypeARM, 9 , "armv7" }, { llvm::MachO::CPUTypePowerPC, CPU_ANY , "ppc" }, { llvm::MachO::CPUTypePowerPC, 0 , "ppc" }, { llvm::MachO::CPUTypePowerPC, 1 , "ppc601" }, { llvm::MachO::CPUTypePowerPC, 2 , "ppc602" }, { llvm::MachO::CPUTypePowerPC, 3 , "ppc603" }, { llvm::MachO::CPUTypePowerPC, 4 , "ppc603e" }, { llvm::MachO::CPUTypePowerPC, 5 , "ppc603ev" }, { llvm::MachO::CPUTypePowerPC, 6 , "ppc604" }, { llvm::MachO::CPUTypePowerPC, 7 , "ppc604e" }, { llvm::MachO::CPUTypePowerPC, 8 , "ppc620" }, { llvm::MachO::CPUTypePowerPC, 9 , "ppc750" }, { llvm::MachO::CPUTypePowerPC, 10 , "ppc7400" }, { llvm::MachO::CPUTypePowerPC, 11 , "ppc7450" }, { llvm::MachO::CPUTypePowerPC, 100 , "ppc970" }, { llvm::MachO::CPUTypePowerPC64, 0 , "ppc64" }, { llvm::MachO::CPUTypePowerPC64, 100 , "ppc970-64" }, { llvm::MachO::CPUTypeI386, 3 , "i386" }, { llvm::MachO::CPUTypeI386, 4 , "i486" }, { llvm::MachO::CPUTypeI386, 0x84 , "i486sx" }, { llvm::MachO::CPUTypeI386, CPU_ANY , "i386" }, { llvm::MachO::CPUTypeX86_64, 3 , "x86_64" }, { llvm::MachO::CPUTypeX86_64, CPU_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__) { llvm::MachO::CPUTypeX86_64, 3 , LLDB_ARCH_DEFAULT }, { llvm::MachO::CPUTypeI386, 3 , LLDB_ARCH_DEFAULT_32BIT }, { llvm::MachO::CPUTypeX86_64, 3 , LLDB_ARCH_DEFAULT_64BIT }, #elif defined (__arm__) { llvm::MachO::CPUTypeARM, 6 , LLDB_ARCH_DEFAULT }, { llvm::MachO::CPUTypeARM, 6 , LLDB_ARCH_DEFAULT_32BIT }, #elif defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) { llvm::MachO::CPUTypePowerPC, 10 , LLDB_ARCH_DEFAULT }, { llvm::MachO::CPUTypePowerPC, 10 , LLDB_ARCH_DEFAULT_32BIT }, { llvm::MachO::CPUTypePowerPC64, 100 , LLDB_ARCH_DEFAULT_64BIT }, #endif }; //---------------------------------------------------------------------- // Figure out how many architecture definitions we have //---------------------------------------------------------------------- const size_t k_num_mach_arch_defs = sizeof(g_mach_arch_defs)/sizeof(ArchDefinition); //---------------------------------------------------------------------- // 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_elf_arch_defs[] = { { llvm::ELF::EM_M32 , 0, "m32" }, // AT&T WE 32100 { llvm::ELF::EM_SPARC , 0, "sparc" }, // AT&T WE 32100 { llvm::ELF::EM_386 , 0, "i386" }, // Intel 80386 { llvm::ELF::EM_68K , 0, "68k" }, // Motorola 68000 { llvm::ELF::EM_88K , 0, "88k" }, // Motorola 88000 { llvm::ELF::EM_486 , 0, "i486" }, // Intel 486 (deprecated) { llvm::ELF::EM_860 , 0, "860" }, // Intel 80860 { llvm::ELF::EM_MIPS , 0, "rs3000" }, // MIPS RS3000 { llvm::ELF::EM_PPC , 0, "ppc" }, // PowerPC { 21 , 0, "ppc64" }, // PowerPC64 { llvm::ELF::EM_ARM , 0, "arm" }, // ARM { llvm::ELF::EM_ALPHA , 0, "alpha" }, // DEC Alpha { llvm::ELF::EM_SPARCV9, 0, "sparc9" }, // SPARC V9 { llvm::ELF::EM_X86_64 , 0, "x86_64" }, // AMD64 #if defined (__i386__) || defined(__x86_64__) { llvm::ELF::EM_X86_64 , 0, LLDB_ARCH_DEFAULT }, { llvm::ELF::EM_386 , 0, LLDB_ARCH_DEFAULT_32BIT }, { llvm::ELF::EM_X86_64 , 0, LLDB_ARCH_DEFAULT_64BIT }, #elif defined (__arm__) { llvm::ELF::EM_ARM , 0, LLDB_ARCH_DEFAULT }, { llvm::ELF::EM_ARM , 0, LLDB_ARCH_DEFAULT_32BIT }, #elif defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) { llvm::ELF::EM_PPC , 0, LLDB_ARCH_DEFAULT }, { llvm::ELF::EM_PPC , 0, LLDB_ARCH_DEFAULT_32BIT }, { llvm::ELF::EM_PPC64 , 0, LLDB_ARCH_DEFAULT_64BIT }, #endif }; //---------------------------------------------------------------------- // Figure out how many architecture definitions we have //---------------------------------------------------------------------- const size_t k_num_elf_arch_defs = sizeof(g_elf_arch_defs)/sizeof(ArchDefinition); //---------------------------------------------------------------------- // Default constructor //---------------------------------------------------------------------- ArchSpec::ArchSpec() : m_type (eArchTypeMachO), // Use the most complete arch definition which will always be translatable to any other ArchitectureType values m_cpu (LLDB_INVALID_CPUTYPE), m_sub (0) { } //---------------------------------------------------------------------- // Constructor that initializes the object with supplied cpu and // subtypes. //---------------------------------------------------------------------- ArchSpec::ArchSpec (lldb::ArchitectureType arch_type, uint32_t cpu, uint32_t sub) : m_type (arch_type), 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_type (eArchTypeMachO), // Use the most complete arch definition which will always be translatable to any other ArchitectureType values 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_type = rhs.m_type; 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_type, m_cpu, m_sub); } //---------------------------------------------------------------------- // Class function to get a C string representation given a CPU type // and subtype. //---------------------------------------------------------------------- const char * ArchSpec::AsCString (lldb::ArchitectureType arch_type, uint32_t cpu, uint32_t sub) { if (arch_type >= kNumArchTypes) return NULL; switch (arch_type) { case kNumArchTypes: case eArchTypeInvalid: break; case eArchTypeMachO: for (uint32_t i=0; i