
    dP=                         d dl mZmZ d dlZddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZmZ  ed	d
      Z G d de      Zy)    )
namedtupleOrderedDictN   )
DWARFError)	bytes2strstruct_parsepreserve_stream_pos   )DW_FORM_raw2name)_resolve_via_offset_table_get_base_offsetAttributeValuez3name form value raw_value offset indirection_lengthc                   j    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zy)DIEa   A DWARF debugging information entry. On creation, parses itself from
        the stream. Each DIE is held by a CU.

        Accessible attributes:

            tag:
                The DIE tag

            size:
                The size this DIE occupies in the section

            offset:
                The offset of this DIE in the stream

            attributes:
                An ordered dictionary mapping attribute names to values. It's
                ordered to preserve the order of attributes in the section

            has_children:
                Specifies whether this DIE has children

            abbrev_code:
                The abbreviation code pointing to an abbreviation entry (note
                that this is for informational purposes only - this object
                interacts with its abbreviation table transparently).

        See also the public methods.
    c                     || _         | j                   j                  | _        || _        || _        t	               | _        d| _        d| _        d| _        d| _	        d| _
        d| _        | j                          y)a   cu:
                CompileUnit object this DIE belongs to. Used to obtain context
                information (structs, abbrev table, etc.)

            stream, offset:
                The stream and offset into it where this DIE's data is located
        Nr   )cu	dwarfinfostreamoffsetr   
attributestaghas_childrenabbrev_codesize_terminator_parent
_parse_DIE)selfr   r   r   s       4/usr/lib/python3/dist-packages/elftools/dwarf/die.py__init__zDIE.__init__K   sl     **%- 	      c                     | j                   du S )z Is this a null entry?
        N)r   r   s    r   is_nullzDIE.is_nulld   s     xx4r!   c                 p   | j                   |   }|j                  dv r>| j                  j                  |j                  z   }| j                  j                  |      S |j                  dv r/| j                  j                  j                  |j                        S |j                  dv rt        d|j                  z        |j                  dv r]| j                  j                  r/| j                  j                  j                  |j                        S t        d|j                  z        t        d|z        )z Return the DIE referenced by the named attribute of this DIE.
            The attribute must be in the reference attribute class.

            name:
                The name of the attribute in the reference class.
        )DW_FORM_ref1DW_FORM_ref2DW_FORM_ref4DW_FORM_ref8DW_FORM_refDW_FORM_ref_udataDW_FORM_ref_addrDW_FORM_ref_sig8z%s (type unit by signature))DW_FORM_ref_sup4DW_FORM_ref_sup8DW_FORM_GNU_ref_altz	%s to dwoz*%s is not a reference class form attribute)
r   formr   	cu_offset	raw_valueget_DIE_from_refaddrr   NotImplementedErrorsupplementary_dwarfinfor   )r   nameattrrefaddrs       r   get_DIE_from_attributezDIE.get_DIE_from_attributei   s    t$99 M Mgg''$..8G77//88YY-.77$$99$..IIYY-.%&Cdii&OPPYYYY~~55~~==RRSWSaSabb%kDII&=>>IDPQQr!   c                 R    | j                   | j                          | j                   S )zt Return the parent DIE of this DIE, or None if the DIE has no
            parent (i.e. is a top-level DIE).
        )r   _search_ancestor_offspringr#   s    r   
get_parentzDIE.get_parent   s$     <<++-||r!   c                    | j                   j                  dd      }|rt        |j                        nd}| j                   j                  dd      }|rt        |j                        nd}t        j
                  j                  ||      S )aF   Return the full path filename for the DIE.

            The filename is the join of 'DW_AT_comp_dir' and 'DW_AT_name',
            either of which may be missing in practice. Note that its value is
            usually a string taken from the .debug_string section and the
            returned value will be a string.
        DW_AT_comp_dirN 
