ART: PIC testing

Adds run-test support for PIC testing.

For the core image, enable with ART_TEST_PIC_IMAGE=true.
For the tests themselves, enable with ART_TEST_PIC_TEST=true.
Off by default.

Bug: 18035729
Change-Id: I23e396a2fa47b9471145f45b3c63f447871ebebf
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index ca718f1..2493565 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -63,6 +63,12 @@
 # Do you want optimizing compiler tests run?
 ART_TEST_OPTIMIZING ?= $(ART_TEST_FULL)
 
+# Do we want to test a PIC-compiled core image?
+ART_TEST_PIC_IMAGE ?= $(ART_TEST_FULL)
+
+# Do we want to test PIC-compiled tests ("apps")?
+ART_TEST_PIC_TEST ?= $(ART_TEST_FULL)
+
 # Do you want tracing tests run?
 ART_TEST_TRACE ?= $(ART_TEST_FULL)
 
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index db7257a..9e640c6 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -59,11 +59,11 @@
 ART_GTEST_transaction_test_DEX_DEPS := Transaction
 
 # The elf writer test has dependencies on core.oat.
-ART_GTEST_elf_writer_test_HOST_DEPS := $(HOST_CORE_OAT_OUT) $(2ND_HOST_CORE_OAT_OUT)
-ART_GTEST_elf_writer_test_TARGET_DEPS := $(TARGET_CORE_OAT_OUT) $(2ND_TARGET_CORE_OAT_OUT)
+ART_GTEST_elf_writer_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
+ART_GTEST_elf_writer_test_TARGET_DEPS := $(TARGET_CORE_IMAGE_default_no-pic_64) $(TARGET_CORE_IMAGE_default_no-pic_32)
 ART_GTEST_jni_internal_test_TARGET_DEPS := $(TARGET_CORE_DEX_FILES)
 ART_GTEST_proxy_test_TARGET_DEPS := $(TARGET_CORE_DEX_FILES)
-ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_OAT_OUT) $(2ND_HOST_CORE_OAT_OUT)
+ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
 
 # The path for which all the source files are relative, not actually the current directory.
 LOCAL_PATH := art
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index 823ef7d..80a000b 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -24,8 +24,9 @@
 include art/build/Android.common_build.mk
 
 # Use dex2oat debug version for better error reporting
-# $(1): compiler
-# $(2): 2ND_ or undefined, 2ND_ for 32-bit host builds.
+# $(1): compiler - default, optimizing or interpreter.
+# $(2): pic/no-pic
+# $(3): 2ND_ or undefined, 2ND_ for 32-bit host builds.
 # NB depending on HOST_CORE_DEX_LOCATIONS so we are sure to have the dex files in frameworks for
 # run-test --no-image
 define create-core-oat-host-rules
@@ -33,6 +34,7 @@
   core_image_name :=
   core_oat_name :=
   core_infix :=
+  core_pic_infix :=
 
   ifeq ($(1),optimizing)
     core_compile_options += --compiler-backend=optimizing
@@ -49,14 +51,27 @@
     #Technically this test is not precise, but hopefully good enough.
     $$(error found $(1) expected default, interpreter or optimizing)
   endif
-  core_image_name := $($(2)HOST_CORE_IMG_OUT_BASE)$$(core_infix)$(CORE_IMG_SUFFIX)
-  core_oat_name := $($(2)HOST_CORE_OAT_OUT_BASE)$$(core_infix)$(CORE_OAT_SUFFIX)
+
+  ifeq ($(2),pic)
+    core_compile_options += --compile-pic
+    core_pic_infix := -pic
+  endif
+  ifeq ($(2),no-pic)
+    # No change for non-pic
+  endif
+  ifneq ($(filter-out pic no-pic,$(2)),)
+    # Technically this test is not precise, but hopefully good enough.
+    $$(error found $(2) expected pic or no-pic)
+  endif
+
+  core_image_name := $($(3)HOST_CORE_IMG_OUT_BASE)$$(core_infix)$$(core_pic_infix)$(CORE_IMG_SUFFIX)
+  core_oat_name := $($(3)HOST_CORE_OAT_OUT_BASE)$$(core_infix)$$(core_pic_infix)$(CORE_OAT_SUFFIX)
 
   # Using the bitness suffix makes it easier to add as a dependency for the run-test mk.
