3553|0

222

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

gcc -O3优化后readelf查看地址对齐方式【探讨】 [复制链接]

本帖最后由 lzwml 于 2014-12-15 10:59 编辑

为了给控制端加入的命令特性,我借鉴uboot的U_BOOT_CMD方式定义一个端,命名为W_BOOT_CMD,并在Uboot基础上添加些独有特性。但是我在地址对齐上遇到个bug,目前bug已经解决,发帖只是想和大家探讨关于gcc优化的问题。

如下代码:
W_BOOT_CMDn(cmd1,do_null,"shell help");
W_BOOT_CMDn(cmd2,do_null,"shell help");
W_BOOT_CMDn(cmd3,do_null,"shell help");
W_BOOT_CMDn(cmd4,do_null,"shell help");
连接脚本没使用4字节对齐
          -------------省略---------------------------------------------------------------------------------------
        . = ALIGN(4);
        .rodata : {*(.rodata)}

       . = .;               从这个段开始不对其
        __u_boot_cmd_start = .;
        .u_boot_cmd : { *(.u_boot_cmd) }
        __u_boot_cmd_end = .;

       . = .;
        __w_boot_cmd_start = .;
        .w_boot_cmd : { *(.w_boot_cmd) }
        __w_boot_cmd_end = .;
                 -------------省略--------------------------------------------------------------------------------

测试1:编译后采用不优化(或者-O1优化),然后用readelf -s release/download.elf | grep __w查看"__w_boot_cmd_xxx"相关内容,下面的内容与我期望的相同,代码在这里
  405: 3000997c     0 NOTYPE  GLOBAL DEFAULT  ABS __w_boot_cmd_start
   428: 300099a0    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd4
   479: 30009994    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd3
   525: 300099ac     0 NOTYPE  GLOBAL DEFAULT  ABS __w_boot_cmd_end
   535: 30009988    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd2
   590: 3000997c    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd1
我所定义的结构体的长度是12字节,这4个命令的段地址依次排列start-->cmd1-->cmd2-->cmd3-->cmd4--end,并且start地址和cmd1一样

测试2:编译采用-O3(其实-O2优化就出现以下错误),
  352: 3000d5fe     0 NOTYPE  GLOBAL DEFAULT  ABS __w_boot_cmd_start
   375: 3000d600    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd4
   426: 3000d60c    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd3
   472: 3000d630     0 NOTYPE  GLOBAL DEFAULT  ABS __w_boot_cmd_end
   482: 3000d618    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd2
   537: 3000d624    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd1
这4个命令的段地址依次排列start-->cmd4-->cmd3-->cmd2-->cmd1--end,并且start不地址不等于cmd4地址相差2字节,编译后地址分配顺序和C语言代码里的相反。就是因为start相当于野指针,所以我的代码跑到这里就飞了

解决方案测试3:将连接脚本修改成4字节对齐,依旧采用-O3优化
        . = ALIGN(4);
        __u_boot_cmd_start = .;
        .u_boot_cmd : { *(.u_boot_cmd) }
        __u_boot_cmd_end = .;

        . = ALIGN(4);
        __w_boot_cmd_start = .;
        .w_boot_cmd : { *(.w_boot_cmd) }
        __w_boot_cmd_end = .;


   352: 3000d600     0 NOTYPE  GLOBAL DEFAULT  ABS __w_boot_cmd_start
   375: 3000d600    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd4
   426: 3000d60c    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd3
   472: 3000d630     0 NOTYPE  GLOBAL DEFAULT  ABS __w_boot_cmd_end
   482: 3000d618    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd2
   537: 3000d624    12 OBJECT  GLOBAL DEFAULT    8 __w_boot_cmd_cmd1
这4个命令的段地址依次排列start-->cmd4-->cmd3-->cmd2-->cmd1--end,现在start和cmd4相等,虽然和预期的start等于cmd1有出入,但地址是对齐的不影响我的代码。

测试4:更改c文件编译顺序
原始的c代码编译顺序是:
模块1.c 模块2.c  模块3.c  我自己的模仿uboot写的shell.c  一个编译后很大的模块.c
改成
模块1.c 模块2.c  模块3.c 一个编译后很大的模块.c   我自己的模仿uboot写的shell.c

接着在链接脚本里不使用4字节对齐声明,采用-O3优化编译。代码对齐方式和测试3一样。

问题:
1、有什么办法能在优化的情况下,命令地址顺序依旧是start-->cmd1-->cmd2-->cmd3-->cmd4--end
2、uboot默认采用-Os优化(不知道优化级别怎么样man的解释看不懂),于是我用-O3优化测试,他的命令顺序同-Os一样暂时没找到uboot的Makefie哪个编译选项能达到此目的
3、大家对采用-O3优化代码时有什么调试经验,或者有什么技巧可以避免优化后的可执行文件出现不可预料情况。
4、在采用-O2即以上优化时readelf -S 看到会生成一个.rodata.str1.4段,不知道是干什么用的

此帖出自Linux开发论坛
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表