1

I'm trying to find structure member memory address(Non Virtual Memory, embedded) from dwarf.

And there's two things i don't understand.

First, In below dwarf Info1 DW_AT_location value = [3, 192, 63, 2, 128].

According to dwarf standards, [192, 63, 2, 128] is a address which encoded unsigned LEB128 and little endian.

But when i check this structure variable memory adress using other third party software, memory address is 0x80023fc0.

It means [192, 63, 2, 128] is not encoded unsigned LEB128, but it just little endian decimal.

Please explain why it happens.(i parse dwarf information using python elftools module)

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)

Second, In below dwarf Information there are two structure members with DW_AT_data_member_location = [35, 196, 1], [35, 144, 2].

This structure members is member of first question structure variable. (1) k_u16_LCS_VarStrTq_1En2Nm(address : 0x80024084), (2) k_s16_LCS_LacDeActvLatestCtrlLine_LCHold_1En3m(address : 0x800240D0).

I don't understand what DW_AT_data_member_location value is stands for.

k_u16_LCS_VarStrTq_1En2Nm address is structure start address(0x80023fc0) + 196(0xC4).

But k_s16_LCS_LacDeActvLatestCtrlLine_LCHold_1En3m address is not structure start address(0x80023fc0) + 144(0x90) = 0x80024050.

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=5216743)
    |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)

Please explain what DW_AT_data_member_location means and how can i calculate structure member addresss using it.

In advanced, Thank you for all you guys.

1
  • Provide a minimal reproducible example. Also it seems you are using an ancient version of Pyelftools. Commented Dec 6, 2022 at 9:14

2 Answers 2

1

DW_AT_data_member_location.value is an offset location from the base address of DW_TAG_variable (DW_AT_location.value). So, in your case, base address is 0x80023fc0 + 1C4. This is the simplest i could understand. The best method is to read the DW_AT_data_member_location as an expression and then that search for the value of DW_OP_plus_uconst:

example code for expression for DW_AT_location:

if 'DW_AT_location' in die.attributes:
        loc_attr = die.attributes.get('DW_AT_location')
        if loc_attr:
            loc_expr = loc_attr.value
            expr_parser = DWARFExprParser(die.dwarfinfo.structs)
            expr_descriptions = expr_parser.parse_expr(loc_expr)
            #print(expr_descriptions) #for debugging
            for addr_value_str in expr_descriptions:
                if addr_value_str.op_name == 'DW_OP_addr':
                    addr_value = addr_value_str.args[0]
                    return hex(addr_value)
Sign up to request clarification or add additional context in comments.

Comments

0

The value of DW_AT_location of form DW_FORM_block is a DWARF expression. So are DW_AT_data_member_location values. Read up on DWARF expressions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.