Merge "Allow multiple patterns in rblf_wildcard"
diff --git a/core/Makefile b/core/Makefile
index b3841e9..a580ac8 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1597,6 +1597,7 @@
     $(BOARD_ODM_DLKMIMAGE_FILE_SYSTEM_TYPE) \
   ,erofs),)
 INTERNAL_USERIMAGES_DEPS += $(MKEROFSUSERIMG)
+BOARD_EROFS_COMPRESSOR ?= "lz4hc,9"
 endif
 
 ifneq ($(filter \
diff --git a/core/combo/HOST_CROSS_linux_bionic-arm64.mk b/core/combo/HOST_CROSS_linux_bionic-arm64.mk
deleted file mode 100644
index df6865f..0000000
--- a/core/combo/HOST_CROSS_linux_bionic-arm64.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Configuration for builds hosted on linux_arm-arm64
-# Included by combo/select.mk
-
-define $(combo_var_prefix)transform-shared-lib-to-toc
-$(call _gen_toc_command_for_elf,$(1),$(2))
-endef
diff --git a/core/combo/HOST_CROSS_windows-x86.mk b/core/combo/HOST_CROSS_windows-x86.mk
deleted file mode 100644
index d924901..0000000
--- a/core/combo/HOST_CROSS_windows-x86.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (C) 2006 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Settings to use MinGW as a cross-compiler under Linux
-# Included by combo/select.make
-
-define $(combo_var_prefix)transform-shared-lib-to-toc
-$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OBJDUMP) -x $(1) | grep "^Name" | cut -f3 -d" " > $(2)
-$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)NM) -g -f p $(1) | cut -f1-2 -d" " >> $(2)
-endef
diff --git a/core/combo/HOST_CROSS_windows-x86_64.mk b/core/combo/HOST_CROSS_windows-x86_64.mk
deleted file mode 100644
index d924901..0000000
--- a/core/combo/HOST_CROSS_windows-x86_64.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (C) 2006 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Settings to use MinGW as a cross-compiler under Linux
-# Included by combo/select.make
-
-define $(combo_var_prefix)transform-shared-lib-to-toc
-$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OBJDUMP) -x $(1) | grep "^Name" | cut -f3 -d" " > $(2)
-$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)NM) -g -f p $(1) | cut -f1-2 -d" " >> $(2)
-endef
diff --git a/core/combo/select.mk b/core/combo/select.mk
index 33c8e6d..7617558 100644
--- a/core/combo/select.mk
+++ b/core/combo/select.mk
@@ -27,6 +27,13 @@
 combo_var_prefix := $(combo_2nd_arch_prefix)$(combo_target)
 
 # Set reasonable defaults for the various variables
+ifeq ($(combo_target),HOST_CROSS_)
+$(KATI_obsolete_var \
+  $(combo_var_prefix)GLOBAL_ARFLAGS \
+  $(combo_var_prefix)STATIC_LIB_SUFFIX \
+  $(combo_var_prefix)transform-shared-lib-to-toc \
+  ,HOST_CROSS builds are not supported in Make)
+else
 
 $(combo_var_prefix)GLOBAL_ARFLAGS := crsPD -format=gnu
 
@@ -34,3 +41,5 @@
 
 # Now include the combo for this specific target.
 include $(BUILD_COMBOS)/$(combo_target)$(combo_os_arch).mk
+
+endif
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 21eac7f..b673050 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -167,6 +167,10 @@
   else
     $(error Unsupported HOST_CROSS_OS $(HOST_CROSS_OS))
   endif
+else ifeq ($(HOST_OS),darwin)
+  HOST_CROSS_OS := darwin
+  HOST_CROSS_ARCH := arm64
+  HOST_CROSS_2ND_ARCH :=
 endif
 
 ifeq ($(HOST_OS),)
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index 94917f5..aaeefcb 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -62,8 +62,12 @@
     init.gsi.rc \
     init.vndk-nodef.rc \
 
-# Support additional P, Q and R VNDK packages
-PRODUCT_EXTRA_VNDK_VERSIONS := 28 29 30
+# Support additional VNDK snapshots
+PRODUCT_EXTRA_VNDK_VERSIONS := \
+    28 \
+    29 \
+    30 \
+    31 \
 
 # Do not build non-GSI partition images.
 PRODUCT_BUILD_CACHE_IMAGE := false
