Skip to content

Commit cfec208

Browse files
committed
[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
1 parent 42b3a5f commit cfec208

File tree

9 files changed

+80
-20
lines changed

9 files changed

+80
-20
lines changed

llvm/test/ObjectYAML/Offload/default.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: obj2yaml %t > %t.stdout.yaml
3+
# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
4+
# RUN: FileCheck --input-file=%t.stdout.yaml %s
5+
# RUN: diff %t.stdout.yaml %t.file.yaml
26
!Offload
37
Members:
48
-

llvm/test/ObjectYAML/wasm/header.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: obj2yaml %t > %t.stdout.yaml
3+
# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
4+
# RUN: FileCheck --input-file=%t.stdout.yaml %s
5+
# RUN: diff %t.stdout.yaml %t.file.yaml
26
--- !WASM
37
FileHeader:
48
Version: 0x00000001

llvm/test/tools/obj2yaml/Archives/regular.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
## Check how we dump an empty archive.
44

55
# RUN: yaml2obj %s --docnum=1 -o %t.empty.a
6-
# RUN: obj2yaml %t.empty.a | FileCheck %s --check-prefix=EMPTY
6+
# RUN: obj2yaml %t.empty.a > %t.stdout.yaml
7+
# RUN: obj2yaml %t.empty.a -o %t.file.yaml 2>&1 | count 0
8+
# RUN: FileCheck --input-file=%t.stdout.yaml %s --check-prefix=EMPTY
9+
# RUN: diff %t.stdout.yaml %t.file.yaml
710

811
# EMPTY: --- !Arch
912
# EMPTY-NEXT: Members: []
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
# RUN: obj2yaml %S/Inputs/test-1.o | yaml2obj -o %t.o
1+
# RUN: obj2yaml %S/Inputs/test-1.o > %t.stdout.yaml
2+
# RUN: obj2yaml %S/Inputs/test-1.o -o %t.file.yaml 2>&1 | count 0
3+
# RUN: yaml2obj %t.stdout.yaml -o %t.o
24
# RUN: llvm-pdbutil dump --types %t.o | FileCheck %s -check-prefix=ALL
5+
# RUN: diff %t.stdout.yaml %t.file.yaml
36

47
# ALL: {{.*}} guid = {00C903AB-0968-4639-84F8-7D3E719A1BE1}

llvm/test/tools/obj2yaml/DXContainer/DXILPart.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: obj2yaml %t > %t.stdout.yaml
3+
# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
4+
# RUN: FileCheck --input-file=%t.stdout.yaml %s
5+
# RUN: diff %t.stdout.yaml %t.file.yaml
26

37
--- !dxcontainer
48
Header:

llvm/test/tools/obj2yaml/Minidump/basic.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
# RUN: yaml2obj %s | obj2yaml - | FileCheck %s
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: obj2yaml %t > %t.stdout.yaml
3+
# RUN: obj2yaml %t -o %t.file.yaml 2>&1 | count 0
4+
# RUN: FileCheck --input-file=%t.stdout.yaml %s
5+
# RUN: diff %t.stdout.yaml %t.file.yaml
26

37
--- !minidump
48
Streams:

llvm/test/tools/obj2yaml/XCOFF/aix.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
# RUN: yaml2obj %s -DMAGIC=0x01DF -o %t-32
33
# RUN: obj2yaml %t-32 | FileCheck %s --check-prefix=CHECK32
44
# RUN: yaml2obj %s -DMAGIC=0x01F7 -o %t-64
5-
# RUN: obj2yaml %t-64 | FileCheck %s --check-prefix=CHECK64
5+
# RUN: obj2yaml %t-64 -o %t-64.yaml 2>&1 | count 0
6+
# RUN: FileCheck --input-file %t-64.yaml %s --check-prefix=CHECK64
67

78
# CHECK32: --- !XCOFF
89
# CHECK32-NEXT: FileHeader:
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## Test that -o sets the output file name.
2+
3+
# RUN: yaml2obj %s -o %t
4+
# RUN: rm -f %t.yaml && obj2yaml %t -o %t.yaml
5+
# RUN: ls %t.yaml
6+
# RUN: rm -f %t.yaml && cat %t | obj2yaml -o%t.yaml
7+
# RUN: ls %t.yaml
8+
9+
## In case of an error, don't create the output file.
10+
# RUN: rm -f %t.yaml
11+
# RUN: echo | not obj2yaml -o %t.yaml
12+
# RUN: not ls %t.yaml
13+
14+
# RUN: not obj2yaml %t -o %p/path/does/not/exist 2>&1 | FileCheck -DMSG=%errc_ENOENT %s
15+
16+
# CHECK: obj2yaml: error: failed to open '{{.*}}/path/does/not/exist': [[MSG]]
17+
18+
!ELF
19+
FileHeader:
20+
Class: ELFCLASS64
21+
Data: ELFDATA2LSB
22+
Type: ET_REL
23+
Machine: EM_NONE

llvm/tools/obj2yaml/obj2yaml.cpp

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,40 @@
1414
#include "llvm/Support/CommandLine.h"
1515
#include "llvm/Support/Errc.h"
1616
#include "llvm/Support/InitLLVM.h"
17+
#include "llvm/Support/ToolOutputFile.h"
18+
#include "llvm/Support/WithColor.h"
1719

1820
using namespace llvm;
1921
using namespace llvm::object;
2022

2123
static cl::opt<std::string>
2224
InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
25+
static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"),
26+
cl::value_desc("filename"),
27+
cl::init("-"), cl::Prefix);
2328
static cl::bits<RawSegments> RawSegment(
2429
"raw-segment",
2530
cl::desc("Mach-O: dump the raw contents of the listed segments instead of "
2631
"parsing them:"),
2732
cl::values(clEnumVal(data, "__DATA"), clEnumVal(linkedit, "__LINKEDIT")));
2833

