Skip to content

Commit 8edad8f

Browse files
author
Ulya Trafimovich
committed
Preserve <uses-library> order in dexpreopt.config files.
Library order is important because it is used to construct class loader context, which is then written into OAT/ODEX files and chacked against class loader context constructed by PackageManager on the device. If the orders are different, dexpreopted code is rejected. This CL fixes a few problems that caused reordering: - 'filter' function arguments are swapped so that patterns list comes first, and the library list second - JSON representation of class loader context is changed to avoid unmarshaling it to Go maps, which may reorder keys - library list is no longer sorted (it's unclear why it was sorted) Bug: 132357300 Test: lunch cf_x86_64_phone-userdebug && m && launch_cvd \ adb wait-for-device && adb root && adb logcat \ | grep -E 'ClassLoaderContext [a-z ]+ mismatch' # empty grep output, no errors Change-Id: Ie76996d497e60da0948f1879d6db589ff3e968a2
1 parent b976c07 commit 8edad8f

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

Diff for: common/json.mk

+3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ add_json_list =$= $(call add_json_val,$(1),$(call json_list,$(patsubst %,%,$(2))
2424
add_json_csv =$= $(call add_json_val,$(1),$(call csv_to_json_list,$(strip $(2))))
2525
add_json_bool =$= $(call add_json_val,$(1),$(if $(strip $(2)),true,false))
2626
add_json_map =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent)"$$(strip $$(1))": {$$(newline))$(json_increase_indent)
27+
add_json_map_anon =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent){$$(newline))$(json_increase_indent)
2728
end_json_map =$= $(json_decrease_indent)$(eval _json_contents := $$(_json_contents)$$(if $$(filter %$$(comma),$$(lastword $$(_json_contents))),__SV_END)$$(_json_indent)},$$(newline))
29+
add_json_array =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent)"$$(strip $$(1))": [$$(newline))$(json_increase_indent)
30+
end_json_array =$= $(json_decrease_indent)$(eval _json_contents := $$(_json_contents)$$(if $$(filter %$$(comma),$$(lastword $$(_json_contents))),__SV_END)$$(_json_indent)],$$(newline))
2831

2932
# Clears _json_contents to start a new json file
3033
json_start =$= $(eval _json_contents := {$$(newline))$(eval _json_indent := $$(4space))

Diff for: core/dex_preopt_config_merger.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,25 @@ def main():
6767
# the loop in case this changes in the future.
6868
for sdk_ver in clc_map:
6969
clcs = clc_map[sdk_ver]
70-
clcs2 = OrderedDict()
71-
for lib in clcs:
72-
clc = clcs[lib]
70+
clcs2 = []
71+
for clc in clcs:
72+
lib = clc['Name']
7373
if lib in uses_libs:
7474
ulib = uses_libs[lib]
75+
# The real <uses-library> name (may be different from the module name).
76+
clc['Name'] = ulib['ProvidesUsesLibrary']
7577
# On-device (install) path to the dependency DEX jar file.
7678
clc['Device'] = ulib['DexLocation']
7779
# CLC of the dependency becomes a subcontext. We only need sub-CLC for
7880
# 'any' version because all other versions are for compatibility
7981
# libraries, which exist only for apps and not for libraries.
8082
clc['Subcontexts'] = ulib['ClassLoaderContexts'].get('any')
81-
# Patch the library name in the CLC as well.
82-
clcs2[ulib['ProvidesUsesLibrary']] = clc
8383
else:
8484
# dexpreopt.config for this <uses-library> is not among the script
8585
# arguments, which may be the case with compatibility libraries that
8686
# don't need patching anyway. Just use the original CLC.
87-
clcs2[lib] = clc
87+
pass
88+
clcs2.append(clc)
8889
clc_map2[sdk_ver] = clcs2
8990

9091
# Overwrite the original class loader context with the patched one.

Diff for: core/dex_preopt_odex_install.mk

+9-9
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ ifdef LOCAL_DEX_PREOPT
196196
# to load dexpreopt code on device. We should fix this, either by deferring
197197
# dependency computation until the full list of product packages is known, or
198198
# by adding product-specific lists of missing libraries.
199-
my_filtered_optional_uses_libraries := $(filter $(my_filtered_optional_uses_libraries), \
200-
$(PRODUCT_PACKAGES))
199+
my_filtered_optional_uses_libraries := $(filter $(PRODUCT_PACKAGES), \
200+
$(my_filtered_optional_uses_libraries))
201201

202202
ifeq ($(LOCAL_MODULE_CLASS),APPS)
203203
# compatibility libraries are added to class loader context of an app only if
@@ -222,10 +222,9 @@ ifdef LOCAL_DEX_PREOPT
222222
my_dexpreopt_libs_compat :=
223223
endif
224224

225-
my_dexpreopt_libs := $(sort \
225+
my_dexpreopt_libs := \
226226
$(LOCAL_USES_LIBRARIES) \
227-
$(my_filtered_optional_uses_libraries) \
228-
)
227+
$(my_filtered_optional_uses_libraries)
229228

230229
# 1: SDK version
231230
# 2: list of libraries
@@ -243,14 +242,15 @@ ifdef LOCAL_DEX_PREOPT
243242
# which are special and not handled by dex_preopt_config_merger.py.
244243
#
245244
add_json_class_loader_context = \
246-
$(call add_json_map, $(1)) \
245+
$(call add_json_array, $(1)) \
247246
$(foreach lib, $(2),\
248-
$(call add_json_map, $(lib)) \
247+
$(call add_json_map_anon) \
248+
$(call add_json_str, Name, $(lib)) \
249249
$(call add_json_str, Host, $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
250250
$(call add_json_str, Device, /system/framework/$(lib).jar) \
251-
$(call add_json_map, Subcontexts, ${$}) $(call end_json_map) \
251+
$(call add_json_val, Subcontexts, null) \
252252
$(call end_json_map)) \
253-
$(call end_json_map)
253+
$(call end_json_array)
254254

255255
# Record dex-preopt config.
256256
DEXPREOPT.$(LOCAL_MODULE).DEX_PREOPT := $(LOCAL_DEX_PREOPT)

0 commit comments

Comments
 (0)