[llvm] cfec208 - [obj2yaml] Add -o to specify output filename

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 14 00:32:58 PDT 2022


Author: Fangrui Song
Date: 2022-07-14T00:32:48-07:00
New Revision: cfec2080b7a6ffb023044219630bcb44a1dad14b

URL: https://github.com/llvm/llvm-project/commit/cfec2080b7a6ffb023044219630bcb44a1dad14b
DIFF: https://github.com/llvm/llvm-project/commit/cfec2080b7a6ffb023044219630bcb44a1dad14b.diff

LOG: [obj2yaml] Add -o to specify output filename

-o is very common among tools. yaml2obj supports -o and it surprised me that
obj2yaml doesn't support -o. Just add it which doesn't take much code.

Differential Revision: https://reviews.llvm.org/D129713

Added: 
    llvm/test/tools/obj2yaml/output-file.yaml

Modified: 
    llvm/test/ObjectYAML/Offload/default.yaml
    llvm/test/ObjectYAML/wasm/header.yaml
    llvm/test/tools/obj2yaml/Archives/regular.yaml
    llvm/test/tools/obj2yaml/COFF/test-1.test
    llvm/test/tools/obj2yaml/DXContainer/DXILPart.yaml
    llvm/test/tools/obj2yaml/Minidump/basic.yaml
    llvm/test/tools/obj2yaml/XCOFF/aix.yaml
    llvm/tools/obj2yaml/obj2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/ObjectYAML/Offload/default.yaml b/llvm/test/ObjectYAML/Offload/default.yaml
index 7b147b8526457..ac8e89e6d0457 100644
--- a/llvm/test/ObjectYAML/Offload/default.yaml
+++ b/llvm/test/ObjectYAML/Offload/default.yaml
@@ -1,4 +1,8 @@
-# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t > %t.stdout.yaml
+# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
+# RUN: FileCheck --input-file=%t.stdout.yaml %s
+# RUN: 
diff  %t.stdout.yaml %t.file.yaml
 !Offload
 Members:
   - 

diff  --git a/llvm/test/ObjectYAML/wasm/header.yaml b/llvm/test/ObjectYAML/wasm/header.yaml
index a182d3e797ce4..7cfd6a9d0fed7 100644
--- a/llvm/test/ObjectYAML/wasm/header.yaml
+++ b/llvm/test/ObjectYAML/wasm/header.yaml
@@ -1,4 +1,8 @@
-# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t > %t.stdout.yaml
+# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
+# RUN: FileCheck --input-file=%t.stdout.yaml %s
+# RUN: 
diff  %t.stdout.yaml %t.file.yaml
 --- !WASM
 FileHeader:
   Version:         0x00000001

diff  --git a/llvm/test/tools/obj2yaml/Archives/regular.yaml b/llvm/test/tools/obj2yaml/Archives/regular.yaml
index 923d99dec812c..0ad47ec410ae1 100644
--- a/llvm/test/tools/obj2yaml/Archives/regular.yaml
+++ b/llvm/test/tools/obj2yaml/Archives/regular.yaml
@@ -3,7 +3,10 @@
 ## Check how we dump an empty archive.
 
 # RUN: yaml2obj %s --docnum=1 -o %t.empty.a
-# RUN: obj2yaml %t.empty.a | FileCheck %s --check-prefix=EMPTY
+# RUN: obj2yaml %t.empty.a > %t.stdout.yaml
+# RUN: obj2yaml %t.empty.a -o %t.file.yaml 2>&1 | count 0
+# RUN: FileCheck --input-file=%t.stdout.yaml %s --check-prefix=EMPTY
+# RUN: 
diff  %t.stdout.yaml %t.file.yaml
 
 # EMPTY:      --- !Arch
 # EMPTY-NEXT: Members: []

diff  --git a/llvm/test/tools/obj2yaml/COFF/test-1.test b/llvm/test/tools/obj2yaml/COFF/test-1.test
index 0d7880b06a372..ce05b72b97d73 100755
--- a/llvm/test/tools/obj2yaml/COFF/test-1.test
+++ b/llvm/test/tools/obj2yaml/COFF/test-1.test
@@ -1,4 +1,7 @@
-# RUN: obj2yaml %S/Inputs/test-1.o | yaml2obj -o %t.o
+# RUN: obj2yaml %S/Inputs/test-1.o > %t.stdout.yaml
+# RUN: obj2yaml %S/Inputs/test-1.o -o %t.file.yaml 2>&1 | count 0
+# RUN: yaml2obj %t.stdout.yaml -o %t.o
 # RUN: llvm-pdbutil dump --types %t.o | FileCheck %s -check-prefix=ALL
