[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Execute-only memory (XOM) for AArch64 binaries\n\n| **Important:** XOM support has been removed in the upstream Linux kernel. XOM is only supported in Android 10 and has been removed in Android 11 and kernel changes removing it have been backported to 4.9, so the common kernel no longer supports XOM. More details on why XOM support was removed upstream can be found at [PAN mitigation bypass](https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/frequently-asked-questions#pan)\n\nExecutable code sections for AArch64 system binaries are by default marked\nexecute-only (non-readable) as a hardening mitigation against just-in-time code\nreuse attacks. Code that mixes data and code together and code that purposefully\ninspects these sections (without first remapping the memory segments as readable)\nno longer function. Apps with a target SDK of 10\n(API level 29 or higher) are impacted if the app attempts to read code sections of\nexecute-only memory (XOM) enabled system libraries in memory without first\nmarking the section as readable.\n\nTo fully benefit from this mitigation, both hardware and kernel support are\nrequired. Without this support, the mitigation might only be partially enforced. The\n[Android 4.9 common kernel](/devices/architecture/kernel/android-common) contains the appropriate patches to provide full\nsupport for this on ARMv8.2 devices.\n\nImplementation\n--------------\n\nAArch64 binaries generated by the compiler assume that code and data aren't\nintermixed. Enabling this feature doesn't negatively affect the performance of\nthe device.\n\nFor code that has to perform intentional memory introspection on its\nexecutable segments, it's advisable to call `mprotect` on the\nsegments of code requiring inspection to allow them to be readable, then\nremove the readability when the inspection is complete. \n\nThis implementation causes reads into memory segments marked as\nexecute-only to result in a segmentation fault (`SEGFAULT`).\nThis might occur as a result of a bug, vulnerability, data mixed with\ncode (literal pooling), or intentional memory introspection.\n\n### Device support and impact\n\nDevices with earlier hardware or earlier kernels (lower than 4.9) without the\nrequired patches might not fully support or benefit from this feature. Devices\nwithout kernel support may not enforce user accesses of execute-only memory,\nhowever kernel code which explicitly checks whether a page is readable may still\nenforce this property, such as `process_vm_readv()`.\n\nThe kernel flag `CONFIG_ARM64_UAO` must be set in the kernel to\nensure that the kernel respects userland pages marked execute-only. Earlier ARMv8\ndevices, or ARMv8.2 devices with User Access Override (UAO) disabled, may not\nfully benefit from this and may still be able to read execute-only pages using\nsyscalls.\n| **Note:** Calls to `ptrace` and ptrace debugging aren't affected by this change.\n\n### Refactor existing code\n\nCode that has been ported from AArch32 might contain intermixed data and\ncode, causing issues to arise. In many cases, fixing these issues is as simple\nas moving the constants to a `.data` section in the assembly file.\n\nHandwritten assembly may need to be refactored to separate locally pooled\nconstants.\n\nExamples:\n\n- [`libjpeg-turbo`](https://android-review.googlesource.com/c/platform/external/libjpeg-turbo/+/867910)\n- [`libRSCpuRef`](https://android-review.googlesource.com/c/platform/frameworks/rs/+/876172)\n\nBinaries generated by the Clang compiler should have no issues with data\nbeing intermixed in code. If GNU compiler collection (GCC) generated code is\nincluded (from a static library), inspect the output binary to\nensure that constants have not been pooled into code sections.\n\nIf code introspection is necessary on executable code sections,\nfirst call `mprotect` to mark the code readable. Then after the operation\nis complete, call `mprotect` again to mark it unreadable.\n\n### Enable XOM\n\nExecute-only is enabled by default for all 64-bit binaries in the build\nsystem.\n\n### Disable XOM\n\nYou can disable execute-only at a module level, by an entire subdirectory tree, or\nglobally for an entire build.\n\nXOM can be disabled for individual modules that can't be refactored, or need to read their\nexecutable code, by setting the `LOCAL_XOM`\nand `xom` variables to `false`. \n\n```carbon\n// Android.mk\nLOCAL_XOM := false\n\n// Android.bp\ncc_binary { // or other module types\n ...\n xom: false,\n}\n```\n\nIf execute-only memory is disabled in a static library, the build system applies\nthis to all dependent modules of that static library. You can override\nthis by using `xom: true,`.\n| **Caution:** Don't override the build system defaults if the execute-only incompatible code is being used in the dependent module.\n\nTo disable execute-only memory in a particular subdirectory (for example,\nfoo/bar/), pass the value to `XOM_EXCLUDE_PATHS`. \n\n```scdoc\nmake -j XOM_EXCLUDE_PATHS=foo/bar\n```\n\nAlternatively, you can set the `PRODUCT_XOM_EXCLUDE_PATHS`\nvariable in your product configuration.\n\nYou can disable execute-only binaries globally by passing\n`ENABLE_XOM=false` to your `make` command. \n\n```scdoc\nmake -j ENABLE_XOM=false\n```\n\n### Validation\n\nThere are no CTS or verification tests available for execute-only\nmemory. You can manually verify binaries using `readelf` and checking\nthe segment flags."]]