GCC Arm 12.2编译提示 LOAD segment with RWX permissions 警告
使用GCC Arm工具链开发的项目, 在升级到 arm-gnu-toolchain-12.2 之后, 编译出现警告
arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld: warning: Build/app.elf has a LOAD segment with RWX permissions
关于 LOAD segment with RWX permissions 警告
这是 Binutils 2.39 引入的一个新的安全类型的警告, GCC在升级版本时会带着新版本的 Binutils 一起发布. 如果要消除这个警告, 要么修改ld文件, 要么屏蔽掉它.
说明
这篇文章里有比较详细的说明
https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments
The executable segment warnings
当程序载入内存时会分段载入, 一些属于可执行的代码,一些属于数据, 可读或者可读可写, 可能还有一些用于其它特殊用途. 每一段内存都会区分可读、可写和可执行这三个属性, 如果一个内存段同时具有这三种属性, 则存在受到攻击的可能性, 因此在这种情况下链接器将产生以下警告
warning: <file> has a LOAD segment with RWX permissions
这个警告表示elf文件中存在一个或多个存在安全问题的段, 可以通过运行readelf程序进行查看
readelf -lW <file>
注意: 在readelf的输出中, 段的可执行标志被标记为E而不是X, 三个属性的标识为RWE而不是RWX. 警告出现的常见原因是使用自定义连接脚本进行链接, 该脚本未将代码和数据分成不同的段, 所以最好的解决办法是更新连接脚本. readelf命令将显示每个段包含哪些部分, 可以通过这些信息计算出连接器映射需要如何更新, 才能将代码部分和可写的数据部分分开.
消除 LOAD segment with RWX permissions 警告
选项一: 使用 --no-warn-rwx-segments 屏蔽
- 如果连接使用的是ld, 可以用
--no-warn-rwx-segments选项 - 如果连接使用的是gcc, 直接用会提示无法识别的选项, 需要用
-Wl,--no-warn-rwx-segments这样的方式 
选项二: 修改连接描述
对于存在问题的elf, 可以通过这个命令查看文件结构, 注意后面的Flg部分, RWE分别表示Read,Write,Execute.
$ readelf -lW app.elf 
Elf file type is EXEC (Executable file)
Entry point 0x15e1
There are 3 program headers, starting at offset 52
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00000000 0x00000000 0x026f4 0x026f4 RWE 0x10000
  LOAD           0x020000 0x20000000 0x000026f4 0x00088 0x00334 RW  0x10000
  LOAD           0x000334 0x20000334 0x0000277c 0x00000 0x00004 RW  0x10000
 Section to Segment mapping:
  Segment Sections...
   00     .isr_vector .text .rodata .init_array .fini_array
   01     .data .bss
   02     ._user_heap_stack
其中LOAD           0x010000 0x08000000 0x08000000 0x03ffc 0x03ffc RWE 0x10000就是存在问题的segment, 如果要消除这个警告, 可以将ld文件中的 .init_array 和 .fini_array 这部分注释掉, 代码如下. 这部分是 startup 文件中 __libc_init_array使用的, 如果不需要可以直接删除, 对应的编译参数也可以加上-nostartfiles.
  .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
这样编译完之后的结果如下, 第一个segment中, Flg变成了R E就没问题了.
$ readelf -lW app.elf 
Elf file type is EXEC (Executable file)
Entry point 0x1549
There are 3 program headers, starting at offset 52
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00000000 0x00000000 0x02654 0x02654 R E 0x10000
  LOAD           0x020000 0x20000000 0x00002654 0x00088 0x00318 RW  0x10000
  LOAD           0x000318 0x20000318 0x000026dc 0x00000 0x00300 RW  0x10000
 Section to Segment mapping:
  Segment Sections...
   00     .isr_vector .text .rodata
   01     .data .bss
   02     ._user_heap_stack
上面这种修改并不是通用的, 对于需要使用libc的应用而言并不可行.
实际上, 对于Cortex M系列的MCU而言, elf中第一个segment对应的实际上是烧录到flash中的部分(可执行), 第二个segment对应的才是运行时可读写的内存部分(数据), 第一个segment在通过flash启动正常运行时并不存在修改的可能性.
因此结论是可以通过选项一, 简单地将警告屏蔽掉
参考
- https://github.com/raspberrypi/pico-sdk/issues/1029
 - https://stackoverflow.com/questions/73429929/gnu-linker-elf-has-a-load-segment-with-rwx-permissions-embedded-arm-project
 - https://github.com/OP-TEE/optee_os/issues/5471
 
GCC Arm 12.2编译提示 LOAD segment with RWX permissions 警告的更多相关文章
- busybox-1.12.2编译提示“混合的隐含和普通规则”错误解决
		
