#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
static opt<bool> DumpUUID("uuid", desc("Show the UUID for each architecture"),
cat(DwarfDumpCategory));
static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID));
-
+static opt<std::string>
+ OutputFilename("out-file", cl::init(""),
+ cl::desc("Redirect output to the specified file"),
+ cl::value_desc("filename"));
+static alias OutputFilenameAlias("o", desc("Alias for -out-file"),
+ aliasopt(OutputFilename),
+ cat(DwarfDumpCategory));
static opt<bool>
ShowChildren("show-children",
desc("Show a debug info entry's children when selectively "
/// @}
//===----------------------------------------------------------------------===//
-
-static void error(StringRef Filename, std::error_code EC) {
+static void error(StringRef Prefix, std::error_code EC) {
if (!EC)
return;
- errs() << Filename << ": " << EC.message() << "\n";
+ errs() << Prefix << ": " << EC.message() << "\n";
exit(1);
}
return false;
}
-using HandlerFn = std::function<bool(ObjectFile &, DWARFContext &DICtx, Twine)>;
+using HandlerFn = std::function<bool(ObjectFile &, DWARFContext &DICtx, Twine,
+ raw_ostream &)>;
-static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
- Twine Filename) {
+static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
+ raw_ostream &OS) {
logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
Filename.str() + ": ");
// The UUID dump already contains all the same information.
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
- outs() << Filename << ":\tfile format " << Obj.getFileFormatName() << '\n';
+ OS << Filename << ":\tfile format " << Obj.getFileFormatName() << '\n';
// Dump the complete DWARF structure.
- DICtx.dump(outs(), getDumpOpts(), DumpOffsets);
+ DICtx.dump(OS, getDumpOpts(), DumpOffsets);
return true;
}
static bool verifyObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
- Twine Filename) {
+ Twine Filename, raw_ostream &OS) {
// Verify the DWARF and exit with non-zero exit status if verification
// fails.
- raw_ostream &stream = Quiet ? nulls() : outs();
+ raw_ostream &stream = Quiet ? nulls() : OS;
stream << "Verifying " << Filename.str() << ":\tfile format "
<< Obj.getFileFormatName() << "\n";
bool Result = DICtx.verify(stream, getDumpOpts());
}
static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
- HandlerFn HandleObj);
+ HandlerFn HandleObj, raw_ostream &OS);
static bool handleArchive(StringRef Filename, Archive &Arch,
- HandlerFn HandleObj) {
+ HandlerFn HandleObj, raw_ostream &OS) {
bool Result = true;
Error Err = Error::success();
for (auto Child : Arch.children(Err)) {
auto NameOrErr = Child.getName();
error(Filename, errorToErrorCode(NameOrErr.takeError()));
std::string Name = (Filename + "(" + NameOrErr.get() + ")").str();
- Result &= handleBuffer(Name, BuffOrErr.get(), HandleObj);
+ Result &= handleBuffer(Name, BuffOrErr.get(), HandleObj, OS);
}
error(Filename, errorToErrorCode(std::move(Err)));
}
static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
- HandlerFn HandleObj) {
+ HandlerFn HandleObj, raw_ostream &OS) {
Expected<std::unique_ptr<Binary>> BinOrErr = object::createBinary(Buffer);
error(Filename, errorToErrorCode(BinOrErr.takeError()));
if (auto *Obj = dyn_cast<ObjectFile>(BinOrErr->get())) {
if (filterArch(*Obj)) {
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(*Obj);
- Result = HandleObj(*Obj, *DICtx, Filename);
+ Result = HandleObj(*Obj, *DICtx, Filename, OS);
}
}
else if (auto *Fat = dyn_cast<MachOUniversalBinary>(BinOrErr->get()))
auto &Obj = **MachOOrErr;
if (filterArch(Obj)) {
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
- Result &= HandleObj(Obj, *DICtx, ObjName);
+ Result &= HandleObj(Obj, *DICtx, ObjName, OS);
}
continue;
} else
consumeError(MachOOrErr.takeError());
if (auto ArchiveOrErr = ObjForArch.getAsArchive()) {
error(ObjName, errorToErrorCode(ArchiveOrErr.takeError()));
- Result &= handleArchive(ObjName, *ArchiveOrErr.get(), HandleObj);
+ Result &= handleArchive(ObjName, *ArchiveOrErr.get(), HandleObj, OS);
continue;
} else
consumeError(ArchiveOrErr.takeError());
}
else if (auto *Arch = dyn_cast<Archive>(BinOrErr->get()))
- Result = handleArchive(Filename, *Arch, HandleObj);
+ Result = handleArchive(Filename, *Arch, HandleObj, OS);
return Result;
}
-static bool handleFile(StringRef Filename, HandlerFn HandleObj) {
+static bool handleFile(StringRef Filename, HandlerFn HandleObj,
+ raw_ostream &OS) {
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
MemoryBuffer::getFileOrSTDIN(Filename);
error(Filename, BuffOrErr.getError());
std::unique_ptr<MemoryBuffer> Buffer = std::move(BuffOrErr.get());
- return handleBuffer(Filename, *Buffer, HandleObj);
+ return handleBuffer(Filename, *Buffer, HandleObj, OS);
}
/// If the input path is a .dSYM bundle (as created by the dsymutil tool),
return 0;
}
+ std::unique_ptr<tool_output_file> OutputFile;
+ if (!OutputFilename.empty()) {
+ std::error_code EC;
+ OutputFile =
+ make_unique<tool_output_file>(OutputFilename, EC, sys::fs::F_None);
+ error("Unable to open output file" + OutputFilename, EC);
+ // Don't remove output file if we exit with an error.
+ OutputFile->keep();
+ }
+
+ raw_ostream &OS = OutputFile ? OutputFile->os() : outs();
+
// Defaults to dumping all sections, unless brief mode is specified in which
// case only the .debug_info section in dumped.
#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
if (Verify) {
// If we encountered errors during verify, exit with a non-zero exit status.
- if (!std::all_of(Objects.begin(), Objects.end(), [](std::string Object) {
- return handleFile(Object, verifyObjectFile);
+ if (!std::all_of(Objects.begin(), Objects.end(), [&](std::string Object) {
+ return handleFile(Object, verifyObjectFile, OS);
}))
exit(1);
} else
for (auto Object : Objects)
- handleFile(Object, dumpObjectFile);
+ handleFile(Object, dumpObjectFile, OS);
return EXIT_SUCCESS;
}