[llvm-readobj] Print section type values for unknown sections.

Summary:
This patch displays a hexadecimal section value (Elf_Shdr::sh_type) or section-relative offset when printing unknown sections.

Here is a subset of the output (ignoring the fields following "Type" when dumping an ELF's GNU `--section-headers` table).
Section Headers:
```
  [Nr] Name              Type
  [16] android_rel       LOOS+0x1
  [17] android_rela      LOOS+0x2
  [27] unknown           0x1000: <unknown>
  [28] loos              LOOS+0
  [30] hios              VERSYM
  [31] loproc            LOPROC+0
  [33] hiproc            LOPROC+0xFFFFFFF
  [34] louser            LOUSER+0
  [36] hiuser            LOUSER+0x7FFFFFFF
```

As a comparison, the previous output looked something like the above, but with a blank "Type" field:
```
  [Nr] Name              Type
  [27] unknown
  [28] loos
  [30] hios              VERSYM
  [31] loproc
  [33] hiproc
  [34] louser
  [36] hiuser
```

This fixes PR40773

Reviewers: jhenderson, rupprecht, Bigcheese

Reviewed By: jhenderson, rupprecht, Bigcheese

Subscribers: MaskRay, Bigcheese, srhines, jdoerfert, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D58701

llvm-svn: 355014
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 21ab930..3597acf 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -2830,7 +2830,21 @@
     OS << "\nThere are no relocations in this file.\n";
 }
 
-std::string getSectionTypeString(unsigned Arch, unsigned Type) {
+// Print the offset of a particular section from anyone of the ranges:
+// [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
+// If 'Type' does not fall within any of those ranges, then a string is
+// returned as '<unknown>' followed by the type value.
+static std::string getSectionTypeOffsetString(unsigned Type) {
+  if (Type >= SHT_LOOS && Type <= SHT_HIOS)
+    return "LOOS+0x" + to_hexString(Type - SHT_LOOS);
+  else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC)
+    return "LOPROC+0x" + to_hexString(Type - SHT_LOPROC);
+  else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER)
+    return "LOUSER+0x" + to_hexString(Type - SHT_LOUSER);
+  return "0x" + to_hexString(Type) + ": <unknown>";
+}
+
+static std::string getSectionTypeString(unsigned Arch, unsigned Type) {
   using namespace ELF;
 
   switch (Arch) {
@@ -2903,6 +2917,10 @@
     return "GROUP";
   case SHT_SYMTAB_SHNDX:
     return "SYMTAB SECTION INDICES";
+  case SHT_ANDROID_REL:
+    return "ANDROID_REL";
+  case SHT_ANDROID_RELA:
+    return "ANDROID_RELA";
   case SHT_RELR:
   case SHT_ANDROID_RELR:
     return "RELR";
@@ -2926,7 +2944,7 @@
   case SHT_GNU_versym:
     return "VERSYM";
   default:
-    return "";
+    return getSectionTypeOffsetString(Type);
   }
   return "";
 }