gnu ld 链接脚本引入的字节对齐问题,求解

sincostan 2016-04-13 04:01:02
gnu ld 链接脚本片段:

. = ALIGN(4);
_device_enmu_start = .;
*(.data.enmu.dev)
_device_enmu_end = .;

源代码中定义了两个struct A (共20字节)的结构体全局变量,放在data.enmu.dev特定的数据段中。本意是想 _device_enmu_start 这个脚本变量,指向结构体的首地址。通过 _device_enmu_start 遍历出struct A 类型的所有数据。

而实际反汇编查看到,_device_enmu_start 和结构体首地址之间,增加了4字节0,作为填充!! 导致它不能指向结构体首地址,程序错误!
804bf614 <_device_enmu_start>:
804bf614: 00000000 nop <---- 这个就是添加的额外4字节

804bf618 <__device__AAAAAA>: <---- 这里才是结构体首地址
804bf618: 80458be8 lb a1,-29720(v0)
804bf61c: 80458bf8 lb a1,-29704(v0)
804bf620: 80458c08 lb a1,-29688(v0)
804bf624: 804980a8 lb a5,-32600(v0)
804bf628: 12345678
...

如何禁止掉链接器自动添加的字节,使得全局变量紧密排列?
...全文
743 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
sincostan 2016-04-14
  • 打赏
  • 举报
回复
如果彻底解决的话,感觉需要在结构体里加 magic number 字段。代码动态判断 magic value, 以便判断出结构体在哪里。似乎除此之外没好的方法。代码稍微复杂点,但也不难。
sincostan 2016-04-14
  • 打赏
  • 举报
回复
经过仔细分析和上板调试,MIPS板上必须8字节对齐。为了快速调试,链接脚本里在第一个变量前加8字节对齐,这样变量和数据结构第一个首地址之间,不再插那 4字节0 了。 但是在结构体变量之间又插了 4字节。 于是修改结构体定义,追加了void* padding字段,使得结构体由20字节,变为24字节,8的倍数。 重新编译反汇编,OK了。 上板测试结果,完全正确! 但是代码里加了详细的注释,避免以后再改动结构体造成不是8的倍数问题,使得将来的维护人一目了然,注意这个问题
fly 100% 2016-04-14
  • 打赏
  • 举报
回复
那你不要设置字节对齐啊,他为了字节对其在前面添加的。 . = ALIGN(4); 删掉

21,615

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