DW_AT_name)r   getr   valueospathjoin)r   comp_dir_attrcomp_dir
fname_attrfnames        r   get_full_pathzDIE.get_full_path   sn     ++,<dC5B9]001__((t<
/9	***+rww||He,,r!   c                 8    | j                   j                  |       S )z+ Iterates all children of this DIE
        )r   iter_DIE_childrenr#   s    r   iter_childrenzDIE.iter_children   s     ww((..r!   c              #      K   | j                         }|r|j                         D ]  }|| us|  yt               w)z( Yield all siblings of this DIE
        N)r=   rN   StopIteration)r   parentsiblings      r   iter_siblingszDIE.iter_siblings   sF      "!//1 "$&!M"  /!s   *>>c                     || _         y N)r   )r   dies     r   
set_parentzDIE.set_parent   s	    r!   c                 
   | j                   j                         }|j                  | j                  k  r|}|j                         D ]/  }|j	                  |       |j                  | j                  k  s.|}1 |j
                  r/|j                  j                  | j                  k  r|j                  }||u r0t        d| j                  d| j                   j                  d      |}|j                  | j                  k  ryy)a   Search our ancestors identifying their offspring to find our parent.

            DIEs are stored as a flattened tree.  The top DIE is the ancestor
            of all DIEs in the unit.  Each parent is guaranteed to be at
            an offset less than their children.  In each generation of children
            the sibling with the closest offset not greater than our offset is
            our ancestor.
        zoffset z not in CU z	 DIE treeN)	r   get_top_DIEr   rN   rW   r   r   
ValueErrorr2   )r   searchprevchilds       r   r<   zDIE._search_ancestor_offspring   s     $$&mmdkk)D--/ !  (<<4;;. D! ""v'9'9'@'@DKK'O!--D
 v~ [[$''"3"3"5 6 6 F% mmdkk)r!   c                     d| j                   d| j                  d| j                  d}| j                  j	                         D ]  \  }}|d|dd|dz  } |S )NzDIE z, size=z, has_children=
z    |18z:  )r   r   r   r   items)r   sattrnameattrvals       r   __repr__zDIE.__repr__   sS    HHdii!2!24!%!6!6!8 	;Hg'::A	;r!   c                 "    | j                         S rU   )re   r#   s    r   __str__zDIE.__str__   s    }}r!   c           	         | j                   j                  }t        |j                  d      | j                  | j
                        | _        | j                  dk(  r-| j                  j                         | j
                  z
  | _        y| j                   j                         j                  | j                        }|d   | _        |j                         | _        |d   D ]  }|j                  }|j                  }| j                  j                         }d}|dk(  r|j                  }|}	na|dk(  r'| j!                         \  }}	}| j#                  ||	      }n5t        |j$                  |   | j                        }	| j#                  ||	      }t'        ||||	||      | j(                  |<    | j                  j                         | j
                  z
  | _        y)	ze Parses the DIE info from the section, based on the abbreviation
            table of the CU
        r@   r   Nr   	attr_specDW_FORM_implicit_constDW_FORM_indirectr7   r1   rC   r3   r   indirection_length)r   structsr   Dwarf_uleb128r   r   r   tellr   get_abbrev_table
get_abbrevr   r   r1   r7   rC   _resolve_indirect_translate_attr_valueDwarf_dw_formr   r   )
r   rn   abbrev_declspecr1   r7   attr_offsetrm   rC   r3   s
             r   r   zDIE._parse_DIE   s    ''// (!!"%t{{DKKA q ((*T[[8DIgg..0;;D<L<LMu%'446  , 	9D99D99D++**,K!" //

!	++8<8N8N8P5y"4224C()>)>t)DdkkR	224C$2#"%7%9DOOD!#	92 KK$$&4	r!   c                 :   | j                   j                  }d}t        |j                  d      | j                        }	 	 t
        |   }t        |j                  |   | j                        }|dk7  r|||fS |dz  }|}?# t        $ r}t        d|z        d }~ww xY w)Nr
   r@   z2Found DW_FORM_indirect with unknown real form 0x%xrk   )	r   rn   r   ro   r   r   KeyErrorr   ru   )r   rn   lengthreal_form_code	real_formerrr3   s          r   rs   zDIE._resolve_indirect  s     ''//%g&;&;B&?Mh,^<	 %W%:%:9%Et{{SI..!9f55!!*   h !UXf!fgghs    	A> >	BBBc                    | j                   j                         xs# | j                  | j                   j                  k7  }d}|dk(  r;t	        | j
                        5  | j                  j                  |      }ddd       |S |dk(  r;t	        | j
                        5  | j                  j                  |      }ddd       |S |dv r?| j                  j                  r%| j                  j                  j                  |      S |}|S |dk(  r|dk(   }|S |dk(  rd}|S |d	v r4|r2| j                   j                  j                  | j                   |      }|S |d
