Reduce the size of __LINKEDIT Export Info section in stripped binaries#18408
Reduce the size of __LINKEDIT Export Info section in stripped binaries#18408rolfbjarne merged 7 commits intodotnet:mainfrom
__LINKEDIT Export Info section in stripped binaries#18408Conversation
…round the strip tool not resizing the stripped export section
|
/cc: @rolfbjarne |
|
|
||
| <Target Name="_ComputeLinkNativeExecutableInputs" Condition="'$(IsMacEnabled)' == 'true'"> | ||
| <PropertyGroup> | ||
| <_ExportedSymbolsFile Condition="'$(_ExportedSymbolsFile)' == '' and '$(_MtouchSymbolsList)' == ''">/dev/null</_ExportedSymbolsFile> <!-- nothing to export --> |
There was a problem hiding this comment.
In case there are no symbols to export, this workaround works just fine making the export info section empty.
|
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
The CI looks 🆗 should I also try adding this:
|
That should be in a different PR. |
|
Actually I think we can just enable this by default, since there's an escape hatch if something goes wrong at some point. |
__LINKEDIT Export Info section in stripped binaries__LINKEDIT Export Info section in stripped binaries
|
/azp run |
|
Commenter does not have sufficient privileges for PR 18408 in repo xamarin/xamarin-macios |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
💻 [CI Build] Windows Integration Tests passed 💻✅ All Windows Integration Tests passed. Pipeline on Agent |
📚 [PR Build] Artifacts 📚Packages generatedView packagesPipeline on Agent |
💻 [PR Build] Tests on macOS M1 - Mac Big Sur (11.5) passed 💻✅ All tests on macOS M1 - Mac Big Sur (11.5) passed. Pipeline on Agent |
💻 [PR Build] Tests on macOS M1 - Mac Ventura (13.0) passed 💻✅ All tests on macOS M1 - Mac Ventura (13.0) passed. Pipeline on Agent |
✅ API diff for current PR / commitLegacy Xamarin (No breaking changes)
NET (empty diffs)
✅ API diff vs stableLegacy Xamarin (No breaking changes).NET (No breaking changes)✅ Generator diffGenerator diff is empty Pipeline on Agent |
This comment has been minimized.
This comment has been minimized.
🚀 [CI Build] Test results 🚀Test results✅ All tests passed on VSTS: simulator tests. 🎉 All 235 tests passed 🎉 Tests counts✅ bcl: All 69 tests passed. Html Report (VSDrops) Download Pipeline on Agent |
Description
This PR reduces the application's SOD (size on disk) by making
__LINKEDIT Export Infosection smaller in the stripped Mach-O binaries.The feature is controlled by
_ExportSymbolsExplicitlyMSBuild property and can be disabled by specifying:-p:_ExportSymbolsExplicitly=trueFixes #18332
Initial problem
It has been noticed that during stripping, the strip tool does not resize the export info section after it removes the symbols. Instead it only zeroes out the entries (achieved by calling
prune_triefunction):Thanks @lambdageek for helping to track this down.
Proposed approach
As Xamarin build process already collects all the required symbols needed for the application to run and preserves them during the strip phase, we can use the same file to instruct clang toolchain to export only those symbols via the command line options:
-exported_symbols_list <file>(source). This will make the export info section only include what is necessary for the runtime - and at the same time eliminate the problem of thestriptool which does not resize stripped symbols.Investigation setup
The issue is observable by building and inspecting the test application: https://github.com/xamarin/xamarin-macios/blob/main/tests/dotnet/MySingleView/MySingleView.csproj and targeting iOS platform in Release mode.
Results:
Even though zeroes are compressed well, the SOD is still affected and unused section takes around 1.5% of the most simplistic app size.
Much bigger impact has been noted when trying out a MAUI iOS template app with NativeAOT where the
__LINKEDIT Export Infozeroes take up to 20MB of the SOD, but also with the regular macOS applications: dotnet/runtime#86707Repros (outdated - see note)
NOTE I will leave the detailed analysis as part of this PR description for reference. However it should be noted that the used make targets listed bellow are outdated and are used during investigation.
Bellow I listed 3 scenarios for reproducing the current app sizes (with and without stripping) and the app size that we can get by using changes of this PR:
-exported_symbols_list <file>+strip)The repro steps assume that this PR has been checkout and that tools are invoked from the test sample directory:
cd tests/dotnet/MySingleViewRepro current state of MySingleView.app with stripped binary
otool -l bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > load_cmds_strip.listxxd -s 5942960 -l 207712 bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > hex_dump_strip.listdyld_info -exports bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > dyld_info_strip.listRepro current state of MySingleView.app with unstripped binary
otool -l bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > load_cmds_nostrip.listxxd -s 5942960 -l 207712 bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > hex_dump_nostrip.listdyld_info -exports bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > dyld_info_nostrip.listRepro the new approach
otool -l bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > load_cmds_export.listxxd -s 5942432 -l 1048 bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > hex_dump_export.listdyld_info -exports bin/Release/net7.0-ios/ios-arm64/MySingleView.app/MySingleView > dyld_info_export.listAdditional benefits
strip -S -xinstead of passing the file with symbols to preserve. This would remove the warning that we are currently getting (which is being ignored):Other references: