使用 C 的 ARM9 上未对齐内存访问异常的解决方法是什么?
架构ARM9。 编程语言 C。
我们有一个第三方堆栈,其中一个调用需要一个指向内存位置的指针 (pBuffer
)。 在堆栈内,它们可以自由地在传递的指针周围移动并根据需要访问它。 不幸的是,它们偏移了传入的指针,并将其传递到另一个函数中,该函数试图从
((uint16 *)pBuffer)[index] = value;
value
类型为 uint16 的 奇数/未对齐内存位置执行此操作
和 index
进行边界检查并索引 pBuffer
。 这会导致未对齐的内存访问异常。 pBuffer
指向堆上的char *
。
如前所述,即使我们可以查看第三方堆栈,我们也无法正式更新代码。 因此,我们通知提供商,他们会在下一个版本中提供更新。
我想了解是否有解决方法。 如何在不违反未对齐访问的情况下执行上述分配? 解决此类问题的最佳方法是什么。
Architecture ARM9. Programming Language C.
We have a third-party stack and one of the calls takes a pointer(pBuffer
) to a memory location. Within the stack, they are free to move around the pointer passed and access it as they wish. Unfortunately, they offset the passed in pointer and passed it into a another function that tried to do this from an odd/unalighed memory location
((uint16 *)pBuffer)[index] = value;
where value
is of type uint16
and index
is bounds checked and indexes pBuffer
. This causes a unaligned memory access exception. pBuffer
points to char *
on the heap.
As mentioned, even though we can peek into the third-party stack, we can not update the code officially. So we notify the provider and they provide the update in the next release.
I want to understand if there is a work around for this. How do I perform the above assignment without violating the unaligned access? What is the best approach to resolving such problems.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
逐字节复制值。 将其转换为(无符号)字符指针,然后一次复制一个字节。
这并不漂亮,但听起来你没有很多选择。
Copy the value byte by byte. Cast it to a (unsigned) char pointer, and then copy a byte at a time.
It's not pretty, but it doesn't sound like you have many options.
存在三种可能性,目前我无法从你的问题中确定是哪种情况。
情况 1:索引始终为奇数。 解决方案:memmove() pBuffer超过1个字节
情况 2:索引有时会很奇怪,您可以预先预测什么时候会很奇怪。 解决方案:当您知道索引将为奇数时, memmove() pBuffer 超过 1 个字节。
情况3:索引有时是奇数,你无法预测什么时候会是奇数。 这是不幸的,因为代码将会出错。
There are three possibilities, and I cannot determine from your question so far which is the case.
Case 1: The index is always odd. Solution: memmove() pBuffer over 1 bytes
Case 2: The index is sometimes odd, and you can predict up front when it will be. Solution: memmove() pBuffer over 1 byte when you know index will be odd.
Case 3: The index is sometimes odd, and you cannot predict when it will be. This is unfortunate, because the code will fault.
如果您控制 pBuffer,作为解决方法,您可以将其声明为 uint32_t 数组(或与您的架构对齐的任何内容)。 通过将缓冲区声明为 uint32_t,编译器将选择正确的对齐方式。 您可以在调用目标函数时将其强制转换为 uint8_t*。
这应该适用于您发布的示例代码,但如果第三方代码将任何未对齐的偏移量应用于缓冲区,则可能仍然会失败。
If you are in control of pBuffer, as a work around, you could declare it as an array of uint32_t (or whatever matches the alignment of your architecture). With declaring the buffer as uint32_t, the compiler will choose the correct alignment. You can cast it to uint8_t* when calling your target function.
This should work with the example code you posted, but may still fail if the third party code applies any unaligned offset to the buffer.