v r|r| j                  j                  j
                  }t        | j                   d      }| j                   j                  j                  dk(  rdnd}t	        |      5  t        | j                   j                  j!                  d      ||||z  z         }ddd       | j                  j                        }|S |dk(  r:|r8t#        | j                  j$                  j
                  | j                   |d      }|S |dk(  r:|r8t#        | j                  j&                  j
                  | j                   |d      }|S |}|S # 1 sw Y   |S xY w# 1 sw Y   |S xY w# 1 sw Y   xY w)z: Translate a raw attr value according to the form
        NDW_FORM_strpDW_FORM_line_strp)DW_FORM_GNU_strp_altDW_FORM_strp_supDW_FORM_flagr   DW_FORM_flag_presentT)DW_FORM_addrxDW_FORM_addrx1DW_FORM_addrx2DW_FORM_addrx3DW_FORM_addrx4)DW_FORM_strxDW_FORM_strx1DW_FORM_strx2DW_FORM_strx3DW_FORM_strx4DW_AT_str_offsets_base          r@   DW_FORM_loclistxDW_AT_loclists_baseDW_FORM_rnglistxDW_AT_rnglists_base)r   has_top_DIEr   cu_die_offsetr	   r   r   get_string_from_tableget_string_from_linetabler6   get_addrdebug_str_offsets_secr   rn   dwarf_formatr   Dwarf_offsetr   debug_loclists_secdebug_rnglists_sec)	r   r1   r3   translate_indirectrC   r   base_offsetoffset_size
str_offsets	            r   rt   zDIE._translate_attr_value)  s    "WW002ZdkkTWWEZEZ6Z>!$T[[1 H<<YGH: 7 (($T[[1 L@@KL4 1 AA~~55~~==SST]^^!( ' ^#!Q&E$ # ++E   nn  tFGG%%..tww	BE  ii  oA^^99@@F*4774LMK#ww;;rA!qK$V, y)$''//*F*Fr*JFT_bklwbwTwx
yNN88DE  '',>-dnn.O.O.V.VX\X_X_aj  mB  CE
 	 '',>-dnn.O.O.V.VX\X_X_aj  mB  CE  E;H: 5L4 y ys$   JJ,7J9J),J69Kc           	      J   | j                   D ]  }| j                   |   }|j                  dv s!t        |j                  |j                  | j	                  |j                  |j
                        |j
                  |j                  |j                        | j                   |<    y)a\   This is a hook to translate the DW_FORM_...x values in the top DIE
            once the top DIE is parsed to the end. They can't be translated 
            while the top DIE is being parsed, because they implicitly make a
            reference to the DW_AT_xxx_base attribute in the same DIE that may
            not have been parsed yet.
        )r   r   r   r   r   r   r   r   r   r   r   r   rl   N)r   r1   r   r7   rt   r3   r   rm   )r   keyr8   s      r   _translate_indirect_attributesz"DIE._translate_indirect_attributesS  s     ?? 	@C??3'Dyy 8 8 (644TYYO"nn;;'+'>'>(@$	@r!   N)__name__
__module____qualname____doc__r    r$   r:   r=   rK   rN   rS   rW   r<   re   rg   r   rs   rt   r    r!   r   r   r   .   sW    82 
R2-/
	"
"H15f+.(T@r!   r   )collectionsr   r   rD   common.exceptionsr   common.utilsr   r   r	   enumsr   
dwarf_utilr   r   r   objectr   r   r!   r   <module>r      s?    0 	 * G G # C6 KMx@& x@r!   