背景
sdk 中发现 memcpy 函数没有达到预期,执行后,目的地址与源地址中的内容不一致。
复现方法
通过单步调试 memcpy 汇编代码,发现使用了 ldrh 指令,该指令在对 uncacheable memory 同时该 memory 非对齐的情况下,并不会按照预期执行(从内存 load 两字节到目标寄存器),如下汇编代码。
.text
.global my_memcpy
.type my_memcpy, %function
my_memcpy:
push {r10,lr}
ldrh r10, [r1] # 如果 r1 不对齐且为 uncacheble,并不会 load 2 字节到 r10
strh r10, [r0]
pop {r10, pc}
.size my_memcpy, .-my_memcpy
关闭了非对齐访问检查,所以不会产生 fault
该指令执行结果,如图:
实锤
newlibc 中 memcpy 存在非对齐访问,某些 cpu (cortex-a5 与 cortex-a9)非对齐访问时,行为不一致,可参考 ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf
第 109 页。
对于非对齐访问(cpu 使能非对齐访问,SCTLR 寄存器的 bit1),会产生不可预测行为。