编译环境:CentOs 7.1 Ubuntu 12.0.4 都可以 交叉编译工具:gcc -4.3.2 (博创6410平台) 问题描述:执行make menuconfig命令的时候,提示Makefil ...
 - gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解
		
摘自http://blog.csdn.net/elfprincexu/article/details/45043971 gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解 C和C+ ...
 - Xamarin.Android编译提示找不到mscorlib.dll.so文件
		
Xamarin.Android编译提示找不到mscorlib.dll.so文件 错误信息:AOT module ‘mscorlib.dll.so’ not found: Cannot load lib ...
 - 对<< ubuntu 12.04编译安装linux-3.6.10内核笔记>>的修正
		
前题: 在前几个月的时候,写了一篇笔记,说的是kernel compile的事情,当时经验不足,虽说编译过了,但有些地方写的有错误--因为当时的理解是有错误的.今天一一更正,记录如下: 前文笔记链接: ...
 - 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程
		
一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...
 - gcc 学习笔记(一) - 编译C程序 及 编译过程
		
一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...
 - nginx-1.12.2编译安装指导
		
nginx-1.12.2编译安装 下载源码包 安装 安装后配置 下载源码包 下载地址:http://nginx.org/en/download.html nginx-1.12.2:http://ngi ...
 - [20191213]toad 12下BIND_AWARE提示无效.txt
		
[20191213]toad 12下BIND_AWARE提示无效.txt --//链接http://blog.itpub.net/267265/viewspace-2130781/的测试,发现当时测试 ...
 - coreseek 在gcc 4.9+ 上编译不通过 [sphinxexpr.o] Error 1 错误解决方案
		
这几天玩hhvm,把gcc环境都装到4.9了,然后编译coreseek的时候就出问题,google一大圈,貌似捕风捉影看到一些信息说是gcc4.7+的c++作用域必须用this->去引用,这里整 ...
 
随机推荐
- python 操作xml、html文件
			
简介 在一些项目中可能会使用到解析html文件,尤其是爬虫相关的,需要解析获取到的html内容,通常我们会使用lxml模块去进行html文件的解析. html文件 当前存在一个简单的html < ...
 - 从matlab的bwmorph函数的'majority'参数中扩展的一种二值图像边缘光滑的实时算法。
			
在matlab的图像处理工具箱中,有一系列关于Binary Images的处理函数,都是以字母bw开头的,其中以bwmorph函数选项最为丰富,一共有'bothat'.'branchpoints'.' ...
 - V8中的快慢数组(附源码、图文更易理解😃)
			
接上一篇掘金 V8 中的快慢属性,本篇分析V8 中的快慢数组,了解数组全填充还是带孔.快慢数组.快慢转化.动态扩缩容等等.其实很多语言底层都采用类似的处理方式,比如:Golang中切片的append操 ...
 - RestTemplate上传文件
			
1.上传的文件是File类型 如果文件保存在本地,即可以通过File file = new File(path) 或者 文件路径地址获取到指定文件 public String uploadFile(F ...
 - Apache DolphinScheduler 使用文档(2-3/8):集群规划及环境准备
			
本文章经授权转载,原文链接: https://blog.csdn.net/MiaoSO/article/details/104770720 目录 2. 集群规划 2.1 集群配置 2.2 软件版本 2 ...
 - day20--Java集合03
			
Java集合03 8.LinkedList 1)linkedList底层实现了双向链表和双端队列的特点 2)可以添加任意元素(元素可以重复),包括null 3)线程不安全,没有实现同步 LinkedL ...
 - linux设置系统环境变量的天坑
			
在设置系统环境变量,也就是 .bash_profile 或者 /etc/proflie 或者 .bashrc 中把path写错或者是把设置系统环境变量的格式写错! 会 导致 系统无法进入.登录无限循环 ...
 - 盘点Vue2和Vue3的10种组件通信方式(值得收藏)
			
Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异:本文将通过选项式API 组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式.其中将要实现的通信 ...
 - 轻松月薪过万,NISP证书含金量有多重|NISP管理中心|网安伴|nisp
			
nisp一级证书含金量 NISP一级证书是面向各个行业工作人员信息安全意识普及化和网络信息安全基础培训的国家级验证.持NISP一级证书可以从信息安全保密较高的单位得到加分.证书由中国信息安全测评中心授 ...
 - [网鼎杯 2018]Comment-1|SQL注入|二次注入
			
1.打开之后只有一个留言页面,很自然的就想到了二次注入得问题,顺带查看了下源代码信息,并没有什么提示,显示界面如下: 2.那先扫描一下目录,同时随便留言一个测试以下,但是显示需要登录,账户.密码给出了 ...