newlibc memcpy 存在问题

背景

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),会产生不可预测行为。

相关推荐
2035去旅行3 天前
U-Boot DM(Driver Model)驱动框架
嵌入式·arm·soc
凉、介3 天前
深入理解 ARMv7-M | 异常/中断处理
笔记·学习·嵌入式·arm
凉、介3 天前
深入理解 ARMv7-M|处理器模式与寄存器
笔记·学习·嵌入式·arm
2035去旅行5 天前
U-Boot简介
嵌入式·arm·soc
zbyyd8 天前
Linux驱动:UART串口通信、GT9147触摸屏与IIO-ADC驱动开发
linux·驱动开发·arm
zbyyd8 天前
Linux驱动:SPI子系统与ADXL345三轴加速度传感器驱动开发
linux·驱动开发·arm
2035去旅行8 天前
SOC 里的 CPU 处理器 和 L1/L2 Cache
嵌入式·arm·soc
一直C9 天前
嵌入式 Linux 驱动开发学习笔记:设备树、pinctrl 与 GPIO 驱动开发
驱动开发·嵌入式·arm·dt
2035去旅行9 天前
两核 CPU:CPU1 和 CPU2 是如何协同工作的?
嵌入式·arm·soc
奔跑的架构师11 天前
[A-51]ARMv9/v8-SCMI系统架构
linux·arm开发·架构·系统架构·arm