Skip to content

[r8-obfuscation] Enable R8 JNI name obfuscation for CoreCLR - #12632

Open
simonrozsival wants to merge 21 commits into
simonrozsival-trimmable-typemap-jni-rewritingfrom
simonrozsival-coreclr-r8-jni-integration
Open

[r8-obfuscation] Enable R8 JNI name obfuscation for CoreCLR#12632
simonrozsival wants to merge 21 commits into
simonrozsival-trimmable-typemap-jni-rewritingfrom
simonrozsival-coreclr-r8-jni-integration

Conversation

@simonrozsival

@simonrozsivalsimonrozsival commented Sep 1, 2026

Copy link
Copy Markdown
Member

Related to #12535

Depends on #12631

Layer 5 of 6 in the replacement stack for #12575. This layer adds the shared two-pass R8 seed/final mapping machinery and enables opt-in JNI name obfuscation for trimmed CoreCLR builds. NativeAOT support follows in layer 6.

Testing:

  • Parsed all modified MSBuild targets and resources as XML.
  • Built Xamarin.Android.Build.Tasks.csproj and the complete Xamarin.Android.Build.Tests.csproj.
  • Passed all 35 focused GenerateProguardConfiguration/R8 task tests, including canonical LF manifest output for the Windows failure in build 1577218.
  • Attempted all three CoreCLR integration tests; the local environment blocked project restore with NETSDK1147 because the unrelated wasm-tools workload is not installed.

@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from bdfec0a to 7c15701CompareSeptember 1, 2026 19:34
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from f51fbae to f88d2f4CompareSeptember 1, 2026 22:33
@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from 1cee050 to 65740e9CompareSeptember 2, 2026 09:05
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from 2f3c599 to 5e41251CompareSeptember 2, 2026 11:23
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from 5e41251 to cbc7457CompareSeptember 2, 2026 11:59
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from cbc7457 to 61d0a23CompareSeptember 2, 2026 12:23
@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from 61d0a23 to ed2522dCompareSeptember 2, 2026 15:23
@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from 60b031c to 15c4b79CompareSeptember 2, 2026 21:34
simonrozsivaland others added 17 commits September 3, 2026 07:00
Use platform-aware path identity for in-place rewrites, validate custom attribute prologs, and diagnose unsafe member-only mappings without polluting rewrite manifests or reverse scans.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Allow seed R8 to rename ACWs, track final R8 generated inputs, and keep validation mappings private when public mapping output is disabled.
Use canonical LF expectations for generated reachability manifests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Build the seed R8 configuration from user and library consumer rules instead of final generated configuration, whose baseline native-method rule pins ACW names.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Generate identity keep rules directly from the merged text manifest so seed R8 does not require resources to be linked early. Keep final AAPT resource rules on their normal late path and cover manifest normalization, provenance, and resource independence.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Assert that an activity alias identity is not treated as a Java class while its target activity remains protected.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Prepare the manifest merger directory before seed manifest rule generation, and keep generated ACW pinning rules out of final JNI-obfuscating R8 passes while retaining final AAPT and mapped reachability rules.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copy the shared trimmable manifest into each inner build before seed manifest merging, and validate final R8 output through its configured public mapping path.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Allow blank records when validating generated reachability manifests, and resolve the final AAPT rules through their explicit configuration provenance instead of filesystem name uniqueness.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Convert manifest-style JNI paths to the native directory separator at the filesystem copy boundary.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-coreclr-r8-jni-integration branch from 15c4b79 to 6a05a22CompareSeptember 3, 2026 05:00
@simonrozsival
simonrozsival marked this pull request as ready for review September 3, 2026 10:26
CopilotAI lite review requested due to automatic review settings September 3, 2026 10:26
@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/review

@simonrozsivalsimonrozsival added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Sep 3, 2026
@github-actions

github-actionsBot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer failed. Please review the logs for details.

Generated by Android PR Reviewer for #12632

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The new manifest keep-rule generator currently treats a <process> element as a Java class source, which can produce incorrect keep rules and should be corrected before merge.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity · 1 Low severity

New issues introduced by this change (2)
SeverityFinding
Medium severitysrc/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateR8JniManifestProguardConfiguration.cs — ❌ error: The manifest keep-rule generator treats a <process android:name="..."/> element as a Java…
Low severitysrc/​Xamarin.Android.Build.Tasks/​Tasks/​R8.cs — 💡 suggestion: GenerateCommonXamarinConfiguration writes the generated ProGuard config via…
What changed in this PR