+# RUN: 
diff  %t.stdout.yaml %t.file.yaml
 
 # ALL: {{.*}} guid = {00C903AB-0968-4639-84F8-7D3E719A1BE1}

diff  --git a/llvm/test/tools/obj2yaml/DXContainer/DXILPart.yaml b/llvm/test/tools/obj2yaml/DXContainer/DXILPart.yaml
index 546ebcb9cf596..4ee8c4282611b 100644
--- a/llvm/test/tools/obj2yaml/DXContainer/DXILPart.yaml
+++ b/llvm/test/tools/obj2yaml/DXContainer/DXILPart.yaml
@@ -1,4 +1,8 @@
-# RUN: yaml2obj %s | obj2yaml | FileCheck %s 
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t > %t.stdout.yaml
+# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
+# RUN: FileCheck --input-file=%t.stdout.yaml %s
+# RUN: 
diff  %t.stdout.yaml %t.file.yaml
 
 --- !dxcontainer
 Header:

diff  --git a/llvm/test/tools/obj2yaml/Minidump/basic.yaml b/llvm/test/tools/obj2yaml/Minidump/basic.yaml
index 15076604309e0..dfabc132d8e71 100644
--- a/llvm/test/tools/obj2yaml/Minidump/basic.yaml
+++ b/llvm/test/tools/obj2yaml/Minidump/basic.yaml
@@ -1,4 +1,8 @@
-# RUN: yaml2obj %s | obj2yaml - | FileCheck %s
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t > %t.stdout.yaml
+# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
+# RUN: FileCheck --input-file=%t.stdout.yaml %s
+# RUN: 
diff  %t.stdout.yaml %t.file.yaml
 
 --- !minidump
 Streams:

diff  --git a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
index f49d981aaf010..cd1e88dec11d2 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
@@ -2,7 +2,8 @@
 # RUN: yaml2obj %s -DMAGIC=0x01DF -o %t-32
 # RUN: obj2yaml %t-32 | FileCheck %s --check-prefix=CHECK32
 # RUN: yaml2obj %s -DMAGIC=0x01F7 -o %t-64
-# RUN: obj2yaml %t-64 | FileCheck %s --check-prefix=CHECK64
+# RUN: obj2yaml %t-64 -o %t-64.yaml 2>&1 | count 0
+# RUN: FileCheck --input-file %t-64.yaml %s --check-prefix=CHECK64
 
 # CHECK32:      --- !XCOFF
 # CHECK32-NEXT: FileHeader:

diff  --git a/llvm/test/tools/obj2yaml/output-file.yaml b/llvm/test/tools/obj2yaml/output-file.yaml
new file mode 100644
index 0000000000000..196999e8a324f
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/output-file.yaml
@@ -0,0 +1,23 @@
+## Test that -o sets the output file name.
+
+# RUN: yaml2obj %s -o %t
+# RUN: rm -f %t.yaml && obj2yaml %t -o %t.yaml
+# RUN: ls %t.yaml
+# RUN: rm -f %t.yaml && cat %t | obj2yaml -o%t.yaml
+# RUN: ls %t.yaml
+
+## In case of an error, don't create the output file.
+# RUN: rm -f %t.yaml
+# RUN: echo | not obj2yaml -o %t.yaml
+# RUN: not ls %t.yaml
+
+# RUN: not obj2yaml %t -o %p/path/does/not/exist 2>&1 | FileCheck -DMSG=%errc_ENOENT %s
+
+# CHECK: obj2yaml: error: failed to open '{{.*}}/path/does/not/exist': [[MSG]]
+
+!ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_NONE

