
    d^                     
   d dl Z d dlmZ d dlmZ ddlm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 ddlmZ ddlmZ ddlmZ ddlmZmZ ddlmZmZ ddlmZ ddlm Z  ddl!m"Z"  edd      Z# edd      Z$ G d de%      Z&y)    N)
namedtuple)bisect_right   )	Container)
DWARFError)struct_parsedwarf_assertparse_cstring_from_stream   )DWARFStructs)CompileUnit)AbbrevTable)LineProgram)CallFrameInfo)LocationListsLocationListsPair)
RangeListsRangeListsPair)ARanges)NameLUT)_get_base_offsetDebugSectionDescriptorz&stream name global_offset size addressDwarfConfigz/little_endian machine_arch default_address_sizec                       e Zd ZdZd Zed        Zd Zd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d ZddZd Zd Zd Zd Zd Zy) 	DWARFInfozw Acts also as a "context" to other major objects, bridging between
        various parts of the debug information.
    c                    || _         || _        || _        || _        || _        || _        || _        || _        |	| _        |
| _	        || _
        || _        || _        || _        || _        || _        || _        || _        || _        d| _        t)        | j                   j*                  d| j                   j,                        | _        i | _        i | _        g | _        g | _        y)a   config:
                A DwarfConfig object

            debug_*_sec:
                DebugSectionDescriptor for a section. Pass None for sections
                that don't exist. These arguments are best given with
                keyword syntax.
        N    )little_endiandwarf_formataddress_size)configdebug_info_secdebug_aranges_secdebug_abbrev_secdebug_frame_seceh_frame_secdebug_str_secdebug_loc_secdebug_ranges_secdebug_line_secdebug_addr_secdebug_str_offsets_secdebug_line_str_secdebug_pubtypes_secdebug_pubnames_secdebug_loclists_secdebug_rnglists_secdebug_sup_secgnu_debugaltlink_secsupplementary_dwarfinfor   r   default_address_sizestructs_abbrevtable_cache_linetable_cache	_cu_cache_cu_offsets_map)selfr!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r.   r/   r+   r,   r-   r0   r1   r2   r3   s                       :/usr/lib/python3/dist-packages/elftools/dwarf/dwarfinfo.py__init__zDWARFInfo.__init__A   s    : ,!2 0.(** 0,,%:""4"4"4"4"4*$8!
 (,$
 $++3399; #% " !    c                 ,    t        | j                        S )z Return whether this contains debug information.

        It can be not the case when the ELF only contains .eh_frame, which is
        encoded DWARF but not actually for debugging.
        )boolr"   r;   s    r<   has_debug_infozDWARFInfo.has_debug_info   s     D''((r>   c                 p    | j                  |j                        }| j                  |j                  |      S )z Get the DIE from the pubnames or putbtypes lookup table entry.

            lut_entry:
                A NameLUTEntry object from a NameLUT instance (see
                .get_pubmames and .get_pubtypes methods).
        )	get_CU_atcu_ofsget_DIE_from_refaddrdie_ofs)r;   	lut_entrycus      r<   get_DIE_from_lut_entryz DWARFInfo.get_DIE_from_lut_entry   s1     ^^I,,-(():):B??r>   Nc                 J    || j                  |      }|j                  |      S )aG   Given a .debug_info section offset of a DIE, return the DIE.

            refaddr:
                The refaddr may come from a DW_FORM_ref_addr attribute.

            cu:
                The compile unit object, if known.  If None a search
                from the closest offset less than refaddr will be performed.
        )get_CU_containingrF   )r;   refaddrrI   s      r<   rF   zDWARFInfo.get_DIE_from_refaddr   s*     :''0B&&w//r>   c                    t        | j                  d       t        d|cxk  xr | j                  j                  k  nc d|z         t	        | j
                  |      }|dkD  r| j
                  |dz
     nd}| j                  |      D ]4  }|j                  |cxk  r |j                  |j                  z   k  s0|c S  6 t        d|z        )a   Find the CU that includes the given reference address in the
            .debug_info section.

            refaddr:
                Either a refaddr of a DIE (possibly from a DW_FORM_ref_addr
                attribute) or the section offset of a CU (possibly from an
                aranges table).

           This function will parse and cache CUs until the search criteria
           is met, starting from the closest known offset lessthan or equal
           to the given address.
        #CU lookup but no debug info sectionr   z"refaddr %s beyond .debug_info sizer   z%CU for reference address %s not found)	r	   rB   r"   sizer   r:   _parse_CUs_iter	cu_offset
