1
0
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:
Shoaib Meenai 2019-06-07 20:47:58 +00:00
parent 2d127b3a65
commit 2365b4ea23
9 changed files with 254 additions and 13 deletions

View 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
...

View 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
...

View 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
...

View 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
...

View 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
...

View File

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

View File

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

View File

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

View 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;
}