[llvm] r359878 - [Object][XCOFF] Add an XCOFF dumper for llvm-readobj.

Sean Fertile via llvm-commits llvm-commits at lists.llvm.org
Fri May 3 05:57:07 PDT 2019


Author: sfertile
Date: Fri May  3 05:57:07 2019
New Revision: 359878

URL: http://llvm.org/viewvc/llvm-project?rev=359878&view=rev
Log:
[Object][XCOFF] Add an XCOFF dumper for llvm-readobj.

Patch adds support for dumping of file headers with llvm-readobj. XCOFF
object files are added to test dumping a well formed file, and dumping
both negative timestamps and negative symbol counts, both of which are
allowed in the XCOFF definition.

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

Added:
    llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-sym-count.o   (with props)
    llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-time.o   (with props)
    llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic.o   (with props)
    llvm/trunk/test/tools/llvm-readobj/xcoff-basic.test
    llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp
Modified:
    llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
    llvm/trunk/lib/Object/XCOFFObjectFile.cpp
    llvm/trunk/tools/llvm-readobj/CMakeLists.txt
    llvm/trunk/tools/llvm-readobj/ObjDumper.h
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp

Modified: llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/XCOFFObjectFile.h?rev=359878&r1=359877&r2=359878&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/XCOFFObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/XCOFFObjectFile.h Fri May  3 05:57:07 2019
@@ -71,7 +71,6 @@ private:
 
   const XCOFFSectionHeader *toSection(DataRefImpl Ref) const;
 
-  uint16_t getNumberOfSections() const;
 
 public:
   void moveSymbolNext(DataRefImpl &Symb) const override;
@@ -122,6 +121,18 @@ public:
   XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
 
   const XCOFFFileHeader *getFileHeader() const { return FileHdrPtr; }
+
+  uint16_t getMagic() const;
+  uint16_t getNumberOfSections() const;
+  int32_t  getTimeStamp() const;
+  uint32_t  getSymbolTableOffset() const;
+
+  // Note that this value is signed and might return a negative value. Negative
+  // values are reserved for future use.
+  int32_t  getNumberOfSymbolTableEntries() const;
+
+  uint16_t getOptionalHeaderSize() const;
+  uint16_t getFlags() const;
 }; // XCOFFObjectFile
 
 } // namespace object

Modified: llvm/trunk/lib/Object/XCOFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/XCOFFObjectFile.cpp?rev=359878&r1=359877&r2=359878&view=diff
==============================================================================
--- llvm/trunk/lib/Object/XCOFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/XCOFFObjectFile.cpp Fri May  3 05:57:07 2019
@@ -69,10 +69,6 @@ size_t XCOFFObjectFile::getSectionHeader
   return sizeof(XCOFFSectionHeader);
 }
 
-uint16_t XCOFFObjectFile::getNumberOfSections() const {
-  return FileHdrPtr->NumberOfSections;
-}
-
 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
   llvm_unreachable("Not yet implemented!");
   return;
@@ -247,9 +243,9 @@ section_iterator XCOFFObjectFile::sectio
 }
 
 uint8_t XCOFFObjectFile::getBytesInAddress() const {
-  uint8_t Result = 0;
-  llvm_unreachable("Not yet implemented!");
-  return Result;
+  // Only support 32-bit object files for now ...
+  assert(getFileHeaderSize() ==  XCOFF32FileHeaderSize);
+  return 4;
 }
 
 StringRef XCOFFObjectFile::getFileFormatName() const {
@@ -300,6 +296,37 @@ XCOFFObjectFile::XCOFFObjectFile(MemoryB
   }
 }
 
