静态库代码对驻留在应用程序代码中的外部结构使用了错误的地址

问题描述

我这边真的很奇怪。我正在为运行 Nucleus RTOS 的 Cortex-M4f 编写固件。对于我的应用程序,我有一些预构建的静态库(例如 libexternal.a),它们需要应用程序必须提供的全局结构(在静态库中声明为 extern)。

在我的应用程序代码中,我可以很好地访问结构体,但是在静态库的代码中,我总是得到一个 HardFault 中断。

通过调试,我发现处理器试图访问错误地址上的结构。下面是一些示例伪代码:

appconfig.c

struct AppConfiguration g_appconfig = {

/* initialize everything statically */
};

ma​​in.c

include <staticlib.h>

void main(){
  g_appconfig.somemember = 1 /* this works */

  staticlib_lib_init();
}

下面的所有内容都是静态库的一部分,并在编译应用程序之前预先构建。

appconfig.h

struct AppConfiguration{
  uint32_t somemember;
};

staticlib.h

#include "appconfig.h"
extern struct AppConfiguration g_appconfig;

void static_lib_init();

staticlib.c

#include "staticlib.h"

void static_lib_init(){

  g_appconfig.somemember = 1 /* causes a HardFault */
}

静态库是用标志编译的:

-ffunction-sections
-fdata-sections
-fno-builtin-memcpy
-DARM_MATH_CM4=1
-mthumb
-mcpu=cortex-m4
-mfloat-abi=soft
-fPIC
-Wno-unused-but-set-variable

和带有标志的应用程序:

-ffunction-sections
-fdata-sections
-fno-builtin-memcpy
-mthumb
-mcpu=cortex-m4
-g
-mfloat-abi=soft

通过调试,我发现静态库试图在错误的内存地址访问 g_appconfig。例如

g_appconfig 从地址 0x2000061c 开始,static_lib_init() 尝试在地址 0xff7f4342 访问它。我的 SRAM 是 320k 大,从 0x2000000 开始,我的 ROM 是 2MB 大,从 0x8000000 开始。所以在 0xff 处访问内存是没有意义的......(可能是一些硬件寄存器或其他任何东西)。

static_lib_init() 的反汇编如下所示:

00000000 <static_lib_init>:
   0:   b5f0        push    {r4,r5,r6,r7,lr}
   2:   b08f        sub sp,#60 ; 0x3c
   4:   af06        add r7,sp,#24
   6:   6178        str r0,[r7,#20]
   8:   6139        str r1,#16]
   a:   60fa        str r2,#12]
   c:   60bb        str r3,#8]
   e:   4cf9        ldr r4,[pc,#996]  ; (3f4 <static_lib_init+0x3f4>)
  10:   447c        add r4,pc
  12:   4bf9        ldr r3,#996]  ; (3f8 <static_lib_init+0x3f8>)
  14:   58e3        ldr r3,[r4,r3]
  16:   461a        mov r2,r3
  18:   2301        movs    r3,#1
  1a:   f8c2 30d0   str.w   r3,[r2,#208]  ; 0xd0

r2 应该包含 g_appconfig 的起始地址(#208 是我想在现实世界代码中访问的元素的偏移量),但调试时包含 0xff7f4342。

知道这是怎么发生的吗?链接器不应该在链接时替换生成的静态库中 g_appconfig 的地址吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)