STM32BCubeIDE编译报警告“.elf has a LOAD segment with RWX permissions”解决方法

STM32BCubeIDE版本升级后编译报警告“.elf has a LOAD segment with RWX permissions”解决方法

前言

你是否在升级STM32CubeIDE后遇到过这样的编译警告——.elf has a LOAD segment with RWX permissions?当熟悉的工程突然冒出这个提示,不少开发者会陷入困惑:明明代码没改,为什么新版本IDE会报警告?这个看似陌生的"RWX权限"到底意味着什么安全隐患?

作为经历过从旧版本升级到1.18.1的开发者,我曾被这个警告困扰许久。起初以为是代码问题,反复检查却一无所获,直到深入研究ELF文件格式和链接器脚本才发现:这是IDE升级后对内存段权限检查更严格的结果——RWX(可读可写可执行)权限段可能被恶意利用执行代码,而STM32开发中很多场景其实只需RX(可读可执行)权限。

这篇文章将分享我踩坑后总结的解决方案:无需修改代码逻辑,只需调整链接器脚本(.ld文件)中的内存段权限配置,就能轻松消除警告。从ELF文件权限含义到链接器脚本修改细节,每一步都配有截图和代码示例,即使是初次接触链接脚本的开发者也能跟着操作。亲测在STM32CubeIDE 1.18.1及更高版本中有效,赶紧收藏这篇解决方案,下次升级IDE遇到同样问题时,它能帮你5分钟解决警告!

问题概述

我将STM32CubeIDE升级到最新版本之后,编译之前版本建立的工程,会报出警告:“.elf has a LOAD segment with RWX permissions
在这里插入图片描述

问题的原因

在软件开发中,ELF(Executable and Linkable Format)文件是一种常见的二进制文件格式,用于存储程序的代码和数据。在使用STM32CubeIDE等集成开发环境时,可能会遇到ELF文件中包含具有读写执行(RWX)权限的LOAD段的警告。这种情况通常发生在更新IDE版本后,例如我从旧版本升级到1.18.1版本。

LOAD段的RWX权限意味着该段既可以读取、写入,也可以执行,这在某些情况下可能会带来安全风险。在STM32CubeIDE中,这个警告通常是由于链接器脚本(LD文件)中的内存段配置不当导致的。在某些情况下,内存段被错误地标记为具有RWX权限,而实际上应该只有读和执行权限。

问题解决

解决方法是:
ld文件中的相关段权限改为“可读可执行”即可,去掉“可写”的权限。
操作如下:
在RAM.ld和Flash.ld文件中,将权限从wrx改为rx。修改后的结果如下:

/* Memories definition */
MEMORY
{
  CCMRAM    (xr)    : ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xr)    : ORIGIN = 0x20000000,   LENGTH = 128K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 1024K
}

另外,附上图片解释一下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


本文结束,如果对你有帮助,欢迎点赞、转发、收藏!

/* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack / _estack = ORIGIN(RAM) + LENGTH(RAM); / end of RAM / / Generate a link error if heap and stack don’t fit into RAM. These numbers affect the USED size of RAM / _Min_Heap_Size = 0x100; / required amount of heap: 256 bytes / _Min_Stack_Size = 0x200; / required amount of stack: 512 bytes */ /* Specify the memory areas */ MEMORY { /RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 3K/ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 24K RAM (rw) : ORIGIN = 0x20000000, LENGTH = 3K } /* Define output sections / SECTIONS { / SRAM vector table */ .ram_vector : { *(.ram_vector) } >RAM /* The startup code goes first into FLASH / .isr_vector : { . = ALIGN(4); KEEP((.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH / .text : { . = ALIGN(4); (.text) / .text sections (code) / (.text) / .text sections (code) */ (.glue_7) / glue arm to thumb code */ (.glue_7t) / glue thumb to arm code */ *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* Constant data goes into FLASH / .rodata : { . = ALIGN(4); (.rodata) / .rodata sections (constants, strings, etc.) / (.rodata) / .rodata sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH .ARM.extab : { (.ARM.extab .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; (.ARM.exidx) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP ((.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP ((SORT(.init_array.))) KEEP ((.init_array)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP ((SORT(.fini_array.))) KEEP ((.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup to initialize data */ _sidata = LOADADDR(.data); /* Initialized data sections goes into RAM, load LMA copy after code / .data : { . = ALIGN(4); _sdata = .; / create a global symbol at data start / (.data) / .data sections / (.data) / .data sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /* Uninitialized data section / . = ALIGN(4); .bss : { / This is used by the startup in order to initialize the .bss secion / _sbss = .; / define a global symbol at bss start */ bss_start = _sbss; *(.bss) (.bss) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } 这是完整的链接脚本,请检查是否存在导致warning: test.elf has a LOAD segment with RWX permissions的问题
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值