+uint16_t XCOFFObjectFile::getMagic() const {
+  return FileHdrPtr->Magic;
+}
+
+uint16_t XCOFFObjectFile::getNumberOfSections() const {
+  return FileHdrPtr->NumberOfSections;
+}
+
+int32_t XCOFFObjectFile::getTimeStamp() const {
+  return FileHdrPtr->TimeStamp;
+}
+
+uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
+  return FileHdrPtr->SymbolTableOffset;
+}
+
+int32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
+  // As far as symbol table size is concerned, if this field is negative it is
+  // to be treated as a 0. However since this field is also used for printing we
+  // don't want to truncate any negative values.
+  return FileHdrPtr->NumberOfSymTableEntries;
+}
+
+uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
+  return FileHdrPtr->AuxHeaderSize;
+}
+
+uint16_t XCOFFObjectFile::getFlags() const {
+  return FileHdrPtr->Flags;
+}
+
 Expected<std::unique_ptr<ObjectFile>>
 ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object) {
   StringRef Data = Object.getBuffer();

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-sym-count.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-sym-count.o?rev=359878&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-sym-count.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-time.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-time.o?rev=359878&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic-neg-time.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic.o?rev=359878&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-readobj/Inputs/xcoff-basic.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-readobj/xcoff-basic.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/xcoff-basic.test?rev=359878&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/xcoff-basic.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/xcoff-basic.test Fri May  3 05:57:07 2019
@@ -0,0 +1,66 @@
+# RUN: llvm-readobj --file-header %p/Inputs/xcoff-basic.o | \
+# RUN: FileCheck --check-prefix=FILEHEADER %s
+
+# RUN: llvm-readobj --file-header %p/Inputs/xcoff-basic-neg-time.o | \
+# RUN: FileCheck --check-prefix=NEGTIME %s
+
+# RUN: llvm-readobj --file-header %p/Inputs/xcoff-basic-neg-sym-count.o | \
+# RUN: FileCheck --check-prefix=NEGSYMCOUNT %s
+
+# FILEHEADER:     File: {{.*}}xcoff-basic.o
+# FILEHEADER-NEXT: Format: aixcoff-rs6000
+# FILEHEADER-NEXT: Arch: powerpc
+# FILEHEADER-NEXT: AddressSize: 32bit
+# FILEHEADER-NEXT: FileHeader {
+# FILEHEADER-NEXT:   Magic: 0x1DF
+# FILEHEADER-NEXT:   NumberOfSections: 6
+# FILEHEADER-NEXT:   TimeStamp: 2019-03-12T14:04:43Z (0x5C87BC7B)
+# FILEHEADER-NEXT:   SymbolTableOffset: 0x52E
+# FILEHEADER-NEXT:   SymbolTableEntries: 120
+# FILEHEADER-NEXT:   OptionalHeaderSize: 0x1C
+# FILEHEADER-NEXT:   Flags: 0x0
+# FILEHEADER-NEXT: }
+
+# NEGTIME:     File: {{.*}}xcoff-basic-neg-time.o
+# NEGTIME-NEXT:  Format: aixcoff-rs6000
+# NEGTIME-NEXT:  Arch: powerpc
+# NEGTIME-NEXT:  AddressSize: 32bit
+# NEGTIME-NEXT:  FileHeader {
+# NEGTIME-NEXT:    Magic: 0x1DF
+# NEGTIME-NEXT:    NumberOfSections: 6
+# NEGTIME-NEXT:    TimeStamp: Reserved Value (0xDC87BC7B)
+# NEGTIME-NEXT:    SymbolTableOffset: 0x52E
+# NEGTIME-NEXT:    SymbolTableEntries: 120
+# NEGTIME-NEXT:    OptionalHeaderSize: 0x1C
+# NEGTIME-NEXT:    Flags: 0x0
+# NEGTIME-NEXT:  }
+
+# NEGSYMCOUNT:     File: {{.*}}xcoff-basic-neg-sym-count.o
+# NEGSYMCOUNT-NEXT:  Format: aixcoff-rs6000
+# NEGSYMCOUNT-NEXT:  Arch: powerpc
+# NEGSYMCOUNT-NEXT:  AddressSize: 32bit
+# NEGSYMCOUNT-NEXT:  FileHeader {
+# NEGSYMCOUNT-NEXT:    Magic: 0x1DF
+# NEGSYMCOUNT-NEXT:    NumberOfSections: 5
+# NEGSYMCOUNT-NEXT:    TimeStamp: 2019-03-12T14:04:43Z (0x5C87BC7B)
+# NEGSYMCOUNT-NEXT:    SymbolTableOffset: 0x0
+# NEGSYMCOUNT-NEXT:    SymbolTableEntries: Reserved Value (0x80000000)
+# NEGSYMCOUNT-NEXT:    OptionalHeaderSize: 0x1C
+# NEGSYMCOUNT-NEXT:    Flags: 0xD
+# NEGSYMCOUNT-NEXT:  }
+
+# xcoff-basic.o was compiled with `xlc -qtls -O3 -g -c xcoff-basic.c`
+# from the following source:
+# int a = 55;
+# int b;
+# __thread int j = 55;
+# __thread double d;
+# int A() { return a; }
+# int B() { return b; }
+# int J() { return j; }
+# double D() { return d; }
+#
+# xcoff-basic-neg-time.o was manually edited to include a negative time stamp.
+# xcoff-basic-neg-sym-count.o was stripped using the 'strip' utility, and
+# manually edited to have a negative symbol table entry count.
+

Modified: llvm/trunk/tools/llvm-readobj/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CMakeLists.txt?rev=359878&r1=359877&r2=359878&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-readobj/CMakeLists.txt Fri May  3 05:57:07 2019
@@ -22,6 +22,7 @@ add_llvm_tool(llvm-readobj
   WasmDumper.cpp
   Win64EHDumper.cpp
   WindowsResourceDumper.cpp
+  XCOFFDumper.cpp
   )
 
 add_llvm_tool_symlink(llvm-readelf llvm-readobj)

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=359878&r1=359877&r2=359878&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.h (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Fri May  3 05:57:07 2019
@@ -133,6 +133,10 @@ std::error_code createWasmDumper(const o
                                  ScopedPrinter &Writer,
                                  std::unique_ptr<ObjDumper> &Result);
 
+std::error_code createXCOFFDumper(const object::ObjectFile *Obj,
+                                  ScopedPrinter &Writer,
+                                  std::unique_ptr<ObjDumper> &Result);
+
 void dumpCOFFImportFile(const object::COFFImportFile *File,
                         ScopedPrinter &Writer);
 

Added: llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp?rev=359878&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp (added)
+++ llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp Fri May  3 05:57:07 2019
@@ -0,0 +1,121 @@
+//===-- XCOFFDumper.cpp - XCOFF dumping utility -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an XCOFF specific dumper for llvm-readobj.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Error.h"
+#include "ObjDumper.h"
+#include "llvm-readobj.h"
+#include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+using namespace llvm;
+using namespace object;
+
+namespace {
+
+class XCOFFDumper : public ObjDumper {
+public:
+  XCOFFDumper(const XCOFFObjectFile &Obj, ScopedPrinter &Writer)
+      : ObjDumper(Writer), Obj(Obj) {}
+
+  void printFileHeaders() override;
+  void printSectionHeaders() override;
+  void printRelocations() override;
+  void printSymbols() override;
+  void printDynamicSymbols() override;
+  void printUnwindInfo() override;
+  void printStackMap() const override;
+  void printNeededLibraries() override;
+
+private:
+  const XCOFFObjectFile &Obj;
+};
+} // anonymous namespace
+
+void XCOFFDumper::printFileHeaders() {
+  DictScope DS(W, "FileHeader");
+  W.printHex("Magic", Obj.getMagic());
+  W.printNumber("NumberOfSections", Obj.getNumberOfSections());
+
+  // Negative timestamp values are reserved for future use.
+  int32_t TimeStamp = Obj.getTimeStamp();
+  if (TimeStamp > 0) {
+    // This handling of the time stamp assumes that the host system's time_t is
+    // compatible with AIX time_t. If a platform is not compatible, the lit
+    // tests will let us know.
+    time_t TimeDate = TimeStamp;
+
+    char FormattedTime[21] = {};
+    size_t BytesWritten =
+        strftime(FormattedTime, 21, "%Y-%m-%dT%H:%M:%SZ", gmtime(&TimeDate));
+    if (BytesWritten)
+      W.printHex("TimeStamp", FormattedTime, TimeStamp);
+    else
+      W.printHex("Timestamp", TimeStamp);
+  } else {
+    W.printHex("TimeStamp", TimeStamp == 0 ? "None" : "Reserved Value",
+               TimeStamp);
+  }
+
+  W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset());
+  int32_t SymTabEntries = Obj.getNumberOfSymbolTableEntries();
+  if (SymTabEntries >= 0)
+    W.printNumber("SymbolTableEntries", SymTabEntries);
+  else
+    W.printHex("SymbolTableEntries", "Reserved Value", SymTabEntries);
+
+  W.printHex("OptionalHeaderSize", Obj.getOptionalHeaderSize());
+  W.printHex("Flags", Obj.getFlags());
+
+  // TODO FIXME Add support for the auxiliary header (if any) once
+  // XCOFFObjectFile has the necessary support.
+}
+
+void XCOFFDumper::printSectionHeaders() {
+  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+}
+
+void XCOFFDumper::printRelocations() {
+  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+}
+
+void XCOFFDumper::printSymbols() {
+  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+}
+
+void XCOFFDumper::printDynamicSymbols() {
+  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+}
+
+void XCOFFDumper::printUnwindInfo() {
+  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+}
+
+void XCOFFDumper::printStackMap() const {
+  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+}
+
+void XCOFFDumper::printNeededLibraries() {
+  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+}
+
+namespace llvm {
+std::error_code createXCOFFDumper(const object::ObjectFile *Obj,
+                                  ScopedPrinter &Writer,
+                                  std::unique_ptr<ObjDumper> &Result) {
+  const XCOFFObjectFile *XObj = dyn_cast<XCOFFObjectFile>(Obj);
+  if (!XObj)
+    return readobj_error::unsupported_obj_file_format;
+
+  Result.reset(new XCOFFDumper(*XObj, Writer));
+  return readobj_error::success;
+}
+} // namespace llvm

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=359878&r1=359877&r2=359878&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Fri May  3 05:57:07 2019
@@ -440,6 +440,8 @@ static std::error_code createDumper(cons
     return createMachODumper(Obj, Writer, Result);
   if (Obj->isWasm())
     return createWasmDumper(Obj, Writer, Result);
+  if (Obj->isXCOFF())
+    return createXCOFFDumper(Obj, Writer, Result);
 
   return readobj_error::unsupported_obj_file_format;
 }




More information about the llvm-commits mailing list