[llvm] r373132 - [llvm-lipo] Add support for -arch
Alexander Shaposhnikov via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 27 15:33:18 PDT 2019
Author: alexshap
Date: Fri Sep 27 15:33:18 2019
New Revision: 373132
URL: http://llvm.org/viewvc/llvm-project?rev=373132&view=rev
Log:
[llvm-lipo] Add support for -arch
Add support for -arch.
Differential revision: https://reviews.llvm.org/D68116
Test plan: make check-all
Added:
llvm/trunk/test/tools/llvm-lipo/create-arch.test
Modified:
llvm/trunk/test/tools/llvm-lipo/replace-invalid-input.test
llvm/trunk/tools/llvm-lipo/LipoOpts.td
llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp
Added: llvm/trunk/test/tools/llvm-lipo/create-arch.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-lipo/create-arch.test?rev=373132&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-lipo/create-arch.test (added)
+++ llvm/trunk/test/tools/llvm-lipo/create-arch.test Fri Sep 27 15:33:18 2019
@@ -0,0 +1,17 @@
+# RUN: yaml2obj %p/Inputs/i386-slice.yaml > %t-i386.o
+# RUN: yaml2obj %p/Inputs/x86_64-slice.yaml > %t-x86_64.o
+
+# RUN: llvm-lipo %t-i386.o %t-x86_64.o -create -output %t-universal.o
+# RUN: llvm-lipo %t-i386.o -arch x86_64 %t-x86_64.o -create -output %t-universal-1.o
+# RUN: cmp %t-universal.o %t-universal-1.o
+# RUN: llvm-lipo -arch i386 %t-i386.o -arch x86_64 %t-x86_64.o -create -output %t-universal-2.o
+# RUN: cmp %t-universal.o %t-universal-2.o
+#
+# RUN: not llvm-lipo -arch armv7 %t-i386.o -arch x86_64 %t-x86_64.o -create -output /dev/null 2>&1 | FileCheck --check-prefix=ARCH_NOT_MATCHED %s
+# ARCH_NOT_MATCHED: error: specified architecture: armv7 for file: {{.*}} does not match the file's architecture (i386)
+#
+# # RUN: not llvm-lipo -arch i3866 %t-32.o -create -o /dev/null 2>&1 | FileCheck --check-prefix=INVALID_ARCH %s
+# INVALID_ARCH: error: Invalid architecture: i3866
+#
+# RUN: not llvm-lipo -arch i386 %t-33.o -create -o /dev/null 2>&1 | FileCheck --check-prefix=INVALID_FILE %s
+# INVALID_FILE: {{[nN]}}o such file or directory
Modified: llvm/trunk/test/tools/llvm-lipo/replace-invalid-input.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-lipo/replace-invalid-input.test?rev=373132&r1=373131&r2=373132&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-lipo/replace-invalid-input.test (original)
+++ llvm/trunk/test/tools/llvm-lipo/replace-invalid-input.test Fri Sep 27 15:33:18 2019
@@ -5,20 +5,20 @@
# RUN: not llvm-lipo %t-universal.o -replace %t-32.o 2>&1 | FileCheck --check-prefix=MISSING_ARG %s
# MISSING_ARG: error: replace is missing an argument: expects -replace arch_type file_name
-# RUN: not llvm-lipo %t-universal.o -replace %t-32.o i386 2>&1 | FileCheck --check-prefix=OUTPUT_FILE %s
+# RUN: not llvm-lipo %t-universal.o -replace i386 %t-32.o 2>&1 | FileCheck --check-prefix=OUTPUT_FILE %s
# OUTPUT_FILE: error: replace expects a single output file to be specified
-# RUN: not llvm-lipo %t-universal.o %t-universal.o -replace %t-32.o i386 -o %t.o 2>&1 | FileCheck --check-prefix=INPUT_ARGS %s
+# RUN: not llvm-lipo %t-universal.o %t-universal.o -replace i386 %t-32.o -o %t.o 2>&1 | FileCheck --check-prefix=INPUT_ARGS %s
# INPUT_ARGS: error: replace expects a single input file
-# RUN: not llvm-lipo %t-universal.o -replace %t-32.o i386 -o %t.o 2>&1 | FileCheck --check-prefix=INVALID_FILE %s
-# INVALID_FILE: error: 'i386': {{[nN]}}o such file or directory
+# RUN: not llvm-lipo %t-universal.o -replace i386 %t-33.o -o %t.o 2>&1 | FileCheck --check-prefix=INVALID_FILE %s
+# INVALID_FILE: {{[nN]}}o such file or directory
# RUN: not llvm-lipo %t-universal.o -replace i3866 %t-32.o -o %t.o 2>&1 | FileCheck --check-prefix=INVALID_ARCH %s
# INVALID_ARCH: error: Invalid architecture: i3866
# RUN: not llvm-lipo %t-universal.o -replace arm64 %t-32.o -o %t.o 2>&1 | FileCheck --check-prefix=ARCH_NOT_MATCHED %s
-# ARCH_NOT_MATCHED: error: specified architecture: arm64 for replacement file: {{.*}} does not match the file's architecture
+# ARCH_NOT_MATCHED: error: specified architecture: arm64 for file: {{.*}} does not match the file's architecture (i386)
# RUN: not llvm-lipo %t-universal.o -replace arm64 %t-arm64.o -o %t.o 2>&1 | FileCheck --check-prefix=ARCH_NOT_IN_INPUT %s
# ARCH_NOT_IN_INPUT: error: -replace arm64 <file_name> specified but fat file: {{.*}} does not contain that architecture
Modified: llvm/trunk/tools/llvm-lipo/LipoOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lipo/LipoOpts.td?rev=373132&r1=373131&r2=373132&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-lipo/LipoOpts.td (original)
+++ llvm/trunk/tools/llvm-lipo/LipoOpts.td Fri Sep 27 15:33:18 2019
@@ -12,6 +12,10 @@ def segalign
"architecture when creating a universal binary file. The "
"alignment is a hexadecimal number that is a power of 2.">;
+def arch
+ : MultiArg<["-", "--"], "arch", 2>,
+ HelpText<"Specifies the architecture and the corresponding input file">;
+
def action_group : OptionGroup<"action group">;
def verify_arch
Modified: llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp?rev=373132&r1=373131&r2=373132&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp (original)
+++ llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp Fri Sep 27 15:33:18 2019
@@ -86,15 +86,15 @@ enum class LipoAction {
ReplaceArch,
};
-struct Replacement {
- StringRef ArchType;
+struct InputFile {
+ Optional<StringRef> ArchType;
StringRef FileName;
};
struct Config {
- SmallVector<std::string, 1> InputFiles;
+ SmallVector<InputFile, 1> InputFiles;
SmallVector<std::string, 1> VerifyArchList;
- SmallVector<Replacement, 1> Replacements;
+ SmallVector<InputFile, 1> ReplacementFiles;
StringMap<const uint32_t> SegmentAlignments;
std::string ThinArchType;
std::string OutputFile;
@@ -301,7 +301,15 @@ static Config parseLipoOptions(ArrayRef<
reportError("unknown argument '" + Arg->getAsString(InputArgs) + "'");
for (auto Arg : InputArgs.filtered(LIPO_INPUT))
- C.InputFiles.push_back(Arg->getValue());
+ C.InputFiles.push_back({None, Arg->getValue()});
+ for (auto Arg : InputArgs.filtered(LIPO_arch)) {
+ validateArchitectureName(Arg->getValue(0));
+ if (!Arg->getValue(1))
+ reportError(
+ "arch is missing an argument: expects -arch arch_type file_name");
+ C.InputFiles.push_back({StringRef(Arg->getValue(0)), Arg->getValue(1)});
+ }
+
if (C.InputFiles.empty())
reportError("at least one input file should be specified");
@@ -402,8 +410,9 @@ static Config parseLipoOptions(ArrayRef<
reportError(
"replace is missing an argument: expects -replace arch_type "
"file_name");
- C.Replacements.push_back(
- Replacement{Action->getValue(0), Action->getValue(1)});
+ validateArchitectureName(Action->getValue(0));
+ C.ReplacementFiles.push_back(
+ {StringRef(Action->getValue(0)), Action->getValue(1)});
}
if (C.OutputFile.empty())
@@ -419,16 +428,25 @@ static Config parseLipoOptions(ArrayRef<
}
static SmallVector<OwningBinary<Binary>, 1>
-readInputBinaries(ArrayRef<std::string> InputFiles) {
+readInputBinaries(ArrayRef<InputFile> InputFiles) {
SmallVector<OwningBinary<Binary>, 1> InputBinaries;
- for (StringRef InputFile : InputFiles) {
- Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(InputFile);
+ for (const InputFile &IF : InputFiles) {
+ Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(IF.FileName);
if (!BinaryOrErr)
- reportError(InputFile, BinaryOrErr.takeError());
- if (!BinaryOrErr->getBinary()->isArchive() &&
- !BinaryOrErr->getBinary()->isMachO() &&
- !BinaryOrErr->getBinary()->isMachOUniversalBinary())
- reportError("File " + InputFile + " has unsupported binary format");
+ reportError(IF.FileName, BinaryOrErr.takeError());
+ const Binary *B = BinaryOrErr->getBinary();
+ if (!B->isArchive() && !B->isMachO() && !B->isMachOUniversalBinary())
+ reportError("File " + IF.FileName + " has unsupported binary format");
+ if (IF.ArchType && (B->isMachO() || B->isArchive())) {
+ const auto ArchType =
+ B->isMachO() ? Slice(cast<MachOObjectFile>(B)).getArchString()
+ : Slice(cast<Archive>(B)).getArchString();
+ if (Triple(*IF.ArchType).getArch() != Triple(ArchType).getArch())
+ reportError("specified architecture: " + *IF.ArchType +
+ " for file: " + B->getFileName() +
+ " does not match the file's architecture (" + ArchType +
+ ")");
+ }
InputBinaries.push_back(std::move(*BinaryOrErr));
}
return InputBinaries;
@@ -716,32 +734,20 @@ static void createUniversalBinary(ArrayR
static StringMap<Slice>
buildReplacementSlices(ArrayRef<OwningBinary<Binary>> ReplacementBinaries,
- const StringMap<const uint32_t> &Alignments,
- ArrayRef<Replacement> Replacements) {
- assert(ReplacementBinaries.size() == Replacements.size() &&
- "Number of replacment binaries does not match the number of "
- "replacements");
+ const StringMap<const uint32_t> &Alignments) {
StringMap<Slice> Slices;
// populates StringMap of slices to replace with; error checks for mismatched
// replace flag args, fat files, and duplicate arch_types
- for (size_t Index = 0, Size = Replacements.size(); Index < Size; ++Index) {
- StringRef ReplacementArch = Replacements[Index].ArchType;
- const Binary *ReplacementBinary = ReplacementBinaries[Index].getBinary();
- validateArchitectureName(ReplacementArch);
-
+ for (const auto &OB : ReplacementBinaries) {
+ const Binary *ReplacementBinary = OB.getBinary();
auto O = dyn_cast<MachOObjectFile>(ReplacementBinary);
if (!O)
reportError("replacement file: " + ReplacementBinary->getFileName() +
" is a fat file (must be a thin file)");
-
- if (O->getArch() != Triple(ReplacementArch).getArch())
- reportError("specified architecture: " + ReplacementArch +
- " for replacement file: " + ReplacementBinary->getFileName() +
- " does not match the file's architecture");
-
- auto Entry = Slices.try_emplace(ReplacementArch, Slice(O));
+ Slice S(O);
+ auto Entry = Slices.try_emplace(S.getArchString(), S);
if (!Entry.second)
- reportError("-replace " + ReplacementArch +
+ reportError("-replace " + S.getArchString() +
" <file_name> specified multiple times: " +
Entry.first->second.getBinary()->getFileName() + ", " +
O->getFileName());
@@ -756,7 +762,7 @@ LLVM_ATTRIBUTE_NORETURN
static void replaceSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
const StringMap<const uint32_t> &Alignments,
StringRef OutputFileName,
- ArrayRef<Replacement> Replacements) {
+ ArrayRef<InputFile> ReplacementFiles) {
assert(InputBinaries.size() == 1 && "Incorrect number of input binaries");
assert(!OutputFileName.empty() && "Replace expects a single output file");
@@ -765,14 +771,11 @@ static void replaceSlices(ArrayRef<Ownin
InputBinaries.front().getBinary()->getFileName() +
" must be a fat file when the -replace option is specified");
- SmallVector<std::string, 1> ReplacementFiles;
- for (const auto &R : Replacements)
- ReplacementFiles.push_back(R.FileName);
SmallVector<OwningBinary<Binary>, 1> ReplacementBinaries =
readInputBinaries(ReplacementFiles);
StringMap<Slice> ReplacementSlices =
- buildReplacementSlices(ReplacementBinaries, Alignments, Replacements);
+ buildReplacementSlices(ReplacementBinaries, Alignments);
SmallVector<std::unique_ptr<MachOObjectFile>, 2> ExtractedObjects;
SmallVector<Slice, 2> Slices =
buildSlices(InputBinaries, Alignments, ExtractedObjects);
@@ -820,7 +823,7 @@ int main(int argc, char **argv) {
break;
case LipoAction::ReplaceArch:
replaceSlices(InputBinaries, C.SegmentAlignments, C.OutputFile,
- C.Replacements);
+ C.ReplacementFiles);
break;
}
return EXIT_SUCCESS;
More information about the llvm-commits
mailing list