Repository navigation
fix[klibc]: stop gcc from turning the kstring.c byte loops into memset/memcpy calls - #11965
Conversation
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
📌 Code Review Assignment🏷️ Tag: kernelReviewers: @GorrayLi @ReviewSun @hamburger-os @lianux-mm @wdfk-prog @xu18838022837 Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2026-11-02 14:57 CST)
📝 Review Instructions
|
| if rtconfig.CROSS_TOOL == 'gcc': | ||
| local_cflags = ' -fno-tree-loop-distribute-patterns' | ||
|
|
||
| group = DefineGroup('Libc', src, depend = [''], LOCAL_CFLAGS = local_cflags) |
There was a problem hiding this comment.
这里需要排除 --clang-analyzer。这个模式下,CROSS_TOOL 仍然是 gcc,但 building.py 已经把 CFLAGS 转成了列表。传入字符串形式的 LOCAL_CFLAGS 后,local_group() 会执行列表与字符串相加,直接报 TypeError,静态分析无法继续。请在该模式下不要传 LOCAL_CFLAGS,设为空字符串也不行,因为构建脚本判断的是这个字段是否存在。
There was a problem hiding this comment.
已按你的建议改好(commit 9ceb217b):
group_args = {'depend': ['']}
if rtconfig.CROSS_TOOL == 'gcc' and not GetOption('clang-analyzer'):
# --clang-analyzer 下 building.py 会把 CFLAGS 变成 list,
# local_group() 里 list + str 会 TypeError,所以该模式不传这个字段
group_args['LOCAL_CFLAGS'] = ' -fno-tree-loop-distribute-patterns'
group = DefineGroup('Libc', src, **group_args)- 常规构建:仍然传
-fno-tree-loop-distribute-patterns,行为与之前一致; --clang-analyzer:不再传这个字段(不是传空字符串)。
再提供一个信息,可能对 CI 有用:我在 bsp/qemu-vexpress-a9 上试 scons --clang-analyzer 时发现,即使把 src/klibc/SConscript 还原成 master 版本(完全不传 LOCAL_CFLAGS),也会在 building.py:859 报同样的 TypeError。定位到的原因是另外几个组本来就用字符串形式传:
components/finsh/SConscript:12,15(LOCAL_CFLAGS = ''然后+= '-Wstack-usage=...')components/dfs/dfs_v1/SConscript:11,20(+= ' -std=c99')components/drivers/spi/SConscript:9,39(同上)
也就是说这个 BSP 上的静态分析在此之前就会失败;我这条改动只是不再新增一个同样的触发点。如果希望一起治理,我可以另提一个 PR 专门处理这几处(不混进这个修复里)。
|
拉取/合并请求描述:(PR description)
[
为什么提交这份PR (why to submit this PR)
Fixes #6128.
rt_memset()/rt_memcpy()/rt_memmove()insrc/klibc/kstring.cend with byte-wise loops. At-O2/-Os, GCC recognises those loops (-ftree-loop-distribute-patterns) and replaces themwith calls to
memset()/memcpy(). On a target built without a C library those symbols do notexist, so the firmware fails to link - which is exactly what the issue reports for aarch64.
This is not aarch64-specific. Reproduced with
arm-none-eabi-gcc 10.3.1by buildingbsp/qemu-vexpress-a9with-Os(BUILD = 'release'inrtconfig.py, not part of this PR).Before the change,
build/kernel/src/klibc/kstring.ocontains:Both branches into
memsetare insidert_memset()itself.你的解决方案是什么 (what is your solution)
Compile the
Libcgroup with-fno-tree-loop-distribute-patterns, as suggested in the issue.The flag is only appended for GCC, so Keil/IAR builds are untouched:
Only
src/klibc/SConscriptis changed (+10/-1). No C source is modified, so targets that dohave a C library keep the same behaviour; on libc-less targets the loops simply stay in place.
请提供验证的bsp和config (provide the config and bsp)
BUILD = 'release'(-Os) to trigger thetransformation.
rtconfig.pyis not modified in this PR.Verification (
nm -u/objdump -donbuild/kernel/src/klibc/kstring.o):U memsetbl memsetinsidert_memset-Os, before the change-Os, after the change-O0(BSP default), after the changeAlso checked standalone, using the exact
rt_memset()body copied fromkstring.ctogether withthe BSP CFLAGS:
-O2,-Osand-O3all emitU memsetwithout the flag, and none with it.Not covered: Keil/IAR (they do not receive this flag) and the aarch64 toolchain itself - the
problem was reproduced with arm-none-eabi-gcc, which performs the same optimisation.
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up