mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[llvm-lipo] Implement -archs
Displays the architecture names of an input file. Unknown architectures are represented by unknown(cputype,cpusubtype). Patch by Anusha Basana <anusha.basana@gmail.com> Differential Revision: https://reviews.llvm.org/D62753 llvm-svn: 362840
This commit is contained in:
parent
2d127b3a65
commit
2365b4ea23
15
test/tools/llvm-lipo/archs-macho-binary-unknown.test
Normal file
15
test/tools/llvm-lipo/archs-macho-binary-unknown.test
Normal file
@ -0,0 +1,15 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# Tests that the output for an unknown architecture is the same as cctools lipo
|
||||
# RUN: llvm-lipo %t -archs | FileCheck %s
|
||||
# CHECK: unknown(151,3)
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x00000097
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00002000
|
||||
...
|
19
test/tools/llvm-lipo/archs-macho-binary.test
Normal file
19
test/tools/llvm-lipo/archs-macho-binary.test
Normal file
@ -0,0 +1,19 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
|
||||
# RUN: llvm-lipo %t -archs | FileCheck --check-prefix=ARCHS %s
|
||||
# RUN: llvm-lipo %t --archs | FileCheck --check-prefix=ARCHS %s
|
||||
# ARCHS: i386
|
||||
|
||||
# RUN: not llvm-lipo %t %t -archs 2>&1 | FileCheck --check-prefix=MULTIPLE_INPUT_OBJ %s
|
||||
# MULTIPLE_INPUT_OBJ: archs expects a single input file
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00002000
|
||||
...
|
40
test/tools/llvm-lipo/archs-universal-binary-arm.test
Normal file
40
test/tools/llvm-lipo/archs-universal-binary-arm.test
Normal file
@ -0,0 +1,40 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# RUN: llvm-lipo %t -archs | FileCheck %s
|
||||
# CHECK: armv7k arm64
|
||||
|
||||
--- !fat-mach-o
|
||||
FatHeader:
|
||||
magic: 0xCAFEBABE
|
||||
nfat_arch: 2
|
||||
FatArchs:
|
||||
- cputype: 0x0000000C
|
||||
cpusubtype: 0x0000000C
|
||||
offset: 0x0000000000004000
|
||||
size: 28
|
||||
align: 14
|
||||
- cputype: 0x0100000C
|
||||
cpusubtype: 0x00000000
|
||||
offset: 0x000000000001C000
|
||||
size: 32
|
||||
align: 14
|
||||
Slices:
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x0000000C
|
||||
cpusubtype: 0x0000000C
|
||||
filetype: 0x00000002
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00200085
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x0100000C
|
||||
cpusubtype: 0x00000000
|
||||
filetype: 0x00000002
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00210085
|
||||
reserved: 0x00000000
|
||||
...
|
41
test/tools/llvm-lipo/archs-universal-binary-unknown.test
Normal file
41
test/tools/llvm-lipo/archs-universal-binary-unknown.test
Normal file
@ -0,0 +1,41 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# Tests that the output for an unknown architecture is the same as cctools lipo
|
||||
# RUN: llvm-lipo %t -archs 2>&1 | FileCheck %s
|
||||
# CHECK: i386 unknown(16777367,3)
|
||||
|
||||
--- !fat-mach-o
|
||||
FatHeader:
|
||||
magic: 0xCAFEBABE
|
||||
nfat_arch: 2
|
||||
FatArchs:
|
||||
- cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
offset: 0x0000000000001000
|
||||
size: 28
|
||||
align: 12
|
||||
- cputype: 0x01000097
|
||||
cpusubtype: 0x00000003
|
||||
offset: 0x0000000000002000
|
||||
size: 32
|
||||
align: 12
|
||||
Slices:
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00002000
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000097
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00002000
|
||||
reserved: 0x00000000
|
||||
...
|
40
test/tools/llvm-lipo/archs-universal-binary-x86.test
Normal file
40
test/tools/llvm-lipo/archs-universal-binary-x86.test
Normal file
@ -0,0 +1,40 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# RUN: llvm-lipo %t -archs | FileCheck %s
|
||||
# CHECK: i386 x86_64
|
||||
|
||||
--- !fat-mach-o
|
||||
FatHeader:
|
||||
magic: 0xCAFEBABE
|
||||
nfat_arch: 2
|
||||
FatArchs:
|
||||
- cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
offset: 0x0000000000001000
|
||||
size: 28
|
||||
align: 12
|
||||
- cputype: 0x01000007
|
||||
cpusubtype: 0x00000003
|
||||
offset: 0x0000000000002000
|
||||
size: 32
|
||||
align: 12
|
||||
Slices:
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00002000
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000001
|
||||
ncmds: 0
|
||||
sizeofcmds: 0
|
||||
flags: 0x00002000
|
||||
reserved: 0x00000000
|
||||
...
|
@ -8,6 +8,9 @@
|
||||
# RUN: not llvm-lipo -abcabc 2>&1 | FileCheck --check-prefix=LIPO-UNKNOWN-ARG %s
|
||||
# RUN: not llvm-lipo --abcabc 2>&1 | FileCheck --check-prefix=LIPO-UNKNOWN-ARG %s
|
||||
|
||||
# RUN: not llvm-lipo %t -archs -verify_arch i386 2>&1 | FileCheck --check-prefix=MULTIPLE_FLAGS %s
|
||||
# MULTIPLE_FLAGS: only one of the following actions can be specified: -archs -verify_arch
|
||||
|
||||
# LIPO-USAGE: USAGE: llvm-lipo
|
||||
# LIPO-UNKNOWN-ARG: unknown argument '{{-+}}abcabc'
|
||||
# LIPO-VERSION: {{ version }}
|
@ -4,13 +4,15 @@
|
||||
# RUN: llvm-lipo %t -verify_arch i386 x86_64
|
||||
|
||||
# RUN: not llvm-lipo %t -verify_arch aarch64
|
||||
# RUN: not llvm-lipo %t -verify_arch aarch64 i386
|
||||
# RUN: yaml2obj %s | not llvm-lipo - -verify_arch aarch64 i386
|
||||
# lipo does not support this (i.e. yaml2obj %s | not lipo -), included to test function with llvm-lipo
|
||||
# use the temporary %t when checking tests with lipo
|
||||
|
||||
--- !fat-mach-o
|
||||
FatHeader:
|
||||
FatHeader:
|
||||
magic: 0xCAFEBABE
|
||||
nfat_arch: 2
|
||||
FatArchs:
|
||||
FatArchs:
|
||||
- cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
offset: 0x0000000000001000
|
||||
@ -21,9 +23,9 @@ FatArchs:
|
||||
offset: 0x0000000000002000
|
||||
size: 32
|
||||
align: 12
|
||||
Slices:
|
||||
Slices:
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACE
|
||||
cputype: 0x00000007
|
||||
cpusubtype: 0x00000003
|
||||
@ -32,7 +34,7 @@ Slices:
|
||||
sizeofcmds: 0
|
||||
flags: 0x00002000
|
||||
- !mach-o
|
||||
FileHeader:
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x00000003
|
||||
|
@ -6,5 +6,14 @@ def h : Flag<["-"], "h">, Alias<help>;
|
||||
def version : Flag<["-", "--"], "version">,
|
||||
HelpText<"Print the version and exit.">;
|
||||
|
||||
def verify_arch : Option<["-", "--"], "verify_arch", KIND_REMAINING_ARGS>,
|
||||
HelpText<"Verify that the specified arch_types are present in the input file">;
|
||||
def action_group : OptionGroup<"action group">;
|
||||
|
||||
def verify_arch
|
||||
: Option<["-", "--"], "verify_arch", KIND_REMAINING_ARGS>,
|
||||
Group<action_group>,
|
||||
HelpText<
|
||||
"Verify that the specified arch_types are present in the input file">;
|
||||
|
||||
def archs : Option<["-", "--"], "archs", KIND_FLAG>,
|
||||
Group<action_group>,
|
||||
HelpText<"Display the arch_types present in the input file">;
|
||||
|
@ -53,6 +53,8 @@ enum LipoID {
|
||||
#undef OPTION
|
||||
};
|
||||
|
||||
// LipoInfoTable below references LIPO_##PREFIX. OptionGroup has prefix nullptr.
|
||||
const char *const *LIPO_nullptr = nullptr;
|
||||
#define PREFIX(NAME, VALUE) const char *const LIPO_##NAME[] = VALUE;
|
||||
#include "LipoOpts.inc"
|
||||
#undef PREFIX
|
||||
@ -73,9 +75,15 @@ public:
|
||||
LipoOptTable() : OptTable(LipoInfoTable) {}
|
||||
};
|
||||
|
||||
enum class LipoAction {
|
||||
PrintArchs,
|
||||
VerifyArch,
|
||||
};
|
||||
|
||||
struct Config {
|
||||
SmallVector<std::string, 1> InputFiles;
|
||||
SmallVector<std::string, 1> VerifyArchList;
|
||||
LipoAction ActionToPerform;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
@ -113,7 +121,20 @@ static Config parseLipoOptions(ArrayRef<const char *> ArgsArr) {
|
||||
if (C.InputFiles.empty())
|
||||
reportError("at least one input file should be specified");
|
||||
|
||||
if (InputArgs.hasArg(LIPO_verify_arch)) {
|
||||
SmallVector<opt::Arg *, 1> ActionArgs(InputArgs.filtered(LIPO_action_group));
|
||||
if (ActionArgs.empty())
|
||||
reportError("at least one action should be specified");
|
||||
if (ActionArgs.size() > 1) {
|
||||
std::string Buf;
|
||||
raw_string_ostream OS(Buf);
|
||||
OS << "only one of the following actions can be specified:";
|
||||
for (auto Arg : ActionArgs)
|
||||
OS << " " << Arg->getSpelling();
|
||||
reportError(OS.str());
|
||||
}
|
||||
|
||||
switch (ActionArgs[0]->getOption().getID()) {
|
||||
case LIPO_verify_arch:
|
||||
for (auto A : InputArgs.getAllArgValues(LIPO_verify_arch))
|
||||
C.VerifyArchList.push_back(A);
|
||||
if (C.VerifyArchList.empty())
|
||||
@ -121,8 +142,18 @@ static Config parseLipoOptions(ArrayRef<const char *> ArgsArr) {
|
||||
"verify_arch requires at least one architecture to be specified");
|
||||
if (C.InputFiles.size() > 1)
|
||||
reportError("verify_arch expects a single input file");
|
||||
C.ActionToPerform = LipoAction::VerifyArch;
|
||||
return C;
|
||||
|
||||
case LIPO_archs:
|
||||
if (C.InputFiles.size() > 1)
|
||||
reportError("archs expects a single input file");
|
||||
C.ActionToPerform = LipoAction::PrintArchs;
|
||||
return C;
|
||||
|
||||
default:
|
||||
reportError("llvm-lipo action unspecified");
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
static SmallVector<OwningBinary<Binary>, 1>
|
||||
@ -144,8 +175,6 @@ readInputBinaries(ArrayRef<std::string> InputFiles) {
|
||||
LLVM_ATTRIBUTE_NORETURN
|
||||
static void verifyArch(ArrayRef<OwningBinary<Binary>> InputBinaries,
|
||||
ArrayRef<std::string> VerifyArchList) {
|
||||
assert(!InputBinaries.empty() &&
|
||||
"The list of input binaries should be non-empty");
|
||||
assert(!VerifyArchList.empty() &&
|
||||
"The list of architectures should be non-empty");
|
||||
assert(InputBinaries.size() == 1 && "Incorrect number of input binaries");
|
||||
@ -174,12 +203,55 @@ static void verifyArch(ArrayRef<OwningBinary<Binary>> InputBinaries,
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void printArchOrUnknown(const MachOObjectFile *ObjectFile) {
|
||||
// Prints trailing space and unknown in this format for compatibility with
|
||||
// cctools lipo.
|
||||
const std::string ObjectArch = ObjectFile->getArchTriple().getArchName();
|
||||
if (ObjectArch.empty()) {
|
||||
outs() << "unknown(" << ObjectFile->getHeader().cputype << ","
|
||||
<< ObjectFile->getHeader().cpusubtype << ") ";
|
||||
} else {
|
||||
outs() << ObjectArch + " ";
|
||||
}
|
||||
}
|
||||
|
||||
LLVM_ATTRIBUTE_NORETURN
|
||||
static void printArchs(ArrayRef<OwningBinary<Binary>> InputBinaries) {
|
||||
assert(InputBinaries.size() == 1 && "Incorrect number of input binaries");
|
||||
const Binary *InputBinary = InputBinaries.front().getBinary();
|
||||
if (auto UO = dyn_cast<MachOUniversalBinary>(InputBinary)) {
|
||||
for (MachOUniversalBinary::object_iterator I = UO->begin_objects(),
|
||||
E = UO->end_objects();
|
||||
I != E; ++I) {
|
||||
Expected<std::unique_ptr<MachOObjectFile>> BinaryOrError =
|
||||
I->getAsObjectFile();
|
||||
if (!BinaryOrError)
|
||||
reportError(InputBinary->getFileName(), BinaryOrError.takeError());
|
||||
printArchOrUnknown(BinaryOrError.get().get());
|
||||
}
|
||||
} else if (auto O = dyn_cast<MachOObjectFile>(InputBinary)) {
|
||||
printArchOrUnknown(O);
|
||||
} else {
|
||||
llvm_unreachable("Unexpected binary format");
|
||||
}
|
||||
|
||||
outs() << "\n";
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
InitLLVM X(argc, argv);
|
||||
Config C = parseLipoOptions(makeArrayRef(argv + 1, argc));
|
||||
SmallVector<OwningBinary<Binary>, 1> InputBinaries =
|
||||
readInputBinaries(C.InputFiles);
|
||||
if (!C.VerifyArchList.empty())
|
||||
|
||||
switch (C.ActionToPerform) {
|
||||
case LipoAction::VerifyArch:
|
||||
verifyArch(InputBinaries, C.VerifyArchList);
|
||||
break;
|
||||
case LipoAction::PrintArchs:
|
||||
printArchs(InputBinaries);
|
||||
break;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user