ValueError)r;   rM   istartrI   s        r<   rL   zDWARFInfo.get_CU_containing   s     	1	3 	34..33307:	< --w7/01u$$QU+! &&u- 	B||w?)??	 @	 @7JKKr>   c                     t        | j                  d       t        d|cxk  xr | j                  j                  k  nc d|z         | j	                  |      S )a   Given a CU header offset, return the parsed CU.

            offset:
                The offset may be from an accelerated access table such as
                the public names, public types, address range table, or
                prior use.

            This function will directly parse the CU doing no validation of
            the offset beyond checking the size of the .debug_info section.
        rO   r   z!offset %s beyond .debug_info size)r	   rB   r"   rP   _cached_CU_at_offsetr;   offsets     r<   rD   zDWARFInfo.get_CU_at   sV     	1	3 	2$--222/&8	: ((00r>   c                 "    | j                         S )zM Yield all the compile units (CompileUnit objects) in the debug info
        )rQ   rA   s    r<   iter_CUszDWARFInfo.iter_CUs   s     ##%%r>   c                     t        || j                  j                  k  d|z         || j                  vr9t	        | j
                  | j                  j                  |      | j                  |<   | j                  |   S )a   Get an AbbrevTable from the given offset in the debug_abbrev
            section.

            The only verification done on the offset is that it's within the
            bounds of the section (if not, an exception is raised).
            It is the caller's responsibility to make sure the offset actually
            points to a valid abbreviation table.

            AbbrevTable objects are cached internally (two calls for the same
            offset will return the same object).
        z3Offset '0x%x' to abbrev table out of section bounds)r6   streamrY   )r	   r$   rP   r7   r   r6   r]   rX   s     r<   get_abbrev_tablezDWARFInfo.get_abbrev_table   sz     	T**///AFJ	L 000.9,,33/D##F+ &&v..r>   c                 B    t        | j                  j                  |      S zm Obtain a string from the string table section, given an offset
            relative to the section.
        )r
   r'   r]   rX   s     r<   get_string_from_tablezDWARFInfo.get_string_from_table   s     )););)B)BFKKr>   c                 B    t        | j                  j                  |      S r`   )r
   r-   r]   rX   s     r<   get_string_from_linetablez#DWARFInfo.get_string_from_linetable  s     ))@)@)G)GPPr>   c                     |j                         }d|j                  v r3| j                  |j                  d   j                  |j                        S y)a   Given a CU object, fetch the line program it points to from the
            .debug_line section.
            If the CU doesn't point to a line program, return None.

            Note about directory and file names. They are returned as two collections
            in the lineprogram object's header - include_directory and file_entry.

            In DWARFv5, they have introduced a different, extensible format for those
            collections. So in a lineprogram v5+, there are two more collections in
            the header - directories and file_names. Those might contain extra DWARFv5
            information that is not exposed in include_directory and file_entry.
        DW_AT_stmt_listN)get_top_DIE
