You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从DWARF调试信息获取结构体成员内存地址的两类疑问咨询

DWARF调试信息解析疑问解答

问题1:DW_AT_location解析与变量地址匹配问题

你的DW_AT_location值为[3, 192, 63, 2, 128],这里的第一个字节3对应DWARF标准中的DW_OP_addr操作码(编码0x03),该操作码的作用是直接指定变量的内存地址,后续字节是地址的原始字节序列(而非你误以为的无符号LEB128编码),且遵循目标嵌入式平台的字节序(小端)。

具体解析步骤:

  1. 忽略操作码3,取后续4个字节[192, 63, 2, 128]
  2. 按小端字节序反转字节顺序,得到[128, 2, 63, 192]
  3. 将每个字节转换为十六进制:0x80, 0x02, 0x3F, 0xC0
  4. 拼接后得到地址0x80023FC0,与第三方工具结果完全一致

使用Python elftools解析时,库会自动识别DW_OP_addr操作码,并根据目标平台的地址长度(此处为32位)和字节序解析后续字节,无需手动处理LEB128。你之前的误解在于混淆了DW_OP_addr与其他使用LEB128编码的操作码(如DW_OP_plus_uconst)的格式。

相关DIE信息:

DIE DW_TAG_variable, size=37, has_children=False
    |DW_AT_name        :  AttributeValue(name='DW_AT_name', form='DW_FORM_string', value=b'apCalVariant_Appl_LCS', raw_value=b'apCalVariant_Appl_LCS', offset=26734224)
    |DW_AT_decl_file   :  AttributeValue(name='DW_AT_decl_file', form='DW_FORM_udata', value=38, raw_value=38, offset=26734246)
    |DW_AT_decl_line   :  AttributeValue(name='DW_AT_decl_line', form='DW_FORM_udata', value=8, raw_value=8, offset=26734247)
    |DW_AT_decl_column :  AttributeValue(name='DW_AT_decl_column', form='DW_FORM_udata', value=24, raw_value=24, offset=26734248)
    |DW_AT_type        :  AttributeValue(name='DW_AT_type', form='DW_FORM_ref_addr', value=6023079, raw_value=6023079, offset=26734249)
    |DW_AT_external    :  AttributeValue(name='DW_AT_external', form='DW_FORM_flag', value=True, raw_value=1, offset=26734253)
    |DW_AT_location    :  AttributeValue(name='DW_AT_location', form='DW_FORM_block', value=[3, 192, 63, 2, 128], raw_value=[3, 192, 63, 2, 128], offset=26734254)

问题2:DW_AT_data_member_location的含义与结构体成员地址计算

DW_AT_data_member_location用于描述结构体成员相对于结构体起始地址的偏移,其值是一个DWARF表达式(而非直接的十进制偏移)。你的两个成员的属性值第一个字节都是35,对应DW_OP_plus_uconst操作码(编码0x23),该操作码的作用是将后续无符号LEB128编码的偏移量加到结构体起始地址上,得到成员的实际地址。

第一个成员解析([35, 196, 1]):

  1. 操作码35(DW_OP_plus_uconst),后续字节是无符号LEB128编码的偏移
  2. 解析LEB128:
    • 第一个字节196(0xC4),最高位为1,说明需要继续读取下一个字节
    • 取低7位:196 & 0x7F = 68
    • 第二个字节1(0x01),最高位为0,结束解析
    • 总偏移:68 + (1 << 7) = 68 + 128 = 196
  3. 成员地址 = 结构体起始地址(0x80023FC0) + 196,与你观察到的结果一致

第二个成员解析([35, 144, 2]):

  1. 操作码35(DW_OP_plus_uconst),后续字节是无符号LEB128编码的偏移
  2. 解析LEB128:
    • 第一个字节144(0x90),最高位为1,继续读取下一个字节
    • 取低7位:144 & 0x7F = 16
    • 第二个字节2(0x02),最高位为0,结束解析
    • 总偏移:16 + (2 << 7) = 16 + 256 = 272
  3. 成员地址 = 结构体起始地址(0x80023FC0) + 272,而非你之前误以为的+144

相关DIE信息:

DIE DW_TAG_member, size=36, has_children=False
    |DW_AT_name        :  AttributeValue(name='DW_AT_name', form='DW_FORM_string', value=b'k_u16_LCS_VarStrTq_1En2Nm', raw_value=b'k_u16_LCS_VarStrTq_1En2Nm', offset=5215310)
    |DW_AT_type        :  AttributeValue(name='DW_AT_type', form='DW_FORM_ref4', value=312, raw_value=312, offset=5215336)
    |DW_AT_byte_size   :  AttributeValue(name='DW_AT_byte_size', form='DW_FORM_udata', value=2, raw_value=2, offset=5215340)
    |DW_AT_data_member_location:  AttributeValue(name='DW_AT_data_member_location', form='DW_FORM_block', value=[35, 196, 1], raw_value=[35, 196, 1], offset=5215341)
DIE DW_TAG_member, size=57, has_children=False
    |DW_AT_name        :  AttributeValue(name='DW_AT_name', form='DW_FORM_string', value=b'k_s16_LCS_LacDeActvLatestCtrlLine_LCHold_1En3m', raw_value=b'k_s16_LCS_LacDeActvLatestCtrlLine_LCHold_1En3m', offset=5216696)
    |DW_AT_type        :  AttributeValue(name='DW_AT_type', form='DW_FORM_ref4', value=283, raw_value=283, offset=26734249)
    |DW_AT_byte_size   :  AttributeValue(name='DW_AT_byte_size', form='DW_FORM_udata', value=2, raw_value=2, offset=5216747)
    |DW_AT_data_member_location:  AttributeValue(name='DW_AT_data_member_location', form='DW_FORM_block', value=[35, 144, 2], raw_value=[35, 144, 2], offset=5216748)

内容的提问来源于stack exchange,提问作者SangYoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:10:44