summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/llvm-ar/CMakeLists.txt2
-rw-r--r--tools/llvm-ar/llvm-ar.cpp6
-rw-r--r--tools/llvm-mt/CMakeLists.txt13
-rw-r--r--tools/llvm-mt/LLVMBuild.txt22
-rw-r--r--tools/llvm-mt/Opts.td29
-rw-r--r--tools/llvm-mt/llvm-mt.cpp117
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp5
-rw-r--r--tools/llvm-pdbutil/DumpOutputStyle.cpp4
-rw-r--r--tools/llvm-pdbutil/MinimalSymbolDumper.cpp5
-rw-r--r--tools/llvm-pdbutil/MinimalTypeDumper.cpp20
-rw-r--r--tools/llvm-pdbutil/MinimalTypeDumper.h4
-rw-r--r--tools/llvm-pdbutil/PdbYaml.cpp35
-rw-r--r--tools/llvm-pdbutil/PdbYaml.h2
-rw-r--r--tools/llvm-pdbutil/llvm-pdbutil.cpp4
-rw-r--r--tools/llvm-readobj/CMakeLists.txt2
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp3
-rw-r--r--tools/llvm-readobj/ELFDumper.cpp14
-rw-r--r--tools/llvm-readobj/llvm-readobj.cpp22
-rwxr-xr-xtools/opt-viewer/opt-diff.py27
-rwxr-xr-xtools/opt-viewer/opt-stats.py14
-rwxr-xr-xtools/opt-viewer/opt-viewer.py14
-rw-r--r--tools/opt-viewer/optpmap.py1
-rw-r--r--tools/opt-viewer/optrecord.py20
23 files changed, 306 insertions, 79 deletions
diff --git a/tools/llvm-ar/CMakeLists.txt b/tools/llvm-ar/CMakeLists.txt
index 3bb0c8f7b7c55..731bcbd8ac9d7 100644
--- a/tools/llvm-ar/CMakeLists.txt
+++ b/tools/llvm-ar/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
Core
+ DlltoolDriver
LibDriver
Object
Support
@@ -15,3 +16,4 @@ add_llvm_tool(llvm-ar
add_llvm_tool_symlink(llvm-ranlib llvm-ar)
add_llvm_tool_symlink(llvm-lib llvm-ar)
+add_llvm_tool_symlink(llvm-dlltool llvm-ar)
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
index 500507fd49668..af4d3efa52f7e 100644
--- a/tools/llvm-ar/llvm-ar.cpp
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h"
#include "llvm/ToolDrivers/llvm-lib/LibDriver.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"
@@ -863,6 +864,9 @@ int main(int argc, char **argv) {
llvm::InitializeAllAsmParsers();
StringRef Stem = sys::path::stem(ToolName);
+ if (Stem.find("dlltool") != StringRef::npos)
+ return dlltoolDriverMain(makeArrayRef(argv, argc));
+
if (Stem.find("ranlib") == StringRef::npos &&
Stem.find("lib") != StringRef::npos)
return libDriverMain(makeArrayRef(argv, argc));
@@ -878,5 +882,5 @@ int main(int argc, char **argv) {
return ranlib_main();
if (Stem.find("ar") != StringRef::npos)
return ar_main();
- fail("Not ranlib, ar or lib!");
+ fail("Not ranlib, ar, lib or dlltool!");
}
diff --git a/tools/llvm-mt/CMakeLists.txt b/tools/llvm-mt/CMakeLists.txt
new file mode 100644
index 0000000000000..d97cc4fe446fa
--- /dev/null
+++ b/tools/llvm-mt/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(LLVM_LINK_COMPONENTS
+ Option
+ Support
+ )
+
+set(LLVM_TARGET_DEFINITIONS Opts.td)
+
+tablegen(LLVM Opts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(MtTableGen)
+
+add_llvm_tool(llvm-mt
+ llvm-mt.cpp
+ )
diff --git a/tools/llvm-mt/LLVMBuild.txt b/tools/llvm-mt/LLVMBuild.txt
new file mode 100644
index 0000000000000..894d3527924ba
--- /dev/null
+++ b/tools/llvm-mt/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-mt/LLVMBuild.txt ---------------------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Tool
+name = llvm-mt
+parent = Tools
+required_libraries = Option Support
diff --git a/tools/llvm-mt/Opts.td b/tools/llvm-mt/Opts.td
new file mode 100644
index 0000000000000..6dc3eea524e64
--- /dev/null
+++ b/tools/llvm-mt/Opts.td
@@ -0,0 +1,29 @@
+include "llvm/Option/OptParser.td"
+
+def unsupported : OptionGroup<"unsupported">;
+def manifest : Separate<["/", "-"], "manifest">, HelpText<"Used to specify each manifest that need to be processed">, MetaVarName<"manifest">;
+def identity : Joined<["/", "-"], "identity:">, HelpText<"Not supported">, MetaVarName<"identity">, Group<unsupported>;
+def rgs : Joined<["/", "-"], "rgs:">, HelpText<"Not supported">, MetaVarName<"script">, Group<unsupported>;
+def tlb : Joined<["/", "-"], "tlb:">, HelpText<"Not supported">, MetaVarName<"file">, Group<unsupported>;
+def dll : Joined<["/", "-"], "dll:">, HelpText<"Not supported">, MetaVarName<"dll">, Group<unsupported>;
+def replacements : Joined<["/", "-"], "replacements:">, HelpText<"Not supported">, MetaVarName<"file">, Group<unsupported>;
+def managed_assembly_name : Joined<["/", "-"], "managedassemblyname:">, HelpText<"Not supported">, MetaVarName<"assembly">, Group<unsupported>;
+def no_dependency : Flag<["/", "-"], "nodependency">, HelpText<"Not supported">, Group<unsupported>;
+def category : Flag<["/", "-"], "category">, HelpText<"Not supported">, Group<unsupported>;
+def no_logo : Flag<["/", "-"], "nologo">, HelpText<"No effect as this tool never writes copyright data. Included for parity">;
+def out : Joined<["/", "-"], "out:">, HelpText<"Name of the output manifest. If this is skipped and only one manifest is being operated upon by the tool, that manifest is modified in place">, MetaVarName<"manifest">;
+def input_resource : Joined<["/", "-"], "inputresource:">, HelpText<"Not supported">, MetaVarName<"file">, Group<unsupported>;
+def output_resource : Joined<["/", "-"], "outputresource:">, HelpText<"Not supported">, MetaVarName<"file">, Group<unsupported>;
+def output_resource_flag : Flag<["/", "-"], "outputresource">, Alias<output_resource>, HelpText<"Not supported">, Group<unsupported>;
+def update_resource : Joined<["/", "-"], "updateresource:">, HelpText<"Not supported">, MetaVarName<"file">, Group<unsupported>;
+def hash_update : Joined<["/", "-"], "hashupdate:">, HelpText<"Not supported">, MetaVarName<"file">, Group<unsupported>;
+def hash_update_flag : Flag<["/", "-"], "hashupdate">, Alias<hash_update>, HelpText<"Not supported">, Group<unsupported>;
+def validate_manifest : Flag<["/", "-"], "validate_manifest">, HelpText<"Not supported">, Group<unsupported>;
+def validate_file_hashes : Joined<["/", "-"], "validate_file_hashes:">, HelpText<"Not supported">, MetaVarName<"">, Group<unsupported>;
+def canonicalize : Flag<["/", "-"], "canonicalize:">, HelpText<"Not supported">, Group<unsupported>;
+def check_for_duplicates : Flag<["/", "-"], "check_for_duplicates:">, HelpText<"Not supported">, Group<unsupported>;
+def make_cdfs : Flag<["/", "-"], "makecdfs:">, HelpText<"Not supported">, Group<unsupported>;
+def verbose : Flag<["/", "-"], "verbose">, HelpText<"Not supported">, Group<unsupported>;
+def help : Flag<["/", "-"], "?">;
+def help_long : Flag<["/", "-"], "help">, Alias<help>;
+def h : Flag<["/", "-"], "h">, Alias<help>;
diff --git a/tools/llvm-mt/llvm-mt.cpp b/tools/llvm-mt/llvm-mt.cpp
new file mode 100644
index 0000000000000..05c9238c7c645
--- /dev/null
+++ b/tools/llvm-mt/llvm-mt.cpp
@@ -0,0 +1,117 @@
+//===- llvm-mt.cpp - Merge .manifest files ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+//
+// Merge .manifest files. This is intended to be a platform-independent port
+// of Microsoft's mt.exe.
+//
+//===---------------------------------------------------------------------===//
+
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <system_error>
+
+using namespace llvm;
+
+namespace {
+
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "Opts.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "Opts.inc"
+#undef PREFIX
+
+static const opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+{ \
+ PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "Opts.inc"
+#undef OPTION
+};
+
+class CvtResOptTable : public opt::OptTable {
+public:
+ CvtResOptTable() : OptTable(InfoTable, true) {}
+};
+
+static ExitOnError ExitOnErr;
+} // namespace
+
+LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
+ errs() << "llvm-mt error: " << Msg << "\n";
+ exit(1);
+}
+
+int main(int argc, const char **argv) {
+ sys::PrintStackTraceOnErrorSignal(argv[0]);
+ PrettyStackTraceProgram X(argc, argv);
+
+ ExitOnErr.setBanner("llvm-mt: ");
+
+ SmallVector<const char *, 256> argv_buf;
+ SpecificBumpPtrAllocator<char> ArgAllocator;
+ ExitOnErr(errorCodeToError(sys::Process::GetArgumentVector(
+ argv_buf, makeArrayRef(argv, argc), ArgAllocator)));
+
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
+ CvtResOptTable T;
+ unsigned MAI, MAC;
+ ArrayRef<const char *> ArgsArr = makeArrayRef(argv + 1, argc);
+ opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC);
+
+ for (auto &Arg : InputArgs) {
+ if (Arg->getOption().matches(OPT_unsupported)) {
+ outs() << "llvm-mt: ignoring unsupported '" << Arg->getOption().getName()
+ << "' option\n";
+ }
+ }
+
+ if (InputArgs.hasArg(OPT_help)) {
+ T.PrintHelp(outs(), "mt", "Manifest Tool", false);
+ return 0;
+ }
+
+ std::vector<std::string> InputFiles = InputArgs.getAllArgValues(OPT_manifest);
+
+ if (InputFiles.size() == 0) {
+ reportError("no input file specified");
+ }
+
+ StringRef OutputFile;
+
+ if (InputArgs.hasArg(OPT_out)) {
+ OutputFile = InputArgs.getLastArgValue(OPT_out);
+ } else if (InputFiles.size() == 1) {
+ OutputFile = InputFiles[0];
+ } else {
+ reportError("no output file specified");
+ }
+
+ return 0;
+}
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 812f1af3ac680..d54b45515f05f 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -870,7 +870,10 @@ static void printRelocationTargetName(const MachOObjectFile *O,
bool isExtern = O->getPlainRelocationExternal(RE);
uint64_t Val = O->getPlainRelocationSymbolNum(RE);
- if (isExtern) {
+ if (O->getAnyRelocationType(RE) == MachO::ARM64_RELOC_ADDEND) {
+ fmt << format("0x%x", Val);
+ return;
+ } else if (isExtern) {
symbol_iterator SI = O->symbol_begin();
advance(SI, Val);
Expected<StringRef> SOrErr = SI->getName();
diff --git a/tools/llvm-pdbutil/DumpOutputStyle.cpp b/tools/llvm-pdbutil/DumpOutputStyle.cpp
index 0642d841fd9f2..01c7481c30865 100644
--- a/tools/llvm-pdbutil/DumpOutputStyle.cpp
+++ b/tools/llvm-pdbutil/DumpOutputStyle.cpp
@@ -654,7 +654,7 @@ static void dumpFullTypeStream(LinePrinter &Printer,
NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
- Stream.getHashValues());
+ Stream.getNumHashBuckets(), Stream.getHashValues());
if (auto EC = codeview::visitTypeStream(Types, V)) {
Printer.formatLine("An error occurred dumping type records: {0}",
@@ -670,7 +670,7 @@ static void dumpPartialTypeStream(LinePrinter &Printer,
NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
- Stream.getHashValues());
+ Stream.getNumHashBuckets(), Stream.getHashValues());
if (opts::dump::DumpTypeDependents) {
// If we need to dump all dependents, then iterate each index and find
diff --git a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
index ab7045ca44923..d93843649db00 100644
--- a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
+++ b/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
@@ -725,8 +725,9 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
Proc.Parent, Proc.End,
formatSegmentOffset(Proc.Segment, Proc.CodeOffset),
Proc.CodeSize);
- P.formatLine("debug start = {0}, debug end = {1}, flags = {2}", Proc.DbgStart,
- Proc.DbgEnd,
+ // FIXME: It seems FunctionType is sometimes an id and sometimes a type.
+ P.formatLine("type = `{0}`, debug start = {1}, debug end = {2}, flags = {3}",
+ typeIndex(Proc.FunctionType), Proc.DbgStart, Proc.DbgEnd,
formatProcSymFlags(P.getIndentLevel() + 9, Proc.Flags));
return Error::success();
}
diff --git a/tools/llvm-pdbutil/MinimalTypeDumper.cpp b/tools/llvm-pdbutil/MinimalTypeDumper.cpp
index 9621320ea99ad..0079b9e7eaa40 100644
--- a/tools/llvm-pdbutil/MinimalTypeDumper.cpp
+++ b/tools/llvm-pdbutil/MinimalTypeDumper.cpp
@@ -18,6 +18,7 @@
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
@@ -214,10 +215,20 @@ Error MinimalTypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
getLeafTypeName(Record.Type), Record.length());
} else {
std::string H;
- if (Index.toArrayIndex() >= HashValues.size())
+ if (Index.toArrayIndex() >= HashValues.size()) {
H = "(not present)";
- else
- H = utostr(HashValues[Index.toArrayIndex()]);
+ } else {
+ uint32_t Hash = HashValues[Index.toArrayIndex()];
+ Expected<uint32_t> MaybeHash = hashTypeRecord(Record);
+ if (!MaybeHash)
+ return MaybeHash.takeError();
+ uint32_t OurHash = *MaybeHash;
+ OurHash %= NumHashBuckets;
+ if (Hash == OurHash)
+ H = "0x" + utohexstr(Hash);
+ else
+ H = "0x" + utohexstr(Hash) + ", our hash = 0x" + utohexstr(OurHash);
+ }
P.formatLine("{0} | {1} [size = {2}, hash = {3}]",
fmt_align(Index, AlignStyle::Right, Width),
getLeafTypeName(Record.Type), Record.length(), H);
@@ -395,8 +406,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
TypeServer2Record &TS) {
- P.formatLine("name = {0}, age = {1}, guid = {2}", TS.Name, TS.Age,
- fmt_guid(TS.Guid));
+ P.formatLine("name = {0}, age = {1}, guid = {2}", TS.Name, TS.Age, TS.Guid);
return Error::success();
}
diff --git a/tools/llvm-pdbutil/MinimalTypeDumper.h b/tools/llvm-pdbutil/MinimalTypeDumper.h
index 42882b4b40600..4227688f0f71d 100644
--- a/tools/llvm-pdbutil/MinimalTypeDumper.h
+++ b/tools/llvm-pdbutil/MinimalTypeDumper.h
@@ -25,9 +25,10 @@ class MinimalTypeDumpVisitor : public codeview::TypeVisitorCallbacks {
public:
MinimalTypeDumpVisitor(LinePrinter &P, uint32_t Width, bool RecordBytes,
bool Hashes, codeview::LazyRandomTypeCollection &Types,
+ uint32_t NumHashBuckets,
FixedStreamArray<support::ulittle32_t> HashValues)
: P(P), Width(Width), RecordBytes(RecordBytes), Hashes(Hashes),
- Types(Types), HashValues(HashValues) {}
+ Types(Types), NumHashBuckets(NumHashBuckets), HashValues(HashValues) {}
Error visitTypeBegin(codeview::CVType &Record,
codeview::TypeIndex Index) override;
@@ -53,6 +54,7 @@ private:
bool RecordBytes = false;
bool Hashes = false;
codeview::LazyRandomTypeCollection &Types;
+ uint32_t NumHashBuckets;
FixedStreamArray<support::ulittle32_t> HashValues;
};
} // namespace pdb
diff --git a/tools/llvm-pdbutil/PdbYaml.cpp b/tools/llvm-pdbutil/PdbYaml.cpp
index 315ae2e6711f1..9c3beb566d2c2 100644
--- a/tools/llvm-pdbutil/PdbYaml.cpp
+++ b/tools/llvm-pdbutil/PdbYaml.cpp
@@ -38,41 +38,6 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::pdb::PdbRaw_FeatureSig)
namespace llvm {
namespace yaml {
-template <> struct ScalarTraits<llvm::pdb::PDB_UniqueId> {
- static void output(const llvm::pdb::PDB_UniqueId &S, void *,
- llvm::raw_ostream &OS) {
- OS << S;
- }
-
- static StringRef input(StringRef Scalar, void *Ctx,
- llvm::pdb::PDB_UniqueId &S) {
- if (Scalar.size() != 38)
- return "GUID strings are 38 characters long";
- if (Scalar[0] != '{' || Scalar[37] != '}')
- return "GUID is not enclosed in {}";
- if (Scalar[9] != '-' || Scalar[14] != '-' || Scalar[19] != '-' ||
- Scalar[24] != '-')
- return "GUID sections are not properly delineated with dashes";
-
- uint8_t *OutBuffer = S.Guid;
- for (auto Iter = Scalar.begin(); Iter != Scalar.end();) {
- if (*Iter == '-' || *Iter == '{' || *Iter == '}') {
- ++Iter;
- continue;
- }
- uint8_t Value = (llvm::hexDigitValue(*Iter) << 4);
- ++Iter;
- Value |= llvm::hexDigitValue(*Iter);
- ++Iter;
- *OutBuffer++ = Value;
- }
-
- return "";
- }
-
- static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
-};
-
template <> struct ScalarEnumerationTraits<llvm::pdb::PDB_Machine> {
static void enumeration(IO &io, llvm::pdb::PDB_Machine &Value) {
io.enumCase(Value, "Invalid", PDB_Machine::Invalid);
diff --git a/tools/llvm-pdbutil/PdbYaml.h b/tools/llvm-pdbutil/PdbYaml.h
index 62ed608916fce..91e054490a5f6 100644
--- a/tools/llvm-pdbutil/PdbYaml.h
+++ b/tools/llvm-pdbutil/PdbYaml.h
@@ -57,7 +57,7 @@ struct PdbInfoStream {
PdbRaw_ImplVer Version = PdbImplVC70;
uint32_t Signature = 0;
uint32_t Age = 1;
- PDB_UniqueId Guid;
+ codeview::GUID Guid;
std::vector<PdbRaw_FeatureSig> Features;
std::vector<NamedStreamMapping> NamedStreams;
};
diff --git a/tools/llvm-pdbutil/llvm-pdbutil.cpp b/tools/llvm-pdbutil/llvm-pdbutil.cpp
index 6aa08ff3cd872..f2bd194622ed7 100644
--- a/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -956,8 +956,8 @@ static void mergePdbs() {
SmallVector<TypeIndex, 128> IdMap;
if (File.hasPDBTpiStream()) {
auto &Tpi = ExitOnErr(File.getPDBTpiStream());
- ExitOnErr(codeview::mergeTypeRecords(MergedTpi, TypeMap, nullptr,
- Tpi.typeArray()));
+ ExitOnErr(
+ codeview::mergeTypeRecords(MergedTpi, TypeMap, Tpi.typeArray()));
}
if (File.hasPDBIpiStream()) {
auto &Ipi = ExitOnErr(File.getPDBIpiStream());
diff --git a/tools/llvm-readobj/CMakeLists.txt b/tools/llvm-readobj/CMakeLists.txt
index bde486a5f0db2..f5b1a5b256add 100644
--- a/tools/llvm-readobj/CMakeLists.txt
+++ b/tools/llvm-readobj/CMakeLists.txt
@@ -20,3 +20,5 @@ add_llvm_tool(llvm-readobj
WasmDumper.cpp
Win64EHDumper.cpp
)
+
+add_llvm_tool_symlink(llvm-readelf llvm-readobj)
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index 9fb3267e2f9d3..74c44116b1270 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -1215,8 +1215,7 @@ void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVIDs,
error(object_error::parse_failed);
}
SmallVector<TypeIndex, 128> SourceToDest;
- if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, nullptr,
- Types))
+ if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, Types))
return error(std::move(EC));
}
}
diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp
index a1db96cba081d..5698420bbcc23 100644
--- a/tools/llvm-readobj/ELFDumper.cpp
+++ b/tools/llvm-readobj/ELFDumper.cpp
@@ -1532,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";
}
}
@@ -1624,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();
@@ -1687,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:
diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp
index 51991a3f067ba..7bfb18fab12b6 100644
--- a/tools/llvm-readobj/llvm-readobj.cpp
+++ b/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",
@@ -533,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.
diff --git a/tools/opt-viewer/opt-diff.py b/tools/opt-viewer/opt-diff.py
index 9e921f8488d36..f39432c8bc9dd 100755
--- a/tools/opt-viewer/opt-diff.py
+++ b/tools/opt-viewer/opt-diff.py
@@ -20,24 +20,17 @@ import optrecord
import argparse
from collections import defaultdict
from multiprocessing import cpu_count, Pool
-import os, os.path
-import fnmatch
-
-def find_files(dir_or_file):
- if os.path.isfile(dir_or_file):
- return [dir_or_file]
-
- all = []
- for dir, subdirs, files in os.walk(dir_or_file):
- for file in files:
- if fnmatch.fnmatch(file, "*.opt.yaml"):
- all.append( os.path.join(dir, file))
- return all
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=desc)
- parser.add_argument('yaml_dir_or_file_1')
- parser.add_argument('yaml_dir_or_file_2')
+ parser.add_argument(
+ 'yaml_dir_or_file_1',
+ help='An optimization record file or a directory searched for optimization '
+ 'record files that are used as the old version for the comparison')
+ parser.add_argument(
+ 'yaml_dir_or_file_2',
+ help='An optimization record file or a directory searched for optimization '
+ 'record files that are used as the new version for the comparison')
parser.add_argument(
'--jobs',
'-j',
@@ -53,8 +46,8 @@ if __name__ == '__main__':
parser.add_argument('--output', '-o', default='diff.opt.yaml')
args = parser.parse_args()
- files1 = find_files(args.yaml_dir_or_file_1)
- files2 = find_files(args.yaml_dir_or_file_2)
+ files1 = optrecord.find_opt_files([args.yaml_dir_or_file_1])
+ files2 = optrecord.find_opt_files([args.yaml_dir_or_file_2])
print_progress = not args.no_progress_indicator
all_remarks1, _, _ = optrecord.gather_results(files1, args.jobs, print_progress)
diff --git a/tools/opt-viewer/opt-stats.py b/tools/opt-viewer/opt-stats.py
index a7e598fdfd026..205b08ba8a746 100755
--- a/tools/opt-viewer/opt-stats.py
+++ b/tools/opt-viewer/opt-stats.py
@@ -15,7 +15,11 @@ from multiprocessing import cpu_count, Pool
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=desc)
- parser.add_argument('yaml_files', nargs='+')
+ parser.add_argument(
+ 'yaml_dirs_or_files',
+ nargs='+',
+ help='List of optimization record files or directories searched '
+ 'for optimization record files.')
parser.add_argument(
'--jobs',
'-j',
@@ -31,8 +35,14 @@ if __name__ == '__main__':
args = parser.parse_args()
print_progress = not args.no_progress_indicator
+
+ files = optrecord.find_opt_files(args.yaml_dirs_or_files)
+ if not files:
+ parser.error("No *.opt.yaml files found")
+ sys.exit(1)
+
all_remarks, file_remarks, _ = optrecord.gather_results(
- args.yaml_files, args.jobs, print_progress)
+ files, args.jobs, print_progress)
if print_progress:
print('\n')
diff --git a/tools/opt-viewer/opt-viewer.py b/tools/opt-viewer/opt-viewer.py
index e6dd6a0286fe7..69bcaedb7669a 100755
--- a/tools/opt-viewer/opt-viewer.py
+++ b/tools/opt-viewer/opt-viewer.py
@@ -219,7 +219,11 @@ def generate_report(all_remarks,
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=desc)
- parser.add_argument('yaml_files', nargs='+')
+ parser.add_argument(
+ 'yaml_dirs_or_files',
+ nargs='+',
+ help='List of optimization record files or directories searched '
+ 'for optimization record files.')
parser.add_argument(
'--output-dir',
'-o',
@@ -248,8 +252,14 @@ if __name__ == '__main__':
args = parser.parse_args()
print_progress = not args.no_progress_indicator
+
+ files = optrecord.find_opt_files(args.yaml_dirs_or_files)
+ if not files:
+ parser.error("No *.opt.yaml files found")
+ sys.exit(1)
+
all_remarks, file_remarks, should_display_hotness = \
- optrecord.gather_results(args.yaml_files, args.jobs, print_progress)
+ optrecord.gather_results(files, args.jobs, print_progress)
map_remarks(all_remarks)
diff --git a/tools/opt-viewer/optpmap.py b/tools/opt-viewer/optpmap.py
index 01e848e03976d..16cb22e214912 100644
--- a/tools/opt-viewer/optpmap.py
+++ b/tools/opt-viewer/optpmap.py
@@ -20,6 +20,7 @@ def _wrapped_func(func_and_args):
with _current.get_lock():
_current.value += 1
sys.stdout.write('\r\t{} of {}'.format(_current.value, _total.value))
+ sys.stdout.flush()
return func(argument)
diff --git a/tools/opt-viewer/optrecord.py b/tools/opt-viewer/optrecord.py
index 61ed9626cffad..4599e12d7e688 100644
--- a/tools/opt-viewer/optrecord.py
+++ b/tools/opt-viewer/optrecord.py
@@ -12,8 +12,10 @@ except ImportError:
import cgi
from collections import defaultdict
+import fnmatch
import functools
from multiprocessing import Lock
+import os, os.path
import subprocess
import optpmap
@@ -47,7 +49,7 @@ def demangle(name):
def html_file_name(filename):
- return filename.replace('/', '_') + ".html"
+ return filename.replace('/', '_').replace('#', '_') + ".html"
def make_link(File, Line):
@@ -233,3 +235,19 @@ def gather_results(filenames, num_jobs, should_print_progress):
all_remarks.update(all_remarks_job)
return all_remarks, file_remarks, max_hotness != 0
+
+
+def find_opt_files(dirs_or_files):
+ all = []
+ for dir_or_file in dirs_or_files:
+ if os.path.isfile(dir_or_file):
+ all.append(dir_or_file)
+ else:
+ for dir, subdirs, files in os.walk(dir_or_file):
+ # Exclude mounted directories and symlinks (os.walk default).
+ subdirs[:] = [d for d in subdirs
+ if not os.path.ismount(os.path.join(dir, d))]
+ for file in files:
+ if fnmatch.fnmatch(file, "*.opt.yaml"):
+ all.append(os.path.join(dir, file))
+ return all