From 982902c0af0fd83bc4d9c87b7125b1c740d1c7a8 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <enh@google.com>
Date: Sun, 29 Oct 2023 11:02:41 -0700
Subject: [PATCH] riscv: decode ELF header e_flags.

---
 lib/lib.c            | 13 +++++++++++++
 lib/lib.h            |  1 +
 toys/other/readelf.c |  3 ++-
 toys/posix/file.c    |  5 +++--
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/lib/lib.c b/lib/lib.c
index 4473f89f..599f71ed 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -1528,6 +1528,19 @@ char *elf_arch_name(int type)
   return libbuf;
 }
 
+void elf_print_flags(int arch, int flags)
+{
+  if (arch == 243 /*EM_RISCV*/) {
+    if (flags & 1) printf(", C");
+    if (flags & 8) printf(", E");
+    if (flags & 0x10) printf(", TSO");
+    if ((flags & 0x6) == 0) printf(", soft float");
+    else if ((flags & 0x6) == 2) printf(", single float");
+    else if ((flags & 0x6) == 4) printf(", double float");
+    else if ((flags & 0x6) == 6) printf(", quad float");
+  }
+}
+
 // Remove octal escapes from string (common in kernel exports)
 void octal_deslash(char *s)
 {
diff --git a/lib/lib.h b/lib/lib.h
index bc4ff962..b5929696 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -272,6 +272,7 @@ void loggit(int priority, char *format, ...);
 unsigned tar_cksum(void *data);
 int is_tar_header(void *pkt);
 char *elf_arch_name(int type);
+void elf_print_flags(int arch, int flags);
 void octal_deslash(char *s);
 int smemcmp(char *one, char *two, unsigned long len);
 
diff --git a/toys/other/readelf.c b/toys/other/readelf.c
index 72c38191..3f6b49be 100644
--- a/toys/other/readelf.c
+++ b/toys/other/readelf.c
@@ -424,7 +424,8 @@ static void scan_elf()
            TT.phoff);
     printf("  Start of section headers:          %llu (bytes into file)\n",
            TT.shoff);
-    printf("  Flags:                             0x%x\n", flags);
+    printf("  Flags:                             0x%x", flags);
+    elf_print_flags(machine, flags); putchar('\n');
     printf("  Size of this header:               %d (bytes)\n", ehsize);
     printf("  Size of program headers:           %d (bytes)\n", TT.phentsize);
     printf("  Number of program headers:         %d\n", phnum);
diff --git a/toys/posix/file.c b/toys/posix/file.c
index 9428ecf4..25edb58e 100644
--- a/toys/posix/file.c
+++ b/toys/posix/file.c
@@ -33,7 +33,7 @@ GLOBALS(
 static void do_elf_file(int fd)
 {
   unsigned endian = toybuf[5], bits = toybuf[4]-1, i, j, dynamic = 0,
-           stripped = 1, phentsize, phnum, shsize, shnum, bail = 0;
+           stripped = 1, phentsize, phnum, shsize, shnum, bail = 0, arch;
   int64_t (*elf_int)(void *ptr, unsigned size) = (endian==2)?peek_be:peek_le;
   char *map = MAP_FAILED;
   unsigned long phoff, shoff;
@@ -68,7 +68,8 @@ static void do_elf_file(int fd)
   }
 
   // "x86".
-  printf("%s", elf_arch_name(elf_int(toybuf+18, 2)));
+  printf("%s", elf_arch_name(arch = elf_int(toybuf+18, 2)));
+  elf_print_flags(arch, elf_int(toybuf+44+4*bits, 4));
 
   // If what we've seen so far doesn't seem consistent, bail.
   if (bail) goto bad;
-- 
2.42.0.820.g83a721a137-goog

