[llvm] [SystemZ][z/OS] Add goffdumper/llvm-readobj tools (PR #71071)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 2 08:59:20 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: Yusra Syeda (ysyeda)

<details>
<summary>Changes</summary>

This PR adds the GOFFDumper. It contains a test which uses llvm-readobj to check the symbols of the provided GOFF object file.

---
Full diff: https://github.com/llvm/llvm-project/pull/71071.diff


8 Files Affected:

- (modified) llvm/lib/Object/GOFFObjectFile.cpp (+9) 
- (modified) llvm/lib/Object/ObjectFile.cpp (+2-1) 
- (added) llvm/test/tools/llvm-readobj/GOFF/Inputs/goff-basics.o () 
- (added) llvm/test/tools/llvm-readobj/GOFF/goff-basics.test (+69) 
- (modified) llvm/tools/llvm-readobj/CMakeLists.txt (+1) 
- (added) llvm/tools/llvm-readobj/GOFFDumper.cpp (+94) 
- (modified) llvm/tools/llvm-readobj/ObjDumper.h (+4) 
- (modified) llvm/tools/llvm-readobj/llvm-readobj.cpp (+4) 


``````````diff
diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index 76a13559ebfe352..03f86f303668457 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -168,6 +168,15 @@ GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
       LLVM_DEBUG(dbgs() << "  --  ESD " << EsdId << "\n");
       break;
     }
+    case GOFF::RT_TXT:
+      LLVM_DEBUG(dbgs() << "  --  TXT (GOFF record type) unhandled\n");
+      break;
+    case GOFF::RT_RLD:
+      LLVM_DEBUG(dbgs() << "  --  RLD (GOFF record type) unhandled\n");
+      break;
+    case GOFF::RT_LEN:
+      LLVM_DEBUG(dbgs() << "  --  LEN (GOFF record type) unhandled\n");
+      break;
     case GOFF::RT_END:
       LLVM_DEBUG(dbgs() << "  --  END (GOFF record type) unhandled\n");
       break;
diff --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp
index 428166f58070d0b..16c6003db4810ac 100644
--- a/llvm/lib/Object/ObjectFile.cpp
+++ b/llvm/lib/Object/ObjectFile.cpp
@@ -154,7 +154,6 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
   case file_magic::windows_resource:
   case file_magic::pdb:
   case file_magic::minidump:
-  case file_magic::goff_object:
   case file_magic::cuda_fatbinary:
   case file_magic::offload_binary:
   case file_magic::dxcontainer_object:
@@ -182,6 +181,8 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
   case file_magic::macho_kext_bundle:
   case file_magic::macho_file_set:
     return createMachOObjectFile(Object);
+  case file_magic::goff_object:
+    return createGOFFObjectFile(Object);
   case file_magic::coff_object:
   case file_magic::coff_import_library:
   case file_magic::pecoff_executable:
