mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
objdump: Better handling of Mach-O universal binaries
Summary: With Mach-O, there is a flag requirement discrepancy between working with universal binaries and thin binaries. Many flags that don't require the `-macho` flag (for example `-private-headers` and `-disassemble`) fail to work on universal binaries unless `-macho` is given. When this happens, the error message is unhelpful, stating: The file was not recognized as a valid object file. Which can lead to confusion. This change allows generic flags to be used on universal binaries with and without the `-macho` flag. This means flags that can be used for thin files can be used consistently with fat files too. To do this, the universal binary support within `ParseInputMachO()` is extracted into a new function. This new function is called directly from `DumpInput()` when the input binary is universal. Additionally the `-arch` flag validation in `ParseInputMachO()` was extracted to be reused. Reviewers: compnerd Reviewed By: compnerd Subscribers: keith, llvm-commits Differential Revision: https://reviews.llvm.org/D48702 llvm-svn: 338792
This commit is contained in:
parent
5e3a3e7469
commit
956ce46fd0
@ -19,6 +19,8 @@
|
||||
// RUN: | FileCheck %s -check-prefix=THREAD
|
||||
// RUN: llvm-objdump -macho -p -arch i386 %p/Inputs/macho-universal.x86_64.i386 \
|
||||
// RUN: | FileCheck %s -check-prefix=FATi386
|
||||
// RUN: llvm-objdump -p -arch i386 %p/Inputs/macho-universal.x86_64.i386 \
|
||||
// RUN: | FileCheck %s -check-prefix=FATi386
|
||||
// RUN: llvm-objdump -p -non-verbose %p/Inputs/hello.obj.macho-x86_64 \
|
||||
// RUN: | FileCheck %s -check-prefix=NON_VERBOSE
|
||||
// RUN: llvm-objdump -p %p/Inputs/codesig.macho-x86_64 \
|
||||
|
@ -1,5 +1,7 @@
|
||||
RUN: llvm-objdump %p/Inputs/macho-universal.x86_64.i386 -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex -arch all \
|
||||
RUN: | FileCheck %s -check-prefix UEXE-all
|
||||
RUN: llvm-objdump %p/Inputs/macho-universal.x86_64.i386 -d -no-show-raw-insn -full-leading-addr -print-imm-hex -arch all \
|
||||
RUN: | FileCheck %s -check-prefix UEXE-all
|
||||
RUN: llvm-objdump %p/Inputs/macho-universal-archive.x86_64.i386 -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex -arch i386 \
|
||||
RUN: | FileCheck %s -check-prefix UArchive-i386
|
||||
RUN: llvm-objdump %p/Inputs/macho-universal.x86_64.i386 -universal-headers -m \
|
||||
|
@ -1937,11 +1937,7 @@ static void printArchiveHeaders(StringRef Filename, Archive *A, bool verbose,
|
||||
report_error(StringRef(), Filename, std::move(Err), ArchitectureName);
|
||||
}
|
||||
|
||||
// ParseInputMachO() parses the named Mach-O file in Filename and handles the
|
||||
// -arch flags selecting just those slices as specified by them and also parses
|
||||
// archive files. Then for each individual Mach-O file ProcessMachO() is
|
||||
// called to process the file based on the command line options.
|
||||
void llvm::ParseInputMachO(StringRef Filename) {
|
||||
static bool ValidateArchFlags() {
|
||||
// Check for -arch all and verifiy the -arch flags are valid.
|
||||
for (unsigned i = 0; i < ArchFlags.size(); ++i) {
|
||||
if (ArchFlags[i] == "all") {
|
||||
@ -1950,10 +1946,20 @@ void llvm::ParseInputMachO(StringRef Filename) {
|
||||
if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
|
||||
errs() << "llvm-objdump: Unknown architecture named '" + ArchFlags[i] +
|
||||
"'for the -arch option\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ParseInputMachO() parses the named Mach-O file in Filename and handles the
|
||||
// -arch flags selecting just those slices as specified by them and also parses
|
||||
// archive files. Then for each individual Mach-O file ProcessMachO() is
|
||||
// called to process the file based on the command line options.
|
||||
void llvm::ParseInputMachO(StringRef Filename) {
|
||||
if (!ValidateArchFlags())
|
||||
return;
|
||||
|
||||
// Attempt to open the binary.
|
||||
Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
|
||||
@ -1989,186 +1995,16 @@ void llvm::ParseInputMachO(StringRef Filename) {
|
||||
report_error(Filename, std::move(Err));
|
||||
return;
|
||||
}
|
||||
if (UniversalHeaders) {
|
||||
if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
|
||||
printMachOUniversalHeaders(UB, !NonVerbose);
|
||||
}
|
||||
if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
|
||||
// If we have a list of architecture flags specified dump only those.
|
||||
if (!ArchAll && ArchFlags.size() != 0) {
|
||||
// Look for a slice in the universal binary that matches each ArchFlag.
|
||||
bool ArchFound;
|
||||
for (unsigned i = 0; i < ArchFlags.size(); ++i) {
|
||||
ArchFound = false;
|
||||
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
|
||||
E = UB->end_objects();
|
||||
I != E; ++I) {
|
||||
if (ArchFlags[i] == I->getArchFlagName()) {
|
||||
ArchFound = true;
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
|
||||
I->getAsObjectFile();
|
||||
std::string ArchitectureName = "";
|
||||
if (ArchFlags.size() > 1)
|
||||
ArchitectureName = I->getArchFlagName();
|
||||
if (ObjOrErr) {
|
||||
ObjectFile &O = *ObjOrErr.get();
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
|
||||
ProcessMachO(Filename, MachOOF, "", ArchitectureName);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(Filename, StringRef(), std::move(E),
|
||||
ArchitectureName);
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
I->getAsArchive()) {
|
||||
std::unique_ptr<Archive> &A = *AOrErr;
|
||||
outs() << "Archive : " << Filename;
|
||||
if (!ArchitectureName.empty())
|
||||
outs() << " (architecture " << ArchitectureName << ")";
|
||||
outs() << "\n";
|
||||
if (ArchiveHeaders)
|
||||
printArchiveHeaders(Filename, A.get(), !NonVerbose,
|
||||
ArchiveMemberOffsets, ArchitectureName);
|
||||
Error Err = Error::success();
|
||||
for (auto &C : A->children(Err)) {
|
||||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(Filename, C, std::move(E), ArchitectureName);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
|
||||
ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
|
||||
}
|
||||
if (Err)
|
||||
report_error(Filename, std::move(Err));
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for " +
|
||||
"architecture " + StringRef(I->getArchFlagName()) +
|
||||
" is not a Mach-O file or an archive file");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ArchFound) {
|
||||
errs() << "llvm-objdump: file: " + Filename + " does not contain "
|
||||
<< "architecture: " + ArchFlags[i] + "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// No architecture flags were specified so if this contains a slice that
|
||||
// matches the host architecture dump only that.
|
||||
if (!ArchAll) {
|
||||
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
|
||||
E = UB->end_objects();
|
||||
I != E; ++I) {
|
||||
if (MachOObjectFile::getHostArch().getArchName() ==
|
||||
I->getArchFlagName()) {
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
|
||||
std::string ArchiveName;
|
||||
ArchiveName.clear();
|
||||
if (ObjOrErr) {
|
||||
ObjectFile &O = *ObjOrErr.get();
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
|
||||
ProcessMachO(Filename, MachOOF);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(Filename, std::move(E));
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
I->getAsArchive()) {
|
||||
std::unique_ptr<Archive> &A = *AOrErr;
|
||||
outs() << "Archive : " << Filename << "\n";
|
||||
if (ArchiveHeaders)
|
||||
printArchiveHeaders(Filename, A.get(), !NonVerbose,
|
||||
ArchiveMemberOffsets);
|
||||
Error Err = Error::success();
|
||||
for (auto &C : A->children(Err)) {
|
||||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(Filename, C, std::move(E));
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
|
||||
ProcessMachO(Filename, O, O->getFileName());
|
||||
}
|
||||
if (Err)
|
||||
report_error(Filename, std::move(Err));
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for architecture " +
|
||||
StringRef(I->getArchFlagName()) +
|
||||
" is not a Mach-O file or an archive file");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Either all architectures have been specified or none have been specified
|
||||
// and this does not contain the host architecture so dump all the slices.
|
||||
bool moreThanOneArch = UB->getNumberOfObjects() > 1;
|
||||
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
|
||||
E = UB->end_objects();
|
||||
I != E; ++I) {
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
|
||||
std::string ArchitectureName = "";
|
||||
if (moreThanOneArch)
|
||||
ArchitectureName = I->getArchFlagName();
|
||||
if (ObjOrErr) {
|
||||
ObjectFile &Obj = *ObjOrErr.get();
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
|
||||
ProcessMachO(Filename, MachOOF, "", ArchitectureName);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(StringRef(), Filename, std::move(E), ArchitectureName);
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
I->getAsArchive()) {
|
||||
std::unique_ptr<Archive> &A = *AOrErr;
|
||||
outs() << "Archive : " << Filename;
|
||||
if (!ArchitectureName.empty())
|
||||
outs() << " (architecture " << ArchitectureName << ")";
|
||||
outs() << "\n";
|
||||
if (ArchiveHeaders)
|
||||
printArchiveHeaders(Filename, A.get(), !NonVerbose,
|
||||
ArchiveMemberOffsets, ArchitectureName);
|
||||
Error Err = Error::success();
|
||||
for (auto &C : A->children(Err)) {
|
||||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(Filename, C, std::move(E), ArchitectureName);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
|
||||
ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
|
||||
ArchitectureName);
|
||||
}
|
||||
}
|
||||
if (Err)
|
||||
report_error(Filename, std::move(Err));
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for architecture " +
|
||||
StringRef(I->getArchFlagName()) +
|
||||
" is not a Mach-O file or an archive file");
|
||||
}
|
||||
}
|
||||
ParseInputMachO(UB);
|
||||
return;
|
||||
}
|
||||
if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
|
||||
if (!checkMachOAndArchFlags(O, Filename))
|
||||
return;
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O))
|
||||
ProcessMachO(Filename, MachOOF);
|
||||
} else
|
||||
else
|
||||
errs() << "llvm-objdump: '" << Filename << "': "
|
||||
<< "Object is not a Mach-O file type.\n";
|
||||
return;
|
||||
@ -2176,6 +2012,184 @@ void llvm::ParseInputMachO(StringRef Filename) {
|
||||
llvm_unreachable("Input object can't be invalid at this point");
|
||||
}
|
||||
|
||||
void llvm::ParseInputMachO(MachOUniversalBinary *UB) {
|
||||
if (!ValidateArchFlags())
|
||||
return;
|
||||
|
||||
auto Filename = UB->getFileName();
|
||||
|
||||
if (UniversalHeaders)
|
||||
printMachOUniversalHeaders(UB, !NonVerbose);
|
||||
|
||||
// If we have a list of architecture flags specified dump only those.
|
||||
if (!ArchAll && ArchFlags.size() != 0) {
|
||||
// Look for a slice in the universal binary that matches each ArchFlag.
|
||||
bool ArchFound;
|
||||
for (unsigned i = 0; i < ArchFlags.size(); ++i) {
|
||||
ArchFound = false;
|
||||
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
|
||||
E = UB->end_objects();
|
||||
I != E; ++I) {
|
||||
if (ArchFlags[i] == I->getArchFlagName()) {
|
||||
ArchFound = true;
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
|
||||
I->getAsObjectFile();
|
||||
std::string ArchitectureName = "";
|
||||
if (ArchFlags.size() > 1)
|
||||
ArchitectureName = I->getArchFlagName();
|
||||
if (ObjOrErr) {
|
||||
ObjectFile &O = *ObjOrErr.get();
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
|
||||
ProcessMachO(Filename, MachOOF, "", ArchitectureName);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(Filename, StringRef(), std::move(E),
|
||||
ArchitectureName);
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
I->getAsArchive()) {
|
||||
std::unique_ptr<Archive> &A = *AOrErr;
|
||||
outs() << "Archive : " << Filename;
|
||||
if (!ArchitectureName.empty())
|
||||
outs() << " (architecture " << ArchitectureName << ")";
|
||||
outs() << "\n";
|
||||
if (ArchiveHeaders)
|
||||
printArchiveHeaders(Filename, A.get(), !NonVerbose,
|
||||
ArchiveMemberOffsets, ArchitectureName);
|
||||
Error Err = Error::success();
|
||||
for (auto &C : A->children(Err)) {
|
||||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(Filename, C, std::move(E), ArchitectureName);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
|
||||
ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
|
||||
}
|
||||
if (Err)
|
||||
report_error(Filename, std::move(Err));
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for " +
|
||||
"architecture " + StringRef(I->getArchFlagName()) +
|
||||
" is not a Mach-O file or an archive file");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ArchFound) {
|
||||
errs() << "llvm-objdump: file: " + Filename + " does not contain "
|
||||
<< "architecture: " + ArchFlags[i] + "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// No architecture flags were specified so if this contains a slice that
|
||||
// matches the host architecture dump only that.
|
||||
if (!ArchAll) {
|
||||
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
|
||||
E = UB->end_objects();
|
||||
I != E; ++I) {
|
||||
if (MachOObjectFile::getHostArch().getArchName() ==
|
||||
I->getArchFlagName()) {
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
|
||||
std::string ArchiveName;
|
||||
ArchiveName.clear();
|
||||
if (ObjOrErr) {
|
||||
ObjectFile &O = *ObjOrErr.get();
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
|
||||
ProcessMachO(Filename, MachOOF);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(Filename, std::move(E));
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
I->getAsArchive()) {
|
||||
std::unique_ptr<Archive> &A = *AOrErr;
|
||||
outs() << "Archive : " << Filename << "\n";
|
||||
if (ArchiveHeaders)
|
||||
printArchiveHeaders(Filename, A.get(), !NonVerbose,
|
||||
ArchiveMemberOffsets);
|
||||
Error Err = Error::success();
|
||||
for (auto &C : A->children(Err)) {
|
||||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(Filename, C, std::move(E));
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
|
||||
ProcessMachO(Filename, O, O->getFileName());
|
||||
}
|
||||
if (Err)
|
||||
report_error(Filename, std::move(Err));
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for architecture " +
|
||||
StringRef(I->getArchFlagName()) +
|
||||
" is not a Mach-O file or an archive file");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Either all architectures have been specified or none have been specified
|
||||
// and this does not contain the host architecture so dump all the slices.
|
||||
bool moreThanOneArch = UB->getNumberOfObjects() > 1;
|
||||
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
|
||||
E = UB->end_objects();
|
||||
I != E; ++I) {
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
|
||||
std::string ArchitectureName = "";
|
||||
if (moreThanOneArch)
|
||||
ArchitectureName = I->getArchFlagName();
|
||||
if (ObjOrErr) {
|
||||
ObjectFile &Obj = *ObjOrErr.get();
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
|
||||
ProcessMachO(Filename, MachOOF, "", ArchitectureName);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(StringRef(), Filename, std::move(E), ArchitectureName);
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
I->getAsArchive()) {
|
||||
std::unique_ptr<Archive> &A = *AOrErr;
|
||||
outs() << "Archive : " << Filename;
|
||||
if (!ArchitectureName.empty())
|
||||
outs() << " (architecture " << ArchitectureName << ")";
|
||||
outs() << "\n";
|
||||
if (ArchiveHeaders)
|
||||
printArchiveHeaders(Filename, A.get(), !NonVerbose,
|
||||
ArchiveMemberOffsets, ArchitectureName);
|
||||
Error Err = Error::success();
|
||||
for (auto &C : A->children(Err)) {
|
||||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(Filename, C, std::move(E), ArchitectureName);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
|
||||
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
|
||||
ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
|
||||
ArchitectureName);
|
||||
}
|
||||
}
|
||||
if (Err)
|
||||
report_error(Filename, std::move(Err));
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for architecture " +
|
||||
StringRef(I->getArchFlagName()) +
|
||||
" is not a Mach-O file or an archive file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The block of info used by the Symbolizer call backs.
|
||||
struct DisassembleInfo {
|
||||
DisassembleInfo(MachOObjectFile *O, SymbolAddressMap *AddrMap,
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "llvm/Object/COFFImportFile.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Object/MachOUniversal.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Object/Wasm.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
@ -2363,6 +2364,8 @@ static void DumpInput(StringRef file) {
|
||||
DumpArchive(a);
|
||||
else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary))
|
||||
DumpObject(o);
|
||||
else if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Binary))
|
||||
ParseInputMachO(UB);
|
||||
else
|
||||
report_error(file, object_error::invalid_file_type);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ namespace object {
|
||||
class COFFObjectFile;
|
||||
class COFFImportFile;
|
||||
class MachOObjectFile;
|
||||
class MachOUniversalBinary;
|
||||
class ObjectFile;
|
||||
class Archive;
|
||||
class RelocationRef;
|
||||
@ -71,6 +72,7 @@ extern cl::opt<DIDumpType> DwarfDumpType;
|
||||
void error(std::error_code ec);
|
||||
bool RelocAddressLess(object::RelocationRef a, object::RelocationRef b);
|
||||
void ParseInputMachO(StringRef Filename);
|
||||
void ParseInputMachO(object::MachOUniversalBinary *UB);
|
||||
void printCOFFUnwindInfo(const object::COFFObjectFile* o);
|
||||
void printMachOUnwindInfo(const object::MachOObjectFile* o);
|
||||
void printMachOExportsTrie(const object::MachOObjectFile* o);
|
||||
|
Loading…
Reference in New Issue
Block a user