【发布时间】:2022-06-10 17:36:05
【问题描述】:
我已经听了很长时间了。我正在尝试在微控制器上实现与位置无关的代码。这真是个兔子洞。到目前为止,我已经可以将我的在线服务上线,并且可以响应 mqtt 命令。
由于完全未知的原因,我似乎唯一不能做的是 1 个特定的 stdlib 调用:vsnprintf 或其所有兄弟姐妹。我正在使用 arm-none-eabi 工具链 10.2 版。我有这个特定功能的源代码,但它对我不太了解的东西太深入了,所以我一直在尝试解决这个问题。
我正在使用 lwip(轻量级 IP),它可以调用 snprintf。它工作正常,直到我将我的应用程序重新定位到 Flash 中的不同位置。 .got 部分和 sram 内存已使用我在自定义引导加载程序中计算的 lma_offset 正确修补。同样,一切正常,除了对 std 库的这个可怕的单次调用。
出于调试目的,我为snprintf 制作了一个包装器,希望我可以进一步深入了解问题所在。我没有走得更远。
int snprintf_override (
char *__restrict buffer,
size_t size,
const char *__restrict format,
...)
{
int result;
va_list args;
va_start(args, format);
// The next line calls into std lib, and hard faults, I wish I could share anything else that made any sense...
result = vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
return result;
}
问题一:
有没有人可以建议another way 实现与vsnprintf 相同的功能?从头开始写东西是否可行?我感觉这个函数有点复杂?
问题 2:
或者,有没有人知道重定位代码会导致svnprintf 失败的问题是什么?挖掘 stdlib 代码我遇到了REENT / impurepointers (?),并且实现依赖于FILE 实例。仍然是“只是数据”,我天真地说,但也许还不止这些?是否有一些隐藏在某个地方的程序集根本无法重定位(我不敢相信这是不可能的,Linux 操作系统除了使用 -fpic... 编译之外什么都不做)?
恐怕这个问题很少受到关注,但也许,只是也许,对标准库和/或位置无关代码有一定了解的人点击它,并愿意帮助我......
【问题讨论】:
-
为了问题的完整性,如果您使用来自arm 的 arm-none-eabi 发行版,包含的 libc 通常是 newlib。
标签: c position-independent-code arm-none-eabi-gcc