diff --git a/tools/compliance/actionset.go b/tools/compliance/actionset.go
index d575321..656c5de 100644
--- a/tools/compliance/actionset.go
+++ b/tools/compliance/actionset.go
@@ -108,3 +108,12 @@
 	}
 	return true
 }
+
+// conditions returns the set of conditions resolved by the action set.
+func (as actionSet) conditions() *LicenseConditionSet {
+	result := newLicenseConditionSet()
+	for _, cs := range as {
+		result.AddSet(cs)
+	}
+	return result
+}
diff --git a/tools/compliance/cmd/dumpresolutions_test.go b/tools/compliance/cmd/dumpresolutions_test.go
index 1328a36..cab1cc8 100644
--- a/tools/compliance/cmd/dumpresolutions_test.go
+++ b/tools/compliance/cmd/dumpresolutions_test.go
@@ -577,7 +577,9 @@
 				"testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
 				"testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
 				"testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
+				"testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
 				"testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
+				"testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
 				"testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic notice",
 			},
 		},
@@ -610,7 +612,9 @@
 				"highest.apex.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
 				"lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
 				"lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
+				"lib/libc.a.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
 				"lib/libc.a.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
+				"lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
 				"lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libd.so.meta_lic notice",
 			},
 		},
@@ -723,7 +727,9 @@
 				"highest.apex.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
 				"lib/liba.so.meta_lic:restricted lib/liba.so.meta_lic:restricted lib/liba.so.meta_lic:restricted restricted",
 				"lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
+				"lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal lib/liba.so.meta_lic:restricted restricted",
 				"lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal reciprocal",
+				"lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
 				"lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice notice",
 			},
 		},
@@ -755,7 +761,9 @@
 				"testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
 				"testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
 				"testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
+				"testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
 				"testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
+				"testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
 				"testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic notice",
 			},
 		},
@@ -772,6 +780,7 @@
 				"testdata/restricted/application.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
 				"testdata/restricted/bin/bin3.meta_lic testdata/restricted/bin/bin3.meta_lic testdata/restricted/bin/bin3.meta_lic restricted",
 				"testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
+				"testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
 				"testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
 			},
 		},
@@ -786,6 +795,7 @@
 				"testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
 				"testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
 				"testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
+				"testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
 				"testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
 			},
 		},
@@ -821,6 +831,7 @@
 				"testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
 				"testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
 				"testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
+				"testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
 				"testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic notice",
 			},
 		},
@@ -849,6 +860,7 @@
 				"lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic by_exception_only:proprietary",
 				"lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
 				"lib/libc.a.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic by_exception_only:proprietary",
+				"lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
 				"lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libd.so.meta_lic notice",
 			},
 		},
@@ -950,6 +962,7 @@
 				"lib/liba.so.meta_lic:by_exception_only:proprietary lib/liba.so.meta_lic:by_exception_only:proprietary lib/liba.so.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
 				"lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
 				"lib/libc.a.meta_lic:by_exception_only:proprietary lib/libc.a.meta_lic:by_exception_only:proprietary lib/libc.a.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
+				"lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
 				"lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice notice",
 			},
 		},
@@ -977,6 +990,7 @@
 				"testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
 				"testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
 				"testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
+				"testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
 				"testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic notice",
 			},
 		},
@@ -992,6 +1006,7 @@
 				"testdata/proprietary/application.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
 				"testdata/proprietary/bin/bin3.meta_lic testdata/proprietary/bin/bin3.meta_lic testdata/proprietary/bin/bin3.meta_lic restricted",
 				"testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
+				"testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
 				"testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
 			},
 		},
