diff --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64-ios.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64-ios.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64-ios.ll @@ -0,0 +1,6 @@ +target triple = "arm64-apple-ios8.0.0" + +define void @_arm64(){ +entry: + ret void +} diff --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64e-ios.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64e-ios.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/arm64e-ios.ll @@ -0,0 +1,6 @@ +target triple = "arm64e-apple-ios8.0.0" + +define void @_arm64e(){ +entry: + ret void +} diff --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/armv7-ios.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/armv7-ios.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/armv7-ios.ll @@ -0,0 +1,6 @@ +target triple = "thumbv7-apple-ios8.0.0" + +define void @_armv7() { +entry: + ret void +} \ No newline at end of file diff --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx-2.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx-2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx-2.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-apple-macosx10.15.0" + +define void @_x86_64_2() { +entry: + ret void +} \ No newline at end of file diff --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64-osx.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-apple-macosx10.15.0" + +define void @_x86_64() { +entry: + ret void +} \ No newline at end of file diff --git a/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64h-osx.ll b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64h-osx.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/Inputs/x86_64h-osx.ll @@ -0,0 +1,6 @@ +target triple = "x86_64h-apple-macosx10.15.0" + +define void @_x86_64_h() { +entry: + ret void +} \ No newline at end of file diff --git a/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test b/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test --- a/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test +++ b/llvm/test/tools/llvm-libtool-darwin/archive-flattening.test @@ -2,17 +2,19 @@ # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o # RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o +# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc ## Input a correct archive: # RUN: rm -f %t.correct.ar -# RUN: llvm-ar cr %t.correct.ar %t-input1.o %t-input2.o +# RUN: llvm-ar cr %t.correct.ar %t-x86_64.bc %t-input1.o %t-input2.o # RUN: llvm-libtool-darwin -static -o %t.lib %t.correct.ar ## Check that binaries are present: # RUN: llvm-ar t %t.lib | \ # RUN: FileCheck %s --check-prefix=CHECK-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp -# CHECK-NAMES: [[PREFIX]]-input1.o +# CHECK-NAMES: [[PREFIX]]-x86_64.bc +# CHECK-NAMES-NEXT: [[PREFIX]]-input1.o # CHECK-NAMES-NEXT: [[PREFIX]]-input2.o ## Check that symbols are present: @@ -20,6 +22,7 @@ # RUN: FileCheck %s --check-prefix=CHECK-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines # CHECK-SYMBOLS: Archive map +# CHECK-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc # CHECK-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o # CHECK-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o # CHECK-SYMBOLS-EMPTY: @@ -30,24 +33,27 @@ # FORMAT: Archive : [[ARCHIVE]] # FORMAT-NEXT: __.SYMDEF +# FORMAT-NEXT: [[PREFIX]]-x86_64.bc # FORMAT-NEXT: [[PREFIX]]-input1.o # FORMAT-NEXT: [[PREFIX]]-input2.o # FORMAT-NOT: {{.}} -## Passing both archive and object file: -# RUN: llvm-libtool-darwin -static -o %t.lib %t-input2.o %t.correct.ar %t-input1.o +## Passing both archive, bitcode and object file: +# RUN: llvm-libtool-darwin -static -o %t.lib %t-x86_64.bc %t.correct.ar %t-input1.o # RUN: llvm-ar t %t.lib | \ # RUN: FileCheck %s --check-prefix=BOTH-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp # RUN: llvm-nm --print-armap %t.lib | \ # RUN: FileCheck %s --check-prefix=BOTH-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines -# BOTH-NAMES: [[PREFIX]]-input2.o +# BOTH-NAMES: [[PREFIX]]-x86_64.bc +# BOTH-NAMES-NEXT: [[PREFIX]]-x86_64.bc # BOTH-NAMES-NEXT: [[PREFIX]]-input1.o # BOTH-NAMES-NEXT: [[PREFIX]]-input2.o # BOTH-NAMES-NEXT: [[PREFIX]]-input1.o # BOTH-SYMBOLS: Archive map -# BOTH-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o +# BOTH-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc +# BOTH-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc # BOTH-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o # BOTH-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o # BOTH-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o diff --git a/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test b/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test --- a/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test +++ b/llvm/test/tools/llvm-libtool-darwin/cpu-subtype-matching.test @@ -1,22 +1,26 @@ ## This test checks that the CPU subtype matching logic is handled correctly. -# RUN: yaml2obj %s --docnum=1 -o %t.armv6 -# RUN: yaml2obj %s --docnum=2 -o %t.armv7 +# RUN: yaml2obj %s --docnum=1 -o %t-armv6.obj +# RUN: yaml2obj %s --docnum=2 -o %t-armv7.obj +# RUN: llvm-as %p/Inputs/arm64-ios.ll -o %t-arm64.bc +# RUN: llvm-as %p/Inputs/armv7-ios.ll -o %t-armv7.bc -# RUN: llvm-libtool-darwin -static -o %t.lib %t.armv6 %t.armv7 -arch_only armv7 +# RUN: llvm-libtool-darwin -static -o %t.lib %t-armv6.obj %t-armv7.obj %t-arm64.bc %t-armv7.bc -arch_only armv7 ## Check that only armv7 binary is present: # RUN: llvm-ar t %t.lib | \ # RUN: FileCheck %s --check-prefix=ARM-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp -# ARM-NAMES: [[PREFIX]].armv7 +# ARM-NAMES: [[PREFIX]]-armv7.obj +# ARM-NAMES-NEXT: [[PREFIX]]-armv7.bc ## Check that only armv7 symbol is present: # RUN: llvm-nm --print-armap %t.lib | \ # RUN: FileCheck %s --check-prefix=ARM-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines # ARM-SYMBOLS: Archive map -# ARM-SYMBOLS-NEXT: _armv7 in [[PREFIX]].armv7 +# ARM-SYMBOLS-NEXT: _armv7 in [[PREFIX]]-armv7.obj +# ARM-SYMBOLS-NEXT: _armv7 in [[PREFIX]]-armv7.bc # ARM-SYMBOLS-EMPTY: ## armv6.yaml @@ -133,23 +137,27 @@ - '' ... -# RUN: yaml2obj %s --docnum=3 -o %t.x86_64 -# RUN: yaml2obj %s --docnum=4 -o %t.x86_64_h +# RUN: yaml2obj %s --docnum=3 -o %t-x86_64.obj +# RUN: yaml2obj %s --docnum=4 -o %t-x86_64_h.obj +# RUN: llvm-as %p/Inputs/x86_64-osx.ll -o %t-x86_64.bc +# RUN: llvm-as %p/Inputs/x86_64h-osx.ll -o %t-x86_64_h.bc -# RUN: llvm-libtool-darwin -static -o %t.lib %t.x86_64 %t.x86_64_h -arch_only x86_64 +# RUN: llvm-libtool-darwin -static -o %t.lib %t-x86_64.obj %t-x86_64_h.obj %t-x86_64.bc %t-x86_64_h.bc -arch_only x86_64 ## Check that only x86_64 binary is present: # RUN: llvm-ar t %t.lib | \ # RUN: FileCheck %s --check-prefix=X86-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp -# X86-NAMES: [[PREFIX]].x86_64 +# X86-NAMES: [[PREFIX]]-x86_64.obj +# X86-NAMES-NEXT: [[PREFIX]]-x86_64.bc ## Check that only x86_64 symbol is present: # RUN: llvm-nm --print-armap %t.lib | \ # RUN: FileCheck %s --check-prefix=X86-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines # X86-SYMBOLS: Archive map -# X86-SYMBOLS-NEXT: _x86_64 in [[PREFIX]].x86_64 +# X86-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.obj +# X86-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc # X86-SYMBOLS-EMPTY: ## x86_64.yaml diff --git a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test --- a/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test +++ b/llvm/test/tools/llvm-libtool-darwin/create-static-lib.test @@ -2,9 +2,10 @@ # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o # RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o +# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc # RUN: rm -rf %t.lib -# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o %t-input2.o +# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o %t-input2.o %t-x86_64.bc ## Check that binaries are present: # RUN: llvm-ar t %t.lib | \ @@ -12,6 +13,7 @@ # CHECK-NAMES: [[PREFIX]]-input1.o # CHECK-NAMES-NEXT: [[PREFIX]]-input2.o +# CHECK-NAMES-NEXT: [[PREFIX]]-x86_64.bc ## Check that symbols are present: # RUN: llvm-nm --print-armap %t.lib | \ @@ -20,6 +22,7 @@ # CHECK-SYMBOLS: Archive map # CHECK-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o # CHECK-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o +# CHECK-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc # CHECK-SYMBOLS-EMPTY: ## Check that output archive is in Darwin format: @@ -30,6 +33,7 @@ # FORMAT-NEXT: __.SYMDEF # FORMAT-NEXT: [[PREFIX]]-input1.o # FORMAT-NEXT: [[PREFIX]]-input2.o +# FORMAT-NEXT: [[PREFIX]]-x86_64.bc # FORMAT-NOT: {{.}} ## Check that the output file is overwritten: diff --git a/llvm/test/tools/llvm-libtool-darwin/filelist.test b/llvm/test/tools/llvm-libtool-darwin/filelist.test --- a/llvm/test/tools/llvm-libtool-darwin/filelist.test +++ b/llvm/test/tools/llvm-libtool-darwin/filelist.test @@ -2,10 +2,12 @@ # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o # RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o +# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc ## Passing files in a listfile: # RUN: echo %t-input1.o > %t.files.txt # RUN: echo %t-input2.o >> %t.files.txt +# RUN: echo %t-x86_64.bc >> %t.files.txt # RUN: llvm-libtool-darwin -static -o %t.lib -filelist %t.files.txt ## Check that binaries are present: @@ -14,6 +16,7 @@ # CHECK-NAMES: [[PREFIX]]-input1.o # CHECK-NAMES-NEXT: [[PREFIX]]-input2.o +# CHECK-NAMES-NEXT: [[PREFIX]]-x86_64.bc ## Check that symbols are present: # RUN: llvm-nm --print-armap %t.lib | \ @@ -22,6 +25,7 @@ # CHECK-SYMBOLS: Archive map # CHECK-SYMBOLS-NEXT: _symbol1 in [[PREFIX]]-input1.o # CHECK-SYMBOLS-NEXT: _symbol2 in [[PREFIX]]-input2.o +# CHECK-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc # CHECK-SYMBOLS-EMPTY: # RUN: rm -rf %t/dirname && mkdir -p %t/dirname diff --git a/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-flattening.test b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-flattening.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-flattening.test @@ -0,0 +1,86 @@ +## This test checks that a universal bitcode file is flattened correctly. + +# RUN: llvm-as %S/Inputs/arm64-ios.ll -o %t-arm64.bc +# RUN: llvm-as %S/Inputs/x86_64-osx.ll -o %t-x86_64.bc +# RUN: llvm-as %S/Inputs/x86_64-osx-2.ll -o %t-x86_64-2.bc +# RUN: llvm-lipo %t-arm64.bc %t-x86_64.bc -create -output %t-universal.o + +# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o -arch_only arm64 + +## Check that the binary is present: +# RUN: llvm-ar t %t.lib | \ +# RUN: FileCheck %s --check-prefix=CHECK-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp + +# CHECK-NAMES: [[PREFIX]]-universal.o + +## Check that symbols are present: +# RUN: llvm-nm --print-armap %t.lib | \ +# RUN: FileCheck %s --check-prefix=CHECK-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines + +# CHECK-SYMBOLS: Archive map +# CHECK-SYMBOLS-NEXT: _arm64 in [[PREFIX]]-universal.o +# CHECK-SYMBOLS-EMPTY: + +## Check that the output archive is in Darwin format: +# RUN: llvm-objdump --macho --archive-headers %t.lib | \ +# RUN: FileCheck %s --check-prefix=FORMAT -DPREFIX=%basename_t.tmp -DARCHIVE=%t.lib + +# FORMAT: Archive : [[ARCHIVE]] +# FORMAT-NEXT: __.SYMDEF +# FORMAT-NEXT: [[PREFIX]]-universal.o +# FORMAT-NOT: {{.}} + +## Passing both a universal file and a bitcode file: +# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o %t-x86_64-2.bc -arch_only x86_64 +# RUN: llvm-ar t %t.lib | \ +# RUN: FileCheck %s --check-prefix=BOTH-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp +# RUN: llvm-nm --print-armap %t.lib | \ +# RUN: FileCheck %s --check-prefix=BOTH-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines + +# BOTH-NAMES: [[PREFIX]]-universal.o +# BOTH-NAMES-NEXT: [[PREFIX]]-x86_64-2.bc + +# BOTH-SYMBOLS: Archive map +# BOTH-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-universal.o +# BOTH-SYMBOLS-NEXT: _x86_64_2 in [[PREFIX]]-x86_64-2.bc +# BOTH-SYMBOLS-EMPTY: + +## Passing both a universal file and a bitcode file but filtering out the object file: +# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o %t-x86_64.bc -arch_only arm64 +# RUN: llvm-ar t %t.lib | \ +# RUN: FileCheck %s --check-prefix=CHECK-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp +# RUN: llvm-nm --print-armap %t.lib | \ +# RUN: FileCheck %s --check-prefix=CHECK-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines + +## Universal file containing an archive: +# RUN: rm -f %t.ar +# RUN: llvm-ar cr %t.ar %t-x86_64.bc %t-x86_64-2.bc +# RUN: llvm-lipo %t.ar -create -output %t-fat-with-archive.o +# RUN: llvm-libtool-darwin -static -o %t.lib %t-fat-with-archive.o +# RUN: llvm-ar t %t.lib | \ +# RUN: FileCheck %s --check-prefix=ARCHIVE-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp +# RUN: llvm-nm --print-armap %t.lib | \ +# RUN: FileCheck %s --check-prefix=ARCHIVE-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines + +# ARCHIVE-NAMES: [[PREFIX]]-x86_64.bc +# ARCHIVE-NAMES-NEXT: [[PREFIX]]-x86_64-2.bc + +# ARCHIVE-SYMBOLS: Archive map +# ARCHIVE-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-x86_64.bc +# ARCHIVE-SYMBOLS-NEXT: _x86_64_2 in [[PREFIX]]-x86_64-2.bc +# ARCHIVE-SYMBOLS-EMPTY: + +## Allow arch_only to be specified more than once (pick the last one): +# RUN: llvm-libtool-darwin -static -o %t.lib %t-universal.o -arch_only arm64 -arch_only x86_64 +# RUN: llvm-ar t %t.lib | \ +# RUN: FileCheck %s --check-prefix=DOUBLE-NAMES --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp +# RUN: llvm-nm --print-armap %t.lib | \ +# RUN: FileCheck %s --check-prefix=DOUBLE-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines + +# DOUBLE-NAMES: [[PREFIX]]-universal.o + +# DOUBLE-SYMBOLS: Archive map +# DOUBLE-SYMBOLS-NEXT: _x86_64 in [[PREFIX]]-universal.o +# DOUBLE-SYMBOLS-EMPTY: + + diff --git a/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-output.test b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-output.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/universal-bitcode-output.test @@ -0,0 +1,75 @@ +## This test checks that a correct universal binary is produced when +## llvm-libtool-darwin is given bitcode for multiple architectures. + +## Check that the subtypes of cputype CPU_TYPE_ARM are stored in a fat file: +# RUN: llvm-as %p/Inputs/arm64-ios.ll -o %t-arm64.bc +# RUN: llvm-as %p/Inputs/armv7-ios.ll -o %t-armv7.bc + +# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-armv7.bc + +## Check that architectures are present in the universal output: +# RUN: llvm-lipo -info %t.lib | \ +# RUN: FileCheck %s --check-prefix=ARCHS -DFILE=%t.lib + +# ARCHS: Architectures in the fat file: [[FILE]] are: armv7 arm64 + +## Check that the files with the same architecture are combined in an archive: +# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-arm64.bc %t-armv7.bc +# RUN: llvm-lipo -info %t.lib | \ +# RUN: FileCheck %s --check-prefix=ARCHS -DFILE=%t.lib +# RUN: llvm-objdump --macho --arch all --all-headers %t.lib | \ +# RUN: FileCheck %s --check-prefix=UNIVERSAL-MEMBERS -DFILE=%t.lib -DPREFIX=%basename_t.tmp --implicit-check-not=Archive + +# UNIVERSAL-MEMBERS: Archive : [[FILE]] (architecture armv7) +# UNIVERSAL-MEMBERS-NEXT: __.SYMDEF +# UNIVERSAL-MEMBERS-NEXT: [[PREFIX]]-armv7.bc +# UNIVERSAL-MEMBERS: Archive : [[FILE]] (architecture arm64) +# UNIVERSAL-MEMBERS-NEXT: __.SYMDEF +# UNIVERSAL-MEMBERS-NEXT: [[PREFIX]]-arm64.bc +# UNIVERSAL-MEMBERS-NEXT: [[PREFIX]]-arm64.bc + +## Check that the files extracted from a universal output are archives: +# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-armv7.bc +# RUN: llvm-lipo %t.lib -thin armv7 -output %t-extracted-v7.a +# RUN: llvm-ar t %t-extracted-v7.a | \ +# RUN: FileCheck %s --check-prefix=EXTRACT --implicit-check-not={{.}} -DPREFIX=%basename_t.tmp +# RUN: llvm-nm --print-armap %t-extracted-v7.a | \ +# RUN: FileCheck %s --check-prefix=EXTRACT-SYMBOLS -DPREFIX=%basename_t.tmp --match-full-lines + +# EXTRACT: [[PREFIX]]-armv7.bc + +# EXTRACT-SYMBOLS: Archive map +# EXTRACT-SYMBOLS-NEXT: _armv7 in [[PREFIX]]-armv7.bc +# EXTRACT-SYMBOLS-EMPTY: + +## Check that the subtypes of cputype CPU_TYPE_X86_64 are stored in a fat file: +# RUN: llvm-as %p/Inputs/x86_64-osx.ll -o %t-x86_64.bc +# RUN: llvm-as %p/Inputs/x86_64h-osx.ll -o %t-x86_64_h.bc +# RUN: llvm-libtool-darwin -static -o %t.lib %t-x86_64.bc %t-x86_64_h.bc +# RUN: llvm-lipo -info %t.lib | \ +# RUN: FileCheck %s --check-prefix=ARCHS-X86 -DFILE=%t.lib + +# ARCHS-X86: Architectures in the fat file: [[FILE]] are: x86_64 x86_64h + +## Check that the subtypes of cputype CPU_TYPE_ARM64 are stored in a fat file: +## Testing it using llvm-objdump as, currently, there is no support for arm64e +## under llvm/lib/Object/MachOObjectFile.cpp. +# RUN: llvm-as %p/Inputs/arm64e-ios.ll -o %t-arm64e.bc +# RUN: llvm-libtool-darwin -static -o %t.lib %t-arm64.bc %t-arm64e.bc +# RUN: llvm-objdump --macho --arch all --all-headers %t.lib | \ +# RUN: FileCheck %s --check-prefix=UNIVERSAL-MEMBERS-ARM64 -DFILE=%t.lib -DPREFIX=%basename_t.tmp --implicit-check-not=Archive + +# UNIVERSAL-MEMBERS-ARM64: Archive : [[FILE]] (architecture arm64) +# UNIVERSAL-MEMBERS-ARM64-NEXT: __.SYMDEF +# UNIVERSAL-MEMBERS-ARM64-NEXT: [[PREFIX]]-arm64.bc +# UNIVERSAL-MEMBERS-ARM64: Archive : [[FILE]] +# UNIVERSAL-MEMBERS-ARM64-NEXT: __.SYMDEF +# UNIVERSAL-MEMBERS-ARM64-NEXT: [[PREFIX]]-arm64e.bc + +## Check that different cputypes are stored together in a fat file: +# RUN: llvm-libtool-darwin -static -o %t.lib %t-armv7.bc %t-x86_64.bc +# RUN: llvm-lipo -info %t.lib | \ +# RUN: FileCheck %s --check-prefix=ARCHS-CPU -DFILE=%t.lib + +# ARCHS-CPU: Architectures in the fat file: [[FILE]] are: armv7 x86_64 + diff --git a/llvm/test/tools/llvm-libtool-darwin/universal-file-flattening.test b/llvm/test/tools/llvm-libtool-darwin/universal-object-flattening.test rename from llvm/test/tools/llvm-libtool-darwin/universal-file-flattening.test rename to llvm/test/tools/llvm-libtool-darwin/universal-object-flattening.test --- a/llvm/test/tools/llvm-libtool-darwin/universal-file-flattening.test +++ b/llvm/test/tools/llvm-libtool-darwin/universal-object-flattening.test @@ -1,4 +1,4 @@ -## This test checks that a universal file is flattened correctly. +## This test checks that a universal object file is flattened correctly. # RUN: yaml2obj %s -o %t-universal.o # RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o diff --git a/llvm/test/tools/llvm-libtool-darwin/universal-output.test b/llvm/test/tools/llvm-libtool-darwin/universal-object-output.test rename from llvm/test/tools/llvm-libtool-darwin/universal-output.test rename to llvm/test/tools/llvm-libtool-darwin/universal-object-output.test --- a/llvm/test/tools/llvm-libtool-darwin/universal-output.test +++ b/llvm/test/tools/llvm-libtool-darwin/universal-object-output.test @@ -1,5 +1,5 @@ ## This test checks that a correct universal binary is produced when -## llvm-libtool-darwin is given inputs for multiple architectures. +## llvm-libtool-darwin is given object files for multiple architectures. ## Check that the subtypes of cputype CPU_TYPE_ARM are stored in a fat file: # RUN: yaml2obj %s -o %t.armv6 -DTYPE=0xC -DSUBTYPE=0x6 -DSTRING=_armv6 diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -11,7 +11,9 @@ //===----------------------------------------------------------------------===// #include "llvm/BinaryFormat/Magic.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Object/ArchiveWriter.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/MachOUniversalWriter.h" @@ -26,6 +28,8 @@ using namespace llvm; using namespace llvm::object; +static LLVMContext LLVMCtx; + typedef std::map> MembersPerArchitectureMap; @@ -252,6 +256,38 @@ return Error::success(); } +static Error verifyAndAddIRObject(MembersPerArchitectureMap &Members, + NewArchiveMember Member, const Config &C) { + auto MBRef = Member.Buf->getMemBufferRef(); + Expected> IROrErr = + object::IRObjectFile::create(MBRef, LLVMCtx); + + // Throw error if not a valid IR object file. + if (!IROrErr) + return createFileError(Member.MemberName, IROrErr.takeError()); + + Triple TT = Triple(IROrErr->get()->getTargetTriple()); + + Expected FileCPUTypeOrErr = MachO::getCPUType(TT); + if (!FileCPUTypeOrErr) + return FileCPUTypeOrErr.takeError(); + + Expected FileCPUSubTypeOrErr = MachO::getCPUSubType(TT); + if (!FileCPUSubTypeOrErr) + return FileCPUSubTypeOrErr.takeError(); + + // If -arch_only is specified then skip this file if it doesn't match + // the architecture specified. + if (!ArchType.empty() && + !acceptFileArch(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr, C)) { + return Error::success(); + } + + uint64_t FileCPUID = getCPUID(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr); + Members[FileCPUID].push_back(std::move(Member)); + return Error::success(); +} + static Error addChildMember(MembersPerArchitectureMap &Members, const object::Archive::Child &M, const Config &C) { Expected NMOrErr = @@ -259,6 +295,11 @@ if (!NMOrErr) return NMOrErr.takeError(); + file_magic Magic = identify_magic(NMOrErr->Buf->getBuffer()); + + if (Magic == file_magic::bitcode) + return verifyAndAddIRObject(Members, std::move(*NMOrErr), C); + if (Error E = verifyAndAddMachOObject(Members, std::move(*NMOrErr), C)) return E; @@ -320,21 +361,41 @@ continue; } + Expected> IRObjectOrError = + O.getAsIRObject(LLVMCtx); + if (IRObjectOrError) { + // A universal file member can be a MachOObjectFile, an IRObject or an + // Archive. In case we can successfully cast the member as an IRObject, it + // is safe to throw away the error generated due to casting the object as + // a MachOObjectFile. + consumeError(MachOObjOrErr.takeError()); + + NewArchiveMember NewMember = + NewArchiveMember(IRObjectOrError->get()->getMemoryBufferRef()); + NewMember.MemberName = sys::path::filename(NewMember.MemberName); + + if (Error E = verifyAndAddIRObject(Members, std::move(NewMember), C)) + return E; + continue; + } + Expected> ArchiveOrError = O.getAsArchive(); if (ArchiveOrError) { - // A universal file member can either be a MachOObjectFile or an Archive. - // In case we can successfully cast the member as an Archive, it is safe - // to throw away the error generated due to casting the object as a - // MachOObjectFile. + // A universal file member can be a MachOObjectFile, an IRObject or an + // Archive. In case we can successfully cast the member as an Archive, it + // is safe to throw away the error generated due to casting the object as + // a MachOObjectFile. consumeError(MachOObjOrErr.takeError()); + consumeError(IRObjectOrError.takeError()); if (Error E = processArchive(Members, **ArchiveOrError, FileName, C)) return E; continue; } - Error CombinedError = - joinErrors(ArchiveOrError.takeError(), MachOObjOrErr.takeError()); + Error CombinedError = joinErrors( + ArchiveOrError.takeError(), + joinErrors(IRObjectOrError.takeError(), MachOObjOrErr.takeError())); return createFileError(FileName, std::move(CombinedError)); } @@ -367,6 +428,10 @@ return addUniversalMembers(Members, FileBuffers, std::move(*NMOrErr), FileName, C); + // Bitcode files. + if (Magic == file_magic::bitcode) + return verifyAndAddIRObject(Members, std::move(*NMOrErr), C); + if (Error E = verifyAndAddMachOObject(Members, std::move(*NMOrErr), C)) return E; return Error::success(); @@ -378,7 +443,7 @@ for (const auto &OB : OutputBinaries) { const Archive &A = *OB.getBinary(); - Expected ArchiveSlice = Slice::create(A); + Expected ArchiveSlice = Slice::create(A, &LLVMCtx); if (!ArchiveSlice) return ArchiveSlice.takeError(); Slices.push_back(*ArchiveSlice);