diff  --git a/llvm/tools/obj2yaml/obj2yaml.cpp b/llvm/tools/obj2yaml/obj2yaml.cpp
index 4aa154a8d819c..4eec967d9fa6b 100644
--- a/llvm/tools/obj2yaml/obj2yaml.cpp
+++ b/llvm/tools/obj2yaml/obj2yaml.cpp
@@ -14,35 +14,40 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/WithColor.h"
 
 using namespace llvm;
 using namespace llvm::object;
 
 static cl::opt<std::string>
     InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
+static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"),
+                                           cl::value_desc("filename"),
+                                           cl::init("-"), cl::Prefix);
 static cl::bits<RawSegments> RawSegment(
     "raw-segment",
     cl::desc("Mach-O: dump the raw contents of the listed segments instead of "
              "parsing them:"),
     cl::values(clEnumVal(data, "__DATA"), clEnumVal(linkedit, "__LINKEDIT")));
 
-static Error dumpObject(const ObjectFile &Obj) {
+static Error dumpObject(const ObjectFile &Obj, raw_ostream &OS) {
   if (Obj.isCOFF())
-    return errorCodeToError(coff2yaml(outs(), cast<COFFObjectFile>(Obj)));
+    return errorCodeToError(coff2yaml(OS, cast<COFFObjectFile>(Obj)));
 
   if (Obj.isXCOFF())
-    return xcoff2yaml(outs(), cast<XCOFFObjectFile>(Obj));
+    return xcoff2yaml(OS, cast<XCOFFObjectFile>(Obj));
 
   if (Obj.isELF())
-    return elf2yaml(outs(), Obj);
+    return elf2yaml(OS, Obj);
 
   if (Obj.isWasm())
-    return errorCodeToError(wasm2yaml(outs(), cast<WasmObjectFile>(Obj)));
+    return errorCodeToError(wasm2yaml(OS, cast<WasmObjectFile>(Obj)));
 
   llvm_unreachable("unexpected object file format");
 }
 
-static Error dumpInput(StringRef File) {
+static Error dumpInput(StringRef File, raw_ostream &OS) {
   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
       MemoryBuffer::getFileOrSTDIN(File, /*IsText=*/false,
                                    /*RequiresNullTerminator=*/false);
@@ -52,11 +57,11 @@ static Error dumpInput(StringRef File) {
   MemoryBufferRef MemBuf = Buffer->getMemBufferRef();
   switch (identify_magic(MemBuf.getBuffer())) {
   case file_magic::archive:
-    return archive2yaml(outs(), MemBuf);
+    return archive2yaml(OS, MemBuf);
   case file_magic::dxcontainer_object:
-    return dxcontainer2yaml(outs(), MemBuf);
+    return dxcontainer2yaml(OS, MemBuf);
   case file_magic::offload_binary:
-    return offload2yaml(outs(), MemBuf);
+    return offload2yaml(OS, MemBuf);
   default:
     break;
   }
@@ -70,11 +75,11 @@ static Error dumpInput(StringRef File) {
   // Universal MachO is not a subclass of ObjectFile, so it needs to be handled
   // here with the other binary types.
   if (Binary.isMachO() || Binary.isMachOUniversalBinary())
-    return macho2yaml(outs(), Binary, RawSegment.getBits());
+    return macho2yaml(OS, Binary, RawSegment.getBits());
   if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
-    return dumpObject(*Obj);
+    return dumpObject(*Obj, OS);
   if (MinidumpFile *Minidump = dyn_cast<MinidumpFile>(&Binary))
-    return minidump2yaml(outs(), *Minidump);
+    return minidump2yaml(OS, *Minidump);
 
   return Error::success();
 }
@@ -94,10 +99,19 @@ int main(int argc, char *argv[]) {
   InitLLVM X(argc, argv);
   cl::ParseCommandLineOptions(argc, argv);
 
-  if (Error Err = dumpInput(InputFilename)) {
+  std::error_code EC;
+  std::unique_ptr<ToolOutputFile> Out(
+      new ToolOutputFile(OutputFilename, EC, sys::fs::OF_None));
+  if (EC) {
+    WithColor::error(errs(), "obj2yaml")
+        << "failed to open '" + OutputFilename + "': " + EC.message() << '\n';
+    return 1;
+  }
+  if (Error Err = dumpInput(InputFilename, Out->os())) {
     reportError(InputFilename, std::move(Err));
     return 1;
   }
+  Out->keep();
 
   return 0;
 }


        


More information about the llvm-commits mailing list