Index: include/llvm/BinaryFormat/ELF.h =================================================================== --- include/llvm/BinaryFormat/ELF.h +++ include/llvm/BinaryFormat/ELF.h @@ -647,6 +647,14 @@ #include "ELFRelocs/WebAssembly.def" }; +// AMDGPU Specific e_flags +enum : unsigned { + EF_AMDGPU_ARCH_NONE = 0x00000000, // None/unknown. + EF_AMDGPU_ARCH_R600 = 0x10000000, // AMD HD2XXX-HD6XXX GPUs. + EF_AMDGPU_ARCH_GCN = 0x20000000, // AMD GCN GFX6+ GPUs. + EF_AMDGPU_ARCH = 0xf0000000 // EF_AMDGPU_ARCH_XXX selection mask. +}; + // ELF Relocation types for AMDGPU enum { #include "ELFRelocs/AMDGPU.def" Index: include/llvm/Object/ELFObjectFile.h =================================================================== --- include/llvm/Object/ELFObjectFile.h +++ include/llvm/Object/ELFObjectFile.h @@ -1063,14 +1063,17 @@ default: return Triple::UnknownArch; } - case ELF::EM_AMDGPU: - if (EF.getHeader()->e_ident[ELF::EI_CLASS] != ELF::ELFCLASS64) - return Triple::UnknownArch; - if (!IsLittleEndian) + case ELF::EM_AMDGPU: { + unsigned EFlags = EF.getHeader()->e_flags; + switch (EFlags & ELF::EF_AMDGPU_ARCH) { + case ELF::EF_AMDGPU_ARCH_R600: + return Triple::r600; + case ELF::EF_AMDGPU_ARCH_GCN: + return Triple::amdgcn; + default: return Triple::UnknownArch; - - // TODO: Determine r600/amdgcn architecture based e_flags. - return Triple::amdgcn; + } + } case ELF::EM_BPF: return IsLittleEndian ? Triple::bpfel : Triple::bpfeb; Index: lib/ObjectYAML/ELFYAML.cpp =================================================================== --- lib/ObjectYAML/ELFYAML.cpp +++ lib/ObjectYAML/ELFYAML.cpp @@ -246,7 +246,6 @@ ECase(ELFOSABI_HPUX); ECase(ELFOSABI_NETBSD); ECase(ELFOSABI_GNU); - ECase(ELFOSABI_GNU); ECase(ELFOSABI_HURD); ECase(ELFOSABI_SOLARIS); ECase(ELFOSABI_AIX); @@ -370,6 +369,9 @@ BCase(EF_RISCV_RVE); break; case ELF::EM_AMDGPU: + BCaseMask(EF_AMDGPU_ARCH_R600, EF_AMDGPU_ARCH); + BCaseMask(EF_AMDGPU_ARCH_GCN, EF_AMDGPU_ARCH); + break; case ELF::EM_X86_64: break; default: Index: lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h +++ lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h @@ -25,15 +25,13 @@ class AMDGPUELFStreamer : public MCELFStreamer { public: - AMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS, - MCCodeEmitter *Emitter) - : MCELFStreamer(Context, MAB, OS, Emitter) { } - + AMDGPUELFStreamer(const Triple &T, MCContext &Context, MCAsmBackend &MAB, + raw_pwrite_stream &OS, MCCodeEmitter *Emitter); }; -MCELFStreamer *createAMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_pwrite_stream &OS, - MCCodeEmitter *Emitter, bool RelaxAll); +MCELFStreamer *createAMDGPUELFStreamer(const Triple &T, MCContext &Context, + MCAsmBackend &MAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll); } // namespace llvm. #endif Index: lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp +++ lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp @@ -9,13 +9,37 @@ #include "AMDGPUELFStreamer.h" #include "Utils/AMDGPUBaseInfo.h" +#include "llvm/BinaryFormat/ELF.h" using namespace llvm; -MCELFStreamer *llvm::createAMDGPUELFStreamer(MCContext &Context, - MCAsmBackend &MAB, - raw_pwrite_stream &OS, - MCCodeEmitter *Emitter, - bool RelaxAll) { - return new AMDGPUELFStreamer(Context, MAB, OS, Emitter); +AMDGPUELFStreamer::AMDGPUELFStreamer(const Triple &T, MCContext &Context, + MCAsmBackend &MAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter) + : MCELFStreamer(Context, MAB, OS, Emitter) { + unsigned Arch = ELF::EF_AMDGPU_ARCH_NONE; + switch (T.getArch()) { + case Triple::r600: + Arch = ELF::EF_AMDGPU_ARCH_R600; + break; + case Triple::amdgcn: + Arch = ELF::EF_AMDGPU_ARCH_GCN; + break; + default: + break; + } + + MCAssembler &MCA = getAssembler(); + unsigned EFlags = MCA.getELFHeaderEFlags(); + EFlags &= ~ELF::EF_AMDGPU_ARCH; + EFlags |= Arch; + MCA.setELFHeaderEFlags(EFlags); +} + +MCELFStreamer *llvm::createAMDGPUELFStreamer(const Triple &T, MCContext &Context, + MCAsmBackend &MAB, + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll) { + return new AMDGPUELFStreamer(T, Context, MAB, OS, Emitter); } Index: lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp @@ -80,10 +80,7 @@ static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter, bool RelaxAll) { - if (T.getOS() == Triple::AMDHSA) - return createAMDGPUELFStreamer(Context, MAB, OS, Emitter, RelaxAll); - - return createELFStreamer(Context, MAB, OS, Emitter, RelaxAll); + return createAMDGPUELFStreamer(T, Context, MAB, OS, Emitter, RelaxAll); } extern "C" void LLVMInitializeAMDGPUTargetMC() { Index: test/CodeGen/AMDGPU/elf-header.ll =================================================================== --- test/CodeGen/AMDGPU/elf-header.ll +++ test/CodeGen/AMDGPU/elf-header.ll @@ -23,11 +23,11 @@ ; RUN: llc -mtriple=amdgcn-unknown-mesa3d -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck --check-prefix=GCN --check-prefix=GCN-OSABI-MESA3D %s ; R600: Format: ELF32-amdgpu -; R600: Arch: unknown +; R600: Arch: r600 ; R600: AddressSize: 32bit -; GCN: Format: ELF64-amdgpu -; GCN: Arch: amdgcn -; GCN: AddressSize: 64bit +; GCN: Format: ELF64-amdgpu +; GCN: Arch: amdgcn +; GCN: AddressSize: 64bit ; R600-OSABI-NONE: OS/ABI: SystemV (0x0) ; GCN-OSABI-NONE: OS/ABI: SystemV (0x0) @@ -36,8 +36,14 @@ ; GCN-OSABI-MESA3D: OS/ABI: AMDGPU_MESA3D (0x42) ; R600: Machine: EM_AMDGPU (0xE0) -; GCN: Machine: EM_AMDGPU (0xE0) +; R600: Flags [ (0x10000000) +; R600: EF_AMDGPU_ARCH_R600 (0x10000000) +; R600: ] +; GCN: Machine: EM_AMDGPU (0xE0) +; GCN: Flags [ (0x20000000) +; GCN: EF_AMDGPU_ARCH_GCN (0x20000000) +; GCN: ] define amdgpu_kernel void @elf_header() { ret void -} \ No newline at end of file +} Index: test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml =================================================================== --- test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml +++ test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml @@ -1,21 +1,34 @@ # RUN: yaml2obj %s > %t.o -# RUN: llvm-readobj -s -file-headers %t.o | FileCheck %s +# RUN: llvm-readobj -s -file-headers %t.o | FileCheck --check-prefix=ELF %s +# RUN: obj2yaml %t.o | FileCheck --check-prefix=YAML %s -# CHECK: Format: ELF64-amdgpu -# CHECK: Arch: amdgcn -# CHECK: ElfHeader { -# CHECK: Ident { -# CHECK: OS/ABI: AMDGPU_HSA (0x40) -# CHECK: ABIVersion: 0 -# CHECK: } -# CHECK: Machine: EM_AMDGPU (0xE0) -# CHECK: } +# ELF: Format: ELF64-amdgpu +# ELF: Arch: amdgcn +# ELF: ElfHeader { +# ELF: Ident { +# ELF: OS/ABI: AMDGPU_HSA (0x40) +# ELF: ABIVersion: 0 +# ELF: } +# ELF: Machine: EM_AMDGPU (0xE0) +# ELF: Flags [ (0x20000000) +# ELF: EF_AMDGPU_ARCH_GCN (0x20000000) +# ELF: ] +# ELF: } + +# YAML: FileHeader +# YAML: Class: ELFCLASS64 +# YAML: Data: ELFDATA2LSB +# YAML: OSABI: ELFOSABI_AMDGPU_HSA +# YAML: Type: ET_REL +# YAML: Machine: EM_AMDGPU +# YAML: Flags: [ EF_AMDGPU_ARCH_GCN ] --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB + OSABI: ELFOSABI_AMDGPU_HSA Type: ET_REL Machine: EM_AMDGPU - OSABI: ELFOSABI_AMDGPU_HSA + Flags: [ EF_AMDGPU_ARCH_GCN ] ... Index: test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml =================================================================== --- test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml +++ test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml @@ -1,21 +1,34 @@ # RUN: yaml2obj %s > %t.o -# RUN: llvm-readobj -s -file-headers %t.o | FileCheck %s +# RUN: llvm-readobj -s -file-headers %t.o | FileCheck --check-prefix=ELF %s +# RUN: obj2yaml %t.o | FileCheck --check-prefix=YAML %s -# CHECK: Format: ELF64-amdgpu -# CHECK: Arch: amdgcn -# CHECK: ElfHeader { -# CHECK: Ident { -# CHECK: OS/ABI: AMDGPU_PAL (0x41) -# CHECK: ABIVersion: 0 -# CHECK: } -# CHECK: Machine: EM_AMDGPU (0xE0) -# CHECK: } +# ELF: Format: ELF64-amdgpu +# ELF: Arch: amdgcn +# ELF: ElfHeader { +# ELF: Ident { +# ELF: OS/ABI: AMDGPU_PAL (0x41) +# ELF: ABIVersion: 0 +# ELF: } +# ELF: Machine: EM_AMDGPU (0xE0) +# ELF: Flags [ (0x20000000) +# ELF: EF_AMDGPU_ARCH_GCN (0x20000000) +# ELF: ] +# ELF: } + +# YAML: FileHeader +# YAML: Class: ELFCLASS64 +# YAML: Data: ELFDATA2LSB +# YAML: OSABI: ELFOSABI_AMDGPU_PAL +# YAML: Type: ET_REL +# YAML: Machine: EM_AMDGPU +# YAML: Flags: [ EF_AMDGPU_ARCH_GCN ] --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB + OSABI: ELFOSABI_AMDGPU_PAL Type: ET_REL Machine: EM_AMDGPU - OSABI: ELFOSABI_AMDGPU_PAL + Flags: [ EF_AMDGPU_ARCH_GCN ] ... Index: test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml =================================================================== --- test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml +++ test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml @@ -1,21 +1,34 @@ # RUN: yaml2obj %s > %t.o -# RUN: llvm-readobj -s -file-headers %t.o | FileCheck %s +# RUN: llvm-readobj -s -file-headers %t.o | FileCheck --check-prefix=ELF %s +# RUN: obj2yaml %t.o | FileCheck --check-prefix=YAML %s -# CHECK: Format: ELF64-amdgpu -# CHECK: Arch: amdgcn -# CHECK: ElfHeader { -# CHECK: Ident { -# CHECK: OS/ABI: AMDGPU_MESA3D (0x42) -# CHECK: ABIVersion: 0 -# CHECK: } -# CHECK: Machine: EM_AMDGPU (0xE0) -# CHECK: } +# ELF: Format: ELF64-amdgpu +# ELF: Arch: amdgcn +# ELF: ElfHeader { +# ELF: Ident { +# ELF: OS/ABI: AMDGPU_MESA3D (0x42) +# ELF: ABIVersion: 0 +# ELF: } +# ELF: Machine: EM_AMDGPU (0xE0) +# ELF: Flags [ (0x20000000) +# ELF: EF_AMDGPU_ARCH_GCN (0x20000000) +# ELF: ] +# ELF: } + +# YAML: FileHeader +# YAML: Class: ELFCLASS64 +# YAML: Data: ELFDATA2LSB +# YAML: OSABI: ELFOSABI_AMDGPU_MESA3D +# YAML: Type: ET_REL +# YAML: Machine: EM_AMDGPU +# YAML: Flags: [ EF_AMDGPU_ARCH_GCN ] --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB + OSABI: ELFOSABI_AMDGPU_MESA3D Type: ET_REL Machine: EM_AMDGPU - OSABI: ELFOSABI_AMDGPU_MESA3D + Flags: [ EF_AMDGPU_ARCH_GCN ] ... Index: test/tools/llvm-readobj/amdgpu-elf-definitions.test =================================================================== --- test/tools/llvm-readobj/amdgpu-elf-definitions.test +++ test/tools/llvm-readobj/amdgpu-elf-definitions.test @@ -1,7 +1,7 @@ RUN: llvm-readobj -file-headers -program-headers -sections -symbols %p/Inputs/trivial.obj.elf-amdhsa-gfx803 | FileCheck %s CHECK: Format: ELF64-amdgpu -CHECK: Arch: amdgcn +CHECK: Arch: unknown CHECK: ElfHeader { CHECK: Ident { CHECK: OS/ABI: AMDGPU_HSA (0x40) Index: tools/llvm-readobj/ELFDumper.cpp =================================================================== --- tools/llvm-readobj/ELFDumper.cpp +++ tools/llvm-readobj/ELFDumper.cpp @@ -1244,6 +1244,12 @@ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6) }; +static const EnumEntry ElfHeaderAMDGPUFlags[] = { + LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_ARCH_NONE), + LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_ARCH_R600), + LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_ARCH_GCN) +}; + static const EnumEntry ElfHeaderRISCVFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_RVC), LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_FLOAT_ABI_SINGLE), @@ -3562,6 +3568,9 @@ W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderMipsFlags), unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI), unsigned(ELF::EF_MIPS_MACH)); + else if (e->e_machine == EM_AMDGPU) + W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderAMDGPUFlags), + unsigned(ELF::EF_AMDGPU_ARCH)); else if (e->e_machine == EM_RISCV) W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderRISCVFlags)); else