-  ifeq ($(2),)
-    HOST_CORE_IMAGE_$(1)_64 := $$(core_image_name)
+  ifeq ($(3),)
+    HOST_CORE_IMAGE_$(1)_$(2)_64 := $$(core_image_name)
   else
-    HOST_CORE_IMAGE_$(1)_32 := $$(core_image_name)
+    HOST_CORE_IMAGE_$(1)_$(2)_32 := $$(core_image_name)
   endif
   HOST_CORE_IMG_OUTS += $$(core_image_name)
   HOST_CORE_OAT_OUTS += $$(core_oat_name)
@@ -71,8 +86,8 @@
 	  --image-classes=$$(PRELOADED_CLASSES) $$(addprefix --dex-file=,$$(HOST_CORE_DEX_FILES)) \
 	  $$(addprefix --dex-location=,$$(HOST_CORE_DEX_LOCATIONS)) --oat-file=$$(PRIVATE_CORE_OAT_NAME) \
 	  --oat-location=$$(PRIVATE_CORE_OAT_NAME) --image=$$(PRIVATE_CORE_IMG_NAME) \
-	  --base=$$(LIBART_IMG_HOST_BASE_ADDRESS) --instruction-set=$$($(2)ART_HOST_ARCH) \
-	  --instruction-set-features=$$($(2)HOST_INSTRUCTION_SET_FEATURES) \
+	  --base=$$(LIBART_IMG_HOST_BASE_ADDRESS) --instruction-set=$$($(3)ART_HOST_ARCH) \
+	  --instruction-set-features=$$($(3)HOST_INSTRUCTION_SET_FEATURES) \
 	  --host --android-root=$$(HOST_OUT) --include-patch-information \
 	  $$(PRIVATE_CORE_COMPILE_OPTIONS)
 
@@ -83,22 +98,31 @@
   core_image_name :=
   core_oat_name :=
   core_infix :=
+  core_pic_infix :=
 endef  # create-core-oat-host-rules
 
-$(eval $(call create-core-oat-host-rules,default,))
-$(eval $(call create-core-oat-host-rules,optimizing,))
-$(eval $(call create-core-oat-host-rules,interpreter,))
-ifneq ($(HOST_PREFER_32_BIT),true)
-$(eval $(call create-core-oat-host-rules,default,2ND_))
-$(eval $(call create-core-oat-host-rules,optimizing,2ND_))
-$(eval $(call create-core-oat-host-rules,interpreter,2ND_))
-endif
+# $(1): compiler - default, optimizing or interpreter.
+define create-core-oat-host-rule-combination
+  $(call create-core-oat-host-rules,$(1),no-pic,)
+  $(call create-core-oat-host-rules,$(1),pic,)
+
+  ifneq ($(HOST_PREFER_32_BIT),true)
+    $(call create-core-oat-host-rules,$(1),no-pic,2ND_)
+    $(call create-core-oat-host-rules,$(1),pic,2ND_)
+  endif
+endef
+
+$(eval $(call create-core-oat-host-rule-combination,default))
+$(eval $(call create-core-oat-host-rule-combination,optimizing))
+$(eval $(call create-core-oat-host-rule-combination,interpreter))
+
 
 define create-core-oat-target-rules
   core_compile_options :=
   core_image_name :=
   core_oat_name :=
   core_infix :=
+  core_pic_infix :=
 
   ifeq ($(1),optimizing)
     core_compile_options += --compiler-backend=optimizing
