Repository navigation
[Deepin-Kernel-SIG] [linux 6.6.y] kbuild: deb-pkg: strip orphaned debug labels from LoongArch modules - #2258
Conversation
With CONFIG_DEBUG_INFO, gcc emits .L-prefixed labels for function and
block boundaries and for location views (.LVL, .LBI, .LBB, .LFB, .LPFE),
and the assembler keeps them in .symtab as long as a debug section
references them. On x86-64 those references are expressed as a section
symbol plus an addend and the labels are discarded, but the LoongArch
assembler has to name them in relocations:
0000000000000057 R_LARCH_64 .LFB1 + 0
0000000000000015 R_LARCH_ADD_ULEB128 .LVL0 + 0
so they end up in the object's symbol table.
INSTALL_MOD_STRIP=1 expands to "strip --strip-debug", which is a section
operation: it drops .debug_* and .rela.debug_* but leaves the symbol
table alone, so every label that was only referenced from debug data
stays behind as an orphan. On 7.2.2-loong64-desktop-rolling 86.7% of the
roughly 3M module symbols are such labels. Nothing uses them at run time,
yet they cost 22% of the module payload (168 MB -> 130 MB) and 19% of the
linux-image package (195 MB -> 157 MB). This is the same problem
commit ac031f2 ("kbuild: add option for stripping modules while
installing them") addressed for the general debug-info case.
Strip them with --discard-locals as well. binutils removes a local
symbol only when its name still follows the assembler's local label
convention (.L, .., _.L_ and the L<digits> pseudo labels) *and* no
relocation in the output still names it: mark_symbols_used_in_relocations()
sets BSF_KEEP on every relocation target and filter_symbols() keeps those
unconditionally. What the module loader needs therefore survives -- the
relocation set of every module is byte-for-byte identical before and
after, .LC, .LPFE and the -fpatchable-function-entry labels stay, exactly
one SHT_SYMTAB remains as elf_validity_cache_index_sym() requires, and
the modules are still signed, because modules_install strips before it
signs. The dbg package is built from the unstripped modules in the build
tree, so it keeps all debug information.
Restrict this to LoongArch on a GNU toolchain, everyone else keeps
INSTALL_MOD_STRIP=1. Other architectures never see these labels: on
x86-64 the option drops two unreferenced .LC symbols out of an amdgpu.ko
and leaves all 429,648 relocations alone, so there is nothing to gain
there. LLVM builds have to keep the plain option, because
kbuild hands the same value to llvm-strip for LLVM=1 and llvm-strip
refuses to strip a symbol that a relocation still names, aborting the
build, while clang does emit such labels for string constants:
llvm-strip: error: 'super.ko': not stripping symbol '.L.str.1'
because it is named in a relocation
Clang none the less generates none of the debug labels that make the
package grow, so an LLVM build loses nothing by being left alone.
Boot tested with qemu-system-loongarch64 (EDK2 firmware, vmlinuz.efi,
test modules loaded from the initramfs with finit_module()): modules
stripped with --strip-debug, --discard-locals and --strip-unneeded all
load with rc=0, while --strip-all is rejected with "module has no symbols
(stripped?)".
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Reviewer's GuideConfigurationAdjust module stripping for GNU-toolchain LoongArch builds to discard orphaned local debug labels while preserving the existing behavior elsewhere.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the LoongArch module-stripping change.
No open issues 🎉
What changed in this PR
Reduces LoongArch kernel module sizes in Debian packages by removing orphaned local debug labels during module installation.
Changes:
- Uses
--strip-debug --discard-localsfor LoongArch builds when the selected strip tool identifies itself as GNU strip. - Preserves
INSTALL_MOD_STRIP=1for other architectures and non-GNU strip tools, including LLVM.
| File | Description |
|---|---|
scripts/package/builddeb |
Selects module stripping options based on architecture and strip tool. |
Review effort: Balanced
With CONFIG_DEBUG_INFO, gcc emits .L-prefixed labels for function and block boundaries and for location views (.LVL, .LBI, .LBB, .LFB, .LPFE), and the assembler keeps them in .symtab as long as a debug section references them. On x86-64 those references are expressed as a section symbol plus an addend and the labels are discarded, but the LoongArch assembler has to name them in relocations:
so they end up in the object's symbol table.
INSTALL_MOD_STRIP=1 expands to "strip --strip-debug", which is a section operation: it drops .debug_* and .rela.debug_* but leaves the symbol table alone, so every label that was only referenced from debug data stays behind as an orphan. On 7.2.2-loong64-desktop-rolling 86.7% of the roughly 3M module symbols are such labels. Nothing uses them at run time, yet they cost 22% of the module payload (168 MB -> 130 MB) and 19% of the linux-image package (195 MB -> 157 MB). This is the same problem commit ac031f2 ("kbuild: add option for stripping modules while installing them") addressed for the general debug-info case.
Strip them with --discard-locals as well. binutils removes a local symbol only when its name still follows the assembler's local label convention (.L, .., .L and the L pseudo labels) and no relocation in the output still names it: mark_symbols_used_in_relocations() sets BSF_KEEP on every relocation target and filter_symbols() keeps those unconditionally. What the module loader needs therefore survives -- the relocation set of every module is byte-for-byte identical before and after, .LC, .LPFE and the -fpatchable-function-entry labels stay, exactly one SHT_SYMTAB remains as elf_validity_cache_index_sym() requires, and the modules are still signed, because modules_install strips before it signs. The dbg package is built from the unstripped modules in the build tree, so it keeps all debug information.
Restrict this to LoongArch on a GNU toolchain, everyone else keeps INSTALL_MOD_STRIP=1. Other architectures never see these labels: on x86-64 the option drops two unreferenced .LC symbols out of an amdgpu.ko and leaves all 429,648 relocations alone, so there is nothing to gain there. LLVM builds have to keep the plain option, because kbuild hands the same value to llvm-strip for LLVM=1 and llvm-strip refuses to strip a symbol that a relocation still names, aborting the build, while clang does emit such labels for string constants:
Clang none the less generates none of the debug labels that make the package grow, so an LLVM build loses nothing by being left alone.
Boot tested with qemu-system-loongarch64 (EDK2 firmware, vmlinuz.efi, test modules loaded from the initramfs with finit_module()): modules stripped with --strip-debug, --discard-locals and --strip-unneeded all load with rc=0, while --strip-all is rejected with "module has no symbols (stripped?)".
Summary by Sourcery
Reduce stripped LoongArch module and kernel package sizes by discarding unused debug labels while preserving required symbols, relocations, and module functionality.
Bug Fixes:
Build: