binutils/readelf: decode AMDGPU-specific e_flags
authorSimon Marchi <simon.marchi@efficios.com>
Wed, 16 Mar 2022 13:01:15 +0000 (09:01 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Wed, 16 Mar 2022 13:01:15 +0000 (09:01 -0400)
Decode and print the AMDGPU-specific fields of e_flags, as documented
here:

  https://llvm.org/docs/AMDGPUUsage.html#header

That is:

 - The specific GPU model
 - Whether the xnack and sramecc features are enabled

The result looks like:

-  Flags:                             0x52f
+  Flags:                             0x52f, gfx906, xnack any, sramecc any

The flags for the "HSA" OS ABI are properly versioned and documented on
that page.  But the NONE, PAL and MESA3D OS ABIs are not well documented
nor versioned.  Taking a peek at the LLVM source code, we see that they
encode their flags the same way as HSA v3.  For example, for PAL:

  https://github.com/llvm/llvm-project/blob/c8b614cd74a92d85936aed5ac7c642af75ffdc29/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp#L601

So for those other OS ABIs, we read them the same as HSA v3.

binutils/ChangeLog:

* readelf.c: Include elf/amdgcn.h.
(decode_AMDGPU_machine_flags): New.
(get_machine_flags): Handle flags for EM_AMDGPU machine type.

include/ChangeLog:

* elf/amdgcn.h: Add EF_AMDGPU_MACH_AMDGCN_* and
EF_AMDGPU_FEATURE_* defines.

Change-Id: Ib5b94df7cae0719a22cf4e4fd0629330e9485c12

binutils/ChangeLog
binutils/readelf.c
include/ChangeLog
include/elf/amdgpu.h

index 694ad49fee55ba155f67b8419f512a4110c19522..3ed0b0a7fd87d6f883da172870df43a6b2289b47 100644 (file)
@@ -1,3 +1,9 @@
+2022-03-16  Simon Marchi  <simon.marchi@efficios.com>
+
+       * readelf.c: Include elf/amdgcn.h.
+       (decode_AMDGPU_machine_flags): New.
+       (get_machine_flags): Handle flags for EM_AMDGPU machine type.
+
 2022-03-16  Simon Marchi  <simon.marchi@efficios.com>
 
        * readelf.c (get_osabi_name): Handle EM_AMDGPU OS ABIs.
index e8974aacec5e4fc441234f19b352a784b41aad09..00b5e546c1e74177be03d07a8103b75fe3af42e9 100644 (file)
@@ -92,6 +92,7 @@
 
 #include "elf/aarch64.h"
 #include "elf/alpha.h"
+#include "elf/amdgpu.h"
 #include "elf/arc.h"
 #include "elf/arm.h"
 #include "elf/avr.h"
@@ -3565,6 +3566,153 @@ decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
     r += snprintf (buf + r, size -r, ", L2C");
 }
 
+static void
+decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
+                            char *buf)
+{
+  unsigned char *e_ident = filedata->file_header.e_ident;
+  unsigned char osabi = e_ident[EI_OSABI];
+  unsigned char abiversion = e_ident[EI_ABIVERSION];
+  unsigned int mach;
+
+  /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
+     it has been deprecated for a while.
+
+     The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
+     of writing, they use the same flags as HSA v3, so the code below uses that
+     assumption.  */
+  if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
+    return;
+
+  mach = e_flags & EF_AMDGPU_MACH;
+  switch (mach)
+    {
+#define AMDGPU_CASE(code, string) \
+  case code: strcat (buf, ", " string); break;
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
+    AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
+    default:
+      sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
+      break;
+#undef AMDGPU_CASE
+    }
+
+  buf += strlen (buf);
+  e_flags &= ~EF_AMDGPU_MACH;
+
+  if ((osabi == ELFOSABI_AMDGPU_HSA
+       && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
+      || osabi != ELFOSABI_AMDGPU_HSA)
+    {
+      /* For HSA v3 and other OS ABIs.  */
+      if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
+       {
+         strcat (buf, ", xnack on");
+         buf += strlen (buf);
+         e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
+       }
+
+      if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
+       {
+         strcat (buf, ", sramecc on");
+         buf += strlen (buf);
+         e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
+       }
+    }
+  else
+    {
+      /* For HSA v4+.  */
+      int xnack, sramecc;
+
+      xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
+      switch (xnack)
+       {
+       case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
+         break;
+
+       case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
+         strcat (buf, ", xnack any");
+         break;
+
+       case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
+         strcat (buf, ", xnack off");
+         break;
+
+       case EF_AMDGPU_FEATURE_XNACK_ON_V4:
+         strcat (buf, ", xnack on");
+         break;
+
+       default:
+         sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
+         break;
+       }
+
+      buf += strlen (buf);
+      e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
+
+      sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
+      switch (sramecc)
+       {
+       case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
+         break;
+
+       case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
+         strcat (buf, ", sramecc any");
+         break;
+
+       case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
+         strcat (buf, ", sramecc off");
+         break;
+
+       case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
+         strcat (buf, ", sramecc on");
+         break;
+
+       default:
+         sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
+         break;
+       }
+
+      buf += strlen (buf);
+      e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
+    }
+
+  if (e_flags != 0)
+    sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
+}
+
 static char *
 get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
 {
@@ -3717,6 +3865,10 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
            }
          break;
 
+       case EM_AMDGPU:
+         decode_AMDGPU_machine_flags (filedata, e_flags, buf);
+         break;
+
        case EM_CYGNUS_MEP:
          switch (e_flags & EF_MEP_CPU_MASK)
            {
index 297dcd69443b31cc47630f013da804254ddbe7f2..7807497b0adefc1e77a561e8c750e6d2087f2ac1 100644 (file)
@@ -1,3 +1,8 @@
+2022-03-16  Simon Marchi  <simon.marchi@efficios.com>
+
+       * elf/amdgcn.h: Add EF_AMDGPU_MACH_AMDGCN_* and
+       EF_AMDGPU_FEATURE_* defines.
+
 2022-03-16  Simon Marchi  <simon.marchi@efficios.com>
 
        * elf/common.h (ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D):
index daa472e5b346513b977ed0d0549e3ac13c4a1a18..005064fc264e6938bbba1275b73dffd162b1cc21 100644 (file)
 #define EF_AMDGPU_MACH 0x0ff
 #define EF_AMDGPU_MACH_AMDGCN_MIN 0x020
 
+#define EF_AMDGPU_MACH_AMDGCN_GFX600  0x020
+#define EF_AMDGPU_MACH_AMDGCN_GFX601  0x021
+#define EF_AMDGPU_MACH_AMDGCN_GFX700  0x022
+#define EF_AMDGPU_MACH_AMDGCN_GFX701  0x023
+#define EF_AMDGPU_MACH_AMDGCN_GFX702  0x024
+#define EF_AMDGPU_MACH_AMDGCN_GFX703  0x025
+#define EF_AMDGPU_MACH_AMDGCN_GFX704  0x026
+#define EF_AMDGPU_MACH_AMDGCN_GFX801  0x028
+#define EF_AMDGPU_MACH_AMDGCN_GFX802  0x029
+#define EF_AMDGPU_MACH_AMDGCN_GFX803  0x02a
+#define EF_AMDGPU_MACH_AMDGCN_GFX810  0x02b
+#define EF_AMDGPU_MACH_AMDGCN_GFX900  0x02c
+#define EF_AMDGPU_MACH_AMDGCN_GFX902  0x02d
+#define EF_AMDGPU_MACH_AMDGCN_GFX904  0x02e
+#define EF_AMDGPU_MACH_AMDGCN_GFX906  0x02f
+#define EF_AMDGPU_MACH_AMDGCN_GFX908  0x030
+#define EF_AMDGPU_MACH_AMDGCN_GFX909  0x031
+#define EF_AMDGPU_MACH_AMDGCN_GFX90C  0x032
+#define EF_AMDGPU_MACH_AMDGCN_GFX1010 0x033
+#define EF_AMDGPU_MACH_AMDGCN_GFX1011 0x034
+#define EF_AMDGPU_MACH_AMDGCN_GFX1012 0x035
+#define EF_AMDGPU_MACH_AMDGCN_GFX1030 0x036
+#define EF_AMDGPU_MACH_AMDGCN_GFX1031 0x037
+#define EF_AMDGPU_MACH_AMDGCN_GFX1032 0x038
+#define EF_AMDGPU_MACH_AMDGCN_GFX1033 0x039
+#define EF_AMDGPU_MACH_AMDGCN_GFX602  0x03a
+#define EF_AMDGPU_MACH_AMDGCN_GFX705  0x03b
+#define EF_AMDGPU_MACH_AMDGCN_GFX805  0x03c
+#define EF_AMDGPU_MACH_AMDGCN_GFX1035 0x03d
+#define EF_AMDGPU_MACH_AMDGCN_GFX1034 0x03e
+#define EF_AMDGPU_MACH_AMDGCN_GFX90A  0x03f
+#define EF_AMDGPU_MACH_AMDGCN_GFX940  0x040
+#define EF_AMDGPU_MACH_AMDGCN_GFX1013 0x042
+#define EF_AMDGPU_MACH_AMDGCN_GFX1036 0x045
+
+/* Code object v3 machine flags.  */
+
+#define EF_AMDGPU_FEATURE_XNACK_V3   0x100
+#define EF_AMDGPU_FEATURE_SRAMECC_V3 0x200
+
+/* Code object v4 (and later) machine flags.  */
+
+#define EF_AMDGPU_FEATURE_XNACK_V4             0x300
+#define EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4 0x000
+#define EF_AMDGPU_FEATURE_XNACK_ANY_V4         0x100
+#define EF_AMDGPU_FEATURE_XNACK_OFF_V4         0x200
+#define EF_AMDGPU_FEATURE_XNACK_ON_V4          0x300
+
+#define EF_AMDGPU_FEATURE_SRAMECC_V4             0xc00
+#define EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4 0x000
+#define EF_AMDGPU_FEATURE_SRAMECC_ANY_V4         0x400
+#define EF_AMDGPU_FEATURE_SRAMECC_OFF_V4         0x800
+#define EF_AMDGPU_FEATURE_SRAMECC_ON_V4          0xc00
+
 #endif /* _ELF_AMDGPU_H */