@@ -112,17 +136,34 @@
     # Default has no infix, no compile options.
   endif
   ifneq ($(filter-out default interpreter optimizing,$(1)),)
-    #Technically this test is not precise, but hopefully good enough.
+    # Technically this test is not precise, but hopefully good enough.
     $$(error found $(1) expected default, interpreter or optimizing)
   endif
-  core_image_name := $($(2)TARGET_CORE_IMG_OUT_BASE)$$(core_infix)$(CORE_IMG_SUFFIX)
-  core_oat_name := $($(2)TARGET_CORE_OAT_OUT_BASE)$$(core_infix)$(CORE_OAT_SUFFIX)
+
+  ifeq ($(2),pic)
+    core_compile_options += --compile-pic
+    core_pic_infix := -pic
+  endif
+  ifeq ($(2),no-pic)
+    # No change for non-pic
+  endif
+  ifneq ($(filter-out pic no-pic,$(2)),)
+    #Technically this test is not precise, but hopefully good enough.
+    $$(error found $(2) expected pic or no-pic)
+  endif
+
+  core_image_name := $($(3)TARGET_CORE_IMG_OUT_BASE)$$(core_infix)$$(core_pic_infix)$(CORE_IMG_SUFFIX)
+  core_oat_name := $($(3)TARGET_CORE_OAT_OUT_BASE)$$(core_infix)$$(core_pic_infix)$(CORE_OAT_SUFFIX)
 
   # Using the bitness suffix makes it easier to add as a dependency for the run-test mk.
-  ifeq ($(2),)
-    TARGET_CORE_IMAGE_$(1)_64 := $$(core_image_name)
+  ifeq ($(3),)
+    ifdef TARGET_2ND_ARCH
+      TARGET_CORE_IMAGE_$(1)_$(2)_64 := $$(core_image_name)
+    else
+      TARGET_CORE_IMAGE_$(1)_$(2)_32 := $$(core_image_name)
+    endif
   else
-    TARGET_CORE_IMAGE_$(1)_32 := $$(core_image_name)
+    TARGET_CORE_IMAGE_$(1)_$(2)_32 := $$(core_image_name)
   endif
   TARGET_CORE_IMG_OUTS += $$(core_image_name)
   TARGET_CORE_OAT_OUTS += $$(core_oat_name)
@@ -137,8 +178,8 @@
 	  --image-classes=$$(PRELOADED_CLASSES) $$(addprefix --dex-file=,$$(TARGET_CORE_DEX_FILES)) \
 	  $$(addprefix --dex-location=,$$(TARGET_CORE_DEX_LOCATIONS)) --oat-file=$$(PRIVATE_CORE_OAT_NAME) \
 	  --oat-location=$$(PRIVATE_CORE_OAT_NAME) --image=$$(PRIVATE_CORE_IMG_NAME) \
-	  --base=$$(LIBART_IMG_TARGET_BASE_ADDRESS) --instruction-set=$$($(2)TARGET_ARCH) \
-	  --instruction-set-features=$$($(2)TARGET_INSTRUCTION_SET_FEATURES) \
+	  --base=$$(LIBART_IMG_TARGET_BASE_ADDRESS) --instruction-set=$$($(3)TARGET_ARCH) \
+	  --instruction-set-features=$$($(3)TARGET_INSTRUCTION_SET_FEATURES) \
 	  --android-root=$$(PRODUCT_OUT)/system --include-patch-information \
 	  $$(PRIVATE_CORE_COMPILE_OPTIONS)
 
@@ -149,13 +190,20 @@
   core_image_name :=
   core_oat_name :=
   core_infix :=
+  core_pic_infix :=
 endef  # create-core-oat-target-rules
 
