Author: satyanarayana reddy janga Date: 2026-07-04T10:59:19-05:00 New Revision: 4a2ad970c6fe783f026be47292be93b6cdfe7d9b
URL: https://github.com/llvm/llvm-project/commit/4a2ad970c6fe783f026be47292be93b6cdfe7d9b DIFF: https://github.com/llvm/llvm-project/commit/4a2ad970c6fe783f026be47292be93b6cdfe7d9b.diff LOG: [lldb] Add AMD GPU architectures to ArchSpec (#206369) ## Summary Teach ArchSpec and ObjectFileELF about AMD (R600 and GCN/amdgcn) GPU architectures so GPU ELF object files and triples resolve to a precise architecture. ## Tests: unit-test the ELF-header -> architecture mapping in ArchSpecTest and an end-to-end AMDGPU ELF in TestObjectFileELF. The processor list, e_flags machine values, OSABI and ABI versions follow llvm/include/llvm/BinaryFormat/ELF.h (AMDGPU_MACH_LIST) and the AMDGPU code-object spec documented at https://llvm.org/docs/AMDGPUUsage.html. Added: Modified: lldb/include/lldb/Utility/ArchSpec.h lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp lldb/source/Utility/ArchSpec.cpp lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp lldb/unittests/Utility/ArchSpecTest.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h index 160f81c2fa501..d38a61e4a9c2f 100644 --- a/lldb/include/lldb/Utility/ArchSpec.h +++ b/lldb/include/lldb/Utility/ArchSpec.h @@ -240,6 +240,85 @@ class ArchSpec { eCore_wasm32, + eCore_amd_gpu_r600_R600, + eCore_amd_gpu_r600_R630, + eCore_amd_gpu_r600_RS880, + eCore_amd_gpu_r600_RV670, + eCore_amd_gpu_r600_RV710, + eCore_amd_gpu_r600_RV730, + eCore_amd_gpu_r600_RV770, + eCore_amd_gpu_r600_CEDAR, + eCore_amd_gpu_r600_CYPRESS, + eCore_amd_gpu_r600_JUNIPER, + eCore_amd_gpu_r600_REDWOOD, + eCore_amd_gpu_r600_SUMO, + eCore_amd_gpu_r600_BARTS, + eCore_amd_gpu_r600_CAICOS, + eCore_amd_gpu_r600_CAYMAN, + eCore_amd_gpu_r600_TURKS, + eCore_amd_gpu_gcn_GFX600, + eCore_amd_gpu_gcn_GFX601, + eCore_amd_gpu_gcn_GFX602, + eCore_amd_gpu_gcn_GFX700, + eCore_amd_gpu_gcn_GFX701, + eCore_amd_gpu_gcn_GFX702, + eCore_amd_gpu_gcn_GFX703, + eCore_amd_gpu_gcn_GFX704, + eCore_amd_gpu_gcn_GFX705, + eCore_amd_gpu_gcn_GFX801, + eCore_amd_gpu_gcn_GFX802, + eCore_amd_gpu_gcn_GFX803, + eCore_amd_gpu_gcn_GFX805, + eCore_amd_gpu_gcn_GFX810, + eCore_amd_gpu_gcn_GFX900, + eCore_amd_gpu_gcn_GFX902, + eCore_amd_gpu_gcn_GFX904, + eCore_amd_gpu_gcn_GFX906, + eCore_amd_gpu_gcn_GFX908, + eCore_amd_gpu_gcn_GFX909, + eCore_amd_gpu_gcn_GFX90A, + eCore_amd_gpu_gcn_GFX90C, + eCore_amd_gpu_gcn_GFX942, + eCore_amd_gpu_gcn_GFX950, + eCore_amd_gpu_gcn_GFX1010, + eCore_amd_gpu_gcn_GFX1011, + eCore_amd_gpu_gcn_GFX1012, + eCore_amd_gpu_gcn_GFX1013, + eCore_amd_gpu_gcn_GFX1030, + eCore_amd_gpu_gcn_GFX1031, + eCore_amd_gpu_gcn_GFX1032, + eCore_amd_gpu_gcn_GFX1033, + eCore_amd_gpu_gcn_GFX1034, + eCore_amd_gpu_gcn_GFX1035, + eCore_amd_gpu_gcn_GFX1036, + eCore_amd_gpu_gcn_GFX1100, + eCore_amd_gpu_gcn_GFX1101, + eCore_amd_gpu_gcn_GFX1102, + eCore_amd_gpu_gcn_GFX1103, + eCore_amd_gpu_gcn_GFX1150, + eCore_amd_gpu_gcn_GFX1151, + eCore_amd_gpu_gcn_GFX1152, + eCore_amd_gpu_gcn_GFX1153, + eCore_amd_gpu_gcn_GFX1154, + eCore_amd_gpu_gcn_GFX1170, + eCore_amd_gpu_gcn_GFX1171, + eCore_amd_gpu_gcn_GFX1172, + eCore_amd_gpu_gcn_GFX1200, + eCore_amd_gpu_gcn_GFX1201, + eCore_amd_gpu_gcn_GFX1250, + eCore_amd_gpu_gcn_GFX1251, + eCore_amd_gpu_gcn_GFX1310, + eCore_amd_gpu_gcn_GFX9_GENERIC, + eCore_amd_gpu_gcn_GFX9_4_GENERIC, + eCore_amd_gpu_gcn_GFX10_1_GENERIC, + eCore_amd_gpu_gcn_GFX10_3_GENERIC, + eCore_amd_gpu_gcn_GFX11_GENERIC, + eCore_amd_gpu_gcn_GFX12_GENERIC, + eCore_amd_gpu_gcn_GFX12_5_GENERIC, + eCore_amd_gpu_gcn_GFX11_7_GENERIC, + eCore_amd_gpu_gcn_GFX13_GENERIC, + eCore_amd_gpu_unknown, + kNumCores, kCore_invalid, @@ -286,7 +365,10 @@ class ArchSpec { kCore_mips64el_last = eCore_mips64r6el, kCore_mips_first = eCore_mips32, - kCore_mips_last = eCore_mips64r6el + kCore_mips_last = eCore_mips64r6el, + + kCore_amd_gpu_first = eCore_amd_gpu_r600_R600, + kCore_amd_gpu_last = eCore_amd_gpu_unknown }; @@ -454,6 +536,8 @@ class ArchSpec { uint32_t GetMachOCPUSubType() const; + uint32_t GetElfCPUSubType() const; + /// Architecture triple accessor. /// /// \return A triple describing this ArchSpec. diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 1f8783b8f1fe3..eccb24e3d7aa1 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -362,6 +362,26 @@ static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header) { } } +static uint32_t AMDGPUVariantFromElfFlags(const elf::ELFHeader &header) { + // Only HSA objects encode the exact GPU model, as an EF_AMDGPU_MACH value. + if (header.e_ident[EI_OSABI] == ELFOSABI_AMDGPU_HSA) { + switch (header.e_ident[EI_ABIVERSION]) { + // HSA V2 does not encode a CPU model. + case ELFABIVERSION_AMDGPU_HSA_V2: + break; + + case ELFABIVERSION_AMDGPU_HSA_V3: + case ELFABIVERSION_AMDGPU_HSA_V4: + case ELFABIVERSION_AMDGPU_HSA_V5: + case ELFABIVERSION_AMDGPU_HSA_V6: + // The CPU model is the EF_AMDGPU_MACH value in the bottom byte of + // e_flags. + return header.e_flags & EF_AMDGPU_MACH; + } + } + return LLDB_INVALID_CPUTYPE; +} + static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { if (header.e_machine == llvm::ELF::EM_MIPS) return mipsVariantFromElfFlags(header); @@ -371,6 +391,8 @@ static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { return riscvVariantFromElfFlags(header); else if (header.e_machine == llvm::ELF::EM_LOONGARCH) return loongarchVariantFromElfFlags(header); + else if (header.e_machine == llvm::ELF::EM_AMDGPU) + return AMDGPUVariantFromElfFlags(header); return LLDB_INVALID_CPUTYPE; } @@ -584,6 +606,9 @@ static bool GetOsFromOSABI(unsigned char osabi_byte, case ELFOSABI_SOLARIS: ostype = llvm::Triple::OSType::Solaris; break; + case ELFOSABI_AMDGPU_HSA: + ostype = llvm::Triple::OSType::AMDHSA; + break; default: ostype = llvm::Triple::OSType::UnknownOS; } @@ -618,7 +643,6 @@ ModuleSpecList ObjectFileELF::GetModuleSpecifications( if (spec.GetArchitecture().IsValid()) { llvm::Triple::OSType ostype; - llvm::Triple::VendorType vendor; llvm::Triple::OSType spec_ostype = spec.GetArchitecture().GetTriple().getOS(); @@ -626,12 +650,6 @@ ModuleSpecList ObjectFileELF::GetModuleSpecifications( __FUNCTION__, file.GetPath().c_str(), OSABIAsCString(header.e_ident[EI_OSABI])); - // SetArchitecture should have set the vendor to unknown - vendor = spec.GetArchitecture().GetTriple().getVendor(); - assert(vendor == llvm::Triple::UnknownVendor); - UNUSED_IF_ASSERT_DISABLED(vendor); - - // // Validate it is ok to remove GetOsFromOSABI GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); assert(spec_ostype == ostype); diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index 6eecf4f1b0995..0a27e2d2b30ec 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -13,6 +13,7 @@ #include "lldb/Utility/StringList.h" #include "lldb/lldb-defines.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/BinaryFormat/MachO.h" @@ -40,6 +41,22 @@ struct CoreDefinition { } // namespace lldb_private +#define AMD_GPU_CORE_DEF_R600(sub) \ + {eByteOrderLittle, \ + 4, \ + 4, \ + 16, \ + llvm::Triple::r600, \ + ArchSpec::eCore_amd_gpu_r600_##sub, \ + "r600"} +#define AMD_GPU_CORE_DEF_GCN(sub) \ + {eByteOrderLittle, \ + 8, \ + 4, \ + 16, \ + llvm::Triple::amdgcn, \ + ArchSpec::eCore_amd_gpu_gcn_##sub, \ + "amdgcn"} // This core information can be looked using the ArchSpec::Core as the index static constexpr const CoreDefinition g_core_definitions[] = { {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_generic, @@ -254,6 +271,85 @@ static constexpr const CoreDefinition g_core_definitions[] = { {eByteOrderLittle, 4, 1, 4, llvm::Triple::wasm32, ArchSpec::eCore_wasm32, "wasm32"}, + AMD_GPU_CORE_DEF_R600(R600), + AMD_GPU_CORE_DEF_R600(R630), + AMD_GPU_CORE_DEF_R600(RS880), + AMD_GPU_CORE_DEF_R600(RV670), + AMD_GPU_CORE_DEF_R600(RV710), + AMD_GPU_CORE_DEF_R600(RV730), + AMD_GPU_CORE_DEF_R600(RV770), + AMD_GPU_CORE_DEF_R600(CEDAR), + AMD_GPU_CORE_DEF_R600(CYPRESS), + AMD_GPU_CORE_DEF_R600(JUNIPER), + AMD_GPU_CORE_DEF_R600(REDWOOD), + AMD_GPU_CORE_DEF_R600(SUMO), + AMD_GPU_CORE_DEF_R600(BARTS), + AMD_GPU_CORE_DEF_R600(CAICOS), + AMD_GPU_CORE_DEF_R600(CAYMAN), + AMD_GPU_CORE_DEF_R600(TURKS), + AMD_GPU_CORE_DEF_GCN(GFX600), + AMD_GPU_CORE_DEF_GCN(GFX601), + AMD_GPU_CORE_DEF_GCN(GFX602), + AMD_GPU_CORE_DEF_GCN(GFX700), + AMD_GPU_CORE_DEF_GCN(GFX701), + AMD_GPU_CORE_DEF_GCN(GFX702), + AMD_GPU_CORE_DEF_GCN(GFX703), + AMD_GPU_CORE_DEF_GCN(GFX704), + AMD_GPU_CORE_DEF_GCN(GFX705), + AMD_GPU_CORE_DEF_GCN(GFX801), + AMD_GPU_CORE_DEF_GCN(GFX802), + AMD_GPU_CORE_DEF_GCN(GFX803), + AMD_GPU_CORE_DEF_GCN(GFX805), + AMD_GPU_CORE_DEF_GCN(GFX810), + AMD_GPU_CORE_DEF_GCN(GFX900), + AMD_GPU_CORE_DEF_GCN(GFX902), + AMD_GPU_CORE_DEF_GCN(GFX904), + AMD_GPU_CORE_DEF_GCN(GFX906), + AMD_GPU_CORE_DEF_GCN(GFX908), + AMD_GPU_CORE_DEF_GCN(GFX909), + AMD_GPU_CORE_DEF_GCN(GFX90A), + AMD_GPU_CORE_DEF_GCN(GFX90C), + AMD_GPU_CORE_DEF_GCN(GFX942), + AMD_GPU_CORE_DEF_GCN(GFX950), + AMD_GPU_CORE_DEF_GCN(GFX1010), + AMD_GPU_CORE_DEF_GCN(GFX1011), + AMD_GPU_CORE_DEF_GCN(GFX1012), + AMD_GPU_CORE_DEF_GCN(GFX1013), + AMD_GPU_CORE_DEF_GCN(GFX1030), + AMD_GPU_CORE_DEF_GCN(GFX1031), + AMD_GPU_CORE_DEF_GCN(GFX1032), + AMD_GPU_CORE_DEF_GCN(GFX1033), + AMD_GPU_CORE_DEF_GCN(GFX1034), + AMD_GPU_CORE_DEF_GCN(GFX1035), + AMD_GPU_CORE_DEF_GCN(GFX1036), + AMD_GPU_CORE_DEF_GCN(GFX1100), + AMD_GPU_CORE_DEF_GCN(GFX1101), + AMD_GPU_CORE_DEF_GCN(GFX1102), + AMD_GPU_CORE_DEF_GCN(GFX1103), + AMD_GPU_CORE_DEF_GCN(GFX1150), + AMD_GPU_CORE_DEF_GCN(GFX1151), + AMD_GPU_CORE_DEF_GCN(GFX1152), + AMD_GPU_CORE_DEF_GCN(GFX1153), + AMD_GPU_CORE_DEF_GCN(GFX1154), + AMD_GPU_CORE_DEF_GCN(GFX1170), + AMD_GPU_CORE_DEF_GCN(GFX1171), + AMD_GPU_CORE_DEF_GCN(GFX1172), + AMD_GPU_CORE_DEF_GCN(GFX1200), + AMD_GPU_CORE_DEF_GCN(GFX1201), + AMD_GPU_CORE_DEF_GCN(GFX1250), + AMD_GPU_CORE_DEF_GCN(GFX1251), + AMD_GPU_CORE_DEF_GCN(GFX1310), + AMD_GPU_CORE_DEF_GCN(GFX9_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX9_4_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX10_1_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX10_3_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX11_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX12_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX12_5_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX11_7_GENERIC), + AMD_GPU_CORE_DEF_GCN(GFX13_GENERIC), + {eByteOrderLittle, 8, 4, 16, llvm::Triple::amdgcn, + ArchSpec::eCore_amd_gpu_unknown, "amdgcn"}, }; // Ensure that we have an entry in the g_core_definitions for each core. If you @@ -383,6 +479,12 @@ static const ArchDefinition g_macho_arch_def = {eArchTypeMachO, std::size(g_macho_arch_entries), g_macho_arch_entries, "mach-o"}; +#define AMD_GPU_ARCH_DEF_R600(sub) \ + {ArchSpec::eCore_amd_gpu_r600_##sub, llvm::ELF::EM_AMDGPU, \ + llvm::ELF::EF_AMDGPU_MACH_R600_##sub} +#define AMD_GPU_ARCH_DEF_GCN(sub) \ + {ArchSpec::eCore_amd_gpu_gcn_##sub, llvm::ELF::EM_AMDGPU, \ + llvm::ELF::EF_AMDGPU_MACH_AMDGCN_##sub} //===----------------------------------------------------------------------===// // A table that gets searched linearly for matches. This table is used to // convert cpu type and subtypes to architecture names, and to convert @@ -421,6 +523,85 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { {ArchSpec::eCore_riscv64, llvm::ELF::EM_RISCV, ArchSpec::eRISCVSubType_riscv64}, // riscv64 {ArchSpec::eCore_loongarch32, llvm::ELF::EM_LOONGARCH, ArchSpec::eLoongArchSubType_loongarch32}, // loongarch32 {ArchSpec::eCore_loongarch64, llvm::ELF::EM_LOONGARCH, ArchSpec::eLoongArchSubType_loongarch64}, // loongarch64 + AMD_GPU_ARCH_DEF_R600(R600), + AMD_GPU_ARCH_DEF_R600(R630), + AMD_GPU_ARCH_DEF_R600(RS880), + AMD_GPU_ARCH_DEF_R600(RV670), + AMD_GPU_ARCH_DEF_R600(RV710), + AMD_GPU_ARCH_DEF_R600(RV730), + AMD_GPU_ARCH_DEF_R600(RV770), + AMD_GPU_ARCH_DEF_R600(CEDAR), + AMD_GPU_ARCH_DEF_R600(CYPRESS), + AMD_GPU_ARCH_DEF_R600(JUNIPER), + AMD_GPU_ARCH_DEF_R600(REDWOOD), + AMD_GPU_ARCH_DEF_R600(SUMO), + AMD_GPU_ARCH_DEF_R600(BARTS), + AMD_GPU_ARCH_DEF_R600(CAICOS), + AMD_GPU_ARCH_DEF_R600(CAYMAN), + AMD_GPU_ARCH_DEF_R600(TURKS), + AMD_GPU_ARCH_DEF_GCN(GFX600), + AMD_GPU_ARCH_DEF_GCN(GFX601), + AMD_GPU_ARCH_DEF_GCN(GFX602), + AMD_GPU_ARCH_DEF_GCN(GFX700), + AMD_GPU_ARCH_DEF_GCN(GFX701), + AMD_GPU_ARCH_DEF_GCN(GFX702), + AMD_GPU_ARCH_DEF_GCN(GFX703), + AMD_GPU_ARCH_DEF_GCN(GFX704), + AMD_GPU_ARCH_DEF_GCN(GFX705), + AMD_GPU_ARCH_DEF_GCN(GFX801), + AMD_GPU_ARCH_DEF_GCN(GFX802), + AMD_GPU_ARCH_DEF_GCN(GFX803), + AMD_GPU_ARCH_DEF_GCN(GFX805), + AMD_GPU_ARCH_DEF_GCN(GFX810), + AMD_GPU_ARCH_DEF_GCN(GFX900), + AMD_GPU_ARCH_DEF_GCN(GFX902), + AMD_GPU_ARCH_DEF_GCN(GFX904), + AMD_GPU_ARCH_DEF_GCN(GFX906), + AMD_GPU_ARCH_DEF_GCN(GFX908), + AMD_GPU_ARCH_DEF_GCN(GFX909), + AMD_GPU_ARCH_DEF_GCN(GFX90A), + AMD_GPU_ARCH_DEF_GCN(GFX90C), + AMD_GPU_ARCH_DEF_GCN(GFX942), + AMD_GPU_ARCH_DEF_GCN(GFX950), + AMD_GPU_ARCH_DEF_GCN(GFX1010), + AMD_GPU_ARCH_DEF_GCN(GFX1011), + AMD_GPU_ARCH_DEF_GCN(GFX1012), + AMD_GPU_ARCH_DEF_GCN(GFX1013), + AMD_GPU_ARCH_DEF_GCN(GFX1030), + AMD_GPU_ARCH_DEF_GCN(GFX1031), + AMD_GPU_ARCH_DEF_GCN(GFX1032), + AMD_GPU_ARCH_DEF_GCN(GFX1033), + AMD_GPU_ARCH_DEF_GCN(GFX1034), + AMD_GPU_ARCH_DEF_GCN(GFX1035), + AMD_GPU_ARCH_DEF_GCN(GFX1036), + AMD_GPU_ARCH_DEF_GCN(GFX1100), + AMD_GPU_ARCH_DEF_GCN(GFX1101), + AMD_GPU_ARCH_DEF_GCN(GFX1102), + AMD_GPU_ARCH_DEF_GCN(GFX1103), + AMD_GPU_ARCH_DEF_GCN(GFX1150), + AMD_GPU_ARCH_DEF_GCN(GFX1151), + AMD_GPU_ARCH_DEF_GCN(GFX1152), + AMD_GPU_ARCH_DEF_GCN(GFX1153), + AMD_GPU_ARCH_DEF_GCN(GFX1154), + AMD_GPU_ARCH_DEF_GCN(GFX1170), + AMD_GPU_ARCH_DEF_GCN(GFX1171), + AMD_GPU_ARCH_DEF_GCN(GFX1172), + AMD_GPU_ARCH_DEF_GCN(GFX1200), + AMD_GPU_ARCH_DEF_GCN(GFX1201), + AMD_GPU_ARCH_DEF_GCN(GFX1250), + AMD_GPU_ARCH_DEF_GCN(GFX1251), + AMD_GPU_ARCH_DEF_GCN(GFX1310), + AMD_GPU_ARCH_DEF_GCN(GFX9_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX9_4_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX10_1_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX10_3_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX11_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX12_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX12_5_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX11_7_GENERIC), + AMD_GPU_ARCH_DEF_GCN(GFX13_GENERIC), + // Any AMDGPU object with no recognized model resolves here. + {ArchSpec::eCore_amd_gpu_unknown, llvm::ELF::EM_AMDGPU}, }; // clang-format on @@ -524,6 +705,8 @@ FindArchDefinitionEntry(const ArchDefinition *def, ArchSpec::Core core) { return nullptr; } +static llvm::StringRef GetAMDGPUVariantName(uint32_t sub); + //===----------------------------------------------------------------------===// // Constructors and destructors. @@ -652,33 +835,49 @@ std::string ArchSpec::GetClangTargetCPU() const { if (GetTriple().isARM()) cpu = llvm::ARM::getARMCPUForArch(GetTriple(), "").str(); + + if (GetTriple().isAMDGPU()) { + uint32_t sub = GetElfCPUSubType(); + if (sub != LLDB_INVALID_CPUTYPE) + cpu = GetAMDGPUVariantName(sub); + } return cpu; } -uint32_t ArchSpec::GetMachOCPUType() const { - const CoreDefinition *core_def = FindCoreDefinition(m_core); - if (core_def) { - const ArchDefinitionEntry *arch_def = - FindArchDefinitionEntry(&g_macho_arch_def, core_def->core); - if (arch_def) { - return arch_def->cpu; - } - } +static const ArchDefinitionEntry * +FindArchDefEntryIfCoreIsValid(const ArchDefinition *def, ArchSpec::Core core) { + if (const CoreDefinition *core_def = FindCoreDefinition(core)) + return FindArchDefinitionEntry(def, core_def->core); + + return nullptr; +} + +static uint32_t GetCPUType(const ArchDefinition *def, ArchSpec::Core core) { + if (const ArchDefinitionEntry *arch_def = + FindArchDefEntryIfCoreIsValid(def, core)) + return arch_def->cpu; return LLDB_INVALID_CPUTYPE; } -uint32_t ArchSpec::GetMachOCPUSubType() const { - const CoreDefinition *core_def = FindCoreDefinition(m_core); - if (core_def) { - const ArchDefinitionEntry *arch_def = - FindArchDefinitionEntry(&g_macho_arch_def, core_def->core); - if (arch_def) { - return arch_def->sub; - } - } +static uint32_t GetCPUSubType(const ArchDefinition *def, ArchSpec::Core core) { + if (const ArchDefinitionEntry *arch_def = + FindArchDefEntryIfCoreIsValid(def, core)) + return arch_def->sub; return LLDB_INVALID_CPUTYPE; } +uint32_t ArchSpec::GetMachOCPUType() const { + return GetCPUType(&g_macho_arch_def, m_core); +} + +uint32_t ArchSpec::GetMachOCPUSubType() const { + return GetCPUSubType(&g_macho_arch_def, m_core); +} + +uint32_t ArchSpec::GetElfCPUSubType() const { + return GetCPUSubType(&g_elf_arch_def, m_core); +} + llvm::Triple::ArchType ArchSpec::GetMachine() const { const CoreDefinition *core_def = FindCoreDefinition(m_core); if (core_def) @@ -849,6 +1048,255 @@ void ArchSpec::MergeFrom(const ArchSpec &other) { } } +static llvm::StringRef GetAMDGPUVariantName(uint32_t sub) { + switch (sub) { + case llvm::ELF::EF_AMDGPU_MACH_R600_R600: + return "r600"; + case llvm::ELF::EF_AMDGPU_MACH_R600_R630: + return "r630"; + case llvm::ELF::EF_AMDGPU_MACH_R600_RS880: + return "rs880"; + case llvm::ELF::EF_AMDGPU_MACH_R600_RV670: + return "rv670"; + case llvm::ELF::EF_AMDGPU_MACH_R600_RV710: + return "rv710"; + case llvm::ELF::EF_AMDGPU_MACH_R600_RV730: + return "rv730"; + case llvm::ELF::EF_AMDGPU_MACH_R600_RV770: + return "rv770"; + case llvm::ELF::EF_AMDGPU_MACH_R600_CEDAR: + return "cedar"; + case llvm::ELF::EF_AMDGPU_MACH_R600_CYPRESS: + return "cypress"; + case llvm::ELF::EF_AMDGPU_MACH_R600_JUNIPER: + return "juniper"; + case llvm::ELF::EF_AMDGPU_MACH_R600_REDWOOD: + return "redwood"; + case llvm::ELF::EF_AMDGPU_MACH_R600_SUMO: + return "sumo"; + case llvm::ELF::EF_AMDGPU_MACH_R600_BARTS: + return "barts"; + case llvm::ELF::EF_AMDGPU_MACH_R600_CAICOS: + return "caicos"; + case llvm::ELF::EF_AMDGPU_MACH_R600_CAYMAN: + return "cayman"; + case llvm::ELF::EF_AMDGPU_MACH_R600_TURKS: + return "turks"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX600: + return "gfx600"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX601: + return "gfx601"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX602: + return "gfx602"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX700: + return "gfx700"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX701: + return "gfx701"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX702: + return "gfx702"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX703: + return "gfx703"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX704: + return "gfx704"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX705: + return "gfx705"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX801: + return "gfx801"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX802: + return "gfx802"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX803: + return "gfx803"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX805: + return "gfx805"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX810: + return "gfx810"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX900: + return "gfx900"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX902: + return "gfx902"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX904: + return "gfx904"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX906: + return "gfx906"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX908: + return "gfx908"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX909: + return "gfx909"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A: + return "gfx90a"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C: + return "gfx90c"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX942: + return "gfx942"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX950: + return "gfx950"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010: + return "gfx1010"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011: + return "gfx1011"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012: + return "gfx1012"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013: + return "gfx1013"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030: + return "gfx1030"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031: + return "gfx1031"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032: + return "gfx1032"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033: + return "gfx1033"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034: + return "gfx1034"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035: + return "gfx1035"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036: + return "gfx1036"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100: + return "gfx1100"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101: + return "gfx1101"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102: + return "gfx1102"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103: + return "gfx1103"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1150: + return "gfx1150"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151: + return "gfx1151"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152: + return "gfx1152"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1153: + return "gfx1153"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1154: + return "gfx1154"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1170: + return "gfx1170"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1171: + return "gfx1171"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1172: + return "gfx1172"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200: + return "gfx1200"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201: + return "gfx1201"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1250: + return "gfx1250"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1251: + return "gfx1251"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1310: + return "gfx1310"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC: + return "gfx9-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC: + return "gfx9-4-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC: + return "gfx10-1-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC: + return "gfx10-3-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC: + return "gfx11-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC: + return "gfx12-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_5_GENERIC: + return "gfx12-5-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_7_GENERIC: + return "gfx11-7-generic"; + case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX13_GENERIC: + return "gfx13-generic"; + default: + break; + } + return llvm::StringRef("unknown"); +} + +static ArchSpec::Core GetAMDGPUVariantToCoreR600(llvm::StringRef core_name) { + return llvm::StringSwitch<ArchSpec::Core>(core_name) + .Case("r600", ArchSpec::eCore_amd_gpu_r600_R600) + .Case("r630", ArchSpec::eCore_amd_gpu_r600_R630) + .Case("rs880", ArchSpec::eCore_amd_gpu_r600_RS880) + .Case("rv670", ArchSpec::eCore_amd_gpu_r600_RV670) + .Case("rv710", ArchSpec::eCore_amd_gpu_r600_RV710) + .Case("rv730", ArchSpec::eCore_amd_gpu_r600_RV730) + .Case("rv770", ArchSpec::eCore_amd_gpu_r600_RV770) + .Case("cedar", ArchSpec::eCore_amd_gpu_r600_CEDAR) + .Case("cypress", ArchSpec::eCore_amd_gpu_r600_CYPRESS) + .Case("juniper", ArchSpec::eCore_amd_gpu_r600_JUNIPER) + .Case("redwood", ArchSpec::eCore_amd_gpu_r600_REDWOOD) + .Case("sumo", ArchSpec::eCore_amd_gpu_r600_SUMO) + .Case("barts", ArchSpec::eCore_amd_gpu_r600_BARTS) + .Case("caicos", ArchSpec::eCore_amd_gpu_r600_CAICOS) + .Case("cayman", ArchSpec::eCore_amd_gpu_r600_CAYMAN) + .Case("turks", ArchSpec::eCore_amd_gpu_r600_TURKS) + .Default(ArchSpec::eCore_amd_gpu_unknown); +} + +static ArchSpec::Core GetAMDGPUVariantToCoreGCN(llvm::StringRef core_name) { + return llvm::StringSwitch<ArchSpec::Core>(core_name) + .Case("gfx600", ArchSpec::eCore_amd_gpu_gcn_GFX600) + .Case("gfx601", ArchSpec::eCore_amd_gpu_gcn_GFX601) + .Case("gfx602", ArchSpec::eCore_amd_gpu_gcn_GFX602) + .Case("gfx700", ArchSpec::eCore_amd_gpu_gcn_GFX700) + .Case("gfx701", ArchSpec::eCore_amd_gpu_gcn_GFX701) + .Case("gfx702", ArchSpec::eCore_amd_gpu_gcn_GFX702) + .Case("gfx703", ArchSpec::eCore_amd_gpu_gcn_GFX703) + .Case("gfx704", ArchSpec::eCore_amd_gpu_gcn_GFX704) + .Case("gfx705", ArchSpec::eCore_amd_gpu_gcn_GFX705) + .Case("gfx801", ArchSpec::eCore_amd_gpu_gcn_GFX801) + .Case("gfx802", ArchSpec::eCore_amd_gpu_gcn_GFX802) + .Case("gfx803", ArchSpec::eCore_amd_gpu_gcn_GFX803) + .Case("gfx805", ArchSpec::eCore_amd_gpu_gcn_GFX805) + .Case("gfx810", ArchSpec::eCore_amd_gpu_gcn_GFX810) + .Case("gfx900", ArchSpec::eCore_amd_gpu_gcn_GFX900) + .Case("gfx902", ArchSpec::eCore_amd_gpu_gcn_GFX902) + .Case("gfx904", ArchSpec::eCore_amd_gpu_gcn_GFX904) + .Case("gfx906", ArchSpec::eCore_amd_gpu_gcn_GFX906) + .Case("gfx908", ArchSpec::eCore_amd_gpu_gcn_GFX908) + .Case("gfx909", ArchSpec::eCore_amd_gpu_gcn_GFX909) + .Case("gfx90a", ArchSpec::eCore_amd_gpu_gcn_GFX90A) + .Case("gfx90c", ArchSpec::eCore_amd_gpu_gcn_GFX90C) + .Case("gfx942", ArchSpec::eCore_amd_gpu_gcn_GFX942) + .Case("gfx950", ArchSpec::eCore_amd_gpu_gcn_GFX950) + .Case("gfx1010", ArchSpec::eCore_amd_gpu_gcn_GFX1010) + .Case("gfx1011", ArchSpec::eCore_amd_gpu_gcn_GFX1011) + .Case("gfx1012", ArchSpec::eCore_amd_gpu_gcn_GFX1012) + .Case("gfx1013", ArchSpec::eCore_amd_gpu_gcn_GFX1013) + .Case("gfx1030", ArchSpec::eCore_amd_gpu_gcn_GFX1030) + .Case("gfx1031", ArchSpec::eCore_amd_gpu_gcn_GFX1031) + .Case("gfx1032", ArchSpec::eCore_amd_gpu_gcn_GFX1032) + .Case("gfx1033", ArchSpec::eCore_amd_gpu_gcn_GFX1033) + .Case("gfx1034", ArchSpec::eCore_amd_gpu_gcn_GFX1034) + .Case("gfx1035", ArchSpec::eCore_amd_gpu_gcn_GFX1035) + .Case("gfx1036", ArchSpec::eCore_amd_gpu_gcn_GFX1036) + .Case("gfx1100", ArchSpec::eCore_amd_gpu_gcn_GFX1100) + .Case("gfx1101", ArchSpec::eCore_amd_gpu_gcn_GFX1101) + .Case("gfx1102", ArchSpec::eCore_amd_gpu_gcn_GFX1102) + .Case("gfx1103", ArchSpec::eCore_amd_gpu_gcn_GFX1103) + .Case("gfx1150", ArchSpec::eCore_amd_gpu_gcn_GFX1150) + .Case("gfx1151", ArchSpec::eCore_amd_gpu_gcn_GFX1151) + .Case("gfx1152", ArchSpec::eCore_amd_gpu_gcn_GFX1152) + .Case("gfx1153", ArchSpec::eCore_amd_gpu_gcn_GFX1153) + .Case("gfx1154", ArchSpec::eCore_amd_gpu_gcn_GFX1154) + .Case("gfx1170", ArchSpec::eCore_amd_gpu_gcn_GFX1170) + .Case("gfx1171", ArchSpec::eCore_amd_gpu_gcn_GFX1171) + .Case("gfx1172", ArchSpec::eCore_amd_gpu_gcn_GFX1172) + .Case("gfx1200", ArchSpec::eCore_amd_gpu_gcn_GFX1200) + .Case("gfx1201", ArchSpec::eCore_amd_gpu_gcn_GFX1201) + .Case("gfx1250", ArchSpec::eCore_amd_gpu_gcn_GFX1250) + .Case("gfx1251", ArchSpec::eCore_amd_gpu_gcn_GFX1251) + .Case("gfx1310", ArchSpec::eCore_amd_gpu_gcn_GFX1310) + .Case("gfx9-generic", ArchSpec::eCore_amd_gpu_gcn_GFX9_GENERIC) + .Case("gfx9-4-generic", ArchSpec::eCore_amd_gpu_gcn_GFX9_4_GENERIC) + .Case("gfx10-1-generic", ArchSpec::eCore_amd_gpu_gcn_GFX10_1_GENERIC) + .Case("gfx10-3-generic", ArchSpec::eCore_amd_gpu_gcn_GFX10_3_GENERIC) + .Case("gfx11-generic", ArchSpec::eCore_amd_gpu_gcn_GFX11_GENERIC) + .Case("gfx12-generic", ArchSpec::eCore_amd_gpu_gcn_GFX12_GENERIC) + .Case("gfx12-5-generic", ArchSpec::eCore_amd_gpu_gcn_GFX12_5_GENERIC) + .Case("gfx11-7-generic", ArchSpec::eCore_amd_gpu_gcn_GFX11_7_GENERIC) + .Case("gfx13-generic", ArchSpec::eCore_amd_gpu_gcn_GFX13_GENERIC) + .Default(ArchSpec::eCore_amd_gpu_unknown); +} + bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os) { m_core = kCore_invalid; @@ -900,6 +1348,10 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu, case llvm::ELF::ELFOSABI_STANDALONE: m_triple.setOS(llvm::Triple::OSType::UnknownOS); break; + case llvm::ELF::ELFOSABI_AMDGPU_HSA: + m_triple.setVendor(llvm::Triple::VendorType::AMD); + m_triple.setOS(llvm::Triple::OSType::AMDHSA); + break; } } else if (arch_type == eArchTypeCOFF && os == llvm::Triple::Win32) { m_triple.setVendor(llvm::Triple::PC); @@ -911,10 +1363,24 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu, m_triple.setVendor(llvm::Triple::UnknownVendor); m_triple.setOS(llvm::Triple::UnknownOS); } - // Fall back onto setting the machine type if the arch by name - // failed... - if (m_triple.getArch() == llvm::Triple::UnknownArch) + switch (m_triple.getArch()) { + case llvm::Triple::UnknownArch: + // Fall back onto setting the machine type if the arch by name + // failed... m_triple.setArch(core_def->machine); + break; + case llvm::Triple::r600: + case llvm::Triple::amdgcn: { + // AMDGPU arches are special: they append a 5th element to the triple + // that comes after the environment and contains the sub type name. + std::string environment("-"); + environment += GetAMDGPUVariantName(arch_def_entry->sub); + m_triple.setEnvironmentName(environment); + break; + } + default: + break; + } } } else { Log *log(GetLog(LLDBLog::Target | LLDBLog::Process | LLDBLog::Platform)); @@ -1065,6 +1531,16 @@ void ArchSpec::UpdateCore() { // can be modified if needed for cases when cores handle both big and // little endian m_byte_order = core_def->default_byte_order; + + // amdgcn/r600 match their first table entry (GFX600/R600), so refine the + // core from the model in the triple environment. + if (m_core == eCore_amd_gpu_gcn_GFX600) { + m_core = GetAMDGPUVariantToCoreGCN( + m_triple.getEnvironmentName().split('-').second); + } else if (m_core == eCore_amd_gpu_r600_R600) { + m_core = GetAMDGPUVariantToCoreR600( + m_triple.getEnvironmentName().split('-').second); + } } else { Clear(); } diff --git a/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp b/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp index 6da2663ff3ae4..f7dcc91b7bee8 100644 --- a/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ b/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp @@ -17,8 +17,10 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Compression.h" #include "llvm/Support/FileUtilities.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" @@ -191,6 +193,132 @@ TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithOffsetFile) { EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 4640UL); } +// Verify an AMDGPU ELF header decodes to its exact GPU model. +// An AMDGPU object with no decodable model resolves to the generic "unknown" +// catch-all. +TEST_F(ObjectFileELFTest, GPUArchitectureUnknownAMDGPUModel) { + // No model byte is parsed unless the OS ABI is AMDGPU HSA. + { + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_NONE + Type: ET_DYN + Machine: EM_AMDGPU +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000000020 + Size: 0x0000000000000040 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec()); + const ArchSpec &arch = module_sp->GetArchitecture(); + ASSERT_TRUE(arch.IsValid()); + EXPECT_EQ(ArchSpec::eCore_amd_gpu_unknown, arch.GetCore()); + } + + // HSA code-object v2 (ABIVersion 0) carries no model byte, so even a + // populated mach flag is ignored. + { + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_AMDGPU_HSA + ABIVersion: 0x0 + Type: ET_DYN + Machine: EM_AMDGPU + Flags: [ EF_AMDGPU_MACH_AMDGCN_GFX942 ] +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000000020 + Size: 0x0000000000000040 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec()); + const ArchSpec &arch = module_sp->GetArchitecture(); + ASSERT_TRUE(arch.IsValid()); + EXPECT_EQ(ArchSpec::eCore_amd_gpu_unknown, arch.GetCore()); + } +} + +namespace { +struct AMDGPUModel { + uint32_t mach; // EF_AMDGPU_MACH value. + const char *flag; // ELF flag name used in the YAML "Flags" field. + const char *name; // Canonical model name, e.g. "gfx942". +}; + +// Every AMD GPU model, taken from llvm's AMDGPU_MACH_LIST so the tests track +// the authoritative list instead of duplicating it. +const AMDGPUModel kAMDGPUModels[] = { +#define AMDGPU_MODEL(NUM, ENUM, NAME) {NUM, #ENUM, NAME}, + AMDGPU_MACH_LIST(AMDGPU_MODEL) +#undef AMDGPU_MODEL +}; + +std::string AMDGPUModelName(const testing::TestParamInfo<AMDGPUModel> &info) { + // Test names allow only [A-Za-z0-9_]; the generic models contain dashes. + std::string name = info.param.name; + for (char &c : name) + if (c == '-') + c = '_'; + return name; +} +} // namespace + +class ObjectFileELFAMDGPUTest + : public ObjectFileELFTest, + public ::testing::WithParamInterface<AMDGPUModel> {}; + +// Every AMD GPU model must decode from an ELF header (built from YAML) to the +// right arch and core. The model is the EF_AMDGPU_MACH value in e_flags. +TEST_P(ObjectFileELFAMDGPUTest, DecodesAMDGPUModel) { + const AMDGPUModel &model = GetParam(); + const char *yaml_template = R"(--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_AMDGPU_HSA + ABIVersion: 0x1 + Type: ET_DYN + Machine: EM_AMDGPU + Flags: [ {0} ] +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000000020 + Size: 0x0000000000000040 +... +)"; + std::string yaml = llvm::formatv(yaml_template, model.flag).str(); + auto ExpectedFile = TestFile::fromYaml(yaml); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec()); + const ArchSpec &arch = module_sp->GetArchitecture(); + ASSERT_TRUE(arch.IsValid()); + EXPECT_NE(ArchSpec::eCore_amd_gpu_unknown, arch.GetCore()); + EXPECT_EQ(model.name, arch.GetClangTargetCPU()); + bool is_gcn = llvm::StringRef(model.name).starts_with("gfx"); + EXPECT_EQ(is_gcn ? llvm::Triple::amdgcn : llvm::Triple::r600, + arch.GetTriple().getArch()); + EXPECT_EQ(llvm::Triple::AMD, arch.GetTriple().getVendor()); + EXPECT_EQ(llvm::Triple::AMDHSA, arch.GetTriple().getOS()); +} + +INSTANTIATE_TEST_SUITE_P(AMDGPUModels, ObjectFileELFAMDGPUTest, + ::testing::ValuesIn(kAMDGPUModels), AMDGPUModelName); + TEST_F(ObjectFileELFTest, GetSymtab_SynthesizedEntryPointSymbol) { auto ExpectedFile = TestFile::fromYaml(R"( --- !ELF diff --git a/lldb/unittests/Utility/ArchSpecTest.cpp b/lldb/unittests/Utility/ArchSpecTest.cpp index 2f6cc01a315e8..32ea5796650b7 100644 --- a/lldb/unittests/Utility/ArchSpecTest.cpp +++ b/lldb/unittests/Utility/ArchSpecTest.cpp @@ -155,6 +155,71 @@ TEST(ArchSpecTest, TestSetTriple) { EXPECT_FALSE(AS.SetTriple("")); } +namespace { +struct AMDGPUModel { + uint32_t mach; // EF_AMDGPU_MACH value. + const char *flag; // ELF flag name used in the YAML "Flags" field. + const char *name; // Canonical model name, e.g. "gfx942". +}; + +// Every AMD GPU model, taken from llvm's AMDGPU_MACH_LIST so the tests track +// the authoritative list instead of duplicating it. +const AMDGPUModel kAMDGPUModels[] = { +#define AMDGPU_MODEL(NUM, ENUM, NAME) {NUM, #ENUM, NAME}, + AMDGPU_MACH_LIST(AMDGPU_MODEL) +#undef AMDGPU_MODEL +}; + +std::string AMDGPUModelName(const testing::TestParamInfo<AMDGPUModel> &info) { + // Test names allow only [A-Za-z0-9_]; the generic models contain dashes. + std::string name = info.param.name; + for (char &c : name) + if (c == '-') + c = '_'; + return name; +} +} // namespace + +class ArchSpecAMDGPUTest : public ::testing::TestWithParam<AMDGPUModel> {}; + +// SetTriple() must resolve every AMD GPU triple to the right arch and core. +// This exercises ArchSpec::UpdateCore(), which refines the core from the GPU +// model in the triple environment. +TEST_P(ArchSpecAMDGPUTest, SetTriple) { + const AMDGPUModel &model = GetParam(); + bool is_gcn = llvm::StringRef(model.name).starts_with("gfx"); + std::string triple = + (is_gcn ? "amdgcn" : "r600") + std::string("-amd-amdhsa--") + model.name; + + ArchSpec AS; + EXPECT_TRUE(AS.SetTriple(triple)); + EXPECT_EQ(is_gcn ? llvm::Triple::amdgcn : llvm::Triple::r600, + AS.GetTriple().getArch()); + EXPECT_NE(ArchSpec::eCore_amd_gpu_unknown, AS.GetCore()); + EXPECT_EQ(model.name, AS.GetClangTargetCPU()); +} + +// SetArchitecture() from an ELF header must resolve every AMD GPU model to the +// right arch, vendor, OS, sub type and core. +TEST_P(ArchSpecAMDGPUTest, SetArchitectureFromELF) { + const AMDGPUModel &model = GetParam(); + bool is_gcn = llvm::StringRef(model.name).starts_with("gfx"); + + ArchSpec AS; + EXPECT_TRUE(AS.SetArchitecture(eArchTypeELF, llvm::ELF::EM_AMDGPU, model.mach, + llvm::ELF::ELFOSABI_AMDGPU_HSA)); + EXPECT_EQ(is_gcn ? llvm::Triple::amdgcn : llvm::Triple::r600, + AS.GetTriple().getArch()); + EXPECT_EQ(llvm::Triple::AMD, AS.GetTriple().getVendor()); + EXPECT_EQ(llvm::Triple::AMDHSA, AS.GetTriple().getOS()); + EXPECT_EQ(model.mach, AS.GetElfCPUSubType()); + EXPECT_NE(ArchSpec::eCore_amd_gpu_unknown, AS.GetCore()); + EXPECT_EQ(model.name, AS.GetClangTargetCPU()); +} + +INSTANTIATE_TEST_SUITE_P(AMDGPU, ArchSpecAMDGPUTest, + ::testing::ValuesIn(kAMDGPUModels), AMDGPUModelName); + TEST(ArchSpecTest, MergeFrom) { { ArchSpec A; _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
