2011年(15)
分类: 嵌入式
2011-12-19 11:55:07
GAS重要数据结构
Symbol是GAS中的重要数据结构之一,主要字段为BFD的asymbol,用于输出,frag类型的指针,用于指明符号所在frag,还有为expression的符号值。其余的字段用于指示符号所处的环境和属性,一般用于符号的处理和输出等操作。
/* BFD中的asymbol,用以输出 */ asymbol *bsym; /* 符号的值,后文介绍 */ expressionS sy_value; /* 前后引用,构成链表结构 */ struct symbol *sy_next; struct symbol *sy_previous; /*符号所在的frag */ struct frag *sy_frag; /* 该符号是否已经输出 */ unsigned int written : 1; // 后两个是表示状态量 /*该符号是否已经完全解析 */ unsigned int sy_resolved : 1; /*该符号是否正在解析 */ unsigned int sy_resolving : 1; /*该符号是否会使用在重定位当中(是的话,会强制输出) */ unsigned int sy_used_in_reloc : 1; /* 符号是否作为操作数或者表达式(符号还可以做标号等) */ unsigned int sy_used : 1; /* 符号是否可以重定义 */ unsigned int sy_volatile : 1; /* 符号是否是前向引用 */ unsigned int sy_forward_ref : 1; /* 符号是否定义与MRI段中 */ unsigned int sy_mri_common : 1; /* 符号是否定义在.weakref符号后 */ unsigned int sy_weakrefr : 1; /* 符号是否在.weakref之后,并且符号没有在符号表中定义 */ unsigned int sy_weakrefd : 1; |
除了Symbol之外,还有一种Symbol类型,用于表示未确定的也就是未解析的符号类型,是local_symbol。
/* 占位符,恒为NULL,表示此符号为local_symbol */ asymbol *lsy_marker; /* 占位符,如果为reg_section的话,则表示符号解析完毕 */ segT lsy_section; /* 符号的字符串名称 */ const char *lsy_name; /* 当符号尚未解析,则为frag;如果解析成功,则为实际符号 */ union { fragS *lsy_frag; symbolS *lsy_sym; } u; /* 符号值,为地址值,即当时定义符号所在的地址 */ valueT lsy_value; |
Local_symbol表示未解析的符号类型,当解析成功之后,local_symbol中会包含实际符号值,而并不会删除对应的local_symbol。可以看到,local_symbol内部除了实际符号字段外,大多为标志占位符,表示解析是否成功。
二者关系图如下:
表达式Expression的数据结构:
/*主符号 */ symbolS *X_add_symbol; /*第二个操作的符号 */ symbolS *X_op_symbol; /*可有可无的立即数(可以代表地址) */ offsetT X_add_number; /* 如何解释该表达式 */ operatorT X_op : 8; /* 表明X_add_number是否为无符号 */ unsigned int X_unsigned : 1; |
Expression类型不止是如其字面意思所示,除了表达表达式或复杂表达式(复杂表达式会使用在伪段expr_section定义的符号表达),还可以表达符号的值,而其中X_op(为枚举值)则指示了如何将X_add_symbol,X_op_symbol和X_add_number组合起来形成表达式值。如下则是X_op所代表的表达式组合:
/* 非法表达式 */ O_illegal, /* 不存在的表达式 */ O_absent, /* X_add_number (a constant expression). */ O_constant, /* X_add_symbol + X_add_number. */ O_symbol, /* X_add_symbol + X_add_number - the base address of the image. */ O_symbol_rva, /* A register (X_add_number is register number). */ O_register, /* 如果X_add_number小于等于0,则表示浮点数,否则,表示整数 */ O_big, /* (- X_add_symbol) + X_add_number. */ O_uminus, /* (~ X_add_symbol) + X_add_number. */ O_bit_not, /* (! X_add_symbol) + X_add_number. */ O_logical_not, /* (X_add_symbol * X_op_symbol) + X_add_number. */ O_multiply, /* (X_add_symbol / X_op_symbol) + X_add_number. */ O_divide, /* (X_add_symbol % X_op_symbol) + X_add_number. */ O_modulus, /* (X_add_symbol << X_op_symbol) + X_add_number. */ O_left_shift, /* (X_add_symbol >> X_op_symbol) + X_add_number. */ O_right_shift, /* (X_add_symbol | X_op_symbol) + X_add_number. */ O_bit_inclusive_or, /* (X_add_symbol |~ X_op_symbol) + X_add_number. */ O_bit_or_not, /* (X_add_symbol ^ X_op_symbol) + X_add_number. */ O_bit_exclusive_or, /* (X_add_symbol & X_op_symbol) + X_add_number. */ O_bit_and, /* (X_add_symbol + X_op_symbol) + X_add_number. */ O_add, /* (X_add_symbol – X_op_symbol) + X_add_number. */ O_subtract, /* (X_add_symbol == X_op_symbol) + X_add_number. */ O_eq, /* (X_add_symbol != X_op_symbol) + X_add_number. */ O_ne, /* (X_add_symbol < X_op_symbol) + X_add_number. */ O_lt, /* (X_add_symbol <= X_op_symbol) + X_add_number. */ O_le, /* (X_add_symbol >= X_op_symbol) + X_add_number. */ O_ge, /* (X_add_symbol > X_op_symbol) + X_add_number. */ O_gt, /* (X_add_symbol && X_op_symbol) + X_add_number. */ O_logical_and, /* (X_add_symbol || X_op_symbol) + X_add_number. */ O_logical_or, /* X_op_symbol [ X_add_symbol ] */ O_index, /* 机器相关表达式类型 */ O_md1, O_md2, O_md3, O_md4, O_md5, O_md6, O_md7, O_md8, O_md9, O_md10, O_md11, O_md12, O_md13, O_md14, O_md15, O_md16, O_md17, O_md18, O_md19, O_md20, O_md21, O_md22, O_md23, O_md24, O_md25, O_md26, O_md27, O_md28, O_md29, O_md30, O_md31, O_md32, /* 表达式最大值 */ O_max |
通过上述的X_op所代表的表达式组合方式,可以看到,Expression可以表达诸如LHS op RHS + offset的表达式,并且通过这样的方式,生成相应的值。