diff options
Diffstat (limited to 'source/Core/ArchSpec.cpp')
-rw-r--r-- | source/Core/ArchSpec.cpp | 205 |
1 files changed, 162 insertions, 43 deletions
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp index ffe717f29c43..24aba81350a6 100644 --- a/source/Core/ArchSpec.cpp +++ b/source/Core/ArchSpec.cpp @@ -9,16 +9,19 @@ #include "lldb/Core/ArchSpec.h" -#include <stdio.h> -#include <errno.h> - +// C Includes +// C++ Includes +#include <cstdio> +#include <cerrno> #include <string> +// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/Support/COFF.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Host.h" +// Project includes #include "lldb/Core/RegularExpression.h" #include "lldb/Core/StringList.h" #include "lldb/Host/Endian.h" @@ -35,9 +38,6 @@ using namespace lldb; using namespace lldb_private; -#define ARCH_SPEC_SEPARATOR_CHAR '-' - - static bool cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match); namespace lldb_private { @@ -53,7 +53,7 @@ namespace lldb_private { const char * const name; }; -} +} // namespace lldb_private // This core information can be looked using the ArchSpec::Core as the index static const CoreDefinition g_core_definitions[] = @@ -130,6 +130,8 @@ static const CoreDefinition g_core_definitions[] = { eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "powerpc64" }, { eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" }, + { eByteOrderBig , 8, 2, 6, llvm::Triple::systemz, ArchSpec::eCore_s390x_generic , "s390x" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" }, { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" }, @@ -156,7 +158,6 @@ static const CoreDefinition g_core_definitions[] = // you will need to comment out the corresponding ArchSpec::Core enumeration. static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) == ArchSpec::kNumCores, "make sure we have one core definition for each core"); - struct ArchDefinitionEntry { ArchSpec::Core core; @@ -174,14 +175,12 @@ struct ArchDefinition const char *name; }; - size_t ArchSpec::AutoComplete (const char *name, StringList &matches) { - uint32_t i; if (name && name[0]) { - for (i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) + for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name)) matches.AppendString (g_core_definitions[i].name); @@ -189,14 +188,12 @@ ArchSpec::AutoComplete (const char *name, StringList &matches) } else { - for (i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) + for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) matches.AppendString (g_core_definitions[i].name); } return matches.GetSize(); } - - #define CPU_ANY (UINT32_MAX) //===----------------------------------------------------------------------===// @@ -205,6 +202,7 @@ ArchSpec::AutoComplete (const char *name, StringList &matches) // architecture names to cpu types and subtypes. The ordering is important and // allows the precedence to be set when the table is built. #define SUBTYPE_MASK 0x00FFFFFFu + static const ArchDefinitionEntry g_macho_arch_entries[] = { { ArchSpec::eCore_arm_generic , llvm::MachO::CPU_TYPE_ARM , CPU_ANY, UINT32_MAX , UINT32_MAX }, @@ -267,6 +265,7 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = { ArchSpec::eCore_uknownMach32 , 0 , 0 , 0xFF000000u, 0x00000000u }, { ArchSpec::eCore_uknownMach64 , llvm::MachO::CPU_ARCH_ABI64 , 0 , 0xFF000000u, 0x00000000u } }; + static const ArchDefinition g_macho_arch_def = { eArchTypeMachO, llvm::array_lengthof(g_macho_arch_entries), @@ -288,6 +287,7 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { ArchSpec::eCore_ppc64_generic , llvm::ELF::EM_PPC64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC64 { ArchSpec::eCore_arm_generic , llvm::ELF::EM_ARM , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM { ArchSpec::eCore_arm_aarch64 , llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM64 + { ArchSpec::eCore_s390x_generic , llvm::ELF::EM_S390 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SystemZ { ArchSpec::eCore_sparc9_generic , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SPARC V9 { ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // AMD64 { ArchSpec::eCore_mips32 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32 @@ -346,7 +346,6 @@ static const size_t k_num_arch_definitions = llvm::array_lengthof(g_arch_definit //===----------------------------------------------------------------------===// // Static helper functions. - // Get the architecture definition for a given object type. static const ArchDefinition * FindArchDefinition (ArchitectureType arch_type) @@ -357,7 +356,7 @@ FindArchDefinition (ArchitectureType arch_type) if (def->type == arch_type) return def; } - return NULL; + return nullptr; } // Get an architecture definition by name. @@ -369,7 +368,7 @@ FindCoreDefinition (llvm::StringRef name) if (name.equals_lower(g_core_definitions[i].name)) return &g_core_definitions[i]; } - return NULL; + return nullptr; } static inline const CoreDefinition * @@ -377,15 +376,15 @@ FindCoreDefinition (ArchSpec::Core core) { if (core >= 0 && core < llvm::array_lengthof(g_core_definitions)) return &g_core_definitions[core]; - return NULL; + return nullptr; } // Get a definition entry by cpu type and subtype. static const ArchDefinitionEntry * FindArchDefinitionEntry (const ArchDefinition *def, uint32_t cpu, uint32_t sub) { - if (def == NULL) - return NULL; + if (def == nullptr) + return nullptr; const ArchDefinitionEntry *entries = def->entries; for (size_t i = 0; i < def->num_entries; ++i) @@ -394,14 +393,14 @@ FindArchDefinitionEntry (const ArchDefinition *def, uint32_t cpu, uint32_t sub) if (entries[i].sub == (sub & entries[i].sub_mask)) return &entries[i]; } - return NULL; + return nullptr; } static const ArchDefinitionEntry * FindArchDefinitionEntry (const ArchDefinition *def, ArchSpec::Core core) { - if (def == NULL) - return NULL; + if (def == nullptr) + return nullptr; const ArchDefinitionEntry *entries = def->entries; for (size_t i = 0; i < def->num_entries; ++i) @@ -409,7 +408,7 @@ FindArchDefinitionEntry (const ArchDefinition *def, ArchSpec::Core core) if (entries[i].core == core) return &entries[i]; } - return NULL; + return nullptr; } //===----------------------------------------------------------------------===// @@ -467,9 +466,7 @@ ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype) SetArchitecture (arch_type, cpu, subtype); } -ArchSpec::~ArchSpec() -{ -} +ArchSpec::~ArchSpec() = default; //===----------------------------------------------------------------------===// // Assignment and initialization. @@ -501,7 +498,6 @@ ArchSpec::Clear() //===----------------------------------------------------------------------===// // Predicates. - const char * ArchSpec::GetArchitectureName () const { @@ -511,6 +507,68 @@ ArchSpec::GetArchitectureName () const return "unknown"; } +bool +ArchSpec::IsMIPS() const +{ + const llvm::Triple::ArchType machine = GetMachine(); + if(machine == llvm::Triple::mips || + machine == llvm::Triple::mipsel || + machine == llvm::Triple::mips64 || + machine == llvm::Triple::mips64el) + return true; + return false; +} + +std::string +ArchSpec::GetClangTargetCPU () +{ + std::string cpu; + const llvm::Triple::ArchType machine = GetMachine(); + + if (machine == llvm::Triple::mips || + machine == llvm::Triple::mipsel || + machine == llvm::Triple::mips64 || + machine == llvm::Triple::mips64el) + { + switch (m_core) + { + case ArchSpec::eCore_mips32: + case ArchSpec::eCore_mips32el: + cpu = "mips32"; break; + case ArchSpec::eCore_mips32r2: + case ArchSpec::eCore_mips32r2el: + cpu = "mips32r2"; break; + case ArchSpec::eCore_mips32r3: + case ArchSpec::eCore_mips32r3el: + cpu = "mips32r3"; break; + case ArchSpec::eCore_mips32r5: + case ArchSpec::eCore_mips32r5el: + cpu = "mips32r5"; break; + case ArchSpec::eCore_mips32r6: + case ArchSpec::eCore_mips32r6el: + cpu = "mips32r6"; break; + case ArchSpec::eCore_mips64: + case ArchSpec::eCore_mips64el: + cpu = "mips64"; break; + case ArchSpec::eCore_mips64r2: + case ArchSpec::eCore_mips64r2el: + cpu = "mips64r2"; break; + case ArchSpec::eCore_mips64r3: + case ArchSpec::eCore_mips64r3el: + cpu = "mips64r3"; break; + case ArchSpec::eCore_mips64r5: + case ArchSpec::eCore_mips64r5el: + cpu = "mips64r5"; break; + case ArchSpec::eCore_mips64r6: + case ArchSpec::eCore_mips64r6el: + cpu = "mips64r6"; break; + default: + break; + } + } + return cpu; +} + uint32_t ArchSpec::GetMachOCPUType () const { @@ -680,7 +738,6 @@ ArchSpec::SetTriple (const llvm::Triple &triple) Clear(); } - return IsValid(); } @@ -690,7 +747,7 @@ ParseMachCPUDashSubtypeTriple (const char *triple_cstr, ArchSpec &arch) // Accept "12-10" or "12.10" as cpu type/subtype if (isdigit(triple_cstr[0])) { - char *end = NULL; + char *end = nullptr; errno = 0; uint32_t cpu = (uint32_t)::strtoul (triple_cstr, &end, 0); if (errno == 0 && cpu != 0 && end && ((*end == '-') || (*end == '.'))) @@ -729,6 +786,7 @@ ParseMachCPUDashSubtypeTriple (const char *triple_cstr, ArchSpec &arch) } return false; } + bool ArchSpec::SetTriple (const char *triple_cstr) { @@ -855,6 +913,17 @@ ArchSpec::MergeFrom(const ArchSpec &other) if (other.TripleVendorWasSpecified()) GetTriple().setEnvironment(other.GetTriple().getEnvironment()); } + // If this and other are both arm ArchSpecs and this ArchSpec is a generic "some kind of arm" + // spec but the other ArchSpec is a specific arm core, adopt the specific arm core. + if (GetTriple().getArch() == llvm::Triple::arm + && other.GetTriple().getArch() == llvm::Triple::arm + && IsCompatibleMatch (other) + && GetCore() == ArchSpec::eCore_arm_generic + && other.GetCore() != ArchSpec::eCore_arm_generic) + { + m_core = other.GetCore(); + CoreUpdated (true); + } } bool @@ -945,6 +1014,30 @@ ArchSpec::IsCompatibleMatch (const ArchSpec& rhs) const return IsEqualTo (rhs, false); } +static bool +isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs) +{ + if (lhs == rhs) + return true; + + // If any of the environment is unknown then they are compatible + if (lhs == llvm::Triple::UnknownEnvironment || rhs == llvm::Triple::UnknownEnvironment) + return true; + + // If one of the environment is Android and the other one is EABI then they are considered to + // be compatible. This is required as a workaround for shared libraries compiled for Android + // without the NOTE section indicating that they are using the Android ABI. + if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) || + (rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) || + (lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) || + (rhs == llvm::Triple::GNUEABI && lhs == llvm::Triple::EABI) || + (lhs == llvm::Triple::GNUEABIHF && rhs == llvm::Triple::EABIHF) || + (rhs == llvm::Triple::GNUEABIHF && lhs == llvm::Triple::EABIHF)) + return true; + + return false; +} + bool ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const { @@ -999,14 +1092,9 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment(); const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment(); - - if (lhs_triple_env != rhs_triple_env) - { - // Only fail if both environment types are not unknown - if (lhs_triple_env != llvm::Triple::UnknownEnvironment && - rhs_triple_env != llvm::Triple::UnknownEnvironment) - return false; - } + + if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env)) + return false; return true; } return false; @@ -1050,7 +1138,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in case ArchSpec::eCore_arm_generic: if (enforce_exact_match) break; - // Fall through to case below + LLVM_FALLTHROUGH; case ArchSpec::kCore_arm_any: if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last) return true; @@ -1207,6 +1295,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in return true; try_inverse = false; } + break; case ArchSpec::eCore_mips64: if (!enforce_exact_match) @@ -1217,6 +1306,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in return true; try_inverse = false; } + break; case ArchSpec::eCore_mips64el: if (!enforce_exact_match) @@ -1227,6 +1317,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in return true; try_inverse = false; } + break; case ArchSpec::eCore_mips64r2: case ArchSpec::eCore_mips64r3: @@ -1287,7 +1378,6 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in { if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el) return true; - return true; } break; @@ -1393,7 +1483,7 @@ StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread) if (opcode <= UINT32_MAX) { const uint32_t condition = Bits32((uint32_t)opcode, 31, 28); - if (ARMConditionPassed(condition, cpsr) == false) + if (!ARMConditionPassed(condition, cpsr)) { // We ARE stopped on an ARM instruction whose condition doesn't // pass so this instruction won't get executed. @@ -1410,7 +1500,7 @@ StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread) if (ITSTATE != 0) { const uint32_t condition = Bits32(ITSTATE, 7, 4); - if (ARMConditionPassed(condition, cpsr) == false) + if (!ARMConditionPassed(condition, cpsr)) { // We ARE stopped in a Thumb IT instruction on an instruction whose // condition doesn't pass so this instruction won't get executed. @@ -1429,7 +1519,7 @@ ArchSpec::GetStopInfoOverrideCallback () const const llvm::Triple::ArchType machine = GetMachine(); if (machine == llvm::Triple::arm) return StopInfoOverrideCallbackTypeARM; - return NULL; + return nullptr; } bool @@ -1476,6 +1566,31 @@ ArchSpec::PiecewiseTripleCompare (const ArchSpec &other, env_different = (me.getEnvironment() != them.getEnvironment()); } +bool +ArchSpec::IsAlwaysThumbInstructions () const +{ + std::string Error; + if (GetTriple().getArch() == llvm::Triple::arm || GetTriple().getArch() == llvm::Triple::thumb) + { + // v. https://en.wikipedia.org/wiki/ARM_Cortex-M + // + // Cortex-M0 through Cortex-M7 are ARM processor cores which can only + // execute thumb instructions. We map the cores to arch names like this: + // + // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m + // Cortex-M3: armv7m + // Cortex-M4, Cortex-M7: armv7em + + if (GetCore() == ArchSpec::Core::eCore_arm_armv7m + || GetCore() == ArchSpec::Core::eCore_arm_armv7em + || GetCore() == ArchSpec::Core::eCore_arm_armv6m) + { + return true; + } + } + return false; +} + void ArchSpec::DumpTriple(Stream &s) const { @@ -1483,10 +1598,14 @@ ArchSpec::DumpTriple(Stream &s) const llvm::StringRef arch_str = triple.getArchName(); llvm::StringRef vendor_str = triple.getVendorName(); llvm::StringRef os_str = triple.getOSName(); + llvm::StringRef environ_str = triple.getEnvironmentName(); s.Printf("%s-%s-%s", arch_str.empty() ? "*" : arch_str.str().c_str(), vendor_str.empty() ? "*" : vendor_str.str().c_str(), os_str.empty() ? "*" : os_str.str().c_str() ); + + if (!environ_str.empty()) + s.Printf("-%s", environ_str.str().c_str()); } |