@@ -2886,11 +2901,21 @@
 				matchResolution(
 					"testdata/restricted/lib/libc.a.meta_lic",
 					"testdata/restricted/lib/libc.a.meta_lic",
+					"testdata/restricted/lib/liba.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"testdata/restricted/lib/libc.a.meta_lic",
+					"testdata/restricted/lib/libc.a.meta_lic",
 					"testdata/restricted/lib/libc.a.meta_lic",
 					"reciprocal"),
 				matchResolution(
 					"testdata/restricted/lib/libd.so.meta_lic",
 					"testdata/restricted/lib/libd.so.meta_lic",
+					"testdata/restricted/lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"testdata/restricted/lib/libd.so.meta_lic",
+					"testdata/restricted/lib/libd.so.meta_lic",
 					"testdata/restricted/lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -3026,11 +3051,21 @@
 				matchResolution(
 					"lib/libc.a.meta_lic",
 					"lib/libc.a.meta_lic",
+					"lib/liba.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"lib/libc.a.meta_lic",
+					"lib/libc.a.meta_lic",
 					"lib/libc.a.meta_lic",
 					"reciprocal"),
 				matchResolution(
 					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
+					"lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"lib/libd.so.meta_lic",
+					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -3409,11 +3444,21 @@
 				matchResolution(
 					"lib/libc.a.meta_lic",
 					"lib/libc.a.meta_lic",
+					"lib/liba.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"lib/libc.a.meta_lic",
+					"lib/libc.a.meta_lic",
 					"lib/libc.a.meta_lic",
 					"reciprocal"),
 				matchResolution(
 					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
+					"lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"lib/libd.so.meta_lic",
+					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -3548,11 +3593,21 @@
 				matchResolution(
 					"testdata/restricted/lib/libc.a.meta_lic",
 					"testdata/restricted/lib/libc.a.meta_lic",
+					"testdata/restricted/lib/liba.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"testdata/restricted/lib/libc.a.meta_lic",
+					"testdata/restricted/lib/libc.a.meta_lic",
 					"testdata/restricted/lib/libc.a.meta_lic",
 					"reciprocal"),
 				matchResolution(
 					"testdata/restricted/lib/libd.so.meta_lic",
 					"testdata/restricted/lib/libd.so.meta_lic",
+					"testdata/restricted/lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"testdata/restricted/lib/libd.so.meta_lic",
+					"testdata/restricted/lib/libd.so.meta_lic",
 					"testdata/restricted/lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -3607,6 +3662,11 @@
 					"testdata/restricted/lib/liba.so.meta_lic",
 					"restricted"),
 				matchResolution(
+					"testdata/restricted/lib/liba.so.meta_lic",
+					"testdata/restricted/lib/liba.so.meta_lic",
+					"testdata/restricted/lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
 					"testdata/restricted/lib/libb.so.meta_lic",
 					"testdata/restricted/lib/libb.so.meta_lic",
 					"testdata/restricted/lib/libb.so.meta_lic",
@@ -3654,6 +3714,11 @@
 				matchResolution(
 					"testdata/restricted/lib/libc.a.meta_lic",
 					"testdata/restricted/lib/libc.a.meta_lic",
+					"testdata/restricted/lib/liba.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"testdata/restricted/lib/libc.a.meta_lic",
+					"testdata/restricted/lib/libc.a.meta_lic",
 					"testdata/restricted/lib/libc.a.meta_lic",
 					"reciprocal"),
 			},
@@ -3789,6 +3854,11 @@
 				matchResolution(
 					"testdata/proprietary/lib/libd.so.meta_lic",
 					"testdata/proprietary/lib/libd.so.meta_lic",
+					"testdata/proprietary/lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"testdata/proprietary/lib/libd.so.meta_lic",
+					"testdata/proprietary/lib/libd.so.meta_lic",
 					"testdata/proprietary/lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -3912,6 +3982,11 @@
 				matchResolution(
 					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
+					"lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"lib/libd.so.meta_lic",
+					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -4240,6 +4315,11 @@
 				matchResolution(
 					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
+					"lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"lib/libd.so.meta_lic",
+					"lib/libd.so.meta_lic",
 					"lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -4362,6 +4442,11 @@
 				matchResolution(
 					"testdata/proprietary/lib/libd.so.meta_lic",
 					"testdata/proprietary/lib/libd.so.meta_lic",
+					"testdata/proprietary/lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
+					"testdata/proprietary/lib/libd.so.meta_lic",
+					"testdata/proprietary/lib/libd.so.meta_lic",
 					"testdata/proprietary/lib/libd.so.meta_lic",
 					"notice"),
 			},
@@ -4413,6 +4498,11 @@
 					"by_exception_only",
 					"proprietary"),
 				matchResolution(
+					"testdata/proprietary/lib/liba.so.meta_lic",
+					"testdata/proprietary/lib/liba.so.meta_lic",
+					"testdata/proprietary/lib/libb.so.meta_lic",
+					"restricted"),
+				matchResolution(
 					"testdata/proprietary/lib/libb.so.meta_lic",
 					"testdata/proprietary/lib/libb.so.meta_lic",
 					"testdata/proprietary/lib/libb.so.meta_lic",
diff --git a/tools/compliance/policy/resolve.go b/tools/compliance/policy/resolve.go
index 9962e68..58547f8 100644
--- a/tools/compliance/policy/resolve.go
+++ b/tools/compliance/policy/resolve.go
@@ -41,59 +41,7 @@
 	// must be indexed for fast lookup
 	lg.indexForward()
 
-	rs = newResolutionSet()
-
-	// cmap contains an entry for every target that was previously walked as a pure aggregate only.
-	cmap := make(map[string]bool)
-
-	var walk func(f string, treatAsAggregate bool) actionSet
-
-	walk = func(f string, treatAsAggregate bool) actionSet {
-		target := lg.targets[f]
-		result := make(actionSet)
-		result[target] = newLicenseConditionSet()
-		result[target].add(target, target.proto.LicenseConditions...)
-		if preresolved, ok := rs.resolutions[target]; ok {
-			if treatAsAggregate {
-				result.addSet(preresolved)
-				return result
-			}
-			if _, asAggregate := cmap[f]; !asAggregate {
-				result.addSet(preresolved)
-				return result
-			}
-			// previously walked in a pure aggregate context,
-			// needs to walk again in non-aggregate context
-			delete(cmap, f)
-		}
-		if treatAsAggregate {
-			cmap[f] = true
-		}
-
-		// add all the conditions from all the dependencies
-		for _, edge := range lg.index[f] {
-			// walk dependency to get its conditions
-			as := walk(edge.dependency, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
-
-			// turn those into the conditions that apply to the target
-			as = depActionsApplicableToTarget(TargetEdge{lg, edge}, as, treatAsAggregate)
-
-			// add them to the result
-			result.addSet(as)
-		}
-
-		// record these conditions as applicable to the target
-		rs.addConditions(target, result)
-		rs.addSelf(target, result.byName(ImpliesRestricted))
-
-		// return this up the tree
-		return result
-	}
-
-	// walk each of the roots
-	for _, r := range lg.rootFiles {
-		_ = walk(r, lg.targets[r].IsContainer())
-	}
+	rs = resolveBottomUp(lg, make(map[*TargetNode]actionSet) /* empty map; no prior resolves */)
 
 	// if not yet cached, save the result
 	lg.mu.Lock()
@@ -133,61 +81,61 @@
 	//
 	// rmap is the resulting ResolutionSet
 	rmap := make(map[*TargetNode]actionSet)
-	for attachesTo, as := range rs.resolutions {
-		rmap[attachesTo] = as.copy()
-	}
 
-	path := make([]*dependencyEdge, 0, 32)
+	// cmap contains the set of targets walked as pure aggregates. i.e. containers
+	cmap := make(map[*TargetNode]bool)
 
-	var walk func(f string, cs *LicenseConditionSet, treatAsAggregate bool)
+	var walk func(fnode *TargetNode, cs *LicenseConditionSet, treatAsAggregate bool)
 
-	walk = func(f string, cs *LicenseConditionSet, treatAsAggregate bool) {
-		fnode := lg.targets[f]
-		if !cs.IsEmpty() {
-			parentsAllAggregate := true
-			for _, e := range path {
-				target := lg.targets[e.target]
-				if _, ok := rmap[target]; !ok {
-					rmap[target] = make(actionSet)
-				}
-				rmap[target].add(fnode, cs)
-				if !target.IsContainer() {
-					parentsAllAggregate = false
-					break
-				}
-			}
-			if parentsAllAggregate {
-				if _, ok := rmap[fnode]; !ok {
-					rmap[fnode] = make(actionSet)
-				}
-				rmap[fnode].add(fnode, cs)
-			}
+	walk = func(fnode *TargetNode, cs *LicenseConditionSet, treatAsAggregate bool) {
+		if _, ok := rmap[fnode]; !ok {
+			rmap[fnode] = make(actionSet)
 		}
-		// add conditions attached to `f`
+		rmap[fnode].add(fnode, cs)
+		if treatAsAggregate {
+			cmap[fnode] = true
+		}
+		// add conditions attached to `fnode`
 		cs = cs.Copy()
 		for _, fcs := range rs.resolutions[fnode] {
 			cs.AddSet(fcs)
 		}
 		// for each dependency
-		for _, edge := range lg.index[f] {
+		for _, edge := range lg.index[fnode.name] {
 			e := TargetEdge{lg, edge}
 			// dcs holds the dpendency conditions inherited from the target
 			dcs := targetConditionsApplicableToDep(e, cs, treatAsAggregate)
-			if dcs.IsEmpty() {
-				if !treatAsAggregate || (!edgeIsDerivation(e) && !edgeIsDynamicLink(e)) {
-					continue
+			if dcs.IsEmpty() && !treatAsAggregate {
+				continue
+			}
+			dnode := lg.targets[edge.dependency]
+			if as, alreadyWalked := rmap[dnode]; alreadyWalked {
+				diff := dcs.Copy()
+				diff.RemoveSet(as.conditions())
+				if diff.IsEmpty() {
+					// no new conditions
+
+					// pure aggregates never need walking a 2nd time with same conditions
+					if treatAsAggregate {
+						continue
+					}
+					// non-aggregates don't need walking as non-aggregate a 2nd time
+					if _, asAggregate := cmap[dnode]; !asAggregate {
+						continue
+					}
+					// previously walked as pure aggregate; need to re-walk as non-aggregate
+					delete(cmap, dnode)
 				}
 			}
-			path = append(path, edge)
 			// add the conditions to the dependency
-			walk(edge.dependency, dcs, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
-			path = path[:len(path)-1]
+			walk(dnode, dcs, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
 		}
 	}
 
 	// walk each of the roots
 	for _, r := range lg.rootFiles {
-		as, ok := rs.resolutions[lg.targets[r]]
+		rnode := lg.targets[r]
+		as, ok := rs.resolutions[rnode]
 		if !ok {
 			// no conditions in root or transitive closure of dependencies
 			continue
@@ -196,12 +144,21 @@
 			continue
 		}
 
-		path = path[:0]
 		// add the conditions to the root and its transitive closure
-		walk(r, newLicenseConditionSet(), lg.targets[r].IsContainer())
+		walk(rnode, newLicenseConditionSet(), lg.targets[r].IsContainer())
 	}
 
-	rs = &ResolutionSet{rmap}
+	// back-fill any bottom-up conditions on targets missed by top-down walk
+	for attachesTo, as := range rs.resolutions {
+		if _, ok := rmap[attachesTo]; !ok {
+			rmap[attachesTo] = as.copy()
+		} else {
+			rmap[attachesTo].addSet(as)
+		}
+	}
+
+	// propagate any new conditions back up the graph
+	rs = resolveBottomUp(lg, rmap)
 
 	// if not yet cached, save the result
 	lg.mu.Lock()
@@ -215,3 +172,70 @@
 
 	return rs
 }
+
+// resolveBottomUp implements a bottom-up resolve propagating conditions both
+// from the graph, and from a `priors` map of resolutions.
+func resolveBottomUp(lg *LicenseGraph, priors map[*TargetNode]actionSet) *ResolutionSet {
+	rs := newResolutionSet()
+
+	// cmap contains an entry for every target that was previously walked as a pure aggregate only.
+	cmap := make(map[string]bool)
+
+	var walk func(f string, treatAsAggregate bool) actionSet
+
+	walk = func(f string, treatAsAggregate bool) actionSet {
+		target := lg.targets[f]
+		result := make(actionSet)
+		result[target] = newLicenseConditionSet()
+		result[target].add(target, target.proto.LicenseConditions...)
+		if pas, ok := priors[target]; ok {
+			result.addSet(pas)
+		}
+		if preresolved, ok := rs.resolutions[target]; ok {
+			if treatAsAggregate {
+				result.addSet(preresolved)
+				return result
+			}
+			if _, asAggregate := cmap[f]; !asAggregate {
+				result.addSet(preresolved)
+				return result
+			}
+			// previously walked in a pure aggregate context,
+			// needs to walk again in non-aggregate context
+			delete(cmap, f)
+		}
+		if treatAsAggregate {
+			cmap[f] = true
+		}
+
+		// add all the conditions from all the dependencies
+		for _, edge := range lg.index[f] {
+			// walk dependency to get its conditions
+			as := walk(edge.dependency, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
+
+			// turn those into the conditions that apply to the target
+			as = depActionsApplicableToTarget(TargetEdge{lg, edge}, as, treatAsAggregate)
+
+			// add them to the result
+			result.addSet(as)
+		}
+
+		// record these conditions as applicable to the target
+		rs.addConditions(target, result)
+		if len(priors) == 0 {
+			// on the first bottom-up resolve, parents have their own sharing and notice needs
+			// on the later resolve, if priors is empty, there will be nothing new to add
+			rs.addSelf(target, result.byName(ImpliesRestricted))
+		}
+
+		// return this up the tree
+		return result
+	}
+
+	// walk each of the roots
+	for _, r := range lg.rootFiles {
+		_ = walk(r, lg.targets[r].IsContainer())
+	}
+
+	return rs
+}
diff --git a/tools/compliance/policy/resolve_test.go b/tools/compliance/policy/resolve_test.go
index aa5bb2a..4c99d35 100644
--- a/tools/compliance/policy/resolve_test.go
+++ b/tools/compliance/policy/resolve_test.go
@@ -434,6 +434,7 @@
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 				{"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
@@ -480,6 +481,7 @@
 				{"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
 				{"mitBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+				{"mplLib.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"mplLib.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
 			},
 		},
@@ -512,6 +514,7 @@
 				{"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
@@ -540,6 +543,7 @@
 				{"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+				{"mplLib.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"mplLib.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
 			},
 		},
@@ -573,6 +577,7 @@
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
 				{"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
@@ -612,6 +617,7 @@
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
 				{"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
@@ -687,6 +693,7 @@
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
@@ -704,6 +711,7 @@
 				{"dependentModule.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 				{"dependentModule.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
@@ -735,6 +743,7 @@
 				{"dependentModule.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 				{"dependentModule.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
diff --git a/tools/compliance/policy/resolvenotices_test.go b/tools/compliance/policy/resolvenotices_test.go
index b428d5b..275c0a5 100644
--- a/tools/compliance/policy/resolvenotices_test.go
+++ b/tools/compliance/policy/resolvenotices_test.go
@@ -153,6 +153,7 @@
 				{"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
 				{"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"apacheBin.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
+				{"mitLib.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
 				{"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
 			},
 		},
diff --git a/tools/compliance/policy/resolveshare_test.go b/tools/compliance/policy/resolveshare_test.go
index 7371ccf..ad3630d 100644
--- a/tools/compliance/policy/resolveshare_test.go
+++ b/tools/compliance/policy/resolveshare_test.go
@@ -176,6 +176,7 @@
 			expectedResolutions: []res{
 				{"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
 				{"gplBin.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+				{"apacheLib.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
 			},
 		},
 		{
@@ -218,6 +219,7 @@
 			expectedResolutions: []res{
 				{"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+				{"dependentModule.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 			},
 		},
 		{
diff --git a/tools/compliance/policy/walk_test.go b/tools/compliance/policy/walk_test.go
index 2eef702..07710aa 100644
--- a/tools/compliance/policy/walk_test.go
+++ b/tools/compliance/policy/walk_test.go
@@ -336,6 +336,7 @@
 			expectedResolutions: []res{
 				{"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
 				{"gplBin.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+				{"apacheLib.meta_lic", "apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
 			},
 		},
 		{
@@ -428,6 +429,7 @@
 			expectedResolutions: []res{
 				{"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 				{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+				{"dependentModule.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
 			},
 		},
 		{