attributes_parse_line_program_at_offsetvaluer6   )r;   CUtop_DIEs      r<   line_program_for_CUzDWARFInfo.line_program_for_CU  sS     .." 2 2255&&'89??M M r>   c                     | j                   duS )z> Does this dwarf info have a dwarf_frame CFI section?
        N)r%   rA   s    r<   has_CFIzDWARFInfo.has_CFI  s     ##4//r>   c                     t        | j                  j                  | j                  j                  | j                  j                  | j
                        }|j                         S )zN Get a list of dwarf_frame CFI entries from the .debug_frame section.
        )r]   rP   addressbase_structs)r   r%   r]   rP   rp   r6   get_entriesr;   cfis     r<   CFI_entrieszDWARFInfo.CFI_entries"  sQ     ''..%%**((00	'
   r>   c                     | j                   duS )z; Does this dwarf info have a eh_frame CFI section?
        N)r&   rA   s    r<   
has_EH_CFIzDWARFInfo.has_EH_CFI,  s       ,,r>   c                     t        | j                  j                  | j                  j                  | j                  j                  | j
                  d      }|j                         S )zH Get a list of eh_frame CFI entries from the .eh_frame section.
        T)r]   rP   rp   rq   for_eh_frame)r   r&   r]   rP   rp   r6   rr   rs   s     r<   EH_CFI_entrieszDWARFInfo.EH_CFI_entries1  sT     $$++""''%%--   r>   c                     | j                   r?t        | j                   j                  | j                   j                  | j                        S y)a  
        Returns a NameLUT object that contains information read from the
        .debug_pubtypes section in the ELF file.

        NameLUT is essentially a dictionary containing the CU/DIE offsets of
        each symbol. See the NameLUT doc string for more details.
        N)r.   r   r]   rP   r6   rA   s    r<   get_pubtypeszDWARFInfo.get_pubtypes<  C     ""42299++00LL" " r>   c                     | j                   r?t        | j                   j                  | j                   j                  | j                        S y)a  
        Returns a NameLUT object that contains information read from the
        .debug_pubnames section in the ELF file.

        NameLUT is essentially a dictionary containing the CU/DIE offsets of
        each symbol. See the NameLUT doc string for more details.
        N)r/   r   r]   rP   r6   rA   s    r<   get_pubnameszDWARFInfo.get_pubnamesL  r}   r>   c                     | j                   r?t        | j                   j                  | j                   j                  | j                        S y)z Get an ARanges object representing the .debug_aranges section of
            the DWARF data, or None if the section doesn't exist
        N)r#   r   r]   rP   r6   rA   s    r<   get_arangeszDWARFInfo.get_aranges\  sC     !!41188&&++  r>   c                    | j                   r8| j                  ,t        | j                   j                  | j                  d|       S | j                  r8| j                   ,t        | j                  j                  | j                  d|       S | j                  rL| j                   r@t        | j                   j                  | j                   j                  | j                  |       S y)z Get a LocationLists object representing the .debug_loc/debug_loclists section of
            the DWARF data, or None if this section doesn't exist.

            If both sections exist, it returns a LocationListsPair.
        N      )r0   r(   r   r]   r6   r   rA   s    r<   location_listszDWARFInfo.location_listsg  s     ""t'9'9'A !8!8!?!?qRVWWD$;$;$C !3!3!:!:DLL!TRRD$;$;$T%<%<%C%CTE\E\EcEceieqeqswxxr>   c                    | j                   r8| j                  ,t        | j                   j                  | j                  d|       S | j                  r8| j                   ,t        | j                  j                  | j                  d|       S | j                  rL| j                   r@t        | j                  j                  | j                   j                  | j                  |       S y)z Get a RangeLists object representing the .debug_ranges/.debug_rnglists section of
            the DWARF data, or None if this section doesn't exist.

            If both sections exist, it returns a RangeListsPair.
        Nr   r   )r1   r)   r   r]   r6   r   rA   s    r<   range_listszDWARFInfo.range_listsv  s     ""t'<'<'Dd55<<dllAtTT""t'>'>'Fd33::DLL!TRR""t'>'>!$"7"7">">@W@W@^@^`d`l`lnrssr>   c                     | j                   st        d      t        |d      }t        |j                  j                  d      | j                   j                  |||j                  j                  z  z         S )zUProvided a CU and an index, retrieves an address from the debug_addr section
        zJThe file does not contain a debug_addr section for indirect address accessDW_AT_addr_base )	r+   r   r   r   r6   Dwarf_target_addrr]   headerr    )r;   rI   
addr_indexcu_addr_bases       r<   get_addrzDWARFInfo.get_addr  s     ""ijj',=>BJJ88<d>Q>Q>X>XZfistvt}t}  uK  uK  jK  [K  L  	Lr>   c              #      K   | j                   y|| j                   j                  k  rS| j                  |      }||d   z   |j                  j	                         z   }| || j                   j                  k  rRyyw)a.   Iterate CU objects in order of appearance in the debug_info section.

            offset:
                The offset of the first CU to yield.  Additional iterations
                will return the sequential unit objects.

            See .iter_CUs(), .get_CU_containing(), and .get_CU_at().
        Nunit_length)r"   rP   rW   r6   initial_length_field_size)r;   rY   rI   s      r<   rQ   zDWARFInfo._parse_CUs_iter  s      &t**///**62B =)*

<<>?F H t**///s   A8A=;A=c                    t        | j                  |      }|dk\  r'|| j                  |dz
     k(  r| j                  |dz
     S | j                  |      }| j                  j	                  ||       | j                  j	                  ||       |S )a   Return the CU with unit header at the given offset into the
            debug_info section from the cache.  If not present, the unit is
            header is parsed and the object is installed in the cache.

            offset:
                The offset of the unit header in the .debug_info section
                to of the unit to fetch from the cache.

            See get_CU_at().
        r   )r   r:   r9   _parse_CU_at_offsetinsert)r;   rY   rT   rI   s       r<   rW   zDWARFInfo._cached_CU_at_offset  s     --v66f 4 4QU ;;>>!a%(( %%f-##Av.a$	r>   c                 &   t        | j                  j                  d      | j                  j                  |      }|dk(  rdnd}t        | j                  j                  |dd      }t        |j                  | j                  j                  |      }t        | j                  j                  ||d   |d	         }| j                  j                  j                         }t        | j                  |d	         d
|d	   z         t        || |||      S )zM Parse and return a CU at the given offset in the debug_info stream.
        r   l    @   r   r   r   )r   r   r    dwarf_versionr    versionz*Expected supported DWARF version. Got '%s')r   	dwarfinfor6   rR   cu_die_offset)r   r6   Dwarf_uint32r"   r]   r   r!   r   Dwarf_CU_headertellr	   _is_supported_versionr   )r;   rY   initial_lengthr   
cu_structs	cu_headerr   s          r<   r   zDWARFInfo._parse_CU_at_offset  s    &LL%%b)4+>+>+E+EvO+z9rr "++33%	
 !&&(;(;(B(BFL	 "++33%">2#I.	0
 ++22779&&y';<89Y;OO	Q  " +- 	-r>   c                 "    d|cxk  xr dk  S c S )z0 DWARF version supported by this parser
        r   r    )r;   r   s     r<   r   zDWARFInfo._is_supported_version  s     G q    r>   c                 p   || j                   v r| j                   |   S t        |j                  | j                  j                  |      }d } || |dd        || |dd       |j                  dd      r!t        d |j                  D              |_        |j                  dd      r!t        d |j                  D              |_
        ||d	   z   |j                         z   }t        || j                  j                  || j                  j                  j                         |
      }|| j                   |<   |S )z Given an offset to the .debug_line section, parse the line program
            starting at this offset in the section and return it.
            structs is the DWARFStructs object used to do this parsing.
        c                    |j                  |d      r||   }||   D ]  }d }|j                  dk(  r |||j                  | j                         4|j                  dk(  r |||j                  | j                         b|j                  dv rK| j
                  r) |||j                  | j
                  j                          |||j                  d        |j                  dv st                y y )NFc                 .    | D ]  } |||         ||<    y Nr   )datacontent_typereplacerentrys       r<   replace_valuezWDWARFInfo._parse_line_program_at_offset.<locals>.resolve_strings.<locals>.replace_value  s'    %) PE2:5;N2OE,/Pr>   DW_FORM_line_strpDW_FORM_strp)DW_FORM_strp_supDW_FORM_GNU_strp_altc                     t        |       S r   )str)xs    r<   <lambda>zRDWARFInfo._parse_line_program_at_offset.<locals>.resolve_strings.<locals>.<lambda>  s    cRSf r>   )r   DW_FORM_strxDW_FORM_strx1DW_FORM_strx2DW_FORM_strx3DW_FORM_strx4)getformr   rc   ra   r4   get_string_fromtableNotImplementedError)r;   lineprog_headerformat_field
data_fieldr   fieldr   s          r<   resolve_stringsz@DWARFInfo._parse_line_program_at_offset.<locals>.resolve_strings  s    ""<7&z2,\: 4EP zz%88%dE,>,>@^@^_~5%dE,>,>@Z@Z['SS77)$0B0BDD`D`DuDuv)$0B0BDTU  (P  P1334 8r>   directory_entry_formatdirectoriesfile_name_entry_format
file_namesFc              3   4   K   | ]  }|j                     y wr   )DW_LNCT_path).0ds     r<   	<genexpr>z:DWARFInfo._parse_line_program_at_offset.<locals>.<genexpr>  s     5jann5js   c              3      K   | ]P  }t        di |j                  d       |j                  d      |j                  d      |j                  d      d R yw)r   DW_LNCT_directory_indexDW_LNCT_timestampDW_LNCT_size)name	dir_indexmtimelengthNr   )r   r   )r   es     r<   r   z:DWARFInfo._parse_line_program_at_offset.<locals>.<genexpr>  s[      /5   6550!"'@!AUU#67eeN3	5 6/5s   AAr   )r   r]   r6   program_start_offsetprogram_end_offset)r8   r   Dwarf_lineprog_headerr*   r]   r   tupler   include_directoryr   
file_entryr   r   r   )r;   rY   r6   r   r   
end_offsetlineprograms          r<   rh   z'DWARFInfo._parse_line_program_at_offset  s@    T***((00&))&&	4( 	o/GWo/GV }e4055joNiNi5j0jO-|U3). /5 )33/5 *5O& !??99;<
 ""&&--!%!4!4!;!;!@!@!B)+ )4f%r>   c                    | j                   y| j                   j                  j                  d       | j                  j                  j                  | j                   j                        }|j                  dk(  r|j                  S | j                  j| j                  j                  j                  d       | j                  j                  j                  | j                  j                        }|j                  S y)zY
        Extract a filename from either .debug_sup or .gnu_debualtlink sections.
        Nr   )
r2   r]   seekr6   Dwarf_debugsupparse_streamis_supplementarysup_filenamer3   Dwarf_debugaltlink)r;   suplinks     r<   parse_debugsupinfozDWARFInfo.parse_debugsupinfo3  s     )%%**1-ll11>>t?Q?Q?X?XYG''1,+++$$0%%,,11!4ll55BB4C\C\CcCcdG'''r>   r   )r   ) __name__
__module____qualname____doc__r=   propertyrB   rJ   rF   rL   rD   r[   r^   ra   rc   rl   rn   ru   rw   rz   r|   r   r   r   r   r   rQ   rW   r   r   rh   r   r   r>   r<   r   r   =   s    F"P ) )@0 LD1(&
/,LQ,0
!-
	!  	L,4,-\!
>@r>   r   )'oscollectionsr   bisectr   construct.lib.containerr   common.exceptionsr   common.utilsr   r	   r
   r6   r   compileunitr   abbrevtabler   r   r   	callframer   locationlistsr   r   rangesr   r   arangesr   namelutr   
dwarf_utilr   r   r   objectr   r   r>   r<   <module>r      sp    
 "  / *7 7 ! $ $ $ $ ; .   ( $$<,.   57C Cr>   