首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法使用clang和cmake交叉编译arm cortex m4的异常,并且生成了"got“部分

无法使用clang和cmake交叉编译arm cortex m4的异常,并且生成了"got“部分
EN

Stack Overflow用户
提问于 2021-11-17 09:13:55
回答 1查看 57关注 0票数 0

我最近一直在尝试用Clang和CMake为C++编译固件,使用工具链文件。我可以让它正常工作,没有任何异常。当我使用异常时,出现了一个问题。

LLVM版本: 13.0.0

CMake版本: 3.21.3

处理器: STM32L432KC,ARM Cortex M4

为了成功地编译固件,我使用了预编译的libclibmlibgcclibstdc++,并捆绑了ARM GNU GCC工具链,版本10.3.2021-10。

我不会把整个工具链文件放在这里。相信我,到CMAKE_C_COMPILERCMAKE_CXX_COMPILERCMAKE_ASM_COMPILERCMAKE_LINKER的路径都很好。

CMAKE_CXX_FLAGS_INIT定义了C语言的初始编译标志,其定义如下:

代码语言:javascript
运行
复制
-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
-nodefaultlibs
--sysroot=${ARM_GNU_TOOLCHAIN_PATH}/arm-none-eabi
-flto
-fdata-sections -ffunction-sections
# For <iostream>, <string>, ...
-isystem "${ARM_GNU_TOOLCHAIN_PATH}/arm-none-eabi/include/c++/${ARM_GNU_TOOLCHAIN_GCC_VERSION}/" 
# For <bits/*>, ...
-isystem "${ARM_GNU_TOOLCHAIN_PATH}/arm-none-eabi/include/c++/${ARM_GNU_TOOLCHAIN_GCC_VERSION}/arm-none-eabi/thumb/v7e-m+fp/hard/"
-fexceptions

ARM_GNU_TOOLCHAIN_PATH是所提到的ARM GNU GCC工具链的根路径。ARM_GNU_TOOLCHAIN_GCC_VERSION等于10.3.1

链接器标志,使用CMAKE_EXE_LINKER_FLAGS_INIT定义

代码语言:javascript
运行
复制
-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
-nodefaultlibs
--sysroot=${ARM_GNU_TOOLCHAIN_PATH}/arm-none-eabi
-flto
-fdata-sections -ffunction-sections
-Wl,--gc-sections
-flto
-fexceptions
# Path to standard libraries: libc, libm, ...
-L"${ARM_GNU_TOOLCHAIN_PATH}/arm-none-eabi/lib/thumb/v7e-m+fp/hard/"
# Path to libgcc
-L"${ARM_GNU_TOOLCHAIN_PATH}/lib/gcc/arm-none-eabi/${ARM_GNU_TOOLCHAIN_GCC_VERSION}/thumb/v7e-m+fp/hard/"
-lc -lm -lnosys -lstdc++ -lgcc")

如果在二进制文件中没有,则返回try ... catch块。一切都编译得很好,但如果至少有一个代码块:

代码语言:javascript
运行
复制
try
{
    throw std::runtime_error{"Some error!"};
} catch (const std::exception&e)
{
    printf("Error: %s\r\n", e.what());
}

链接器在.data段之前输入.got段,而不需要在链接器脚本中进行指示。RAM起始地址为0x20000000。objdump输出:

代码语言:javascript
运行
复制
...
Contents of section .got:
 20000000 848f0108                             ....
Contents of section .data:
 20000004 00000000 00000000 08000020 08000020  ........... ... 
 20000014 10000020 10000020 18000020 18000020  ... ... ... ... 
 20000024 20000020 20000020 28000020 28000020   ..  .. (.. (.. 
 20000034 30000020 30000020 38000020 38000020  0.. 0.. 8.. 8.. 
...

我的链接器脚本,由CubeMX生成,有LMA .data部分,它应该是内存中的第一部分。:

代码语言:javascript
运行
复制
  .fini_array :
  {
    . = ALIGN(8);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(8);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : 
  {
    . = ALIGN(8);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(8);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH

正如您在注释中看到的,启动代码将使用_sdata来初始化内存中的data。问题是_sdata将被设置为0x20000000,而不是第一个全局变量所在的0x20000008。这意味着所有的全局变量都将具有错误的值。

作为一种解决方法,我添加了一个使用所有got*输入节的.got节:

代码语言:javascript
运行
复制
...
  .fini_array :
  {
    . = ALIGN(8);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(8);
  } >FLASH

  .got :
  {
    . = ALIGN(8);
    *(.got)
    *(.got*)
    . = ALIGN(8);
  } >RAM AT> FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : 
  {
...

因为.got部分与动态符号解析相关,所以我对它不是很熟悉。我只使用静态库来编译固件,因为我编写的裸机程序针对每个项目一个二进制文件。

主要的问题是异常不能正常工作。在上面的try ... catch ...块中没有捕获到异常。固件在Default_Handler内结束。

我猜这与clang生成的.got部分有关。Clang无法正确链接libgcc中的编译器内建来处理异常。

你能帮我调试和修复它吗?

EN

回答 1

Stack Overflow用户

发布于 2021-11-29 09:46:40

编译时使用-Wl,--target2=rel标志。

我已经在llvm-dev邮件列表上创建了一个帖子,可以在here上找到。Peter Smith帮助解决了这个问题,并指出了解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70001611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档