-ifdef TARGET_2ND_ARCH
-$(eval $(call create-core-oat-target-rules,default,2ND_))
-$(eval $(call create-core-oat-target-rules,optimizing,2ND_))
-$(eval $(call create-core-oat-target-rules,interpreter,2ND_))
-endif
-$(eval $(call create-core-oat-target-rules,default,))
-$(eval $(call create-core-oat-target-rules,optimizing,))
-$(eval $(call create-core-oat-target-rules,interpreter,))
+# $(1): compiler - default, optimizing or interpreter.
+define create-core-oat-target-rule-combination
+  $(call create-core-oat-target-rules,$(1),no-pic,)
+  $(call create-core-oat-target-rules,$(1),pic,)
+
+  ifdef TARGET_2ND_ARCH
+    $(call create-core-oat-target-rules,$(1),no-pic,2ND_)
+    $(call create-core-oat-target-rules,$(1),pic,2ND_)
+  endif
+endef
+
+$(eval $(call create-core-oat-target-rule-combination,default))
+$(eval $(call create-core-oat-target-rule-combination,optimizing))
+$(eval $(call create-core-oat-target-rule-combination,interpreter))
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 32dbc86..2bff720 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -113,6 +113,13 @@
 ifeq ($(ART_TEST_RUN_TEST_NO_IMAGE),true)
   IMAGE_TYPES += no-image
 endif
+ifeq ($(ART_TEST_PIC_IMAGE),true)
+  IMAGE_TYPES += picimage
+endif
+PICTEST_TYPES := nopictest
+ifeq ($(ART_TEST_PIC_TEST),true)
+  PICTEST_TYPES += pictest
+endif
 RUN_TYPES :=
 ifeq ($(ART_TEST_RUN_TEST_DEBUG),true)
   RUN_TYPES += debug
@@ -139,10 +146,11 @@
               $(foreach gc, $(7), \
                 $(foreach jni, $(8), \
                   $(foreach image, $(9), \
-                    $(foreach test, $(10), \
-                      $(foreach address_size, $(11), \
-                        test-art-$(target)-run-test-$(run-type)-$(prebuild)-$(compiler)-$(relocate)-$(trace)-$(gc)-$(jni)-$(image)-$(test)$(address_size) \
-                    )))))))))))
+                    $(foreach pictest, $(10), \
+                      $(foreach test, $(11), \
+                        $(foreach address_size, $(12), \
+                          test-art-$(target)-run-test-$(run-type)-$(prebuild)-$(compiler)-$(relocate)-$(trace)-$(gc)-$(jni)-$(image)-$(pictest)-$(test)$(address_size) \
+                    ))))))))))))
 endef  # all-run-test-names
 
 # To generate a full list or tests:
@@ -164,7 +172,7 @@
 ifdef dist_goal
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
         $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-        $(IMAGE_TYPES), $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+        $(IMAGE_TYPES), $(PICTEST_TYPES), $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_TIMING_SENSITIVE_RUN_TESTS :=
@@ -174,7 +182,7 @@
 
 ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
       $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES), $(TEST_ART_BROKEN_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+      $(IMAGE_TYPES), $(PICTEST_TYPES), $(TEST_ART_BROKEN_RUN_TESTS), $(ALL_ADDRESS_SIZES))
 
 TEST_ART_BROKEN_RUN_TESTS :=
 