diff --git a/llvm/test/tools/llvm-readobj/GOFF/Inputs/goff-basics.o b/llvm/test/tools/llvm-readobj/GOFF/Inputs/goff-basics.o
new file mode 100644
index 000000000000000..4988c29ef3dc2f2
Binary files /dev/null and b/llvm/test/tools/llvm-readobj/GOFF/Inputs/goff-basics.o differ
diff --git a/llvm/test/tools/llvm-readobj/GOFF/goff-basics.test b/llvm/test/tools/llvm-readobj/GOFF/goff-basics.test
new file mode 100644
index 000000000000000..812cadd3c9b2654
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/GOFF/goff-basics.test
@@ -0,0 +1,69 @@
+# RUN: llvm-readobj --symbols %p/Inputs/goff-basics.o | \
+# RUN: FileCheck --check-prefix=SYMBOLSEXP %s
+
+# SYMBOLSEXP: File: {{.*}}goff-basics.o
+# SYMBOLSEXP-NEXT: Format: GOFF-SystemZ
+# SYMBOLSEXP-NEXT: Arch: s390x
+# SYMBOLSEXP-NEXT: AddressSize: 64bit
+# SYMBOLSEXP-NEXT: Symbols [
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: goff-basics#S
+# SYMBOLSEXP-NEXT:     Value: 0
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: goff-basics#C
+# SYMBOLSEXP-NEXT:     Value: 0
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: .&ppa2
+# SYMBOLSEXP-NEXT:     Value: 0
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: a
+# SYMBOLSEXP-NEXT:     Value: 0
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: b
+# SYMBOLSEXP-NEXT:     Value: 0
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: d
+# SYMBOLSEXP-NEXT:     Value: 0
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: CELQSTRT
+# SYMBOLSEXP-NEXT:     Value: 0
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: A
+# SYMBOLSEXP-NEXT:     Value: 16
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: B
+# SYMBOLSEXP-NEXT:     Value: 48
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT:   Symbol {
+# SYMBOLSEXP-NEXT:     Name: D
+# SYMBOLSEXP-NEXT:     Value: 80
+# SYMBOLSEXP-NEXT:     Alignment: 0
+# SYMBOLSEXP-NEXT:   }
+# SYMBOLSEXP-NEXT: ]
+
+
+# goff-basics.o was compiled with `clang -c goff-basics.c`
+# from the following source:
+# int a = 55;
+# int b;
+# double d;
+# int A() { return a; }
+# int B() { return b; }
+# double D() { return d; }
diff --git a/llvm/tools/llvm-readobj/CMakeLists.txt b/llvm/tools/llvm-readobj/CMakeLists.txt
index 0051f87b3c1039f..90637084ae7afa2 100644
--- a/llvm/tools/llvm-readobj/CMakeLists.txt
+++ b/llvm/tools/llvm-readobj/CMakeLists.txt
@@ -18,6 +18,7 @@ add_llvm_tool(llvm-readobj
   COFFDumper.cpp
   COFFImportDumper.cpp
   ELFDumper.cpp
+  GOFFDumper.cpp
   llvm-readobj.cpp
   MachODumper.cpp
   ObjDumper.cpp
diff --git a/llvm/tools/llvm-readobj/GOFFDumper.cpp b/llvm/tools/llvm-readobj/GOFFDumper.cpp
new file mode 100644
index 000000000000000..3cd3fd3866348e2
--- /dev/null
+++ b/llvm/tools/llvm-readobj/GOFFDumper.cpp
@@ -0,0 +1,94 @@
+#include "ObjDumper.h"
+#include "llvm-readobj.h"
+#include "llvm/Object/GOFFObjectFile.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+namespace {
+
+class GOFFDumper : public ObjDumper {
+public:
+  GOFFDumper(const GOFFObjectFile *Obj, ScopedPrinter &Writer)
+      : ObjDumper(Writer, Obj->getFileName()), Obj(Obj) {}
+
+  void printFileHeaders() override {}
+  void printSectionHeaders() override;
+  void printRelocations() override;
+  void printSymbols(bool ExtraSymInfo) override;
+  void printDynamicSymbols() override;
+  void printUnwindInfo() override {}
+  void printStackMap() const override {}
+
+  const object::GOFFObjectFile *getGOFFObject() const { return Obj; };
+
+private:
+  void printSymbol(const SymbolRef &Sym);
+
+  const GOFFObjectFile *Obj;
+};
+
+} // End anonymous namespace
+
+namespace llvm {
+std::unique_ptr<ObjDumper> createGOFFDumper(const object::GOFFObjectFile &Obj,
+                                            ScopedPrinter &Writer) {
+  return std::make_unique<GOFFDumper>(&Obj, Writer);
+}
+
+} // namespace llvm
+
+void GOFFDumper::printSymbol(const SymbolRef &Symbol) {
+  DictScope D(W, "Symbol");
+
+  Expected<StringRef> SymbolNameOrErr = Obj->getSymbolName(Symbol);
+  if (!SymbolNameOrErr)
+    reportError(SymbolNameOrErr.takeError(), Obj->getFileName());
+  W.printString("Name", SymbolNameOrErr.get());
+  Expected<uint64_t> SymVal = Symbol.getValue();
+  if (!SymVal)
+    reportError(SymVal.takeError(), Obj->getFileName());
+  W.printNumber("Value", *SymVal);
+  W.printNumber("Alignment", Symbol.getAlignment());
+}
+
+void GOFFDumper::printSectionHeaders() {
+  ListScope SectionsD(W, "Sections");
+  for (const SectionRef &Sec : Obj->sections()) {
+    StringRef Name = unwrapOrError(Obj->getFileName(), Sec.getName());
+
+    DictScope D(W, "Section");
+    W.printNumber("Index", Sec.getIndex());
+    W.printString("Name", Name);
+    W.printHex("Address", Sec.getAddress());
+    W.printHex("Size", Sec.getSize());
+    W.printNumber("Alignment", Sec.getAlignment().value());
+
+    if (opts::SectionSymbols) {
+      ListScope D(W, "Symbols");
+      for (const SymbolRef &Symbol : Obj->symbols()) {
+        if (!Sec.containsSymbol(Symbol))
+          continue;
+
+        printSymbol(Symbol);
+      }
+    }
+
+    if (opts::SectionData) {
+      StringRef Data = unwrapOrError(Obj->getFileName(), Sec.getContents());
+      W.printBinaryBlock("SectionData", Data);
+    }
+  }
+}
+
+void GOFFDumper::printSymbols(bool) {
+  ListScope Group(W, "Symbols");
+
+  for (const SymbolRef &Symbol : Obj->symbols())
+    printSymbol(Symbol);
+}
+
+void GOFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); }
+
+void GOFFDumper::printRelocations() {}
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 1d679453581bc84..a457e3bab331518 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -25,6 +25,7 @@ namespace object {
 class Archive;
 class COFFImportFile;
 class ObjectFile;
+class GOFFObjectFile;
 class XCOFFObjectFile;
 class ELFObjectFileBase;
 } // namespace object
@@ -206,6 +207,9 @@ std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,
 std::unique_ptr<ObjDumper> createMachODumper(const object::MachOObjectFile &Obj,
                                              ScopedPrinter &Writer);
 
+std::unique_ptr<ObjDumper> createGOFFDumper(const object::GOFFObjectFile &Obj,
+                                            ScopedPrinter &Writer);
+
 std::unique_ptr<ObjDumper> createWasmDumper(const object::WasmObjectFile &Obj,
                                             ScopedPrinter &Writer);
 
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index ca633ceff90800e..472fdfa882b6059 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/COFFImportFile.h"
 #include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/GOFFObjectFile.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Object/Wasm.h"
@@ -344,6 +345,9 @@ createDumper(const ObjectFile &Obj, ScopedPrinter &Writer) {
   if (const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(&Obj))
     return createMachODumper(*MachOObj, Writer);
 
+  if (const GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>(&Obj))
+    return createGOFFDumper(*GOFFObj, Writer);
+
   if (const WasmObjectFile *WasmObj = dyn_cast<WasmObjectFile>(&Obj))
     return createWasmDumper(*WasmObj, Writer);
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/71071


More information about the llvm-commits mailing list