29-
static Error dumpObject(const ObjectFile &Obj) {
34+
static Error dumpObject(const ObjectFile &Obj, raw_ostream &OS) {
3035
if (Obj.isCOFF())
31-
return errorCodeToError(coff2yaml(outs(), cast<COFFObjectFile>(Obj)));
36+
return errorCodeToError(coff2yaml(OS, cast<COFFObjectFile>(Obj)));
3237

3338
if (Obj.isXCOFF())
34-
return xcoff2yaml(outs(), cast<XCOFFObjectFile>(Obj));
39+
return xcoff2yaml(OS, cast<XCOFFObjectFile>(Obj));
3540

3641
if (Obj.isELF())
37-
return elf2yaml(outs(), Obj);
42+
return elf2yaml(OS, Obj);
3843

3944
if (Obj.isWasm())
40-
return errorCodeToError(wasm2yaml(outs(), cast<WasmObjectFile>(Obj)));
45+
return errorCodeToError(wasm2yaml(OS, cast<WasmObjectFile>(Obj)));
4146

4247
llvm_unreachable("unexpected object file format");
4348
}
4449

45-
static Error dumpInput(StringRef File) {
50+
static Error dumpInput(StringRef File, raw_ostream &OS) {
4651
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
4752
MemoryBuffer::getFileOrSTDIN(File, /*IsText=*/false,
4853
/*RequiresNullTerminator=*/false);
@@ -52,11 +57,11 @@ static Error dumpInput(StringRef File) {
5257
MemoryBufferRef MemBuf = Buffer->getMemBufferRef();
5358
switch (identify_magic(MemBuf.getBuffer())) {
5459
case file_magic::archive:
55-
return archive2yaml(outs(), MemBuf);
60+
return archive2yaml(OS, MemBuf);
5661
case file_magic::dxcontainer_object:
57-
return dxcontainer2yaml(outs(), MemBuf);
62+
return dxcontainer2yaml(OS, MemBuf);
5863
case file_magic::offload_binary:
59-
return offload2yaml(outs(), MemBuf);
64+
return offload2yaml(OS, MemBuf);
6065
default:
6166
break;
6267
}
@@ -70,11 +75,11 @@ static Error dumpInput(StringRef File) {
7075
// Universal MachO is not a subclass of ObjectFile, so it needs to be handled
7176
// here with the other binary types.
7277
if (Binary.isMachO() || Binary.isMachOUniversalBinary())
73-
return macho2yaml(outs(), Binary, RawSegment.getBits());
78+
return macho2yaml(OS, Binary, RawSegment.getBits());
7479
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
75-
return dumpObject(*Obj);
80+
return dumpObject(*Obj, OS);
7681
if (MinidumpFile *Minidump = dyn_cast<MinidumpFile>(&Binary))
77-
return minidump2yaml(outs(), *Minidump);
82+
return minidump2yaml(OS, *Minidump);
7883

7984
return Error::success();
8085
}
@@ -94,10 +99,19 @@ int main(int argc, char *argv[]) {
9499
InitLLVM X(argc, argv);
95100
cl::ParseCommandLineOptions(argc, argv);
96101

97-
if (Error Err = dumpInput(InputFilename)) {
102+
std::error_code EC;
103+
std::unique_ptr<ToolOutputFile> Out(
104+
new ToolOutputFile(OutputFilename, EC, sys::fs::OF_None));
105+
if (EC) {
106+
WithColor::error(errs(), "obj2yaml")
107+
<< "failed to open '" + OutputFilename + "': " + EC.message() << '\n';
108+
return 1;
109+
}
110+
if (Error Err = dumpInput(InputFilename, Out->os())) {
98111
reportError(InputFilename, std::move(Err));
99112
return 1;
100113
}
114+
Out->keep();
101115

102116
return 0;
103117
}

0 commit comments

Comments
 (0)