diff options
Diffstat (limited to 'tools')
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 |