summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/llvm-readobj')
-rw-r--r--contrib/llvm/tools/llvm-readobj/ARMAttributeParser.cpp682
-rw-r--r--contrib/llvm/tools/llvm-readobj/ARMAttributeParser.h126
-rw-r--r--contrib/llvm/tools/llvm-readobj/COFFDumper.cpp687
-rw-r--r--contrib/llvm/tools/llvm-readobj/COFFImportDumper.cpp2
-rw-r--r--contrib/llvm/tools/llvm-readobj/CodeView.h54
-rw-r--r--contrib/llvm/tools/llvm-readobj/ELFDumper.cpp335
-rw-r--r--contrib/llvm/tools/llvm-readobj/MachODumper.cpp20
-rw-r--r--contrib/llvm/tools/llvm-readobj/ObjDumper.h14
-rw-r--r--contrib/llvm/tools/llvm-readobj/WasmDumper.cpp209
-rw-r--r--contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp79
-rw-r--r--contrib/llvm/tools/llvm-readobj/llvm-readobj.h5
11 files changed, 942 insertions, 1271 deletions
diff --git a/contrib/llvm/tools/llvm-readobj/ARMAttributeParser.cpp b/contrib/llvm/tools/llvm-readobj/ARMAttributeParser.cpp
deleted file mode 100644
index 877dd71..0000000
--- a/contrib/llvm/tools/llvm-readobj/ARMAttributeParser.cpp
+++ /dev/null
@@ -1,682 +0,0 @@
-//===--- ARMAttributeParser.cpp - ARM Attribute Information Printer -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARMAttributeParser.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/LEB128.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-using namespace llvm;
-using namespace llvm::ARMBuildAttrs;
-
-
-static const EnumEntry<unsigned> TagNames[] = {
- { "Tag_File", ARMBuildAttrs::File },
- { "Tag_Section", ARMBuildAttrs::Section },
- { "Tag_Symbol", ARMBuildAttrs::Symbol },
-};
-
-namespace llvm {
-#define ATTRIBUTE_HANDLER(Attr_) \
- { ARMBuildAttrs::Attr_, &ARMAttributeParser::Attr_ }
-
-const ARMAttributeParser::DisplayHandler
-ARMAttributeParser::DisplayRoutines[] = {
- { ARMBuildAttrs::CPU_raw_name, &ARMAttributeParser::StringAttribute, },
- { ARMBuildAttrs::CPU_name, &ARMAttributeParser::StringAttribute },
- ATTRIBUTE_HANDLER(CPU_arch),
- ATTRIBUTE_HANDLER(CPU_arch_profile),
- ATTRIBUTE_HANDLER(ARM_ISA_use),
- ATTRIBUTE_HANDLER(THUMB_ISA_use),
- ATTRIBUTE_HANDLER(FP_arch),
- ATTRIBUTE_HANDLER(WMMX_arch),
- ATTRIBUTE_HANDLER(Advanced_SIMD_arch),
- ATTRIBUTE_HANDLER(PCS_config),
- ATTRIBUTE_HANDLER(ABI_PCS_R9_use),
- ATTRIBUTE_HANDLER(ABI_PCS_RW_data),
- ATTRIBUTE_HANDLER(ABI_PCS_RO_data),
- ATTRIBUTE_HANDLER(ABI_PCS_GOT_use),
- ATTRIBUTE_HANDLER(ABI_PCS_wchar_t),
- ATTRIBUTE_HANDLER(ABI_FP_rounding),
- ATTRIBUTE_HANDLER(ABI_FP_denormal),
- ATTRIBUTE_HANDLER(ABI_FP_exceptions),
- ATTRIBUTE_HANDLER(ABI_FP_user_exceptions),
- ATTRIBUTE_HANDLER(ABI_FP_number_model),
- ATTRIBUTE_HANDLER(ABI_align_needed),
- ATTRIBUTE_HANDLER(ABI_align_preserved),
- ATTRIBUTE_HANDLER(ABI_enum_size),
- ATTRIBUTE_HANDLER(ABI_HardFP_use),
- ATTRIBUTE_HANDLER(ABI_VFP_args),
- ATTRIBUTE_HANDLER(ABI_WMMX_args),
- ATTRIBUTE_HANDLER(ABI_optimization_goals),
- ATTRIBUTE_HANDLER(ABI_FP_optimization_goals),
- ATTRIBUTE_HANDLER(compatibility),
- ATTRIBUTE_HANDLER(CPU_unaligned_access),
- ATTRIBUTE_HANDLER(FP_HP_extension),
- ATTRIBUTE_HANDLER(ABI_FP_16bit_format),
- ATTRIBUTE_HANDLER(MPextension_use),
- ATTRIBUTE_HANDLER(DIV_use),
- ATTRIBUTE_HANDLER(DSP_extension),
- ATTRIBUTE_HANDLER(T2EE_use),
- ATTRIBUTE_HANDLER(Virtualization_use),
- ATTRIBUTE_HANDLER(nodefaults)
-};
-
-#undef ATTRIBUTE_HANDLER
-
-uint64_t ARMAttributeParser::ParseInteger(const uint8_t *Data,
- uint32_t &Offset) {
- unsigned Length;
- uint64_t Value = decodeULEB128(Data + Offset, &Length);
- Offset = Offset + Length;
- return Value;
-}
-
-StringRef ARMAttributeParser::ParseString(const uint8_t *Data,
- uint32_t &Offset) {
- const char *String = reinterpret_cast<const char*>(Data + Offset);
- size_t Length = std::strlen(String);
- Offset = Offset + Length + 1;
- return StringRef(String, Length);
-}
-
-void ARMAttributeParser::IntegerAttribute(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- SW.printNumber(ARMBuildAttrs::AttrTypeAsString(Tag),
- ParseInteger(Data, Offset));
-}
-
-void ARMAttributeParser::StringAttribute(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- StringRef TagName = ARMBuildAttrs::AttrTypeAsString(Tag, /*TagPrefix*/false);
-
- DictScope AS(SW, "Attribute");
- SW.printNumber("Tag", Tag);
- if (!TagName.empty())
- SW.printString("TagName", TagName);
- SW.printString("Value", ParseString(Data, Offset));
-}
-
-void ARMAttributeParser::PrintAttribute(unsigned Tag, unsigned Value,
- StringRef ValueDesc) {
- StringRef TagName = ARMBuildAttrs::AttrTypeAsString(Tag, /*TagPrefix*/false);
-
- DictScope AS(SW, "Attribute");
- SW.printNumber("Tag", Tag);
- SW.printNumber("Value", Value);
- if (!TagName.empty())
- SW.printString("TagName", TagName);
- if (!ValueDesc.empty())
- SW.printString("Description", ValueDesc);
-}
-
-void ARMAttributeParser::CPU_arch(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Pre-v4", "ARM v4", "ARM v4T", "ARM v5T", "ARM v5TE", "ARM v5TEJ", "ARM v6",
- "ARM v6KZ", "ARM v6T2", "ARM v6K", "ARM v7", "ARM v6-M", "ARM v6S-M",
- "ARM v7E-M", "ARM v8"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::CPU_arch_profile(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- uint64_t Encoded = ParseInteger(Data, Offset);
-
- StringRef Profile;
- switch (Encoded) {
- default: Profile = "Unknown"; break;
- case 'A': Profile = "Application"; break;
- case 'R': Profile = "Real-time"; break;
- case 'M': Profile = "Microcontroller"; break;
- case 'S': Profile = "Classic"; break;
- case 0: Profile = "None"; break;
- }
-
- PrintAttribute(Tag, Encoded, Profile);
-}
-
-void ARMAttributeParser::ARM_ISA_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "Permitted" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::THUMB_ISA_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "Thumb-1", "Thumb-2" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::FP_arch(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4",
- "VFPv4-D16", "ARMv8-a FP", "ARMv8-a FP-D16"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::WMMX_arch(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "WMMXv1", "WMMXv2" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::Advanced_SIMD_arch(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "NEONv1", "NEONv2+FMA", "ARMv8-a NEON", "ARMv8.1-a NEON"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::PCS_config(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "None", "Bare Platform", "Linux Application", "Linux DSO", "Palm OS 2004",
- "Reserved (Palm OS)", "Symbian OS 2004", "Reserved (Symbian OS)"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_PCS_R9_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "v6", "Static Base", "TLS", "Unused" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_PCS_RW_data(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Absolute", "PC-relative", "SB-relative", "Not Permitted"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_PCS_RO_data(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Absolute", "PC-relative", "Not Permitted"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_PCS_GOT_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "Direct", "GOT-Indirect"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_PCS_wchar_t(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "Unknown", "2-byte", "Unknown", "4-byte"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_FP_rounding(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "IEEE-754", "Runtime" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_FP_denormal(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Unsupported", "IEEE-754", "Sign Only"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_FP_exceptions(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "IEEE-754" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_FP_user_exceptions(AttrType Tag,
- const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "IEEE-754" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_FP_number_model(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "Finite Only", "RTABI", "IEEE-754"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_align_needed(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "8-byte alignment", "4-byte alignment", "Reserved"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
-
- std::string Description;
- if (Value < array_lengthof(Strings))
- Description = std::string(Strings[Value]);
- else if (Value <= 12)
- Description = std::string("8-byte alignment, ") + utostr(1ULL << Value)
- + std::string("-byte extended alignment");
- else
- Description = "Invalid";
-
- PrintAttribute(Tag, Value, Description);
-}
-
-void ARMAttributeParser::ABI_align_preserved(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Required", "8-byte data alignment", "8-byte data and code alignment",
- "Reserved"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
-
- std::string Description;
- if (Value < array_lengthof(Strings))
- Description = std::string(Strings[Value]);
- else if (Value <= 12)
- Description = std::string("8-byte stack alignment, ") +
- utostr(1ULL << Value) + std::string("-byte data alignment");
- else
- Description = "Invalid";
-
- PrintAttribute(Tag, Value, Description);
-}
-
-void ARMAttributeParser::ABI_enum_size(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "Packed", "Int32", "External Int32"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_HardFP_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Tag_FP_arch", "Single-Precision", "Reserved", "Tag_FP_arch (deprecated)"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_VFP_args(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "AAPCS", "AAPCS VFP", "Custom", "Not Permitted"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_WMMX_args(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "AAPCS", "iWMMX", "Custom" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_optimization_goals(AttrType Tag,
- const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", "Debugging",
- "Best Debugging"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_FP_optimization_goals(AttrType Tag,
- const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", "Accuracy",
- "Best Accuracy"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::compatibility(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- uint64_t Integer = ParseInteger(Data, Offset);
- StringRef String = ParseString(Data, Offset);
-
- DictScope AS(SW, "Attribute");
- SW.printNumber("Tag", Tag);
- SW.startLine() << "Value: " << Integer << ", " << String << '\n';
- SW.printString("TagName", AttrTypeAsString(Tag, /*TagPrefix*/false));
- switch (Integer) {
- case 0:
- SW.printString("Description", StringRef("No Specific Requirements"));
- break;
- case 1:
- SW.printString("Description", StringRef("AEABI Conformant"));
- break;
- default:
- SW.printString("Description", StringRef("AEABI Non-Conformant"));
- break;
- }
-}
-
-void ARMAttributeParser::CPU_unaligned_access(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "v6-style" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::FP_HP_extension(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "If Available", "Permitted" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::ABI_FP_16bit_format(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "IEEE-754", "VFPv3" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::MPextension_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "Permitted" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::DIV_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "If Available", "Not Permitted", "Permitted"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::DSP_extension(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "Permitted" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::T2EE_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = { "Not Permitted", "Permitted" };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::Virtualization_use(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- static const char *const Strings[] = {
- "Not Permitted", "TrustZone", "Virtualization Extensions",
- "TrustZone + Virtualization Extensions"
- };
-
- uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc =
- (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
- PrintAttribute(Tag, Value, ValueDesc);
-}
-
-void ARMAttributeParser::nodefaults(AttrType Tag, const uint8_t *Data,
- uint32_t &Offset) {
- uint64_t Value = ParseInteger(Data, Offset);
- PrintAttribute(Tag, Value, "Unspecified Tags UNDEFINED");
-}
-
-void ARMAttributeParser::ParseIndexList(const uint8_t *Data, uint32_t &Offset,
- SmallVectorImpl<uint8_t> &IndexList) {
- for (;;) {
- unsigned Length;
- uint64_t Value = decodeULEB128(Data + Offset, &Length);
- Offset = Offset + Length;
- if (Value == 0)
- break;
- IndexList.push_back(Value);
- }
-}
-
-void ARMAttributeParser::ParseAttributeList(const uint8_t *Data,
- uint32_t &Offset, uint32_t Length) {
- while (Offset < Length) {
- unsigned Length;
- uint64_t Tag = decodeULEB128(Data + Offset, &Length);
- Offset += Length;
-
- bool Handled = false;
- for (unsigned AHI = 0, AHE = array_lengthof(DisplayRoutines);
- AHI != AHE && !Handled; ++AHI) {
- if (DisplayRoutines[AHI].Attribute == Tag) {
- (this->*DisplayRoutines[AHI].Routine)(ARMBuildAttrs::AttrType(Tag),
- Data, Offset);
- Handled = true;
- break;
- }
- }
- if (!Handled) {
- if (Tag < 32) {
- errs() << "unhandled AEABI Tag " << Tag
- << " (" << ARMBuildAttrs::AttrTypeAsString(Tag) << ")\n";
- continue;
- }
-
- if (Tag % 2 == 0)
- IntegerAttribute(ARMBuildAttrs::AttrType(Tag), Data, Offset);
- else
- StringAttribute(ARMBuildAttrs::AttrType(Tag), Data, Offset);
- }
- }
-}
-
-void ARMAttributeParser::ParseSubsection(const uint8_t *Data, uint32_t Length) {
- uint32_t Offset = sizeof(uint32_t); /* SectionLength */
-
- SW.printNumber("SectionLength", Length);
-
- const char *VendorName = reinterpret_cast<const char*>(Data + Offset);
- size_t VendorNameLength = std::strlen(VendorName);
- SW.printString("Vendor", StringRef(VendorName, VendorNameLength));
- Offset = Offset + VendorNameLength + 1;
-
- if (StringRef(VendorName, VendorNameLength).lower() != "aeabi")
- return;
-
- while (Offset < Length) {
- /// Tag_File | Tag_Section | Tag_Symbol uleb128:byte-size
- uint8_t Tag = Data[Offset];
- SW.printEnum("Tag", Tag, makeArrayRef(TagNames));
- Offset = Offset + sizeof(Tag);
-
- uint32_t Size =
- *reinterpret_cast<const support::ulittle32_t*>(Data + Offset);
- SW.printNumber("Size", Size);
- Offset = Offset + sizeof(Size);
-
- if (Size > Length) {
- errs() << "subsection length greater than section length\n";
- return;
- }
-
- StringRef ScopeName, IndexName;
- SmallVector<uint8_t, 8> Indicies;
- switch (Tag) {
- case ARMBuildAttrs::File:
- ScopeName = "FileAttributes";
- break;
- case ARMBuildAttrs::Section:
- ScopeName = "SectionAttributes";
- IndexName = "Sections";
- ParseIndexList(Data, Offset, Indicies);
- break;
- case ARMBuildAttrs::Symbol:
- ScopeName = "SymbolAttributes";
- IndexName = "Symbols";
- ParseIndexList(Data, Offset, Indicies);
- break;
- default:
- errs() << "unrecognised tag: 0x" << utohexstr(Tag) << '\n';
- return;
- }
-
- DictScope ASS(SW, ScopeName);
-
- if (!Indicies.empty())
- SW.printList(IndexName, Indicies);
-
- ParseAttributeList(Data, Offset, Length);
- }
-}
-
-void ARMAttributeParser::Parse(ArrayRef<uint8_t> Section) {
- size_t Offset = 1;
- unsigned SectionNumber = 0;
-
- while (Offset < Section.size()) {
- uint32_t SectionLength =
- *reinterpret_cast<const support::ulittle32_t*>(Section.data() + Offset);
-
- SW.startLine() << "Section " << ++SectionNumber << " {\n";
- SW.indent();
-
- ParseSubsection(Section.data() + Offset, SectionLength);
- Offset = Offset + SectionLength;
-
- SW.unindent();
- SW.startLine() << "}\n";
- }
-}
-}
-
diff --git a/contrib/llvm/tools/llvm-readobj/ARMAttributeParser.h b/contrib/llvm/tools/llvm-readobj/ARMAttributeParser.h
deleted file mode 100644
index 6936b70..0000000
--- a/contrib/llvm/tools/llvm-readobj/ARMAttributeParser.h
+++ /dev/null
@@ -1,126 +0,0 @@
-//===--- ARMAttributeParser.h - ARM Attribute Information Printer ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_LLVM_READOBJ_ARMATTRIBUTEPARSER_H
-#define LLVM_TOOLS_LLVM_READOBJ_ARMATTRIBUTEPARSER_H
-
-#include "llvm/Support/ARMBuildAttributes.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-namespace llvm {
-class StringRef;
-
-class ARMAttributeParser {
- ScopedPrinter &SW;
-
- struct DisplayHandler {
- ARMBuildAttrs::AttrType Attribute;
- void (ARMAttributeParser::*Routine)(ARMBuildAttrs::AttrType,
- const uint8_t *, uint32_t &);
- };
- static const DisplayHandler DisplayRoutines[];
-
- uint64_t ParseInteger(const uint8_t *Data, uint32_t &Offset);
- StringRef ParseString(const uint8_t *Data, uint32_t &Offset);
-
- void IntegerAttribute(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void StringAttribute(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
-
- void PrintAttribute(unsigned Tag, unsigned Value, StringRef ValueDesc);
-
- void CPU_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void CPU_arch_profile(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ARM_ISA_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void THUMB_ISA_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void FP_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void WMMX_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void Advanced_SIMD_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void PCS_config(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_R9_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_RW_data(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_RO_data(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_GOT_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_wchar_t(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_rounding(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_denormal(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_exceptions(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_user_exceptions(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_number_model(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_align_needed(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_align_preserved(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_enum_size(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_HardFP_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_VFP_args(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_WMMX_args(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_optimization_goals(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_optimization_goals(ARMBuildAttrs::AttrType Tag,
- const uint8_t *Data, uint32_t &Offset);
- void compatibility(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void CPU_unaligned_access(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void FP_HP_extension(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_16bit_format(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void MPextension_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void DIV_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void DSP_extension(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void T2EE_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void Virtualization_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void nodefaults(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
-
- void ParseAttributeList(const uint8_t *Data, uint32_t &Offset,
- uint32_t Length);
- void ParseIndexList(const uint8_t *Data, uint32_t &Offset,
- SmallVectorImpl<uint8_t> &IndexList);
- void ParseSubsection(const uint8_t *Data, uint32_t Length);
-public:
- ARMAttributeParser(ScopedPrinter &SW) : SW(SW) {}
-
- void Parse(ArrayRef<uint8_t> Section);
-};
-
-}
-
-#endif
-
diff --git a/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp b/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp
index c83655f..74c4411 100644
--- a/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "ARMWinEHPrinter.h"
-#include "CodeView.h"
#include "Error.h"
#include "ObjDumper.h"
#include "StackMapPrinter.h"
@@ -22,8 +21,15 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
@@ -35,14 +41,16 @@
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
+#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/COFF.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Win64EH.h"
@@ -55,17 +63,24 @@
using namespace llvm;
using namespace llvm::object;
using namespace llvm::codeview;
-using namespace llvm::msf;
using namespace llvm::support;
using namespace llvm::Win64EH;
namespace {
+struct LoadConfigTables {
+ uint64_t SEHTableVA = 0;
+ uint64_t SEHTableCount = 0;
+ uint32_t GuardFlags = 0;
+ uint64_t GuardFidTableVA = 0;
+ uint64_t GuardFidTableCount = 0;
+};
+
class COFFDumper : public ObjDumper {
public:
friend class COFFObjectDumpDelegate;
COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer)
- : ObjDumper(Writer), Obj(Obj), Writer(Writer) {}
+ : ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {}
void printFileHeaders() override;
void printSections() override;
@@ -78,8 +93,11 @@ public:
void printCOFFDirectives() override;
void printCOFFBaseReloc() override;
void printCOFFDebugDirectory() override;
+ void printCOFFResources() override;
+ void printCOFFLoadConfig() override;
void printCodeViewDebugInfo() override;
- void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVTypes) override;
+ void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs,
+ llvm::codeview::TypeTableBuilder &CVTypes) override;
void printStackMap() const override;
private:
void printSymbol(const SymbolRef &Sym);
@@ -91,6 +109,11 @@ private:
template <class PEHeader> void printPEHeader(const PEHeader *Hdr);
void printBaseOfDataField(const pe32_header *Hdr);
void printBaseOfDataField(const pe32plus_header *Hdr);
+ template <typename T>
+ void printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables);
+ typedef void (*PrintExtraCB)(raw_ostream &, const uint8_t *);
+ void printRVATable(uint64_t TableVA, uint64_t Count, uint64_t EntrySize,
+ PrintExtraCB PrintExtra = 0);
void printCodeViewSymbolSection(StringRef SectionName, const SectionRef &Section);
void printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section);
@@ -99,7 +122,7 @@ private:
void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
void printTypeIndex(StringRef FieldName, TypeIndex TI) {
// Forward to CVTypeDumper for simplicity.
- CVTypeDumper::printTypeIndex(Writer, FieldName, TI, TypeDB);
+ codeview::printTypeIndex(Writer, FieldName, TI, Types);
}
void printCodeViewSymbolsSubsection(StringRef Subsection,
@@ -114,11 +137,19 @@ private:
uint32_t RelocOffset, uint32_t Offset,
StringRef *RelocSym = nullptr);
+ uint32_t countTotalTableEntries(ResourceSectionRef RSF,
+ const coff_resource_dir_table &Table,
+ StringRef Level);
+
+ void printResourceDirectoryTable(ResourceSectionRef RSF,
+ const coff_resource_dir_table &Table,
+ StringRef Level);
+
void printBinaryBlockWithRelocs(StringRef Label, const SectionRef &Sec,
StringRef SectionContents, StringRef Block);
/// Given a .debug$S section, find the string table and file checksum table.
- void initializeFileAndStringTables(StringRef Data);
+ void initializeFileAndStringTables(BinaryStreamReader &Reader);
void cacheRelocations();
@@ -133,17 +164,23 @@ private:
void printDelayImportedSymbols(
const DelayImportDirectoryEntryRef &I,
iterator_range<imported_symbol_iterator> Range);
+ ErrorOr<const coff_resource_dir_entry &>
+ getResourceDirectoryTableEntry(const coff_resource_dir_table &Table,
+ uint32_t Index);
typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
const llvm::object::COFFObjectFile *Obj;
bool RelocCached = false;
RelocMapTy RelocMap;
- StringRef CVFileChecksumTable;
- StringRef CVStringTable;
+
+ DebugChecksumsSubsectionRef CVFileChecksumTable;
+
+ DebugStringTableSubsectionRef CVStringTable;
ScopedPrinter &Writer;
- TypeDatabase TypeDB;
+ BinaryByteStream TypeContents;
+ LazyRandomTypeCollection Types;
};
class COFFObjectDumpDelegate : public SymbolDumpDelegate {
@@ -154,7 +191,7 @@ public:
Sec = Obj->getCOFFSection(SR);
}
- uint32_t getRecordOffset(msf::StreamReader Reader) override {
+ uint32_t getRecordOffset(BinaryStreamReader Reader) override {
ArrayRef<uint8_t> Data;
if (auto EC = Reader.readLongestContiguousChunk(Data)) {
llvm::consumeError(std::move(EC));
@@ -180,7 +217,9 @@ public:
return CD.getFileNameForFileOffset(FileOffset);
}
- StringRef getStringTable() override { return CD.CVStringTable; }
+ DebugStringTableSubsectionRef getStringTable() override {
+ return CD.CVStringTable;
+ }
private:
COFFDumper &CD;
@@ -296,6 +335,7 @@ static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ),
@@ -495,19 +535,19 @@ WeakExternalCharacteristics[] = {
};
static const EnumEntry<uint32_t> SubSectionTypes[] = {
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Symbols),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Lines),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, StringTable),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FileChecksums),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FrameData),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, InlineeLines),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeImports),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeExports),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, ILLines),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FuncMDTokenMap),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, TypeMDTokenMap),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, MergedAssemblyInput),
- LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CoffSymbolRVA),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, Symbols),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, Lines),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, StringTable),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, FileChecksums),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, FrameData),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, InlineeLines),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeImports),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeExports),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, ILLines),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, FuncMDTokenMap),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, TypeMDTokenMap),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, MergedAssemblyInput),
+ LLVM_READOBJ_ENUM_CLASS_ENT(DebugSubsectionKind, CoffSymbolRVA),
};
static const EnumEntry<uint32_t> FrameDataFlags[] = {
@@ -523,6 +563,29 @@ static const EnumEntry<uint8_t> FileChecksumKindNames[] = {
LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
};
+static const EnumEntry<COFF::ResourceTypeID> ResourceTypeNames[]{
+ {"kRT_CURSOR (ID 1)", COFF::RID_Cursor},
+ {"kRT_BITMAP (ID 2)", COFF::RID_Bitmap},
+ {"kRT_ICON (ID 3)", COFF::RID_Icon},
+ {"kRT_MENU (ID 4)", COFF::RID_Menu},
+ {"kRT_DIALOG (ID 5)", COFF::RID_Dialog},
+ {"kRT_STRING (ID 6)", COFF::RID_String},
+ {"kRT_FONTDIR (ID 7)", COFF::RID_FontDir},
+ {"kRT_FONT (ID 8)", COFF::RID_Font},
+ {"kRT_ACCELERATOR (ID 9)", COFF::RID_Accelerator},
+ {"kRT_RCDATA (ID 10)", COFF::RID_RCData},
+ {"kRT_MESSAGETABLE (ID 11)", COFF::RID_MessageTable},
+ {"kRT_GROUP_CURSOR (ID 12)", COFF::RID_Group_Cursor},
+ {"kRT_GROUP_ICON (ID 14)", COFF::RID_Group_Icon},
+ {"kRT_VERSION (ID 16)", COFF::RID_Version},
+ {"kRT_DLGINCLUDE (ID 17)", COFF::RID_DLGInclude},
+ {"kRT_PLUGPLAY (ID 19)", COFF::RID_PlugPlay},
+ {"kRT_VXD (ID 20)", COFF::RID_VXD},
+ {"kRT_ANICURSOR (ID 21)", COFF::RID_AniCursor},
+ {"kRT_ANIICON (ID 22)", COFF::RID_AniIcon},
+ {"kRT_HTML (ID 23)", COFF::RID_HTML},
+ {"kRT_MANIFEST (ID 24)", COFF::RID_Manifest}};
+
template <typename T>
static std::error_code getSymbolAuxData(const COFFObjectFile *Obj,
COFFSymbolRef Symbol,
@@ -616,6 +679,7 @@ void COFFDumper::printDOSHeader(const dos_header *DH) {
template <class PEHeader>
void COFFDumper::printPEHeader(const PEHeader *Hdr) {
DictScope D(W, "ImageOptionalHeader");
+ W.printHex ("Magic", Hdr->Magic);
W.printNumber("MajorLinkerVersion", Hdr->MajorLinkerVersion);
W.printNumber("MinorLinkerVersion", Hdr->MinorLinkerVersion);
W.printNumber("SizeOfCode", Hdr->SizeOfCode);
@@ -697,6 +761,129 @@ void COFFDumper::printCOFFDebugDirectory() {
}
}
+void COFFDumper::printRVATable(uint64_t TableVA, uint64_t Count,
+ uint64_t EntrySize, PrintExtraCB PrintExtra) {
+ uintptr_t TableStart, TableEnd;
+ error(Obj->getVaPtr(TableVA, TableStart));
+ error(Obj->getVaPtr(TableVA + Count * EntrySize - 1, TableEnd));
+ TableEnd++;
+ for (uintptr_t I = TableStart; I < TableEnd; I += EntrySize) {
+ uint32_t RVA = *reinterpret_cast<const ulittle32_t *>(I);
+ raw_ostream &OS = W.startLine();
+ OS << "0x" << utohexstr(Obj->getImageBase() + RVA);
+ if (PrintExtra)
+ PrintExtra(OS, reinterpret_cast<const uint8_t *>(I));
+ OS << '\n';
+ }
+}
+
+void COFFDumper::printCOFFLoadConfig() {
+ LoadConfigTables Tables;
+ if (Obj->is64())
+ printCOFFLoadConfig(Obj->getLoadConfig64(), Tables);
+ else
+ printCOFFLoadConfig(Obj->getLoadConfig32(), Tables);
+
+ if (Tables.SEHTableVA) {
+ ListScope LS(W, "SEHTable");
+ printRVATable(Tables.SEHTableVA, Tables.SEHTableCount, 4);
+ }
+
+ if (Tables.GuardFidTableVA) {
+ ListScope LS(W, "GuardFidTable");
+ if (Tables.GuardFlags & uint32_t(coff_guard_flags::FidTableHasFlags)) {
+ auto PrintGuardFlags = [](raw_ostream &OS, const uint8_t *Entry) {
+ uint8_t Flags = *reinterpret_cast<const uint8_t *>(Entry + 4);
+ if (Flags)
+ OS << " flags " << utohexstr(Flags);
+ };
+ printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 5,
+ PrintGuardFlags);
+ } else {
+ printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 4);
+ }
+ }
+}
+
+template <typename T>
+void COFFDumper::printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables) {
+ if (!Conf)
+ return;
+
+ ListScope LS(W, "LoadConfig");
+ char FormattedTime[20] = {};
+ time_t TDS = Conf->TimeDateStamp;
+ strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
+ W.printHex("Size", Conf->Size);
+
+ // Print everything before SecurityCookie. The vast majority of images today
+ // have all these fields.
+ if (Conf->Size < offsetof(T, SEHandlerTable))
+ return;
+ W.printHex("TimeDateStamp", FormattedTime, TDS);
+ W.printHex("MajorVersion", Conf->MajorVersion);
+ W.printHex("MinorVersion", Conf->MinorVersion);
+ W.printHex("GlobalFlagsClear", Conf->GlobalFlagsClear);
+ W.printHex("GlobalFlagsSet", Conf->GlobalFlagsSet);
+ W.printHex("CriticalSectionDefaultTimeout",
+ Conf->CriticalSectionDefaultTimeout);
+ W.printHex("DeCommitFreeBlockThreshold", Conf->DeCommitFreeBlockThreshold);
+ W.printHex("DeCommitTotalFreeThreshold", Conf->DeCommitTotalFreeThreshold);
+ W.printHex("LockPrefixTable", Conf->LockPrefixTable);
+ W.printHex("MaximumAllocationSize", Conf->MaximumAllocationSize);
+ W.printHex("VirtualMemoryThreshold", Conf->VirtualMemoryThreshold);
+ W.printHex("ProcessHeapFlags", Conf->ProcessHeapFlags);
+ W.printHex("ProcessAffinityMask", Conf->ProcessAffinityMask);
+ W.printHex("CSDVersion", Conf->CSDVersion);
+ W.printHex("DependentLoadFlags", Conf->DependentLoadFlags);
+ W.printHex("EditList", Conf->EditList);
+ W.printHex("SecurityCookie", Conf->SecurityCookie);
+
+ // Print the safe SEH table if present.
+ if (Conf->Size < offsetof(coff_load_configuration32, GuardCFCheckFunction))
+ return;
+ W.printHex("SEHandlerTable", Conf->SEHandlerTable);
+ W.printNumber("SEHandlerCount", Conf->SEHandlerCount);
+
+ Tables.SEHTableVA = Conf->SEHandlerTable;
+ Tables.SEHTableCount = Conf->SEHandlerCount;
+
+ // Print everything before CodeIntegrity. (2015)
+ if (Conf->Size < offsetof(T, CodeIntegrity))
+ return;
+ W.printHex("GuardCFCheckFunction", Conf->GuardCFCheckFunction);
+ W.printHex("GuardCFCheckDispatch", Conf->GuardCFCheckDispatch);
+ W.printHex("GuardCFFunctionTable", Conf->GuardCFFunctionTable);
+ W.printNumber("GuardCFFunctionCount", Conf->GuardCFFunctionCount);
+ W.printHex("GuardFlags", Conf->GuardFlags);
+
+ Tables.GuardFidTableVA = Conf->GuardCFFunctionTable;
+ Tables.GuardFidTableCount = Conf->GuardCFFunctionCount;
+ Tables.GuardFlags = Conf->GuardFlags;
+
+ // Print the rest. (2017)
+ if (Conf->Size < sizeof(T))
+ return;
+ W.printHex("GuardAddressTakenIatEntryTable",
+ Conf->GuardAddressTakenIatEntryTable);
+ W.printNumber("GuardAddressTakenIatEntryCount",
+ Conf->GuardAddressTakenIatEntryCount);
+ W.printHex("GuardLongJumpTargetTable", Conf->GuardLongJumpTargetTable);
+ W.printNumber("GuardLongJumpTargetCount", Conf->GuardLongJumpTargetCount);
+ W.printHex("DynamicValueRelocTable", Conf->DynamicValueRelocTable);
+ W.printHex("CHPEMetadataPointer", Conf->CHPEMetadataPointer);
+ W.printHex("GuardRFFailureRoutine", Conf->GuardRFFailureRoutine);
+ W.printHex("GuardRFFailureRoutineFunctionPointer",
+ Conf->GuardRFFailureRoutineFunctionPointer);
+ W.printHex("DynamicValueRelocTableOffset",
+ Conf->DynamicValueRelocTableOffset);
+ W.printNumber("DynamicValueRelocTableSection",
+ Conf->DynamicValueRelocTableSection);
+ W.printHex("GuardRFVerifyStackPointerFunctionPointer",
+ Conf->GuardRFVerifyStackPointerFunctionPointer);
+ W.printHex("HotPatchTableOffset", Conf->HotPatchTableOffset);
+}
+
void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) {
W.printHex("BaseOfData", Hdr->BaseOfData);
}
@@ -719,30 +906,32 @@ void COFFDumper::printCodeViewDebugInfo() {
}
}
-void COFFDumper::initializeFileAndStringTables(StringRef Data) {
- while (!Data.empty() && (CVFileChecksumTable.data() == nullptr ||
- CVStringTable.data() == nullptr)) {
+void COFFDumper::initializeFileAndStringTables(BinaryStreamReader &Reader) {
+ while (Reader.bytesRemaining() > 0 &&
+ (!CVFileChecksumTable.valid() || !CVStringTable.valid())) {
// The section consists of a number of subsection in the following format:
// |SubSectionType|SubSectionSize|Contents...|
uint32_t SubType, SubSectionSize;
- error(consume(Data, SubType));
- error(consume(Data, SubSectionSize));
- if (SubSectionSize > Data.size())
- return error(object_error::parse_failed);
- switch (ModuleSubstreamKind(SubType)) {
- case ModuleSubstreamKind::FileChecksums:
- CVFileChecksumTable = Data.substr(0, SubSectionSize);
+ error(Reader.readInteger(SubType));
+ error(Reader.readInteger(SubSectionSize));
+
+ StringRef Contents;
+ error(Reader.readFixedString(Contents, SubSectionSize));
+
+ BinaryStreamRef ST(Contents, support::little);
+ switch (DebugSubsectionKind(SubType)) {
+ case DebugSubsectionKind::FileChecksums:
+ error(CVFileChecksumTable.initialize(ST));
break;
- case ModuleSubstreamKind::StringTable:
- CVStringTable = Data.substr(0, SubSectionSize);
+ case DebugSubsectionKind::StringTable:
+ error(CVStringTable.initialize(ST));
break;
default:
break;
}
+
uint32_t PaddedSize = alignTo(SubSectionSize, 4);
- if (PaddedSize > Data.size())
- error(object_error::parse_failed);
- Data = Data.drop_front(PaddedSize);
+ error(Reader.skip(PaddedSize - SubSectionSize));
}
}
@@ -765,7 +954,8 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
if (Magic != COFF::DEBUG_SECTION_MAGIC)
return error(object_error::parse_failed);
- initializeFileAndStringTables(Data);
+ BinaryStreamReader FSReader(Data, support::little);
+ initializeFileAndStringTables(FSReader);
// TODO: Convert this over to using ModuleSubstreamVisitor.
while (!Data.empty()) {
@@ -799,20 +989,20 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
printBinaryBlockWithRelocs("SubSectionContents", Section, SectionContents,
Contents);
- switch (ModuleSubstreamKind(SubType)) {
- case ModuleSubstreamKind::Symbols:
+ switch (DebugSubsectionKind(SubType)) {
+ case DebugSubsectionKind::Symbols:
printCodeViewSymbolsSubsection(Contents, Section, SectionContents);
break;
- case ModuleSubstreamKind::InlineeLines:
+ case DebugSubsectionKind::InlineeLines:
printCodeViewInlineeLines(Contents);
break;
- case ModuleSubstreamKind::FileChecksums:
+ case DebugSubsectionKind::FileChecksums:
printCodeViewFileChecksums(Contents);
break;
- case ModuleSubstreamKind::Lines: {
+ case DebugSubsectionKind::Lines: {
// Holds a PC to file:line table. Some data to parse this subsection is
// stored in the other subsections, so just check sanity and store the
// pointers for deferred processing.
@@ -838,39 +1028,33 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
FunctionNames.push_back(LinkageName);
break;
}
- case ModuleSubstreamKind::FrameData: {
+ case DebugSubsectionKind::FrameData: {
// First four bytes is a relocation against the function.
- msf::ByteStream S(Contents);
- msf::StreamReader SR(S);
- const uint32_t *CodePtr;
- error(SR.readObject(CodePtr));
+ BinaryStreamReader SR(Contents, llvm::support::little);
+
+ DebugFrameDataSubsectionRef FrameData;
+ error(FrameData.initialize(SR));
+
StringRef LinkageName;
error(resolveSymbolName(Obj->getCOFFSection(Section), SectionContents,
- CodePtr, LinkageName));
+ FrameData.getRelocPtr(), LinkageName));
W.printString("LinkageName", LinkageName);
// To find the active frame description, search this array for the
// smallest PC range that includes the current PC.
- while (!SR.empty()) {
- const FrameData *FD;
- error(SR.readObject(FD));
-
- if (FD->FrameFunc >= CVStringTable.size())
- error(object_error::parse_failed);
-
- StringRef FrameFunc =
- CVStringTable.drop_front(FD->FrameFunc).split('\0').first;
+ for (const auto &FD : FrameData) {
+ StringRef FrameFunc = error(CVStringTable.getString(FD.FrameFunc));
DictScope S(W, "FrameData");
- W.printHex("RvaStart", FD->RvaStart);
- W.printHex("CodeSize", FD->CodeSize);
- W.printHex("LocalSize", FD->LocalSize);
- W.printHex("ParamsSize", FD->ParamsSize);
- W.printHex("MaxStackSize", FD->MaxStackSize);
+ W.printHex("RvaStart", FD.RvaStart);
+ W.printHex("CodeSize", FD.CodeSize);
+ W.printHex("LocalSize", FD.LocalSize);
+ W.printHex("ParamsSize", FD.ParamsSize);
+ W.printHex("MaxStackSize", FD.MaxStackSize);
W.printString("FrameFunc", FrameFunc);
- W.printHex("PrologSize", FD->PrologSize);
- W.printHex("SavedRegsSize", FD->SavedRegsSize);
- W.printFlags("Flags", FD->Flags, makeArrayRef(FrameDataFlags));
+ W.printHex("PrologSize", FD.PrologSize);
+ W.printHex("SavedRegsSize", FD.SavedRegsSize);
+ W.printFlags("Flags", FD.Flags, makeArrayRef(FrameDataFlags));
}
break;
}
@@ -889,45 +1073,28 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
ListScope S(W, "FunctionLineTable");
W.printString("LinkageName", Name);
- DataExtractor DE(FunctionLineTables[Name], true, 4);
- uint32_t Offset = 6; // Skip relocations.
- uint16_t Flags = DE.getU16(&Offset);
- W.printHex("Flags", Flags);
- bool HasColumnInformation = Flags & codeview::LineFlags::HaveColumns;
- uint32_t FunctionSize = DE.getU32(&Offset);
- W.printHex("CodeSize", FunctionSize);
- while (DE.isValidOffset(Offset)) {
- // For each range of lines with the same filename, we have a segment
- // in the line table. The filename string is accessed using double
- // indirection to the string table subsection using the index subsection.
- uint32_t OffsetInIndex = DE.getU32(&Offset),
- NumLines = DE.getU32(&Offset),
- FullSegmentSize = DE.getU32(&Offset);
-
- uint32_t ColumnOffset = Offset + 8 * NumLines;
- DataExtractor ColumnDE(DE.getData(), true, 4);
-
- if (FullSegmentSize !=
- 12 + 8 * NumLines + (HasColumnInformation ? 4 * NumLines : 0)) {
- error(object_error::parse_failed);
- return;
- }
+ BinaryStreamReader Reader(FunctionLineTables[Name], support::little);
+
+ DebugLinesSubsectionRef LineInfo;
+ error(LineInfo.initialize(Reader));
+
+ W.printHex("Flags", LineInfo.header()->Flags);
+ W.printHex("CodeSize", LineInfo.header()->CodeSize);
+ for (const auto &Entry : LineInfo) {
ListScope S(W, "FilenameSegment");
- printFileNameForOffset("Filename", OffsetInIndex);
- for (unsigned LineIdx = 0;
- LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) {
- // Then go the (PC, LineNumber) pairs. The line number is stored in the
- // least significant 31 bits of the respective word in the table.
- uint32_t PC = DE.getU32(&Offset), LineData = DE.getU32(&Offset);
- if (PC >= FunctionSize) {
+ printFileNameForOffset("Filename", Entry.NameIndex);
+ uint32_t ColumnIndex = 0;
+ for (const auto &Line : Entry.LineNumbers) {
+ if (Line.Offset >= LineInfo.header()->CodeSize) {
error(object_error::parse_failed);
return;
}
- char Buffer[32];
- format("+0x%X", PC).snprint(Buffer, 32);
- ListScope PCScope(W, Buffer);
- LineInfo LI(LineData);
+
+ std::string PC = formatv("+{0:X}", uint32_t(Line.Offset));
+ ListScope PCScope(W, PC);
+ codeview::LineInfo LI(Line.Flags);
+
if (LI.isAlwaysStepInto())
W.printString("StepInto", StringRef("Always"));
else if (LI.isNeverStepInto())
@@ -936,19 +1103,10 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
W.printNumber("LineNumberStart", LI.getStartLine());
W.printNumber("LineNumberEndDelta", LI.getLineDelta());
W.printBoolean("IsStatement", LI.isStatement());
- if (HasColumnInformation &&
- ColumnDE.isValidOffsetForDataOfSize(ColumnOffset, 4)) {
- uint16_t ColStart = ColumnDE.getU16(&ColumnOffset);
- W.printNumber("ColStart", ColStart);
- uint16_t ColEnd = ColumnDE.getU16(&ColumnOffset);
- W.printNumber("ColEnd", ColEnd);
- }
- }
- // Skip over the column data.
- if (HasColumnInformation) {
- for (unsigned LineIdx = 0;
- LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) {
- DE.getU32(&Offset);
+ if (LineInfo.hasColumnInfo()) {
+ W.printNumber("ColStart", Entry.Columns[ColumnIndex].StartColumn);
+ W.printNumber("ColEnd", Entry.Columns[ColumnIndex].EndColumn);
+ ++ColumnIndex;
}
}
}
@@ -962,12 +1120,10 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
Subsection.bytes_end());
auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj,
SectionContents);
-
- CVSymbolDumper CVSD(W, TypeDB, std::move(CODD),
+ CVSymbolDumper CVSD(W, Types, CodeViewContainer::ObjectFile, std::move(CODD),
opts::CodeViewSubsectionBytes);
- ByteStream Stream(BinaryData);
CVSymbolArray Symbols;
- StreamReader Reader(Stream);
+ BinaryStreamReader Reader(BinaryData, llvm::support::little);
if (auto EC = Reader.readArray(Symbols, Reader.getLength())) {
consumeError(std::move(EC));
W.flush();
@@ -982,58 +1138,39 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
}
void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
- msf::ByteStream S(Subsection);
- msf::StreamReader SR(S);
- while (!SR.empty()) {
+ BinaryStreamRef Stream(Subsection, llvm::support::little);
+ DebugChecksumsSubsectionRef Checksums;
+ error(Checksums.initialize(Stream));
+
+ for (auto &FC : Checksums) {
DictScope S(W, "FileChecksum");
- const FileChecksum *FC;
- error(SR.readObject(FC));
- if (FC->FileNameOffset >= CVStringTable.size())
- error(object_error::parse_failed);
- StringRef Filename =
- CVStringTable.drop_front(FC->FileNameOffset).split('\0').first;
- W.printHex("Filename", Filename, FC->FileNameOffset);
- W.printHex("ChecksumSize", FC->ChecksumSize);
- W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind),
+
+ StringRef Filename = error(CVStringTable.getString(FC.FileNameOffset));
+ W.printHex("Filename", Filename, FC.FileNameOffset);
+ W.printHex("ChecksumSize", FC.Checksum.size());
+ W.printEnum("ChecksumKind", uint8_t(FC.Kind),
makeArrayRef(FileChecksumKindNames));
- if (FC->ChecksumSize >= SR.bytesRemaining())
- error(object_error::parse_failed);
- ArrayRef<uint8_t> ChecksumBytes;
- error(SR.readBytes(ChecksumBytes, FC->ChecksumSize));
- W.printBinary("ChecksumBytes", ChecksumBytes);
- unsigned PaddedSize = alignTo(FC->ChecksumSize + sizeof(FileChecksum), 4) -
- sizeof(FileChecksum);
- PaddedSize -= ChecksumBytes.size();
- if (PaddedSize > SR.bytesRemaining())
- error(object_error::parse_failed);
- error(SR.skip(PaddedSize));
+
+ W.printBinary("ChecksumBytes", FC.Checksum);
}
}
void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
- msf::ByteStream S(Subsection);
- msf::StreamReader SR(S);
- uint32_t Signature;
- error(SR.readInteger(Signature));
- bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles);
-
- while (!SR.empty()) {
- const InlineeSourceLine *ISL;
- error(SR.readObject(ISL));
+ BinaryStreamReader SR(Subsection, llvm::support::little);
+ DebugInlineeLinesSubsectionRef Lines;
+ error(Lines.initialize(SR));
+
+ for (auto &Line : Lines) {
DictScope S(W, "InlineeSourceLine");
- printTypeIndex("Inlinee", ISL->Inlinee);
- printFileNameForOffset("FileID", ISL->FileID);
- W.printNumber("SourceLineNum", ISL->SourceLineNum);
-
- if (HasExtraFiles) {
- uint32_t ExtraFileCount;
- error(SR.readInteger(ExtraFileCount));
- W.printNumber("ExtraFileCount", ExtraFileCount);
+ printTypeIndex("Inlinee", Line.Header->Inlinee);
+ printFileNameForOffset("FileID", Line.Header->FileID);
+ W.printNumber("SourceLineNum", Line.Header->SourceLineNum);
+
+ if (Lines.hasExtraFiles()) {
+ W.printNumber("ExtraFileCount", Line.ExtraFiles.size());
ListScope ExtraFiles(W, "ExtraFiles");
- for (unsigned I = 0; I < ExtraFileCount; ++I) {
- uint32_t FileID;
- error(SR.readInteger(FileID));
- printFileNameForOffset("FileID", FileID);
+ for (const auto &FID : Line.ExtraFiles) {
+ printFileNameForOffset("FileID", FID);
}
}
}
@@ -1041,30 +1178,24 @@ void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) {
// The file checksum subsection should precede all references to it.
- if (!CVFileChecksumTable.data() || !CVStringTable.data())
- error(object_error::parse_failed);
- // Check if the file checksum table offset is valid.
- if (FileOffset >= CVFileChecksumTable.size())
+ if (!CVFileChecksumTable.valid() || !CVStringTable.valid())
error(object_error::parse_failed);
- // The string table offset comes first before the file checksum.
- StringRef Data = CVFileChecksumTable.drop_front(FileOffset);
- uint32_t StringOffset;
- error(consume(Data, StringOffset));
+ auto Iter = CVFileChecksumTable.getArray().at(FileOffset);
- // Check if the string table offset is valid.
- if (StringOffset >= CVStringTable.size())
+ // Check if the file checksum table offset is valid.
+ if (Iter == CVFileChecksumTable.end())
error(object_error::parse_failed);
- // Return the null-terminated string.
- return CVStringTable.drop_front(StringOffset).split('\0').first;
+ return error(CVStringTable.getString(Iter->FileNameOffset));
}
void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) {
W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset);
}
-void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVTypes) {
+void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVIDs,
+ TypeTableBuilder &CVTypes) {
for (const SectionRef &S : Obj->sections()) {
StringRef SectionName;
error(S.getName(SectionName));
@@ -1075,19 +1206,17 @@ void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVTypes) {
error(consume(Data, Magic));
if (Magic != 4)
error(object_error::parse_failed);
- ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
- Data.size());
- ByteStream Stream(Bytes);
+
CVTypeArray Types;
- StreamReader Reader(Stream);
+ BinaryStreamReader Reader(Data, llvm::support::little);
if (auto EC = Reader.readArray(Types, Reader.getLength())) {
consumeError(std::move(EC));
W.flush();
error(object_error::parse_failed);
}
-
- if (!mergeTypeStreams(CVTypes, Types))
- return error(object_error::parse_failed);
+ SmallVector<TypeIndex, 128> SourceToDest;
+ if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, Types))
+ return error(std::move(EC));
}
}
}
@@ -1108,12 +1237,11 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName,
if (Magic != COFF::DEBUG_SECTION_MAGIC)
return error(object_error::parse_failed);
- CVTypeDumper CVTD(TypeDB);
- TypeDumpVisitor TDV(TypeDB, &W, opts::CodeViewSubsectionBytes);
- if (auto EC = CVTD.dump({Data.bytes_begin(), Data.bytes_end()}, TDV)) {
- W.flush();
- error(llvm::errorToErrorCode(std::move(EC)));
- }
+ Types.reset(Data, 100);
+
+ TypeDumpVisitor TDV(Types, &W, opts::CodeViewSubsectionBytes);
+ error(codeview::visitTypeStream(Types, TDV));
+ W.flush();
}
void COFFDumper::printSections() {
@@ -1435,12 +1563,18 @@ void COFFDumper::printCOFFImports() {
StringRef Name;
error(I.getName(Name));
W.printString("Name", Name);
- uint32_t Addr;
- error(I.getImportLookupTableRVA(Addr));
- W.printHex("ImportLookupTableRVA", Addr);
- error(I.getImportAddressTableRVA(Addr));
- W.printHex("ImportAddressTableRVA", Addr);
- printImportedSymbols(I.imported_symbols());
+ uint32_t ILTAddr;
+ error(I.getImportLookupTableRVA(ILTAddr));
+ W.printHex("ImportLookupTableRVA", ILTAddr);
+ uint32_t IATAddr;
+ error(I.getImportAddressTableRVA(IATAddr));
+ W.printHex("ImportAddressTableRVA", IATAddr);
+ // The import lookup table can be missing with certain older linkers, so
+ // fall back to the import address table in that case.
+ if (ILTAddr)
+ printImportedSymbols(I.lookup_table_symbols());
+ else
+ printImportedSymbols(I.imported_symbols());
}
// Delay imports
@@ -1502,7 +1636,11 @@ static StringRef getBaseRelocTypeName(uint8_t Type) {
case COFF::IMAGE_REL_BASED_HIGHADJ: return "HIGHADJ";
case COFF::IMAGE_REL_BASED_ARM_MOV32T: return "ARM_MOV32(T)";
case COFF::IMAGE_REL_BASED_DIR64: return "DIR64";
- default: return "unknown (" + llvm::utostr(Type) + ")";
+ default: {
+ static std::string Result;
+ Result = "unknown (" + llvm::utostr(Type) + ")";
+ return Result;
+ }
}
}
@@ -1519,6 +1657,127 @@ void COFFDumper::printCOFFBaseReloc() {
}
}
+void COFFDumper::printCOFFResources() {
+ ListScope ResourcesD(W, "Resources");
+ for (const SectionRef &S : Obj->sections()) {
+ StringRef Name;
+ error(S.getName(Name));
+ if (!Name.startswith(".rsrc"))
+ continue;
+
+ StringRef Ref;
+ error(S.getContents(Ref));
+
+ if ((Name == ".rsrc") || (Name == ".rsrc$01")) {
+ ResourceSectionRef RSF(Ref);
+ auto &BaseTable = unwrapOrError(RSF.getBaseTable());
+ W.printNumber("Total Number of Resources",
+ countTotalTableEntries(RSF, BaseTable, "Type"));
+ W.printHex("Base Table Address",
+ Obj->getCOFFSection(S)->PointerToRawData);
+ W.startLine() << "\n";
+ printResourceDirectoryTable(RSF, BaseTable, "Type");
+ }
+ if (opts::SectionData)
+ W.printBinaryBlock(Name.str() + " Data", Ref);
+ }
+}
+
+uint32_t
+COFFDumper::countTotalTableEntries(ResourceSectionRef RSF,
+ const coff_resource_dir_table &Table,
+ StringRef Level) {
+ uint32_t TotalEntries = 0;
+ for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries;
+ i++) {
+ auto Entry = unwrapOrError(getResourceDirectoryTableEntry(Table, i));
+ if (Entry.Offset.isSubDir()) {
+ StringRef NextLevel;
+ if (Level == "Name")
+ NextLevel = "Language";
+ else
+ NextLevel = "Name";
+ auto &NextTable = unwrapOrError(RSF.getEntrySubDir(Entry));
+ TotalEntries += countTotalTableEntries(RSF, NextTable, NextLevel);
+ } else {
+ TotalEntries += 1;
+ }
+ }
+ return TotalEntries;
+}
+
+void COFFDumper::printResourceDirectoryTable(
+ ResourceSectionRef RSF, const coff_resource_dir_table &Table,
+ StringRef Level) {
+
+ W.printNumber("Number of String Entries", Table.NumberOfNameEntries);
+ W.printNumber("Number of ID Entries", Table.NumberOfIDEntries);
+
+ // Iterate through level in resource directory tree.
+ for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries;
+ i++) {
+ auto Entry = unwrapOrError(getResourceDirectoryTableEntry(Table, i));
+ StringRef Name;
+ SmallString<20> IDStr;
+ raw_svector_ostream OS(IDStr);
+ if (i < Table.NumberOfNameEntries) {
+ ArrayRef<UTF16> RawEntryNameString = unwrapOrError(RSF.getEntryNameString(Entry));
+ std::vector<UTF16> EndianCorrectedNameString;
+ if (llvm::sys::IsBigEndianHost) {
+ EndianCorrectedNameString.resize(RawEntryNameString.size() + 1);
+ std::copy(RawEntryNameString.begin(), RawEntryNameString.end(),
+ EndianCorrectedNameString.begin() + 1);
+ EndianCorrectedNameString[0] = UNI_UTF16_BYTE_ORDER_MARK_SWAPPED;
+ RawEntryNameString = makeArrayRef(EndianCorrectedNameString);
+ }
+ std::string EntryNameString;
+ if (!llvm::convertUTF16ToUTF8String(RawEntryNameString, EntryNameString))
+ error(object_error::parse_failed);
+ OS << ": ";
+ OS << EntryNameString;
+ } else {
+ if (Level == "Type") {
+ ScopedPrinter Printer(OS);
+ Printer.printEnum("", Entry.Identifier.ID,
+ makeArrayRef(ResourceTypeNames));
+ IDStr = IDStr.slice(0, IDStr.find_first_of(")", 0) + 1);
+ } else {
+ OS << ": (ID " << Entry.Identifier.ID << ")";
+ }
+ }
+ Name = StringRef(IDStr);
+ ListScope ResourceType(W, Level.str() + Name.str());
+ if (Entry.Offset.isSubDir()) {
+ W.printHex("Table Offset", Entry.Offset.value());
+ StringRef NextLevel;
+ if (Level == "Name")
+ NextLevel = "Language";
+ else
+ NextLevel = "Name";
+ auto &NextTable = unwrapOrError(RSF.getEntrySubDir(Entry));
+ printResourceDirectoryTable(RSF, NextTable, NextLevel);
+ } else {
+ W.printHex("Entry Offset", Entry.Offset.value());
+ char FormattedTime[20] = {};
+ time_t TDS = time_t(Table.TimeDateStamp);
+ strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
+ W.printHex("Time/Date Stamp", FormattedTime, Table.TimeDateStamp);
+ W.printNumber("Major Version", Table.MajorVersion);
+ W.printNumber("Minor Version", Table.MinorVersion);
+ W.printNumber("Characteristics", Table.Characteristics);
+ }
+ }
+}
+
+ErrorOr<const coff_resource_dir_entry &>
+COFFDumper::getResourceDirectoryTableEntry(const coff_resource_dir_table &Table,
+ uint32_t Index) {
+ if (Index >= (uint32_t)(Table.NumberOfNameEntries + Table.NumberOfIDEntries))
+ return object_error::parse_failed;
+ auto TablePtr = reinterpret_cast<const coff_resource_dir_entry *>(&Table + 1);
+ return TablePtr[Index];
+}
+
void COFFDumper::printStackMap() const {
object::SectionRef StackMapSection;
for (auto Sec : Obj->sections()) {
@@ -1549,20 +1808,30 @@ void COFFDumper::printStackMap() const {
}
void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer,
+ llvm::codeview::TypeTableBuilder &IDTable,
llvm::codeview::TypeTableBuilder &CVTypes) {
// Flatten it first, then run our dumper on it.
- ListScope S(Writer, "MergedTypeStream");
- SmallString<0> Buf;
+ SmallString<0> TypeBuf;
CVTypes.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Record) {
- Buf.append(Record.begin(), Record.end());
+ TypeBuf.append(Record.begin(), Record.end());
});
- TypeDatabase TypeDB;
- CVTypeDumper CVTD(TypeDB);
- TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes);
- if (auto EC =
- CVTD.dump({Buf.str().bytes_begin(), Buf.str().bytes_end()}, TDV)) {
+ TypeTableCollection TpiTypes(CVTypes.records());
+ {
+ ListScope S(Writer, "MergedTypeStream");
+ TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
+ error(codeview::visitTypeStream(TpiTypes, TDV));
+ Writer.flush();
+ }
+
+ // Flatten the id stream and print it next. The ID stream refers to names from
+ // the type stream.
+ TypeTableCollection IpiTypes(IDTable.records());
+ {
+ ListScope S(Writer, "MergedIDStream");
+ TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
+ TDV.setIpiTypes(IpiTypes);
+ error(codeview::visitTypeStream(IpiTypes, TDV));
Writer.flush();
- error(llvm::errorToErrorCode(std::move(EC)));
}
}
diff --git a/contrib/llvm/tools/llvm-readobj/COFFImportDumper.cpp b/contrib/llvm/tools/llvm-readobj/COFFImportDumper.cpp
index 83715e6..c5b8bf7 100644
--- a/contrib/llvm/tools/llvm-readobj/COFFImportDumper.cpp
+++ b/contrib/llvm/tools/llvm-readobj/COFFImportDumper.cpp
@@ -15,9 +15,9 @@
#include "Error.h"
#include "ObjDumper.h"
#include "llvm-readobj.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
-#include "llvm/Support/COFF.h"
using namespace llvm::object;
diff --git a/contrib/llvm/tools/llvm-readobj/CodeView.h b/contrib/llvm/tools/llvm-readobj/CodeView.h
deleted file mode 100644
index cf71396..0000000
--- a/contrib/llvm/tools/llvm-readobj/CodeView.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===-- CodeView.h - On-disk record types for CodeView ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file provides data structures useful for consuming on-disk
-/// CodeView. It is based on information published by Microsoft at
-/// https://github.com/Microsoft/microsoft-pdb/.
-///
-//===----------------------------------------------------------------------===//
-
-// FIXME: Find a home for this in include/llvm/DebugInfo/CodeView/.
-
-#ifndef LLVM_READOBJ_CODEVIEW_H
-#define LLVM_READOBJ_CODEVIEW_H
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/Support/Endian.h"
-
-namespace llvm {
-namespace codeview {
-
-using llvm::support::ulittle16_t;
-using llvm::support::ulittle32_t;
-
-/// Data in the the SUBSEC_FRAMEDATA subection.
-struct FrameData {
- ulittle32_t RvaStart;
- ulittle32_t CodeSize;
- ulittle32_t LocalSize;
- ulittle32_t ParamsSize;
- ulittle32_t MaxStackSize;
- ulittle32_t FrameFunc;
- ulittle16_t PrologSize;
- ulittle16_t SavedRegsSize;
- ulittle32_t Flags;
- enum : uint32_t {
- HasSEH = 1 << 0,
- HasEH = 1 << 1,
- IsFunctionStart = 1 << 2,
- };
-};
-
-
-} // namespace codeview
-} // namespace llvm
-
-#endif // LLVM_READOBJ_CODEVIEW_H
diff --git a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp
index 997af56..5698420 100644
--- a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -1,4 +1,4 @@
-//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===//
+//===- ELFDumper.cpp - ELF-specific dumper --------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,24 +12,49 @@
///
//===----------------------------------------------------------------------===//
-#include "ARMAttributeParser.h"
#include "ARMEHABIPrinter.h"
#include "Error.h"
#include "ObjDumper.h"
#include "StackMapPrinter.h"
#include "llvm-readobj.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/StackMapParser.h"
+#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MipsABIFlags.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cinttypes>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <vector>
using namespace llvm;
using namespace llvm::object;
@@ -49,28 +74,28 @@ using namespace ELF;
return std::string(#enum).substr(3);
#define TYPEDEF_ELF_TYPES(ELFT) \
- typedef ELFFile<ELFT> ELFO; \
- typedef typename ELFO::Elf_Shdr Elf_Shdr; \
- typedef typename ELFO::Elf_Sym Elf_Sym; \
- typedef typename ELFO::Elf_Dyn Elf_Dyn; \
- typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range; \
- typedef typename ELFO::Elf_Rel Elf_Rel; \
- typedef typename ELFO::Elf_Rela Elf_Rela; \
- typedef typename ELFO::Elf_Rel_Range Elf_Rel_Range; \
- typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range; \
- typedef typename ELFO::Elf_Phdr Elf_Phdr; \
- typedef typename ELFO::Elf_Half Elf_Half; \
- typedef typename ELFO::Elf_Ehdr Elf_Ehdr; \
- typedef typename ELFO::Elf_Word Elf_Word; \
- typedef typename ELFO::Elf_Hash Elf_Hash; \
- typedef typename ELFO::Elf_GnuHash Elf_GnuHash; \
- typedef typename ELFO::Elf_Sym_Range Elf_Sym_Range; \
- typedef typename ELFO::Elf_Versym Elf_Versym; \
- typedef typename ELFO::Elf_Verneed Elf_Verneed; \
- typedef typename ELFO::Elf_Vernaux Elf_Vernaux; \
- typedef typename ELFO::Elf_Verdef Elf_Verdef; \
- typedef typename ELFO::Elf_Verdaux Elf_Verdaux; \
- typedef typename ELFO::uintX_t uintX_t;
+ using ELFO = ELFFile<ELFT>; \
+ using Elf_Shdr = typename ELFO::Elf_Shdr; \
+ using Elf_Sym = typename ELFO::Elf_Sym; \
+ using Elf_Dyn = typename ELFO::Elf_Dyn; \
+ using Elf_Dyn_Range = typename ELFO::Elf_Dyn_Range; \
+ using Elf_Rel = typename ELFO::Elf_Rel; \
+ using Elf_Rela = typename ELFO::Elf_Rela; \
+ using Elf_Rel_Range = typename ELFO::Elf_Rel_Range; \
+ using Elf_Rela_Range = typename ELFO::Elf_Rela_Range; \
+ using Elf_Phdr = typename ELFO::Elf_Phdr; \
+ using Elf_Half = typename ELFO::Elf_Half; \
+ using Elf_Ehdr = typename ELFO::Elf_Ehdr; \
+ using Elf_Word = typename ELFO::Elf_Word; \
+ using Elf_Hash = typename ELFO::Elf_Hash; \
+ using Elf_GnuHash = typename ELFO::Elf_GnuHash; \
+ using Elf_Sym_Range = typename ELFO::Elf_Sym_Range; \
+ using Elf_Versym = typename ELFO::Elf_Versym; \
+ using Elf_Verneed = typename ELFO::Elf_Verneed; \
+ using Elf_Vernaux = typename ELFO::Elf_Vernaux; \
+ using Elf_Verdef = typename ELFO::Elf_Verdef; \
+ using Elf_Verdaux = typename ELFO::Elf_Verdaux; \
+ using uintX_t = typename ELFO::uintX_t;
namespace {
@@ -81,15 +106,16 @@ template <class ELFT> class DumpStyle;
/// the size, entity size and virtual address are different entries in arbitrary
/// order (DT_REL, DT_RELSZ, DT_RELENT for example).
struct DynRegionInfo {
- DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
+ DynRegionInfo() = default;
DynRegionInfo(const void *A, uint64_t S, uint64_t ES)
: Addr(A), Size(S), EntSize(ES) {}
+
/// \brief Address in current address space.
- const void *Addr;
+ const void *Addr = nullptr;
/// \brief Size in bytes of the region.
- uint64_t Size;
+ uint64_t Size = 0;
/// \brief Size of each entity in the region.
- uint64_t EntSize;
+ uint64_t EntSize = 0;
template <typename Type> ArrayRef<Type> getAsArrayRef() const {
const Type *Start = reinterpret_cast<const Type *>(Addr);
@@ -129,7 +155,7 @@ public:
void printMipsReginfo() override;
void printMipsOptions() override;
- void printAMDGPURuntimeMD() override;
+ void printAMDGPUCodeObjectMetadata() override;
void printStackMap() const override;
@@ -139,6 +165,7 @@ public:
private:
std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle;
+
TYPEDEF_ELF_TYPES(ELFT)
DynRegionInfo checkDRI(DynRegionInfo DRI) {
@@ -196,6 +223,7 @@ private:
: PointerIntPair<const void *, 1>(verdef, 0) {}
VersionMapEntry(const Elf_Vernaux *vernaux)
: PointerIntPair<const void *, 1>(vernaux, 1) {}
+
bool isNull() const { return getPointer() == nullptr; }
bool isVerdef() const { return !isNull() && getInt() == 0; }
bool isVernaux() const { return !isNull() && getInt() == 1; }
@@ -262,10 +290,11 @@ void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
template <typename ELFT> class DumpStyle {
public:
using Elf_Shdr = typename ELFFile<ELFT>::Elf_Shdr;
- using Elf_Sym = typename ELFFile<ELFT>::Elf_Sym;
+ using Elf_Sym = typename ELFFile<ELFT>::Elf_Sym;
DumpStyle(ELFDumper<ELFT> *Dumper) : Dumper(Dumper) {}
- virtual ~DumpStyle() {}
+ virtual ~DumpStyle() = default;
+
virtual void printFileHeaders(const ELFFile<ELFT> *Obj) = 0;
virtual void printGroupSections(const ELFFile<ELFT> *Obj) = 0;
virtual void printRelocations(const ELFFile<ELFT> *Obj) = 0;
@@ -274,9 +303,7 @@ public:
virtual void printDynamicSymbols(const ELFFile<ELFT> *Obj) = 0;
virtual void printDynamicRelocations(const ELFFile<ELFT> *Obj) = 0;
virtual void printSymtabMessage(const ELFFile<ELFT> *obj, StringRef Name,
- size_t Offset) {
- return;
- }
+ size_t Offset) {}
virtual void printSymbol(const ELFFile<ELFT> *Obj, const Elf_Sym *Symbol,
const Elf_Sym *FirstSym, StringRef StrTable,
bool IsDynamic) = 0;
@@ -284,16 +311,20 @@ public:
virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
virtual void printNotes(const ELFFile<ELFT> *Obj) = 0;
const ELFDumper<ELFT> *dumper() const { return Dumper; }
+
private:
const ELFDumper<ELFT> *Dumper;
};
template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
formatted_raw_ostream OS;
+
public:
TYPEDEF_ELF_TYPES(ELFT)
+
GNUStyle(ScopedPrinter &W, ELFDumper<ELFT> *Dumper)
: DumpStyle<ELFT>(Dumper), OS(W.getOStream()) {}
+
void printFileHeaders(const ELFO *Obj) override;
void printGroupSections(const ELFFile<ELFT> *Obj) override;
void printRelocations(const ELFO *Obj) override;
@@ -301,8 +332,8 @@ public:
void printSymbols(const ELFO *Obj) override;
void printDynamicSymbols(const ELFO *Obj) override;
void printDynamicRelocations(const ELFO *Obj) override;
- virtual void printSymtabMessage(const ELFO *Obj, StringRef Name,
- size_t Offset) override;
+ void printSymtabMessage(const ELFO *Obj, StringRef Name,
+ size_t Offset) override;
void printProgramHeaders(const ELFO *Obj) override;
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
void printNotes(const ELFFile<ELFT> *Obj) override;
@@ -311,6 +342,7 @@ private:
struct Field {
StringRef Str;
unsigned Column;
+
Field(StringRef S, unsigned Col) : Str(S), Column(Col) {}
Field(unsigned Col) : Str(""), Column(Col) {}
};
@@ -348,6 +380,7 @@ private:
template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
public:
TYPEDEF_ELF_TYPES(ELFT)
+
LLVMStyle(ScopedPrinter &W, ELFDumper<ELFT> *Dumper)
: DumpStyle<ELFT>(Dumper), W(W) {}
@@ -368,10 +401,11 @@ private:
void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel);
void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
StringRef StrTable, bool IsDynamic) override;
+
ScopedPrinter &W;
};
-} // namespace
+} // end anonymous namespace
namespace llvm {
@@ -405,7 +439,7 @@ std::error_code createELFDumper(const object::ObjectFile *Obj,
return readobj_error::unsupported_obj_file_format;
}
-} // namespace llvm
+} // end namespace llvm
// Iterate through the versions needed section, and place each Elf_Vernaux
// in the VersionMap according to its index.
@@ -525,8 +559,8 @@ static void printVersionDefinitionSection(ELFDumper<ELFT> *Dumper,
const ELFO *Obj,
const typename ELFO::Elf_Shdr *Sec,
ScopedPrinter &W) {
- typedef typename ELFO::Elf_Verdef VerDef;
- typedef typename ELFO::Elf_Verdaux VerdAux;
+ using VerDef = typename ELFO::Elf_Verdef;
+ using VerdAux = typename ELFO::Elf_Verdaux;
DictScope SD(W, "SHT_GNU_verdef");
if (!Sec)
@@ -581,8 +615,8 @@ static void printVersionDependencySection(ELFDumper<ELFT> *Dumper,
const ELFO *Obj,
const typename ELFO::Elf_Shdr *Sec,
ScopedPrinter &W) {
- typedef typename ELFO::Elf_Verneed VerNeed;
- typedef typename ELFO::Elf_Vernaux VernAux;
+ using VerNeed = typename ELFO::Elf_Verneed;
+ using VernAux = typename ELFO::Elf_Vernaux;
DictScope SD(W, "SHT_GNU_verneed");
if (!Sec)
@@ -978,61 +1012,9 @@ static const EnumEntry<unsigned> ElfSymbolTypes[] = {
{"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}};
static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
- { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL },
- { "AMDGPU_HSA_INDIRECT_FUNCTION", ELF::STT_AMDGPU_HSA_INDIRECT_FUNCTION },
- { "AMDGPU_HSA_METADATA", ELF::STT_AMDGPU_HSA_METADATA }
+ { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL }
};
-static const char *getElfSectionType(unsigned Arch, unsigned Type) {
- switch (Arch) {
- case ELF::EM_ARM:
- switch (Type) {
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
- }
- case ELF::EM_HEXAGON:
- switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
- case ELF::EM_X86_64:
- switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
- case ELF::EM_MIPS:
- case ELF::EM_MIPS_RS3_LE:
- switch (Type) {
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
- }
- }
-
- switch (Type) {
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed );
- LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym );
- default: return "";
- }
-}
-
static const char *getGroupType(uint32_t Flag) {
if (Flag & ELF::GRP_COMDAT)
return "COMDAT";
@@ -1062,13 +1044,6 @@ static const EnumEntry<unsigned> ElfXCoreSectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION)
};
-static const EnumEntry<unsigned> ElfAMDGPUSectionFlags[] = {
- LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_GLOBAL),
- LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_READONLY),
- LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_CODE),
- LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_AGENT)
-};
-
static const EnumEntry<unsigned> ElfARMSectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, SHF_ARM_PURECODE)
};
@@ -1127,13 +1102,6 @@ static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
// Check potentially overlapped processor-specific
// program header type.
switch (Arch) {
- case ELF::EM_AMDGPU:
- switch (Type) {
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM);
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT);
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_READONLY_AGENT);
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_CODE_AGENT);
- }
case ELF::EM_ARM:
switch (Type) {
LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX);
@@ -1189,14 +1157,6 @@ static std::string getElfPtType(unsigned Arch, unsigned Type) {
default:
// All machine specific PT_* types
switch (Arch) {
- case ELF::EM_AMDGPU:
- switch (Type) {
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM);
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT);
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_READONLY_AGENT);
- LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_CODE_AGENT);
- }
- return "";
case ELF::EM_ARM:
if (Type == ELF::PT_ARM_EXIDX)
return "EXIDX";
@@ -1312,7 +1272,6 @@ static const char *getElfMipsOptionsOdkType(unsigned Odk) {
template <typename ELFT>
ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer)
: ObjDumper(Writer), Obj(Obj) {
-
SmallVector<const Elf_Phdr *, 4> LoadSegments;
for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
if (Phdr.p_type == ELF::PT_DYNAMIC) {
@@ -1573,6 +1532,7 @@ static const char *getTypeString(unsigned Arch, uint64_t Type) {
LLVM_READOBJ_TYPE_CASE(TLSDESC_PLT);
LLVM_READOBJ_TYPE_CASE(TLSDESC_GOT);
LLVM_READOBJ_TYPE_CASE(AUXILIARY);
+ LLVM_READOBJ_TYPE_CASE(FILTER);
default: return "unknown";
}
}
@@ -1641,8 +1601,8 @@ static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
template <typename T, typename TFlag>
void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
- typedef EnumEntry<TFlag> FlagEntry;
- typedef SmallVector<FlagEntry, 10> FlagVector;
+ using FlagEntry = EnumEntry<TFlag>;
+ using FlagVector = SmallVector<FlagEntry, 10>;
FlagVector SetFlags;
for (const auto &Flag : Flags) {
@@ -1665,6 +1625,10 @@ StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
return StringRef(DynamicStringTable.data() + Value);
}
+static void printLibrary(raw_ostream &OS, const Twine &Tag, const Twine &Name) {
+ OS << Tag << ": [" << Name << "]";
+}
+
template <class ELFT>
void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) {
raw_ostream &OS = W.getOStream();
@@ -1728,13 +1692,16 @@ void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) {
OS << Value << " (bytes)";
break;
case DT_NEEDED:
- OS << "SharedLibrary (" << getDynamicString(Value) << ")";
+ printLibrary(OS, "Shared library", getDynamicString(Value));
break;
case DT_SONAME:
- OS << "LibrarySoname (" << getDynamicString(Value) << ")";
+ printLibrary(OS, "Library soname", getDynamicString(Value));
break;
case DT_AUXILIARY:
- OS << "Auxiliary library: [" << getDynamicString(Value) << "]";
+ printLibrary(OS, "Auxiliary library", getDynamicString(Value));
+ break;
+ case DT_FILTER:
+ printLibrary(OS, "Filter library", getDynamicString(Value));
break;
case DT_RPATH:
case DT_RUNPATH:
@@ -1761,6 +1728,7 @@ void ELFDumper<ELFT>::printUnwindInfo() {
}
namespace {
+
template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() {
const unsigned Machine = Obj->getHeader()->e_machine;
if (Machine == EM_ARM) {
@@ -1770,7 +1738,8 @@ template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() {
}
W.startLine() << "UnwindInfo not implemented.\n";
}
-}
+
+} // end anonymous namespace
template<class ELFT>
void ELFDumper<ELFT>::printDynamicTable() {
@@ -1816,7 +1785,7 @@ template<class ELFT>
void ELFDumper<ELFT>::printNeededLibraries() {
ListScope D(W, "NeededLibraries");
- typedef std::vector<StringRef> LibsTy;
+ using LibsTy = std::vector<StringRef>;
LibsTy Libs;
for (const auto &Entry : dynamic_table())
@@ -1870,6 +1839,7 @@ void ELFDumper<ELFT>::printAttributes() {
}
namespace {
+
template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() {
if (Obj->getHeader()->e_machine != EM_ARM) {
W.startLine() << "Attributes not implemented.\n";
@@ -1892,16 +1862,15 @@ template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() {
if (Contents.size() == 1)
continue;
- ARMAttributeParser(W).Parse(Contents);
+ ARMAttributeParser(&W).Parse(Contents, true);
}
}
-}
-namespace {
template <class ELFT> class MipsGOTParser {
public:
TYPEDEF_ELF_TYPES(ELFT)
- typedef typename ELFO::Elf_Addr GOTEntry;
+ using GOTEntry = typename ELFO::Elf_Addr;
+
MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
Elf_Dyn_Range DynTable, ScopedPrinter &W);
@@ -1912,11 +1881,11 @@ private:
ELFDumper<ELFT> *Dumper;
const ELFO *Obj;
ScopedPrinter &W;
- llvm::Optional<uint64_t> DtPltGot;
- llvm::Optional<uint64_t> DtLocalGotNum;
- llvm::Optional<uint64_t> DtGotSym;
- llvm::Optional<uint64_t> DtMipsPltGot;
- llvm::Optional<uint64_t> DtJmpRel;
+ Optional<uint64_t> DtPltGot;
+ Optional<uint64_t> DtLocalGotNum;
+ Optional<uint64_t> DtGotSym;
+ Optional<uint64_t> DtMipsPltGot;
+ Optional<uint64_t> DtJmpRel;
std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const;
const GOTEntry *makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum);
@@ -1932,7 +1901,8 @@ private:
const GOTEntry *It, StringRef StrTable,
const Elf_Sym *Sym);
};
-}
+
+} // end anonymous namespace
template <class ELFT>
MipsGOTParser<ELFT>::MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
@@ -2356,7 +2326,7 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
}
}
-template <class ELFT> void ELFDumper<ELFT>::printAMDGPURuntimeMD() {
+template <class ELFT> void ELFDumper<ELFT>::printAMDGPUCodeObjectMetadata() {
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".note");
if (!Shdr) {
W.startLine() << "There is no .note section in the file.\n";
@@ -2364,7 +2334,7 @@ template <class ELFT> void ELFDumper<ELFT>::printAMDGPURuntimeMD() {
}
ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr));
- const uint32_t RuntimeMDNoteType = 7;
+ const uint32_t CodeObjectMetadataNoteType = 10;
for (auto I = reinterpret_cast<const Elf_Word *>(&Sec[0]),
E = I + Sec.size()/4; I != E;) {
uint32_t NameSZ = I[0];
@@ -2378,7 +2348,7 @@ template <class ELFT> void ELFDumper<ELFT>::printAMDGPURuntimeMD() {
I += alignTo<4>(NameSZ)/4;
}
- if (Name == "AMD" && Type == RuntimeMDNoteType) {
+ if (Name == "AMD" && Type == CodeObjectMetadataNoteType) {
StringRef Desc(reinterpret_cast<const char *>(I), DescSZ);
W.printString(Desc);
}
@@ -2403,8 +2373,8 @@ template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
ArrayRef<uint8_t> StackMapContentsArray =
unwrapOrError(Obj->getSectionContents(StackMapSection));
- prettyPrintStackMap(llvm::outs(), StackMapV2Parser<ELFT::TargetEndianness>(
- StackMapContentsArray));
+ prettyPrintStackMap(outs(), StackMapV2Parser<ELFT::TargetEndianness>(
+ StackMapContentsArray));
}
template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
@@ -2505,7 +2475,7 @@ template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
template <class ELFT>
void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
const Elf_Rela &R, bool IsRela) {
- std::string Offset, Info, Addend = "", Value;
+ std::string Offset, Info, Addend, Value;
SmallString<32> RelocName;
StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
StringRef TargetName;
@@ -2599,6 +2569,7 @@ template <class ELFT> void GNUStyle<ELFT>::printRelocations(const ELFO *Obj) {
std::string getSectionTypeString(unsigned Arch, unsigned Type) {
using namespace ELF;
+
switch (Arch) {
case EM_ARM:
switch (Type) {
@@ -2627,6 +2598,8 @@ std::string getSectionTypeString(unsigned Arch, unsigned Type) {
return "MIPS_OPTIONS";
case SHT_MIPS_ABIFLAGS:
return "MIPS_ABIFLAGS";
+ case SHT_MIPS_DWARF:
+ return "SHT_MIPS_DWARF";
}
}
switch (Type) {
@@ -2664,6 +2637,8 @@ std::string getSectionTypeString(unsigned Arch, unsigned Type) {
return "GROUP";
case SHT_SYMTAB_SHNDX:
return "SYMTAB SECTION INDICES";
+ case SHT_LLVM_ODRTAB:
+ return "LLVM_ODRTAB";
// FIXME: Parse processor specific GNU attributes
case SHT_GNU_ATTRIBUTES:
return "ATTRIBUTES";
@@ -2763,7 +2738,7 @@ template <class ELFT> void GNUStyle<ELFT>::printSections(const ELFO *Obj) {
template <class ELFT>
void GNUStyle<ELFT>::printSymtabMessage(const ELFO *Obj, StringRef Name,
size_t Entries) {
- if (Name.size())
+ if (!Name.empty())
OS << "\nSymbol table '" << Name << "' contains " << Entries
<< " entries:\n";
else
@@ -2790,6 +2765,7 @@ std::string GNUStyle<ELFT>::getSymbolSectionNdx(const ELFO *Obj,
case ELF::SHN_XINDEX:
SectionIndex = unwrapOrError(object::getExtendedSymbolTableIndex<ELFT>(
Symbol, FirstSym, this->dumper()->getShndxTable()));
+ LLVM_FALLTHROUGH;
default:
// Find if:
// Processor specific
@@ -2917,7 +2893,7 @@ template <class ELFT> void GNUStyle<ELFT>::printSymbols(const ELFO *Obj) {
template <class ELFT>
void GNUStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) {
- if (this->dumper()->getDynamicStringTable().size() == 0)
+ if (this->dumper()->getDynamicStringTable().empty())
return;
auto StringTable = this->dumper()->getDynamicStringTable();
auto DynSyms = this->dumper()->dynamic_symbols();
@@ -3131,19 +3107,19 @@ void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
SymbolName =
unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable()));
- std::string Addend = "", Info, Offset, Value;
+ std::string Addend, Info, Offset, Value;
Offset = to_string(format_hex_no_prefix(R.r_offset, Width));
Info = to_string(format_hex_no_prefix(R.r_info, Width));
Value = to_string(format_hex_no_prefix(Sym->getValue(), Width));
int64_t RelAddend = R.r_addend;
- if (SymbolName.size() && IsRela) {
+ if (!SymbolName.empty() && IsRela) {
if (R.r_addend < 0)
Addend = " - ";
else
Addend = " + ";
}
- if (!SymbolName.size() && Sym->getValue() == 0)
+ if (SymbolName.empty() && Sym->getValue() == 0)
Value = "";
if (IsRela)
@@ -3278,7 +3254,7 @@ void GNUStyle<ELFT>::printHashHistogram(const ELFFile<ELFT> *Obj) {
size_t MaxChain = 1;
size_t CumulativeNonZero = 0;
- if (Chains.size() == 0 || NBucket == 0)
+ if (Chains.empty() || NBucket == 0)
return;
std::vector<size_t> ChainLen(NBucket, 0);
@@ -3337,9 +3313,38 @@ static std::string getGNUNoteTypeName(const uint32_t NT) {
return string;
}
+static std::string getFreeBSDNoteTypeName(const uint32_t NT) {
+ static const struct {
+ uint32_t ID;
+ const char *Name;
+ } Notes[] = {
+ {ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"},
+ {ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_VMMAP, "NT_PROCSTAT_VMMAP (vmmap data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_GROUPS, "NT_PROCSTAT_GROUPS (groups data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_UMASK, "NT_PROCSTAT_UMASK (umask data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_RLIMIT, "NT_PROCSTAT_RLIMIT (rlimit data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_OSREL, "NT_PROCSTAT_OSREL (osreldate data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS,
+ "NT_PROCSTAT_PSSTRINGS (ps_strings data)"},
+ {ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"},
+ };
+
+ for (const auto &Note : Notes)
+ if (Note.ID == NT)
+ return std::string(Note.Name);
+
+ std::string string;
+ raw_string_ostream OS(string);
+ OS << format("Unknown note type (0x%08x)", NT);
+ return string;
+}
+
template <typename ELFT>
static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
- ArrayRef<typename ELFFile<ELFT>::Elf_Word> Words) {
+ ArrayRef<typename ELFFile<ELFT>::Elf_Word> Words,
+ size_t Size) {
switch (NoteType) {
default:
return;
@@ -3362,16 +3367,14 @@ static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
}
case ELF::NT_GNU_BUILD_ID: {
OS << " Build ID: ";
- ArrayRef<uint8_t> ID(reinterpret_cast<const uint8_t *>(Words.data()),
- Words.size() * 4);
+ ArrayRef<uint8_t> ID(reinterpret_cast<const uint8_t *>(Words.data()), Size);
for (const auto &B : ID)
OS << format_hex_no_prefix(B, 2);
break;
}
case ELF::NT_GNU_GOLD_VERSION:
OS << " Version: "
- << StringRef(reinterpret_cast<const char *>(Words.data()),
- Words.size() * 4);
+ << StringRef(reinterpret_cast<const char *>(Words.data()), Size);
break;
}
@@ -3415,11 +3418,15 @@ void GNUStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
if (Name == "GNU") {
OS << getGNUNoteTypeName(Type) << '\n';
- printGNUNote<ELFT>(OS, Type, Descriptor);
+ printGNUNote<ELFT>(OS, Type, Descriptor, DescriptorSize);
+ } else if (Name == "FreeBSD") {
+ OS << getFreeBSDNoteTypeName(Type) << '\n';
+ } else {
+ OS << "Unknown note type: (" << format_hex(Type, 10) << ')';
}
OS << '\n';
- P = P + 3 * sizeof(Elf_Word) * alignTo<4>(NameSize) +
+ P = P + 3 * sizeof(Elf_Word) + alignTo<4>(NameSize) +
alignTo<4>(DescriptorSize);
}
};
@@ -3578,13 +3585,13 @@ void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, Elf_Rela Rel,
DictScope Group(W, "Relocation");
W.printHex("Offset", Rel.r_offset);
W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
- W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
+ W.printNumber("Symbol", !TargetName.empty() ? TargetName : "-",
Rel.getSymbol(Obj->isMips64EL()));
W.printHex("Addend", Rel.r_addend);
} else {
raw_ostream &OS = W.startLine();
OS << W.hex(Rel.r_offset) << " " << RelocName << " "
- << (TargetName.size() > 0 ? TargetName : "-") << " "
+ << (!TargetName.empty() ? TargetName : "-") << " "
<< W.hex(Rel.r_addend) << "\n";
}
}
@@ -3601,16 +3608,13 @@ template <class ELFT> void LLVMStyle<ELFT>::printSections(const ELFO *Obj) {
DictScope SectionD(W, "Section");
W.printNumber("Index", SectionIndex);
W.printNumber("Name", Name, Sec.sh_name);
- W.printHex("Type",
- getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
- Sec.sh_type);
+ W.printHex(
+ "Type",
+ object::getELFSectionTypeName(Obj->getHeader()->e_machine, Sec.sh_type),
+ Sec.sh_type);
std::vector<EnumEntry<unsigned>> SectionFlags(std::begin(ElfSectionFlags),
std::end(ElfSectionFlags));
switch (Obj->getHeader()->e_machine) {
- case EM_AMDGPU:
- SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
- std::end(ElfAMDGPUSectionFlags));
- break;
case EM_ARM:
SectionFlags.insert(SectionFlags.end(), std::begin(ElfARMSectionFlags),
std::end(ElfARMSectionFlags));
@@ -3778,12 +3782,12 @@ void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
DictScope Group(W, "Relocation");
W.printHex("Offset", Rel.r_offset);
W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
- W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
+ W.printString("Symbol", !SymbolName.empty() ? SymbolName : "-");
W.printHex("Addend", Rel.r_addend);
} else {
raw_ostream &OS = W.startLine();
OS << W.hex(Rel.r_offset) << " " << RelocName << " "
- << (SymbolName.size() > 0 ? SymbolName : "-") << " "
+ << (!SymbolName.empty() ? SymbolName : "-") << " "
<< W.hex(Rel.r_addend) << "\n";
}
}
@@ -3816,4 +3820,3 @@ template <class ELFT>
void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
W.startLine() << "printNotes not implemented!\n";
}
-
diff --git a/contrib/llvm/tools/llvm-readobj/MachODumper.cpp b/contrib/llvm/tools/llvm-readobj/MachODumper.cpp
index 01b0741..39e9092 100644
--- a/contrib/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/contrib/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -713,12 +713,30 @@ void MachODumper::printMachOVersionMin() {
case MachO::LC_VERSION_MIN_WATCHOS:
Cmd = "LC_VERSION_MIN_WATCHOS";
break;
+ case MachO::LC_BUILD_VERSION:
+ Cmd = "LC_BUILD_VERSION";
+ break;
default:
continue;
}
- MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
DictScope Group(W, "MinVersion");
+ // Handle LC_BUILD_VERSION.
+ if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
+ MachO::build_version_command BVC = Obj->getBuildVersionLoadCommand(Load);
+ W.printString("Cmd", Cmd);
+ W.printNumber("Size", BVC.cmdsize);
+ W.printString("Platform",
+ MachOObjectFile::getBuildPlatform(BVC.platform));
+ W.printString("Version", MachOObjectFile::getVersionString(BVC.minos));
+ if (BVC.sdk)
+ W.printString("SDK", MachOObjectFile::getVersionString(BVC.sdk));
+ else
+ W.printString("SDK", StringRef("n/a"));
+ continue;
+ }
+
+ MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
W.printString("Cmd", Cmd);
W.printNumber("Size", VMC.cmdsize);
SmallString<32> Version;
diff --git a/contrib/llvm/tools/llvm-readobj/ObjDumper.h b/contrib/llvm/tools/llvm-readobj/ObjDumper.h
index c91558e..43883c2 100644
--- a/contrib/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/contrib/llvm/tools/llvm-readobj/ObjDumper.h
@@ -59,7 +59,7 @@ public:
virtual void printMipsOptions() { }
// Only implemented for AMDGPU ELF at this time.
- virtual void printAMDGPURuntimeMD() {}
+ virtual void printAMDGPUCodeObjectMetadata() {}
// Only implemented for PE/COFF.
virtual void printCOFFImports() { }
@@ -67,8 +67,11 @@ public:
virtual void printCOFFDirectives() { }
virtual void printCOFFBaseReloc() { }
virtual void printCOFFDebugDirectory() { }
+ virtual void printCOFFResources() {}
+ virtual void printCOFFLoadConfig() { }
virtual void printCodeViewDebugInfo() { }
- virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVTypes) {}
+ virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs,
+ llvm::codeview::TypeTableBuilder &CVTypes) {}
// Only implemented for MachO.
virtual void printMachODataInCode() { }
@@ -96,10 +99,15 @@ std::error_code createMachODumper(const object::ObjectFile *Obj,
ScopedPrinter &Writer,
std::unique_ptr<ObjDumper> &Result);
+std::error_code createWasmDumper(const object::ObjectFile *Obj,
+ ScopedPrinter &Writer,
+ std::unique_ptr<ObjDumper> &Result);
+
void dumpCOFFImportFile(const object::COFFImportFile *File);
void dumpCodeViewMergedTypes(ScopedPrinter &Writer,
- llvm::codeview::TypeTableBuilder &CVTypes);
+ llvm::codeview::TypeTableBuilder &IDTable,
+ llvm::codeview::TypeTableBuilder &TypeTable);
} // namespace llvm
diff --git a/contrib/llvm/tools/llvm-readobj/WasmDumper.cpp b/contrib/llvm/tools/llvm-readobj/WasmDumper.cpp
new file mode 100644
index 0000000..266226d
--- /dev/null
+++ b/contrib/llvm/tools/llvm-readobj/WasmDumper.cpp
@@ -0,0 +1,209 @@
+//===-- WasmDumper.cpp - Wasm-specific object file dumper -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Wasm-specific dumper for llvm-readobj.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Error.h"
+#include "ObjDumper.h"
+#include "llvm-readobj.h"
+#include "llvm/Object/Wasm.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+using namespace llvm;
+using namespace object;
+
+namespace {
+
+static const EnumEntry<unsigned> WasmSymbolTypes[] = {
+#define ENUM_ENTRY(X) { #X, static_cast<unsigned>(WasmSymbol::SymbolType::X) }
+ ENUM_ENTRY(FUNCTION_IMPORT),
+ ENUM_ENTRY(FUNCTION_EXPORT),
+ ENUM_ENTRY(GLOBAL_IMPORT),
+ ENUM_ENTRY(GLOBAL_EXPORT),
+ ENUM_ENTRY(DEBUG_FUNCTION_NAME),
+#undef ENUM_ENTRY
+};
+
+static const EnumEntry<uint32_t> WasmSectionTypes[] = {
+#define ENUM_ENTRY(X) { #X, wasm::WASM_SEC_##X }
+ ENUM_ENTRY(CUSTOM),
+ ENUM_ENTRY(TYPE),
+ ENUM_ENTRY(IMPORT),
+ ENUM_ENTRY(FUNCTION),
+ ENUM_ENTRY(TABLE),
+ ENUM_ENTRY(MEMORY),
+ ENUM_ENTRY(GLOBAL),
+ ENUM_ENTRY(EXPORT),
+ ENUM_ENTRY(START),
+ ENUM_ENTRY(ELEM),
+ ENUM_ENTRY(CODE),
+ ENUM_ENTRY(DATA),
+#undef ENUM_ENTRY
+};
+
+class WasmDumper : public ObjDumper {
+public:
+ WasmDumper(const WasmObjectFile *Obj, ScopedPrinter &Writer)
+ : ObjDumper(Writer), Obj(Obj) {}
+
+ void printFileHeaders() override;
+ void printSections() override;
+ void printRelocations() override;
+ void printSymbols() override;
+ void printDynamicSymbols() override { llvm_unreachable("unimplemented"); }
+ void printUnwindInfo() override { llvm_unreachable("unimplemented"); }
+ void printStackMap() const override { llvm_unreachable("unimplemented"); }
+
+protected:
+ void printSymbol(const SymbolRef &Sym);
+ void printRelocation(const SectionRef &Section, const RelocationRef &Reloc);
+
+private:
+ const WasmObjectFile *Obj;
+};
+
+void WasmDumper::printFileHeaders() {
+ W.printHex("Version", Obj->getHeader().Version);
+}
+
+void WasmDumper::printRelocation(const SectionRef &Section,
+ const RelocationRef &Reloc) {
+ SmallString<64> RelocTypeName;
+ uint64_t RelocType = Reloc.getType();
+ Reloc.getTypeName(RelocTypeName);
+ const wasm::WasmRelocation &WasmReloc = Obj->getWasmRelocation(Reloc);
+
+ bool HasAddend = false;
+ switch (RelocType) {
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
+ HasAddend = true;
+ break;
+ default:
+ break;
+ }
+ if (opts::ExpandRelocs) {
+ DictScope Group(W, "Relocation");
+ W.printNumber("Type", RelocTypeName, RelocType);
+ W.printHex("Offset", Reloc.getOffset());
+ W.printHex("Index", WasmReloc.Index);
+ if (HasAddend)
+ W.printNumber("Addend", WasmReloc.Addend);
+ } else {
+ raw_ostream& OS = W.startLine();
+ OS << W.hex(Reloc.getOffset())
+ << " " << RelocTypeName << "[" << WasmReloc.Index << "]";
+ if (HasAddend)
+ OS << " " << WasmReloc.Addend;
+ OS << "\n";
+ }
+}
+
+void WasmDumper::printRelocations() {
+ ListScope D(W, "Relocations");
+
+ int SectionNumber = 0;
+ for (const SectionRef &Section : Obj->sections()) {
+ bool PrintedGroup = false;
+ StringRef Name;
+ error(Section.getName(Name));
+ ++SectionNumber;
+
+ for (const RelocationRef &Reloc : Section.relocations()) {
+ if (!PrintedGroup) {
+ W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
+ W.indent();
+ PrintedGroup = true;
+ }
+
+ printRelocation(Section, Reloc);
+ }
+
+ if (PrintedGroup) {
+ W.unindent();
+ W.startLine() << "}\n";
+ }
+ }
+}
+
+void WasmDumper::printSymbols() {
+ ListScope Group(W, "Symbols");
+
+ for (const SymbolRef &Symbol : Obj->symbols())
+ printSymbol(Symbol);
+}
+
+void WasmDumper::printSections() {
+ ListScope Group(W, "Sections");
+ for (const SectionRef &Section : Obj->sections()) {
+ const WasmSection &WasmSec = Obj->getWasmSection(Section);
+ DictScope SectionD(W, "Section");
+ W.printEnum("Type", WasmSec.Type, makeArrayRef(WasmSectionTypes));
+ W.printNumber("Size", (uint64_t)WasmSec.Content.size());
+ W.printNumber("Offset", WasmSec.Offset);
+ switch (WasmSec.Type) {
+ case wasm::WASM_SEC_CUSTOM:
+ W.printString("Name", WasmSec.Name);
+ if (WasmSec.Name == "linking") {
+ const wasm::WasmLinkingData &LinkingData = Obj->linkingData();
+ W.printNumber("DataSize", LinkingData.DataSize);
+ if (LinkingData.DataAlignment)
+ W.printNumber("DataAlignment", LinkingData.DataAlignment);
+ }
+ break;
+ case wasm::WASM_SEC_MEMORY:
+ ListScope Group(W, "Memories");
+ for (const wasm::WasmLimits &Memory : Obj->memories()) {
+ DictScope Group(W, "Memory");
+ W.printNumber("InitialPages", Memory.Initial);
+ if (Memory.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) {
+ W.printNumber("MaxPages", WasmSec.Offset);
+ }
+ }
+ break;
+ }
+
+ if (opts::SectionRelocations) {
+ ListScope D(W, "Relocations");
+ for (const RelocationRef &Reloc : Section.relocations())
+ printRelocation(Section, Reloc);
+ }
+
+ if (opts::SectionData) {
+ W.printBinaryBlock("SectionData", WasmSec.Content);
+ }
+ }
+}
+
+void WasmDumper::printSymbol(const SymbolRef &Sym) {
+ DictScope D(W, "Symbol");
+ WasmSymbol Symbol = Obj->getWasmSymbol(Sym.getRawDataRefImpl());
+ W.printString("Name", Symbol.Name);
+ W.printEnum("Type", static_cast<unsigned>(Symbol.Type), makeArrayRef(WasmSymbolTypes));
+ W.printHex("Flags", Symbol.Flags);
+}
+
+}
+
+namespace llvm {
+
+std::error_code createWasmDumper(const object::ObjectFile *Obj,
+ ScopedPrinter &Writer,
+ std::unique_ptr<ObjDumper> &Result) {
+ const WasmObjectFile *WasmObj = dyn_cast<WasmObjectFile>(Obj);
+ assert(WasmObj && "createWasmDumper called with non-wasm object");
+
+ Result.reset(new WasmDumper(WasmObj, Writer));
+ return readobj_error::success;
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp b/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 970e154..7bfb18f 100644
--- a/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -34,6 +34,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/Signals.h"
@@ -50,6 +51,13 @@ namespace opts {
cl::desc("<input object files>"),
cl::ZeroOrMore);
+ // -wide, -W
+ cl::opt<bool> WideOutput("wide",
+ cl::desc("Ignored for compatibility with GNU readelf"));
+ cl::alias WideOutputShort("W",
+ cl::desc("Alias for --wide"),
+ cl::aliasopt(WideOutput));
+
// -file-headers, -h
cl::opt<bool> FileHeaders("file-headers",
cl::desc("Display file headers "));
@@ -57,12 +65,16 @@ namespace opts {
cl::desc("Alias for --file-headers"),
cl::aliasopt(FileHeaders));
- // -sections, -s
+ // -sections, -s, -S
+ // Note: In GNU readelf, -s means --symbols!
cl::opt<bool> Sections("sections",
cl::desc("Display all sections."));
cl::alias SectionsShort("s",
cl::desc("Alias for --sections"),
cl::aliasopt(Sections));
+ cl::alias SectionsShortUpper("S",
+ cl::desc("Alias for --sections"),
+ cl::aliasopt(Sections));
// -section-relocations, -sr
cl::opt<bool> SectionRelocations("section-relocations",
@@ -186,9 +198,10 @@ namespace opts {
cl::opt<bool> MipsOptions("mips-options",
cl::desc("Display the MIPS .MIPS.options section"));
- // -amdgpu-runtime-metadata
- cl::opt<bool> AMDGPURuntimeMD("amdgpu-runtime-metadata",
- cl::desc("Display AMDGPU runtime metadata"));
+ // -amdgpu-code-object-metadata
+ cl::opt<bool> AMDGPUCodeObjectMetadata(
+ "amdgpu-code-object-metadata",
+ cl::desc("Display AMDGPU code object metadata"));
// -coff-imports
cl::opt<bool>
@@ -213,6 +226,15 @@ namespace opts {
COFFDebugDirectory("coff-debug-directory",
cl::desc("Display the PE/COFF debug directory"));
+ // -coff-resources
+ cl::opt<bool> COFFResources("coff-resources",
+ cl::desc("Display the PE/COFF .rsrc section"));
+
+ // -coff-load-config
+ cl::opt<bool>
+ COFFLoadConfig("coff-load-config",
+ cl::desc("Display the PE/COFF load config"));
+
// -macho-data-in-code
cl::opt<bool>
MachODataInCode("macho-data-in-code",
@@ -306,13 +328,6 @@ static void reportError(StringRef Input, std::error_code EC) {
reportError(Twine(Input) + ": " + EC.message());
}
-static void reportError(StringRef Input, StringRef Message) {
- if (Input == "-")
- Input = "<stdin>";
-
- reportError(Twine(Input) + ": " + Message);
-}
-
static void reportError(StringRef Input, Error Err) {
if (Input == "-")
Input = "<stdin>";
@@ -337,10 +352,12 @@ static bool isMipsArch(unsigned Arch) {
}
namespace {
struct ReadObjTypeTableBuilder {
- ReadObjTypeTableBuilder() : Allocator(), Builder(Allocator) {}
+ ReadObjTypeTableBuilder()
+ : Allocator(), IDTable(Allocator), TypeTable(Allocator) {}
llvm::BumpPtrAllocator Allocator;
- llvm::codeview::TypeTableBuilder Builder;
+ llvm::codeview::TypeTableBuilder IDTable;
+ llvm::codeview::TypeTableBuilder TypeTable;
};
}
static ReadObjTypeTableBuilder CVTypes;
@@ -358,6 +375,8 @@ static std::error_code createDumper(const ObjectFile *Obj,
return createELFDumper(Obj, Writer, Result);
if (Obj->isMachO())
return createMachODumper(Obj, Writer, Result);
+ if (Obj->isWasm())
+ return createWasmDumper(Obj, Writer, Result);
return readobj_error::unsupported_obj_file_format;
}
@@ -420,8 +439,8 @@ static void dumpObject(const ObjectFile *Obj) {
Dumper->printMipsOptions();
}
if (Obj->getArch() == llvm::Triple::amdgcn)
- if (opts::AMDGPURuntimeMD)
- Dumper->printAMDGPURuntimeMD();
+ if (opts::AMDGPUCodeObjectMetadata)
+ Dumper->printAMDGPUCodeObjectMetadata();
if (opts::SectionGroups)
Dumper->printGroupSections();
if (opts::HashHistogram)
@@ -440,10 +459,14 @@ static void dumpObject(const ObjectFile *Obj) {
Dumper->printCOFFBaseReloc();
if (opts::COFFDebugDirectory)
Dumper->printCOFFDebugDirectory();
+ if (opts::COFFResources)
+ Dumper->printCOFFResources();
+ if (opts::COFFLoadConfig)
+ Dumper->printCOFFLoadConfig();
if (opts::CodeView)
Dumper->printCodeViewDebugInfo();
if (opts::CodeViewMergedTypes)
- Dumper->mergeCodeViewTypes(CVTypes.Builder);
+ Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable);
}
if (Obj->isMachO()) {
if (opts::MachODataInCode)
@@ -470,11 +493,7 @@ static void dumpArchive(const Archive *Arc) {
Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(ChildOrErr.takeError(), OS, "");
- OS.flush();
- reportError(Arc->getFileName(), Buf);
+ reportError(Arc->getFileName(), ChildOrErr.takeError());
}
continue;
}
@@ -496,11 +515,7 @@ static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary) {
if (ObjOrErr)
dumpObject(&*ObjOrErr.get());
else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(ObjOrErr.takeError(), OS, "");
- OS.flush();
- reportError(UBinary->getFileName(), Buf);
+ reportError(UBinary->getFileName(), ObjOrErr.takeError());
}
else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
dumpArchive(&*AOrErr.get());
@@ -513,7 +528,7 @@ static void dumpInput(StringRef File) {
// Attempt to open the binary.
Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
if (!BinaryOrErr)
- reportError(File, errorToErrorCode(BinaryOrErr.takeError()));
+ reportError(File, BinaryOrErr.takeError());
Binary &Binary = *BinaryOrErr.get().getBinary();
if (Archive *Arc = dyn_cast<Archive>(&Binary))
@@ -530,13 +545,19 @@ static void dumpInput(StringRef File) {
}
int main(int argc, const char *argv[]) {
- sys::PrintStackTraceOnErrorSignal(argv[0]);
+ StringRef ToolName = argv[0];
+ sys::PrintStackTraceOnErrorSignal(ToolName);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y;
// Register the target printer for --version.
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
+ opts::WideOutput.setHiddenFlag(cl::Hidden);
+
+ if (sys::path::stem(ToolName).find("readelf") != StringRef::npos)
+ opts::Output = opts::GNU;
+
cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n");
// Default to stdin if no filename is specified.
@@ -548,7 +569,7 @@ int main(int argc, const char *argv[]) {
if (opts::CodeViewMergedTypes) {
ScopedPrinter W(outs());
- dumpCodeViewMergedTypes(W, CVTypes.Builder);
+ dumpCodeViewMergedTypes(W, CVTypes.IDTable, CVTypes.TypeTable);
}
return 0;
diff --git a/contrib/llvm/tools/llvm-readobj/llvm-readobj.h b/contrib/llvm/tools/llvm-readobj/llvm-readobj.h
index 0156920..840ddba 100644
--- a/contrib/llvm/tools/llvm-readobj/llvm-readobj.h
+++ b/contrib/llvm/tools/llvm-readobj/llvm-readobj.h
@@ -25,6 +25,11 @@ namespace llvm {
LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg);
void error(std::error_code EC);
void error(llvm::Error EC);
+ template <typename T> T error(llvm::Expected<T> &&E) {
+ error(E.takeError());
+ return std::move(*E);
+ }
+
template <class T> T unwrapOrError(ErrorOr<T> EO) {
if (EO)
return *EO;
OpenPOWER on IntegriCloud