@@ -185,7 +193,7 @@
 ifneq (,$(filter prebuild,$(PREBUILD_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),prebuild, \
       $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES), $(TEST_ART_BROKEN_PREBUILD_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+      $(IMAGE_TYPES), $(PICTEST_TYPES), $(TEST_ART_BROKEN_PREBUILD_RUN_TESTS), $(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_PREBUILD_RUN_TESTS :=
@@ -196,7 +204,7 @@
 ifneq (,$(filter no-prebuild,$(PREBUILD_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),no-prebuild, \
       $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES), $(TEST_ART_BROKEN_NO_PREBUILD_TESTS), $(ALL_ADDRESS_SIZES))
+      $(IMAGE_TYPES), $(PICTEST_TYPES), $(TEST_ART_BROKEN_NO_PREBUILD_TESTS), $(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_NO_PREBUILD_TESTS :=
@@ -209,7 +217,7 @@
 ifneq (,$(filter no-relocate,$(RELOCATE_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
       $(COMPILER_TYPES), no-relocate,$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES), $(TEST_ART_BROKEN_NO_RELOCATE_TESTS), $(ALL_ADDRESS_SIZES))
+      $(IMAGE_TYPES), $(PICTEST_TYPES), $(TEST_ART_BROKEN_NO_RELOCATE_TESTS), $(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_NO_RELOCATE_TESTS :=
@@ -222,14 +230,14 @@
 ifneq (,$(filter gcstress,$(GC_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
       $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),gcstress,$(JNI_TYPES), \
-      $(IMAGE_TYPES), $(TEST_ART_BROKEN_GCSTRESS_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+      $(IMAGE_TYPES), $(PICTEST_TYPES), $(TEST_ART_BROKEN_GCSTRESS_RUN_TESTS), $(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_GCSTRESS_RUN_TESTS :=
 
 # 115-native-bridge setup is complicated. Need to implement it correctly for the target.
 ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES),$(COMPILER_TYPES), \
-    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES),115-native-bridge, \
+    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES),$(PICTEST_TYPES),115-native-bridge, \
     $(ALL_ADDRESS_SIZES))
 
 # All these tests check that we have sane behavior if we don't have a patchoat or dex2oat.
@@ -244,20 +252,20 @@
 ifneq (,$(filter no-dex2oat,$(PREBUILD_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),no-dex2oat, \
       $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
-      $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+      $(PICTEST_TYPES),$(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
 endif
 
 
 ifneq (,$(filter no-image,$(IMAGE_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
       $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),no-image, \
-      $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+      $(PICTEST_TYPES), $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
 endif
 
 ifneq (,$(filter relocate-no-patchoat,$(RELOCATE_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
       $(COMPILER_TYPES), relocate-no-patchoat,$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES),$(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+      $(IMAGE_TYPES),$(PICTEST_TYPES),$(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_FALLBACK_RUN_TESTS :=
@@ -280,7 +288,7 @@
 ifneq (,$(filter ndebug,$(RUN_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),ndebug,$(PREBUILD_TYPES), \
       $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
-      $(TEST_ART_BROKEN_NDEBUG_TESTS),$(ALL_ADDRESS_SIZES))
+      $(PICTEST_TYPES),$(TEST_ART_BROKEN_NDEBUG_TESTS),$(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_NDEBUG_TESTS :=
@@ -292,7 +300,7 @@
 ifneq (,$(filter default,$(COMPILER_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
       default,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES),$(TEST_ART_BROKEN_DEFAULT_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+      $(IMAGE_TYPES),$(PICTEST_TYPES),$(TEST_ART_BROKEN_DEFAULT_RUN_TESTS),$(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_BROKEN_DEFAULT_RUN_TESTS :=
@@ -332,7 +340,7 @@
 ifneq (,$(filter optimizing,$(COMPILER_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \
       optimizing,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-      $(IMAGE_TYPES),$(TEST_ART_BROKEN_OPTIMIZING_ARM64_RUN_TESTS),64)
+      $(IMAGE_TYPES),$(PICTEST_TYPES),$(TEST_ART_BROKEN_OPTIMIZING_ARM64_RUN_TESTS),64)
 endif
 
 TEST_ART_BROKEN_OPTIMIZING_ARM64_RUN_TESTS :=
@@ -406,7 +414,7 @@
 # test-art-{1: host or target}-run-test-{2: debug ndebug}-{3: prebuild no-prebuild no-dex2oat}-
 #    {4: interpreter default optimizing}-{5: relocate no-relocate relocate-no-patchoat}-
 #    {6: trace or no-trace}-{7: gcstress gcverify cms}-{8: forcecopy checkjni jni}-
-#    {9: no-image image}-{10: test name}{11: 32 or 64}
+#    {9: no-image image picimage}-{10: pictest nopictest}-{11: test name}{12: 32 or 64}
 define define-test-art-run-test
   run_test_options :=
   prereq_rule :=
@@ -470,12 +478,6 @@
       endif
     endif
   endif
-  # Add the core dependency.
-  ifeq ($(1),host)
-    prereq_rule += $(HOST_CORE_IMAGE_$(4)_$(11))
-  else
-    prereq_rule += $(TARGET_CORE_IMAGE_$(4)_$(11))
-  endif
 
   ifeq ($(5),relocate)
     test_groups += ART_RUN_TEST_$$(uc_host_or_target)_RELOCATE_RULES
@@ -542,23 +544,48 @@
   else
     ifeq ($(9),image)
       test_groups += ART_RUN_TEST_$$(uc_host_or_target)_IMAGE_RULES
+      # Add the core dependency.
+      ifeq ($(1),host)
+        prereq_rule += $(HOST_CORE_IMAGE_$(4)_no-pic_$(12))
+      else
+        prereq_rule += $(TARGET_CORE_IMAGE_$(4)_no-pic_$(12))
+      endif
     else
-      $$(error found $(9) expected $(IMAGE_TYPES))
+      ifeq ($(9),picimage)
+        test_groups += ART_RUN_TEST_$$(uc_host_or_target)_PICIMAGE_RULES
+        run_test_options += --pic-image
+        ifeq ($(1),host)
+          prereq_rule += $(HOST_CORE_IMAGE_$(4)_pic_$(12))
+        else
+          prereq_rule += $(TARGET_CORE_IMAGE_$(4)_pic_$(12))
+        endif
+      else
+        $$(error found $(9) expected $(IMAGE_TYPES))
+      endif
     endif
   endif
-  # $(10) is the test name
-  test_groups += ART_RUN_TEST_$$(uc_host_or_target)_$(call name-to-var,$(10))_RULES
-  ifeq ($(11),64)
+  ifeq ($(10),pictest)
+    run_test_options += --pic-test
+  else
+    ifeq ($(10),nopictest)
+      # Nothing to be done.
+    else
+      $$(error found $(10) expected $(PICTEST_TYPES))
+    endif
+  endif
+  # $(11) is the test name
+  test_groups += ART_RUN_TEST_$$(uc_host_or_target)_$(call name-to-var,$(11))_RULES
+  ifeq ($(12),64)
     test_groups += ART_RUN_TEST_$$(uc_host_or_target)_64_RULES
     run_test_options += --64
   else
-    ifeq ($(11),32)
+    ifeq ($(12),32)
       test_groups += ART_RUN_TEST_$$(uc_host_or_target)_32_RULES
     else
-      $$(error found $(11) expected $(ALL_ADDRESS_SIZES))
+      $$(error found $(12) expected $(ALL_ADDRESS_SIZES))
     endif
   endif
-  run_test_rule_name := test-art-$(1)-run-test-$(2)-$(3)-$(4)-$(5)-$(6)-$(7)-$(8)-$(9)-$(10)$(11)
+  run_test_rule_name := test-art-$(1)-run-test-$(2)-$(3)-$(4)-$(5)-$(6)-$(7)-$(8)-$(9)-$(10)-$(11)$(12)
   run_test_options := --output-path $(ART_HOST_TEST_DIR)/run-test-output/$$(run_test_rule_name) \
       $$(run_test_options)
 $$(run_test_rule_name): PRIVATE_RUN_TEST_OPTIONS := $$(run_test_options)
@@ -568,7 +595,7 @@
 	  DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) \
 	    SMALI=$(abspath $(HOST_OUT_EXECUTABLES)/smali) \
 	    DXMERGER=$(abspath $(HOST_OUT_EXECUTABLES)/dexmerger) \
-	    art/test/run-test $$(PRIVATE_RUN_TEST_OPTIONS) $(10) \
+	    art/test/run-test $$(PRIVATE_RUN_TEST_OPTIONS) $(11) \
 	      && $$(call ART_TEST_PASSED,$$@) || $$(call ART_TEST_FAILED,$$@)
 	$$(hide) (echo $(MAKECMDGOALS) | grep -q $$@ && \
 	  echo "run-test run as top-level target, removing test directory $(ART_HOST_TEST_DIR)" && \
@@ -595,8 +622,9 @@
                 $(foreach gc, $(GC_TYPES), \
                   $(foreach jni, $(JNI_TYPES), \
                     $(foreach image, $(IMAGE_TYPES), \
-                      $(eval $(call define-test-art-run-test,$(target),$(run_type),$(prebuild),$(compiler),$(relocate),$(trace),$(gc),$(jni),$(image),$(test),$(address_size))) \
-                  )))))))))))
+                      $(foreach pictest, $(PICTEST_TYPES), \
+                        $(eval $(call define-test-art-run-test,$(target),$(run_type),$(prebuild),$(compiler),$(relocate),$(trace),$(gc),$(jni),$(image),$(pictest),$(test),$(address_size))) \
+                  ))))))))))))
 define-test-art-run-test :=
 
 # Define a phony rule whose purpose is to test its prerequisites.
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 82d47d7..eec8930 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -136,6 +136,10 @@
         DALVIKVM="dalvikvm64"
         ARCHITECTURES_PATTERN="${ARCHITECTURES_64}"
         shift
+    elif [ "x$1" = "x--pic-test" ]; then
+        FLAGS="${FLAGS} -Xcompiler-option --compile-pic"
+        COMPILE_FLAGS="${COMPILE_FLAGS} --compile-pic"
+        shift
     elif expr "x$1" : "x--" >/dev/null 2>&1; then
         echo "unknown $0 option: $1" 1>&2
         exit 1
diff --git a/test/run-test b/test/run-test
index b7c0ecf..b0a4bb1 100755
--- a/test/run-test
+++ b/test/run-test
@@ -96,6 +96,7 @@
 have_patchoat="yes"
 have_image="yes"
 image_suffix=""
+pic_image_suffix=""
 
 while true; do
     if [ "x$1" = "x--host" ]; then
@@ -126,6 +127,12 @@
     elif [ "x$1" = "x--no-image" ]; then
         have_image="no"
         shift
+    elif [ "x$1" = "x--pic-image" ]; then
+        pic_image_suffix="-pic"
+        shift
+    elif [ "x$1" = "x--pic-test" ]; then
+        run_args="${run_args} --pic-test"
+        shift
     elif [ "x$1" = "x--relocate" ]; then
         relocate="yes"
         shift
@@ -314,12 +321,12 @@
         if [ -z "$ANDROID_HOST_OUT" ]; then
             export ANDROID_HOST_OUT=$ANDROID_BUILD_TOP/out/host/linux-x86
         fi
-        run_args="${run_args} --boot -Ximage:${ANDROID_HOST_OUT}/framework/core${image_suffix}.art"
+        run_args="${run_args} --boot -Ximage:${ANDROID_HOST_OUT}/framework/core${image_suffix}${pic_image_suffix}.art"
         run_args="${run_args} --runtime-option -Djava.library.path=${ANDROID_HOST_OUT}/lib${suffix64}"
     else
         guess_arch_name
         run_args="${run_args} --runtime-option -Djava.library.path=/data/art-test/${target_arch_name}"
-        run_args="${run_args} --boot -Ximage:/data/art-test/core${image_suffix}.art"
+        run_args="${run_args} --boot -Ximage:/data/art-test/core${image_suffix}${pic_image_suffix}.art"
     fi
     if [ "$relocate" = "yes" ]; then
       run_args="${run_args} --relocate"