1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +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:
Dave Lee 2018-08-03 00:06:38 +00:00
parent 5e3a3e7469
commit 956ce46fd0
5 changed files with 202 additions and 179 deletions

View File

@ -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 \

View File

@ -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 \

View File

@ -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 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,11 +1995,32 @@ 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)) {
ParseInputMachO(UB);
return;
}
if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
if (!checkMachOAndArchFlags(O, Filename))
return;
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O))
ProcessMachO(Filename, MachOOF);
else
errs() << "llvm-objdump: '" << Filename << "': "
<< "Object is not a Mach-O file type.\n";
return;
}
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.
@ -2161,19 +2188,6 @@ void llvm::ParseInputMachO(StringRef Filename) {
" is not a Mach-O file or an archive file");
}
}
return;
}
if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
if (!checkMachOAndArchFlags(O, Filename))
return;
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
ProcessMachO(Filename, MachOOF);
} else
errs() << "llvm-objdump: '" << Filename << "': "
<< "Object is not a Mach-O file type.\n";
return;
}
llvm_unreachable("Input object can't be invalid at this point");
}
// The block of info used by the Symbolizer call backs.

View File

@ -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);
}

View File

@ -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);