20
20
#include " llvm/MC/MCSubtargetInfo.h"
21
21
#include " llvm/Support/Casting.h"
22
22
#include " llvm/Support/Endian.h"
23
+ #include " llvm/Support/Format.h"
23
24
#include " llvm/Support/FormattedStream.h"
25
+ #include " llvm/Support/raw_ostream.h"
24
26
#include < algorithm>
25
27
26
28
using namespace llvm ;
@@ -30,10 +32,86 @@ using namespace llvm::support;
30
32
31
33
namespace {
32
34
class XCOFFDumper : public objdump ::Dumper {
35
+ const XCOFFObjectFile &Obj;
36
+ unsigned Width;
37
+
33
38
public:
34
- XCOFFDumper (const object::XCOFFObjectFile &O) : Dumper(O) {}
35
- void printPrivateHeaders () override {}
39
+ XCOFFDumper (const object::XCOFFObjectFile &O) : Dumper(O), Obj(O) {}
40
+
41
+ private:
42
+ void printPrivateHeaders () override ;
43
+ void printFileHeader ();
44
+ FormattedString formatName (StringRef Name);
45
+ void printHex (StringRef Name, uint64_t Value);
46
+ void printNumber (StringRef Name, uint64_t Value);
47
+ void printStrHex (StringRef Name, StringRef Str, uint64_t Value);
48
+ void setWidth (unsigned W) { Width = W; };
36
49
};
50
+
51
+ void XCOFFDumper::printPrivateHeaders () { printFileHeader (); }
52
+
53
+ FormattedString XCOFFDumper::formatName (StringRef Name) {
54
+ return FormattedString (Name, Width, FormattedString::JustifyLeft);
55
+ }
56
+
57
+ void XCOFFDumper::printHex (StringRef Name, uint64_t Value) {
58
+ outs () << formatName (Name) << format_hex (Value, 0 ) << " \n " ;
59
+ }
60
+
61
+ void XCOFFDumper::printNumber (StringRef Name, uint64_t Value) {
62
+ outs () << formatName (Name) << format_decimal (Value, 0 ) << " \n " ;
63
+ }
64
+
65
+ void XCOFFDumper::printStrHex (StringRef Name, StringRef Str, uint64_t Value) {
66
+ outs () << formatName (Name) << Str << " (" << format_decimal (Value, 0 )
67
+ << " )\n " ;
68
+ }
69
+
70
+ void XCOFFDumper::printFileHeader () {
71
+ setWidth (20 );
72
+ outs () << " \n ---File Header:\n " ;
73
+ printHex (" Magic:" , Obj.getMagic ());
74
+ printNumber (" NumberOfSections:" , Obj.getNumberOfSections ());
75
+
76
+ int32_t Timestamp = Obj.getTimeStamp ();
77
+ if (Timestamp > 0 ) {
78
+ // This handling of the timestamp assumes that the host system's time_t is
79
+ // compatible with AIX time_t. If a platform is not compatible, the lit
80
+ // tests will let us know.
81
+ time_t TimeDate = Timestamp;
82
+
83
+ char FormattedTime[20 ] = {};
84
+
85
+ size_t BytesFormatted = std::strftime (FormattedTime, sizeof (FormattedTime),
86
+ " %F %T" , std::gmtime (&TimeDate));
87
+ assert (BytesFormatted && " The size of the buffer FormattedTime is less "
88
+ " than the size of the date/time string." );
89
+ printStrHex (" Timestamp:" , FormattedTime, Timestamp);
90
+ } else {
91
+ // Negative timestamp values are reserved for future use.
92
+ printStrHex (" Timestamp:" , Timestamp == 0 ? " None" : " Reserved Value" ,
93
+ Timestamp);
94
+ }
95
+
96
+ // The number of symbol table entries is an unsigned value in 64-bit objects
97
+ // and a signed value (with negative values being 'reserved') in 32-bit
98
+ // objects.
99
+ if (Obj.is64Bit ()) {
100
+ printHex (" SymbolTableOffset:" , Obj.getSymbolTableOffset64 ());
101
+ printNumber (" SymbolTableEntries:" , Obj.getNumberOfSymbolTableEntries64 ());
102
+ } else {
103
+ printHex (" SymbolTableOffset:" , Obj.getSymbolTableOffset32 ());
104
+ int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries32 ();
105
+ if (SymTabEntries >= 0 )
106
+ printNumber (" SymbolTableEntries:" , SymTabEntries);
107
+ else
108
+ printStrHex (" SymbolTableEntries:" , " Reserved Value" , SymTabEntries);
109
+ }
110
+
111
+ printHex (" OptionalHeaderSize:" , Obj.getOptionalHeaderSize ());
112
+ printHex (" Flags:" , Obj.getFlags ());
113
+ }
114
+
37
115
} // namespace
38
116
39
117
std::unique_ptr<objdump::Dumper>
0 commit comments