diff --git a/llvm/test/tools/llvm-readobj/check-output-order.test b/llvm/test/tools/llvm-readobj/check-output-order.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/check-output-order.test @@ -0,0 +1,45 @@ +## This test checks that `--all --needed-libs` output is the same as the +## printing order in code. One common reason the output could become +## out-of-order is when more than one stream are printing at the same time. +## https://bugs.llvm.org/show_bug.cgi?id=42140 + +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --all --needed-libs %t | FileCheck %s + +# CHECK: ELF Header +# CHECK: Section header string table index +# CHECK: There are 5 section headers, starting at offset +# CHECK: Section Headers: +# CHECK: O (extra OS processing required) o (OS specific), p (processor specific) +# CHECK: There are no relocations in this file. +# CHECK: Symbol table '.symtab' contains 1 entries +# CHECK: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +# CHECK: Dynamic section at offset +# CHECK: 0x0000000000000000 (NULL) 0x0 +# CHECK: NeededLibraries [ +# CHECK: ] +# CHECK: Elf file type is DYN (Shared object file) +# CHECK: Entry point 0x0 +# CHECK: There are 1 program headers, starting at offset 64 +# CHECK: DYNAMIC +# CHECK: Section to Segment mapping: +# CHECK: None .symtab .strtab .shstrtab +# CHECK: There are no section groups in this file. + + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynamic + Type: SHT_DYNAMIC + Entries: + - Tag: DT_NULL + Value: 0 +ProgramHeaders: + - Type: PT_DYNAMIC + Sections: + - Section: .dynamic diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -1565,7 +1565,7 @@ llvm::stable_sort(Libs); for (const auto &L : Libs) { - outs() << " " << L << "\n"; + W.startLine() << L << "\n"; } } diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -382,13 +382,16 @@ }; template class GNUStyle : public DumpStyle { - formatted_raw_ostream OS; + formatted_raw_ostream &OS; public: TYPEDEF_ELF_TYPES(ELFT) GNUStyle(ScopedPrinter &W, ELFDumper *Dumper) - : DumpStyle(Dumper), OS(W.getOStream()) {} + : DumpStyle(Dumper), + OS(static_cast(W.getOStream())) { + assert (&W.getOStream() == &llvm::fouts()); + } void printFileHeaders(const ELFO *Obj) override; void printGroupSections(const ELFFile *Obj) override; diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp --- a/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/llvm/tools/llvm-readobj/MachODumper.cpp @@ -689,7 +689,7 @@ llvm::stable_sort(Libs); for (const auto &L : Libs) { - outs() << " " << L << "\n"; + W.startLine() << L << "\n"; } } diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -609,8 +609,8 @@ } /// Dumps \a WinRes, Windows Resource (.res) file; -static void dumpWindowsResourceFile(WindowsResource *WinRes) { - ScopedPrinter Printer{outs()}; +static void dumpWindowsResourceFile(WindowsResource *WinRes, + ScopedPrinter &Printer) { WindowsRes::Dumper Dumper(WinRes, Printer); if (auto Err = Dumper.printData()) reportError(WinRes->getFileName(), std::move(Err)); @@ -618,9 +618,7 @@ /// Opens \a File and dumps it. -static void dumpInput(StringRef File) { - ScopedPrinter Writer(outs()); - +static void dumpInput(StringRef File, ScopedPrinter &Writer) { // Attempt to open the binary. Expected> BinaryOrErr = createBinary(File); if (!BinaryOrErr) @@ -637,7 +635,7 @@ else if (COFFImportFile *Import = dyn_cast(&Binary)) dumpCOFFImportFile(Import, Writer); else if (WindowsResource *WinRes = dyn_cast(&Binary)) - dumpWindowsResourceFile(WinRes); + dumpWindowsResourceFile(WinRes, Writer); else reportError(File, readobj_error::unrecognized_file_format); @@ -727,15 +725,16 @@ if (opts::InputFilenames.empty()) opts::InputFilenames.push_back("-"); - llvm::for_each(opts::InputFilenames, dumpInput); + ScopedPrinter Writer(fouts()); + for (const std::string &I : opts::InputFilenames) + dumpInput(I, Writer); if (opts::CodeViewMergedTypes) { - ScopedPrinter W(outs()); if (opts::CodeViewEnableGHash) - dumpCodeViewMergedTypes(W, CVTypes.GlobalIDTable.records(), + dumpCodeViewMergedTypes(Writer, CVTypes.GlobalIDTable.records(), CVTypes.GlobalTypeTable.records()); else - dumpCodeViewMergedTypes(W, CVTypes.IDTable.records(), + dumpCodeViewMergedTypes(Writer, CVTypes.IDTable.records(), CVTypes.TypeTable.records()); }