This PR extends the .NET for Android build pipeline to support an opt-in, two-pass R8 workflow that enables JNI name obfuscation for trimmed CoreCLR builds. It introduces seed/final mapping propagation, mapping validation (XA4327), and plumbing for the new mapping/manifests through MSBuild targets and tasks.

Changes:

  • Add two-pass R8 seed/final mapping inputs/outputs and validation for JNI name rewriting, including a new XA4327 error code and documentation.
  • Introduce manifest-only keep-rule generation for the seed pass, plus additional provenance metadata on ProGuard/R8 configuration items for correct filtering.
  • Add/expand unit and integration tests covering mapping validation, reachability manifests, Java source path reverse-mapping, and incrementality.
FileDescription
src/​Xamarin.Android.Build.Tasks/​Xamarin.Android.D8.targetsWire new mapping input/output + validation inputs into the R8 invocation and FileWrites.
src/​Xamarin.Android.Build.Tasks/​Xamarin.Android.Common.targetsAdd property caching, mapping output selection, compile inputs augmentation, and configuration provenance metadata.
src/​Xamarin.Android.Build.Tasks/​Utilities/​JniRemapping/​R8Mapping.csAdd helper for obfuscated-class presence and ignore empty manifest lines in reachability checks.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Utilities/​JniRemapping/​R8MappingTests.csAdd regression test ensuring reachability manifests can contain empty lines.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​TrimmableTypeMapBuildTests.csAdd CoreCLR integration coverage for the JNI rewriting pipeline, including incrementality and multi-RID behavior.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​R8Tests.csAdd focused tests for seed mapping behavior, baseline filtering, ACW keep-rule filtering, and XA4327 validation.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​GenerateTrimmableTypeMapTests.csAdd tests for reverse-mapping obfuscated Java source paths and XA4327 error reporting on conflicts.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​GenerateR8JniManifestProguardConfigurationTests.csNew tests validating deterministic manifest-only keep rules and XA4327 error cases.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​GenerateProguardConfigurationTests.csNew tests validating mapped keep-rule output and reachability manifest generation.
src/​Xamarin.Android.Build.Tasks/​Tasks/​R8.csAdd seed-mapping mode, applymapping support, baseline filtering for JNI obfuscation, and mapping validation plumbing.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateTrimmableTypeMap.csAdd optional R8 mapping + rewrite manifest inputs to reverse-map generated Java source paths back to originals.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateR8JniManifestProguardConfiguration.csNew task to derive seed-pass keep rules from the merged manifest without resource resolution.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateProguardConfiguration.csExtend to emit allowobfuscation keep rules driven by rewritten-assembly scanning plus reachability manifest output.
src/​Xamarin.Android.Build.Tasks/​Properties/​Resources.resxAdd XA4327 and associated detail strings.
src/​Xamarin.Android.Build.Tasks/​Properties/​Resources.Designer.csUpdate generated resource accessors for XA4327 strings.
src/​Xamarin.Android.Build.Tasks/​MSBuild/​Xamarin/​Android/​Xamarin.Android.Aapt2.targetsMark AAPT-generated rules with metadata to preserve/identify provenance for filtering.
src/​Xamarin.Android.Build.Tasks/​Microsoft.Android.Sdk/​targets/​Microsoft.Android.Sdk.TypeMap.Trimmable.targetsAdd seed-pass compilation/mapping targets and shared-output wiring for inner builds.
src/​Xamarin.Android.Build.Tasks/​Microsoft.Android.Sdk/​targets/​Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targetsEnsure proguard config generation participates in dalvik compile deps; add pre-ILLink rewrite stage and extend inputs/outputs.
Documentation/​docs-mobile/​TOC.ymlAdd XA4327 doc entry to TOC.
Documentation/​docs-mobile/​messages/​xa4327.mdNew documentation page for XA4327.
Documentation/​docs-mobile/​messages/​index.mdAdd XA4327 to the error index list.
Documentation/​docs-mobile/​building-apps/​build-properties.mdDocument the new AndroidEnableR8JniNameObfuscation property and requirements.
Files not reviewed (1)
  • src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs: Generated file

Comment on lines +56 to +60
case "provider":
case "instrumentation":
case "process":
AddClass (classes, packageName, element, "name");
break;
return;
}

using var xamcfg = File.CreateText (ProguardCommonXamarinConfiguration);
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-reviewThis PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@simonrozsival@rolfbjarne