如何计算DW_AT_location的值,谁能帮上忙?我还想知道什么时候在这个属性中使用DW_OP_addr和DW_OP_fbreg
.uleb128 0x2 # (DIE (0x75) DW_TAG_variable)
.ascii "c\0" # DW_AT_name
.byte 0x1 # DW_AT_decl_file (DW_TAG_const_type_1.c)
.byte 0x5 # DW_AT_decl_line
.long 0x88 # DW_AT_type
# DW_AT_external
.uleb128 0x9 # DW_AT_location
.byte 0x3 # DW_OP_addr.quad c
.uleb128 0x6 # (DIE (0x6d) DW_TAG_variable)
.ascii "obj\0" # DW_AT_name
.byte 0x1 # DW_AT_decl_file (DW_TAG_base_type_1.c)
.byte 0x5 # DW_AT_decl_line
.long 0x84 # DW_AT_type
.uleb128 0x3 # DW_AT_location
.byte 0x91 # DW_OP_fbreg
.sleb128 -96发布于 2018-02-16 15:51:47
你的问题中没有足够的信息来提供完整的答案。
在每种情况下,似乎DW_AT_location都是用表单DW_FORM_exprloc表示的,该表单是used 128编码的长度,后面跟着相应的字节数,在本例中,这些字节构成了一个矮小表达式,用作位置描述。
在第一种情况下,长度为9,但只显示了第一个字节,即DW_OP_addr。矮4标准包含以下有用的解释:
2.5.1一般业务 每个通用操作表示简单堆栈机器上的后缀操作。堆栈的每个元素都是目标机器上地址的大小。在“执行”矮小表达式之后,堆栈顶部的值被视为结果(对象的地址、数组绑定的值、动态字符串的长度、所需的值本身等等)。 2.5.1.1文字编码 以下操作都将一个值推送到矮小堆栈上。如果这些操作中的常量的值大于可以存储在单个堆栈元素中的值,则将该值截断到元素大小,并将低阶位推到堆栈上。
DW_OP_addr操作只有一个操作数,它编码一个机器地址,其大小是目标机器上地址的大小。
因此,在应用任何重定位之前,您的第一个示例结束后的8个字节将是变量c的地址。
第二个例子也不完整。在SLEB128中编码十进制-96要消耗两个字节,即0xa0 0x7f,所以您有整个位置描述,即DW_OP_fbreg(-96)。然而,正如标准所解释的那样:
2.5.1.2基于寄存器的寻址 以下操作将值推送到堆栈上,这是将寄存器的内容添加到给定的有符号偏移量的结果。
DW_OP_fbreg操作提供了由当前函数的DW_AT_frame_base属性中的位置描述指定的地址的有符号LEB128偏移量。(这通常是一个“堆栈指针”寄存器加或减一些偏移量。在更复杂的系统中,它可能是一个位置列表,根据PC的变化根据堆栈指针的变化调整偏移量。)
因此,您需要为拥有obj的函数找到模具,并计算其DW_AT_frame_base。obj存储在该地址下面的96字节。
https://stackoverflow.com/questions/45295190
复制相似问题