Chinaunix首页 | 论坛 | 博客
  • 博客访问: 60922
  • 博文数量: 15
  • 博客积分: 353
  • 博客等级: 一等列兵
  • 技术积分: 175
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-12 16:15
文章分类
文章存档

2011年(15)

我的朋友

分类: 嵌入式

2011-12-19 12:01:12

Relax_type在输出目标文件时进行relax时所需要的信息,包括跳转的地址范围和目前地址长度,比如,6位偏移,然后左移两位,那么这个地址偏移可以表示前后128字节的地址,并且地址字节长度为1。这个类型主要使用在机器相关的处理,做移植工作的人员需要提供目标机器所对应的跳转类型,即relax表,便于relax的进行。

/* 该跳转向前可以跳转最大偏移 */

offsetT rlx_forward;

/*该跳转向前可以跳转最大偏移*/

offsetT rlx_backward;

/* 地址的字节长度(即表示该跳转地址的字节长度) */

unsigned char rlx_length;

/* 是否还有需要relax,0为结束 */

relax_substateT rlx_more;

 

union

{

//重定位之前

struct

{

symbolS *offset_sym; //偏移量

reloc_howto_type *howto; //重定位类型

symbolS *sym; //需要定位符号

bfd_vma addend; //基址

} a;

//重定位之后

struct

{

asection *sec; //重定位从属的段

asymbol *s; //重定位符号

arelent r; //重定位信息入口

} b;

} u;

Reloc_list包含了重定位信息,包括重定位之前的信息收集(包括基址,偏移和重定位类型),和重定位之后信息(主要是arelent,即BFD中特殊的重定位入口类型)

/*是否是pc相对重定位 */

unsigned fx_pcrel : 1;

/*是否为立即数偏移量 */

unsigned fx_im_disp : 2;

/* 机器相关位,自己备用 */

unsigned fx_tcbit : 1;

unsigned fx_tcbit2 : 1;

/*是否经过重定位 */

unsigned fx_done : 1;

/*是否取消溢出 */

unsigned fx_no_overflow : 1;

/* 是否检查溢出 */

unsigned fx_signed : 1;

/* pc相对偏移量 */

char fx_pcrel_adjust;

/* fix需要多少字节数*/

unsigned char fx_size;

/* 进行fix所对应的frag */

fragS *fx_frag;

/* 要进行fix的起始地址 */

long fx_where;

/*要增加的符号或符号链表 */

symbolS *fx_addsy;

/*要去除的符号或符号链表 */

symbolS *fx_subsy;

/*要增加的绝对偏移 */

valueT fx_offset;

/*当前的dot地址(dot值是特殊的值,类似当前地址,用于计算实际fix后偏移) */

addressT fx_dot_value;

/* 链表结构 */

struct fix *fx_next;

/* 对bit调整,即少于1个字节的fix */

bit_fixS *fx_bit_fixP;

//重定位类型(如何定位相对或者绝对,定位长度64 32等)

bfd_reloc_code_real_type fx_r_type;

Fix结构主要用于在输出目标文件期间,对未解析地址信息进行fix,而fix的信息,是有md_assemble中对于特定指令所生成的fix信息,链接到一个fix链表中,这个fix链表分别保存在frchain(frag的一个控制链表)和segment_info(段信息)中(后文介绍)。

 

/*位于目标文件的原始地址(字节偏移量)*/

addressT fr_address;

/* 最后一遍relax后的地址 */

addressT last_fr_address;

/* fix之后frag中的固定字节大小 */

offsetT fr_fix;

/* 固定字节之后的字节大小 */

offsetT fr_var;

/* 可变尾部的大小 */

offsetT fr_offset;

/* 尾部可变符号(链表) */

symbolS *fr_symbol;

/* opcode地址 */

char *fr_opcode;

/* 构成链表结构 */

struct frag *fr_next; //下一条代码段

/* 是否跳过relax */

unsigned int relax_marker:1;

/* 是否为空frag */

unsigned int has_code:1;

/* 指令地址 */

unsigned int insn_addr:6;

/* relax状态 */

relax_stateT fr_type;

/* 这个也是relax状态,可以用于在机器相关处理的分类 */

relax_substateT fr_subtype;

/* 代码片段所包含的二进制信息 */

char fr_literal[1];

Frag是GAS中基本的数据结构,它是基于汇编代码的最小结构,是最后构成目标输出文件的基本。可以看到,Frag包含了目前代码片段的起始地址和这些代码的二进制信息,而其余的信息,则是帮助该Frag进行relax和重定位。

 

struct frag *frch_root; /* frag头 */

struct frag *frch_last; /* frag尾 */

struct frchain *frch_next; /* 下一个frchain,构成链表 */

subsegT frch_subseg; /* 对应的subsegment */

fixS *fix_root; /* fix头 */

fixS *fix_tail; /* fix尾 */

struct obstack frch_obstack; /* 分配内存区,后文讲述 */

fragS *frch_frag_now; /* 当前的frag */

Frchain是frag的控制结构,可以看到,不仅包含所有对应的frag信息,还有当前操作的frag,同时,还有对应于这系列frag的fix信息。这些fix信息,分别保存在各自的frchain中,会在其后整理保存到相应的segment_info中。

 

上述几者关系如下图:

clip_image002

阅读(1759) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~