
    d                        d dl Z d dl mZ d dlZd dlZd dlZ	 d dlZ ej                         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mZmZmZmZmZmZmZmZmZ dd
lmZmZ ddl m!Z!m"Z"m#Z# ddl$m%Z%m&Z&m'Z' ddl(m)Z)m*Z*m+Z+ ddl,m-Z-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6  G d de7      Z8y# e$ r" 	 d dl	Z	e	j                  Zn# e$ r dZY nw xY wY w xY w)    N)BytesIOi      )ELFErrorELFParseError)struct_parse
elf_assert   )
ELFStructs)
SectionStringTableSectionSymbolTableSectionSymbolTableIndexSectionSUNWSyminfoTableSectionNullSectionNoteSectionStabSectionARMAttributesSectionRISCVAttributesSection)DynamicSectionDynamicSegment)RelocationSectionRelocationHandlerRelrRelocationSection)GNUVerNeedSectionGNUVerDefSectionGNUVerSymSection)SegmentInterpSegmentNoteSegment)	DWARFInfoDebugSectionDescriptorDwarfConfig)	EHABIInfo)ELFHashSectionGNUHashSection)SHN_INDICESc                   0   e Zd ZdZd.dZed        Zd Zd Zd Z	d Z
d.d	Zd
 Zd Zd.dZd/dZd Zd0d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! Z#d" Z$d# Z%d$ Z&d% Z'd& Z(d' Z)d( Z*d) Z+e,d*        Z-d+ Z.d, Z/d- Z0y)1ELFFilea   Creation: the constructor accepts a stream (file-like object) with the
        contents of an ELF file.

        Optionally, a stream_loader function can be passed as the second
        argument. This stream_loader function takes a relative file path to
        load a supplementary object file, and returns a stream suitable for
        creating a new ELFFile. Currently, the only such relative file path is
        obtained from the supplementary object files.

        Accessible attributes:

            stream:
                The stream holding the data of the file - must be a binary
                stream (bytes, not string).

            elfclass:
                32 or 64 - specifies the word size of the target machine

            little_endian:
                boolean - specifies the target machine's endianness

            elftype:
                string or int, either known value of E_TYPE enum defining ELF
                type (e.g. executable, dynamic library or core dump) or integral
                unparsed value

            header:
                the complete ELF file header

            e_ident_raw:
                the raw e_ident field of the header
    Nc                 |   || _         | j                   j                  dt        j                         | j                   j	                         | _        | j                          t        | j                  | j                        | _
        | j                  j                          | j                         | _        | j                  j                  | d   | d   | d   d          | j                   j                  d       | j                   j                  d      | _        | j#                         | _        d | _        || _        y )Nr   )little_endianelfclasse_type	e_machinee_identEI_OSABI   )streamseekioSEEK_ENDtell
stream_len_identify_filer
   r*   r+   structscreate_basic_structs_parse_elf_headerheadercreate_advanced_structsreade_ident_raw_get_section_header_stringtable_section_header_stringtable_section_name_mapstream_loader)selfr1   rB   s      6/usr/lib/python3/dist-packages/elftools/elf/elffile.py__init__zELFFile.__init__O   s    BKK(++**,!,,]]$ 	))+,,.,,X[!Y
+	- 	;;++B/ 002 	(!%*    c                 |    t         j                  j                  |      fd}t        |d      }t	        ||      S )zTakes a path to a file on the local filesystem, and returns an
        ELFFile from it, setting up a correct stream_loader relative to the
        original file.
        c                     t         j                  j                  |       s t         j                  j                  |       } t	        | d      S )Nrb)ospathisabsjoinopen)elf_pathbase_directorys    rD   loaderz&ELFFile.load_from_path.<locals>.loadern   s7    77==*77<<(02$''rF   rI   )rJ   rK   dirnamerN   r(   )clsrK   rQ   r1   rP   s       @rD   load_from_pathzELFFile.load_from_pathg   s7     .	( dD!vv&&rF   c                 V    | d   dk(  ry| d   dk(  r| j                  d      d   S | d   S )z( Number of sections in the file
        e_shoffr   e_shnumsh_size)_get_section_headerrC   s    rD   num_sectionszELFFile.num_sectionsw   sA     	?a 	?a++A.y99IrF   c                 F    | j                  |      }| j                  |      S )z^ Get the section at index #n from the file (Section object or a
            subclass)
        )rY   _make_section)rC   nsection_headers      rD   get_sectionzELFFile.get_section   s%     11!4!!.11rF   c                     | j                   | j                          | j                   j                  |d      }|dS | j                  |      S )zb Get a section from the file, by name. Return None if no such
            section exists.
        N)rA   _make_section_name_mapgetr`   )rC   namesecnums      rD   get_section_by_namezELFFile.get_section_by_name   sN     !!)'')''++D$7~tC4+;+;F+CCrF   c                 r    | j                   | j                          | j                   j                  |d      S )zh Gets the index of the section by name. Return None if no such
            section name exists.
        N)rA   rb   rc   )rC   section_names     rD   get_section_indexzELFFile.get_section_index   s5     !!)'')%%)),==rF   c              #      K   t        | j                               D ]"  }| j                  |      }|	|d   |k(  s| $ yw)a>   Yield all the sections in the file. If the optional |type|
            parameter is passed, this method will only yield sections of the
            given type. The parameter value must be a string containing the
            name of the type as defined in the ELF specification, e.g.
            'SHT_SYMTAB'.
        Nsh_type)ranger[   r`   )rC   typeisections       rD   iter_sectionszELFFile.iter_sections   sK      t((*+ 	A&&q)G|wy1T9	
   8AAc                 D    | d   dk  r| d   S | j                  d      d   S )z( Number of segments in the file
        e_phnumi  r   sh_info)r`   rZ   s    rD   num_segmentszELFFile.num_segments   s0     	?V#	?"##A&y11rF   c                 F    | j                  |      }| j                  |      S )zD Get the segment at index #n from the file (Segment object)
        )_get_segment_header_make_segment)rC   r^   segment_headers      rD   get_segmentzELFFile.get_segment   s%     11!4!!.11rF   c              #      K   t        | j                               D ]"  }| j                  |      }|	|d   |k(  s| $ yw)a;   Yield all the segments in the file. If the optional |type|
            parameter is passed, this method will only yield segments of the
            given type. The parameter value must be a string containing the
            name of the type as defined in the ELF specification, e.g.
            'PT_LOAD'.
        Np_type)rl   ru   rz   )rC   rm   rn   segments       rD   iter_segmentszELFFile.iter_segments   sK      t((*+ 	A&&q)G|wx0D8	rq   c              #      K   ||z   }| j                  d      D ]*  }||d   k\  s||d   |d   z   k  s||d   z
  |d   z    , yw)z Yield a file offset for each ELF segment containing a memory region.

            A memory region is defined by the range [start...start+size). The
            offset of the region is yielded.
        PT_LOADrm   p_vaddrp_fileszp_offsetN)r~   )rC   startsizeendsegs        rD   address_offsetszELFFile.address_offsets   sg      dl%%9%5 	?CY's9~J77c)n,s:>>	?s   #AAAc                     t        | j                  d      xs$ | j                  d      xs | j                  d            S )z Check whether this file appears to have debugging information.
            We assume that if it has the .debug_info or .zdebug_info section, it
            has all the other required sections as well.
        .debug_info.zdebug_info	.eh_frame)boolrf   rZ   s    rD   has_dwarf_infozELFFile.has_dwarf_info   sD    
 D,,]; 2$$^42$$[13 	3rF   c                    d}t        | j                  d            }|rt        t        d |            }|dz  }|\  }}}}}	}
}}}}}}}}}}}}i }|D ]V  }| j                  |      }|d||<   | j	                  ||      }|r"|j                  d      r| j                  |      }|||<   X t        di dt        | j                  | j                  dz  | j                         	      d
||   d||   d||   d||
   d||   d||   d||   d||   d||	   d||   d||   d||   d||   d||   d||   d||   d||   d||   }|r| j                  |      |_        |S )aw   Return a DWARFInfo object representing the debugging information in
            this file.

            If relocate_dwarf_sections is True, relocations for DWARF sections
            are looked up and applied.

            If follow_links is True, we will try to load the supplementary
            object file (if any), and use it to resolve references and imports.
        )r   z.debug_arangesz.debug_abbrevz
.debug_strz.debug_linez.debug_framez
.debug_locz.debug_rangesz.debug_pubtypesz.debug_pubnamesz.debug_addrz.debug_str_offsetsz.debug_line_strz.debug_loclistsz.debug_rnglistsz
.debug_supz.gnu_debugaltlinkr   c                     d| dd  z   S )N.zr	    )xs    rD   <lambda>z(ELFFile.get_dwarf_info.<locals>.<lambda>  s    qu rF   )r   Nr   config   )r*   default_address_sizemachine_arch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_pubtypes_secdebug_pubnames_secdebug_addr_secdebug_str_offsets_secdebug_line_str_secdebug_loclists_secdebug_rnglists_secdebug_sup_secgnu_debugaltlink_secr   )r   rf   tuplemap_read_dwarf_section
startswith_decompress_dwarf_sectionr    r"   r*   r+   get_machine_archget_supplementary_dwarfinfosupplementary_dwarfinfo)rC   relocate_dwarf_sectionsfollow_linkssection_names
compresseddebug_info_sec_namedebug_aranges_sec_namedebug_abbrev_sec_namedebug_str_sec_namedebug_line_sec_namedebug_frame_sec_namedebug_loc_sec_namedebug_ranges_sec_namedebug_pubtypes_namedebug_pubnames_namedebug_addr_namedebug_str_offsets_namedebug_line_str_namedebug_loclists_sec_namedebug_rnglists_sec_namedebug_sup_namegnu_debugaltlink_nameeh_frame_sec_namedebug_sectionssecnamero   dwarf_section	dwarfinfos                               rD   get_dwarf_infozELFFile.get_dwarf_info   so   < $22>BC
!#&<m"LMM 	( FS	C	46K	02F	24G	o/E	57N	.0A$ 
	8G..w7G*.w' $ 8 8+!- '"4"4T":$($B$B=$QM*7w'
	8   ""&"4"4)-!);!%!6!6!8:
  ..AB #11G"H "00E!F !//C D ,,=> --?@ --?@ "00E!F  ..AB $22E#F $22E#F   .o>!" '55K&L#$ $22E#F%& $22I#J'( $22I#J)* -^<+, &44I%J-	0 040P0PQZ0[I-rF   c                     |j                         }|J| j                  >| j                  |      }t        |      }|j                         }|j	                          |S y)z
        Read supplementary dwarfinfo, from either the standared .debug_sup
        section or the GNU proprietary .gnu_debugaltlink.
        N)parse_debugsupinforB   r(   r   close)rC   r   supfilepathr1   
supelffile
dwarf_infos         rD   r   z#ELFFile.get_supplementary_dwarfinfo;  s\    
  224"t'9'9'E''4F J#224JLLNrF   c                 8    t        | j                  d            S )zT Check whether this file appears to have arm exception handler index table.
        SHT_ARM_EXIDXr   )anyrp   rZ   s    rD   has_ehabi_infozELFFile.has_ehabi_infoJ  s     4%%?%;<<rF   c                     g }| d   dk(  rJ d       | j                  d      D ]'  }|j                  t        || j                               ) t	        |      dkD  r|S dS )z Generally, shared library and executable contain 1 .ARM.exidx section.
            Object file contains many .ARM.exidx sections.
            So we must traverse every section and filter sections whose type is SHT_ARM_EXIDX.
        r,   ET_RELz?Current version of pyelftools doesn't support relocatable file.r   r   r   N)rp   appendr#   r*   len)rC   _retro   s      rD   get_ehabi_infoszELFFile.get_ehabi_infosO  sm    
 >X%[[[5)))? 	@GKK	'4+=+=>?	@4y1}t.$.rF   c                    i ddddddddd	d
dddddddddddddddddddddd d!d"i d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDi dEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfi dgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddi ddddddddddddddddddddddddddddddddddi ddddddddddddddddddddddddddēddƓddȓddʓdd̓i ddΓddГddғddԓdd֓ddؓddړddܓddޓddddddddddddddddi ddddddddddddddddddd ddddddddd	d
dddddi ddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1i d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdCdEdCdFdCdGdCdHdIdJdKdLdMdNdOi dPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndo}|j                  | dp   dq      S (r  zK Return the machine architecture, as detected from the ELF header.
        EM_M32zAT&T WE 32100EM_SPARCSPARCEM_386x86EM_68KzMotorola 68000EM_88KzMotorola 88000EM_IAMCUz	Intel MCUEM_860zIntel 80860EM_MIPSMIPSEM_S370zIBM System/370EM_MIPS_RS3_LEzMIPS RS3000 Little-endian	EM_PARISCzHewlett-Packard PA-RISC	EM_VPP500zFujitsu VPP500EM_SPARC32PLUSzEnhanced SPARCEM_960zIntel 80960EM_PPCPowerPCEM_PPC64z64-bit PowerPCEM_S390zIBM System/390EM_SPUzIBM SPU/SPCEM_V800zNEC V800EM_FR20zFujitsu FR20EM_RH32z	TRW RH-32EM_RCEzMotorola RCEEM_ARMARMEM_ALPHAzDigital AlphaEM_SHz
Hitachi SH
EM_SPARCV9zSPARC Version 9
EM_TRICOREz"Siemens TriCore embedded processorEM_ARCz.Argonaut RISC Core, Argonaut Technologies Inc.	EM_H8_300zHitachi H8/300
EM_H8_300HzHitachi H8/300HEM_H8SzHitachi H8S	EM_H8_500zHitachi H8/500EM_IA_64zIntel IA-64	EM_MIPS_XzMIPS-XEM_COLDFIREzMotorola ColdFire	EM_68HC12zMotorola M68HC12EM_MMAzFujitsu MMAEM_PCPzSiemens PCPEM_NCPUz	Sony nCPUEM_NDR1z
Denso NDR1EM_STARCOREzMotorola Star*CoreEM_ME16zToyota ME16EM_ST100zSTMicroelectronics ST100EM_TINYJzAdvanced Logic TinyJ	EM_X86_64x64EM_PDSPzSony DSPEM_PDP10zDigital Equipment PDP-10EM_PDP11zDigital Equipment PDP-11EM_FX66zSiemens FX66
EM_ST9PLUSz STMicroelectronics ST9+ 8/16 bitEM_ST7zSTMicroelectronics ST7 8-bit	EM_68HC16zMotorola MC68HC16	EM_68HC11zMotorola MC68HC11	EM_68HC08zMotorola MC68HC08	EM_68HC05zMotorola MC68HC05EM_SVXzSilicon Graphics SVxEM_ST19zSTMicroelectronics ST19 8-bitEM_VAXzDigital VAXEM_CRISzAxis Communications 32-bit
EM_JAVELINzInfineon Technologies 32-bitEM_FIREPATHzElement 14 64-bit DSPEM_ZSPzLSI Logic 16-bit DSPEM_MMIXz!Donald Knuth's educational 64-bitEM_HUANYz3Harvard University machine-independent object filesEM_PRISMzSiTera PrismEM_AVRzAtmel AVR 8-bitEM_FR30zFujitsu FR30EM_D10VzMitsubishi D10VEM_D30VzMitsubishi D30VEM_V850zNEC v850EM_M32RzMitsubishi M32R
EM_MN10300zMatsushita MN10300
EM_MN10200zMatsushita MN10200EM_PJpicoJavaEM_OPENRISCzOpenRISC 32-bitEM_ARC_COMPACTzARC International ARCompact	EM_XTENSAzTensilica XtensaEM_VIDEOCOREzAlphamosaic VideoCore
EM_TMM_GPPzThompson MultimediaEM_NS32Kz#National Semiconductor 32000 seriesEM_TPCzTenor Network TPCEM_SNP1KzTrebia SNP 1000EM_ST200zSTMicroelectronics ST200EM_IP2KzUbicom IP2xxxEM_MAXMAXEM_CRz"National Semiconductor CompactRISC	EM_F2MC16zFujitsu F2MC16	EM_MSP430zTexas Instruments msp430EM_BLACKFINzAnalog Devices Blackfin	EM_SE_C33zSeiko Epson S1C33EM_SEPSharpEM_ARCAz	Arca RISC
EM_UNICOREzPKU-Unity MPRC	EM_EXCESSeXcessEM_DXPz,Icera Semiconductor Deep Execution ProcessorEM_ALTERA_NIOS2zAltera Nios IIEM_CRXz&National Semiconductor CompactRISC CRXEM_XGATEzMotorola XGATEEM_C166zInfineon C16x/XC16xEM_M16CzRenesas M16CEM_DSPIC30FzMicrochip Technology dsPIC30FEM_CEz(Freescale Communication Engine RISC coreEM_M32CzRenesas M32C
EM_TSK3000zAltium TSK3000EM_RS08zFreescale RS08EM_SHARCzAnalog Devices SHARCEM_ECOG2zCyan Technology eCOG2	EM_SCORE7zSunplus S+core7 RISCEM_DSP24z New Japan Radio (NJR) 24-bit DSPEM_VIDEOCORE3zBroadcom VideoCore IIIEM_LATTICEMICO32zLattice FPGA RISC	EM_SE_C17zSeiko Epson C17EM_TI_C6000zTI TMS320C6000EM_TI_C2000zTI TMS320C2000EM_TI_C5500zTI TMS320C55xEM_TI_ARP32z#TI Application Specific RISC, 32bit	EM_TI_PRUzTI Programmable Realtime UnitEM_MMDSP_PLUSzSTMicroelectronics 64bit VLIWEM_CYPRESS_M8CzCypress M8CEM_R32CzRenesas R32CEM_TRIMEDIAzNXP Semiconductors TriMediaEM_QDSP6zQUALCOMM DSP6EM_8051z
Intel 8051	EM_STXP7XzSTMicroelectronics STxP7xEM_NDS32zAndes Technology RISCEM_ECOG1zCyan Technology eCOG1X	EM_ECOG1X	EM_MAXQ30zDallas Semiconductor MAXQ30	EM_XIMO16zNew Japan Radio (NJR) 16-bitEM_MANIKzM2000 Reconfigurable RISC
EM_CRAYNV2zCray Inc. NV2EM_RXz
Renesas RXEM_METAGzImagination Technologies METAEM_MCST_ELBRUSzMCST Elbrus	EM_ECOG16zCyan Technology eCOG16EM_CR16z.National Semiconductor CompactRISC CR16 16-bitEM_ETPU	FreescaleEM_SLE9XzInfineon Technologies SLE9XEM_L10Mz
Intel L10MEM_K10Mz
Intel K10M
EM_AARCH64AArch64EM_AVR32zAtmel 32-bitEM_STM8zSTMicroeletronics STM8 8-bit	EM_TILE64zTilera TILE64
EM_TILEPROzTilera TILEProEM_MICROBLAZEzXilinx MicroBlaze 32-bit RISCEM_CUDAzNVIDIA CUDA	EM_TILEGXzTilera TILE-GxEM_CLOUDSHIELDCloudShieldEM_COREA_1STz KIPO-KAIST Core-A 1st generationEM_COREA_2NDz KIPO-KAIST Core-A 2nd generationEM_ARC_COMPACT2zSynopsys ARCompact V2EM_OPEN8zOpen8 8-bit RISCEM_RL78zRenesas RL78EM_VIDEOCORE5zBroadcom VideoCore VEM_78KORzRenesas 78KOR
EM_56800EXzFreescale 56800EXEM_BA1z
Beyond BA1EM_BA2z
Beyond BA2EM_XCOREz
XMOS xCOREEM_MCHP_PICzMicrochip 8-bit PICEM_INTEL205zReserved by IntelEM_INTEL206EM_INTEL207EM_INTEL208EM_INTEL209EM_KM32zKM211 KM32 32-bitEM_KMX32zKM211 KMX32 32-bitEM_KMX16zKM211 KMX16 16-bitEM_KMX8zKM211 KMX8 8-bitEM_KVARCzKM211 KVARCEM_CDPz
Paneve CDPEM_COGE	CognitiveEM_COOLzBluechip Systems CoolEngineEM_NORCzNanoradio Optimized RISCEM_CSR_KALIMBAzCSR KalimbaEM_Z80z	Zilog Z80	EM_VISIUM
VISIUMcoreEM_FT32zFTDI Chip FT32 32-bit RISCEM_MOXIEMoxie	EM_AMDGPUzAMD GPUEM_RISCVzRISC-VEM_BPFz%Linux BPF - in-kernel virtual machineEM_CSKYzC-SKYEM_LOONGARCH	LoongArchEM_FRVzFujitsu FR-Vr-   z	<unknown>)rc   )rC   architecturess     rD   r   zELFFile.get_machine_arch\  s;   {
{
{
 {
 !1	{

 !1{
 {
 {
 {
 !1{
 !<{
 !:{
 !1{
 !1{
 {
 {
  !1!{
" !1#{
$ %{
& '{
( ){
* +{
, -{
. /{
0 1{
2 3{
4 !25{
6 !E7{
8 !Q9{
: !1;{
< !2={
> ?{
@ !1A{
B C{
D E{
F !4G{
H !3I{
J K{
L M{
N O{
P Q{
R !5S{
T U{
V !;W{
X !7Y{
Z [{
\ ]{
^ !;_{
` !;a{
b c{
d !Ce{
f !?g{
h !4i{
j !4k{
l !4m{
n !4o{
p !7q{
r !@s{
t u{
v !=w{
x !?y{
z !8{{
| !7}{
~ !E{
@ !VA{
B C{
D !2E{
F G{
H !2I{
J !2K{
L M{
N !2O{
P !5Q{
R !5S{
T U{
V !2W{
X !>Y{
Z !3[{
\ !8]{
^ !6_{
` !Fa{
b !4c{
d !2e{
f !;g{
h i{
j k{
l !Em{
n !1o{
p !;q{
r !:s{
t !4u{
v w{
x y{
z !1{{
| }{
~ !O{
@ !1A{
B !IC{
D !1E{
F !6G{
H I{
J !@K{
L !KM{
N O{
P !1Q{
R !1S{
T !7U{
V !8W{
X !7Y{
Z !C[{
\ !9]{
^ !4_{
` !2a{
b !1c{
d !1e{
f g{
h !Fi{
j !@k{
l !@m{
n o{
p q{
r !>s{
t u{
v w{
x !<y{
z !8{{
| !9}{
~ !9{
@ !>A{
B !?C{
D !<E{
F G{
H I{
J !@K{
L M{
N !9O{
P !QQ{
R S{
T !>U{
V W{
X Y{
Z [{
\ ]{
^ !?_{
` a{
b !1c{
d !@e{
f g{
h !1i{
j k{
l !Cm{
n !Co{
p !8q{
r !3s{
t u{
v !7w{
x y{
z !4{{
| }{
~ {
@ A{
B !6C{
D !4E{
F !4G{
H !4I{
J !4K{
L !4M{
N !4O{
P !5Q{
R !5S{
T !3U{
V W{
X Y{
Z [{
\ !>]{
^ !;_{
` a{
b c{
d e{
f !=g{
h i{
j k{
l m{
n !Ho{
p q{
r s{
t u{
z   k!2K@@rF   c                 `    | d   t         j                  k7  r| d   S | j                  d      d   S )zJ Find the string table section index for the section header table
        
e_shstrndxr   sh_link)r&   
SHN_XINDEXrY   rZ   s    rD   get_shstrndxzELFFile.get_shstrndx  s8     !7!77%%++A.y99rF   c                      | j                   |   S )z6 Implement dict-like access to header entries
        )r;   )rC   rd   s     rD   __getitem__zELFFile.__getitem__-  s     {{4  rF   c                    | j                   j                  d       | j                   j                  d      }t        |dk(  d       | j                   j                  d      }|dk(  rd| _        n$|dk(  rd	| _        nt        d
t        |      z        | j                   j                  d      }|dk(  rd| _        y|dk(  rd| _        yt        dt        |      z        )zD Verify the ELF file and identify its class and endianness.
        r      s   ELFzMagic number does not matchr	             @   zInvalid EI_CLASS %sTFzInvalid EI_DATA %sN)r1   r2   r=   r   r+   r   reprr*   )rC   magicei_classei_datas       rD   r7   zELFFile._identify_file2  s     	  #5J&(EF;;##A&wDM DM04>ABB++""1%g!%D!&D/$w-?@@rF   c                     | d   || d   z  z   S )z6 Compute the offset of section #n in the file
        rV   e_shentsizer   rC   r^   s     rD   _section_offsetzELFFile._section_offsetL       IT-%8!888rF   c                     | d   || d   z  z   S )z6 Compute the offset of segment #n in the file
        e_phoffe_phentsizer   r  s     rD   _segment_offsetzELFFile._segment_offsetQ  r  rF   c                     |d   }|dk(  rt        || j                        S |dk(  rt        || j                  |       S |dk(  rt        || j                  |       S t	        || j                        S )z9 Create a Segment object of the appropriate type
        r|   	PT_INTERP
PT_DYNAMICPT_NOTE)r   r1   r   r   r   )rC   ry   segtypes      rD   rx   zELFFile._make_segmentV  sn     !*k! ==$!.$++tDD	!~t{{DAA>4;;77rF   c                     | j                  |      }|| j                  kD  ryt        | j                  j                  | j
                  |      S )zG Find the header of section #n, parse it and return the struct
        N
stream_pos)r  r6   r   r8   Elf_Shdrr1   )rC   r^   r  s      rD   rY   zELFFile._get_section_headerc  sG     ))!,
'LL!!KK!# 	#rF   c                 p    | j                   t        d      |d   }| j                   j                  |      S )za Given a section header, find this section's name in the file's
            string table
        zString Table not foundsh_name)r@   r   
get_string)rC   r_   name_offsets      rD   _get_section_namezELFFile._get_section_namep  s=     ++3 899$Y///::;GGrF   c                    | j                  |      }|d   }|dk(  rt        |||       S |dk(  rt        |||       S |dv r| j                  ||      S |dk(  r| j	                  ||      S |dk(  r| j                  ||      S |dk(  r| j                  ||      S |dk(  r| j                  ||      S |d	k(  r| j                  ||      S |d
v rt        |||       S |dk(  rt        |||       S |dk(  rt        |||       S |dk(  r|dk(  rt        |||       S |dk(  rt        |||       S |dk(  rt        |||       S |dk(  r| j                  ||      S |dk(  r| j!                  ||      S |dk(  rt#        |||       S t%        |||       S )z9 Create a section object of the appropriate type
        rk   
SHT_STRTABSHT_NULL)
SHT_SYMTAB
SHT_DYNSYMSHT_SUNW_LDYNSYMSHT_SYMTAB_SHNDXSHT_SUNW_syminfoSHT_GNU_verneedSHT_GNU_verdefSHT_GNU_versym)SHT_RELSHT_RELASHT_DYNAMICSHT_NOTESHT_PROGBITSz.stabSHT_ARM_ATTRIBUTESSHT_RISCV_ATTRIBUTESSHT_HASHSHT_GNU_HASHSHT_RELR)r  r   r   _make_symbol_table_section _make_symbol_table_index_section_make_sunwsyminfo_table_section_make_gnu_verneed_section_make_gnu_verdef_section_make_gnu_versym_sectionr   r   r   r   r   r   _make_elf_hash_section_make_gnu_hash_sectionr   r   )rC   r_   rd   sectypes       rD   r]   zELFFile._make_sectionz  s    %%n5 +l"%ndDAA
"~tT::HH22>4HH**88NN**77MM))11.$GG((00FF((00FF//$^T4@@%!.$==
"~tT::&47?~tT::,,'dCC..).$EE
"..~tDD&..~tDD
"(tDD>466rF   c                     i | _         t        | j                               D ]  \  }}|| j                   |j                  <     y N)rA   	enumeraterp   rd   )rC   rn   secs      rD   rb   zELFFile._make_section_name_map  s?    !# 2 2 45 	1FAs/0D""388,	1rF   c                 L    |d   }| j                  |      }t        ||| |      S )z% Create a SymbolTableSection
        r  elffilestringtable)r`   r   rC   r_   rd   linked_strtab_indexstrtab_sections        rD   r  z"ELFFile._make_symbol_table_section  s8     -Y7))*=>!D&( 	(rF   c                 *    |d   }t        ||| |      S )z1 Create a SymbolTableIndexSection object
        r  r  symboltable)r   )rC   r_   rd   linked_symtab_indexs       rD   r  z(ELFFile._make_symbol_table_index_section  s&     -Y7&D$+- 	-rF   c                 L    |d   }| j                  |      }t        ||| |      S )z* Create a SUNWSyminfoTableSection
        r  r  )r`   r   r  s        rD   r  z'ELFFile._make_sunwsyminfo_table_section  s8     -Y7))*=>&D&( 	(rF   c                 L    |d   }| j                  |      }t        ||| |      S )z$ Create a GNUVerNeedSection
        r  r  )r`   r   r  s        rD   r  z!ELFFile._make_gnu_verneed_section  s8     -Y7))*=> D&( 	(rF   c                 L    |d   }| j                  |      }t        ||| |      S )z# Create a GNUVerDefSection
        r  r  )r`   r   r  s        rD   r  z ELFFile._make_gnu_verdef_section  8     -Y7))*=>D&( 	(rF   c                 L    |d   }| j                  |      }t        ||| |      S )z# Create a GNUVerSymSection
        r  r  )r`   r   r  s        rD   r  z ELFFile._make_gnu_versym_section  r  rF   c                 J    |d   }| j                  |      }t        ||| |      S Nr  )r`   r$   rC   r_   rd   r   symtab_sections        rD   r  zELFFile._make_elf_hash_section  4    ,Y7))*=>D$
 	
rF   c                 J    |d   }| j                  |      }t        ||| |      S r  )r`   r%   r  s        rD   r  zELFFile._make_gnu_hash_section  r
  rF   c                 x    t        | j                  j                  | j                  | j	                  |            S )zG Find the header of segment #n, parse it and return the struct
        r  )r   r8   Elf_Phdrr1   r  r  s     rD   rw   zELFFile._get_segment_header  s3     LL!!KK++A.0 	0rF   c                 f    | j                         }| j                  |      }|yt        |d|       S )z] Get the string table section corresponding to the section header
            table.
        N )r;   rd   r  )r  rY   r   )rC   stringtable_section_numstringtable_section_headers      rD   r?   z'ELFFile._get_section_header_stringtable  sD     #'"3"3"5%)%=%=>U%V"%-!1 	rF   c                 Z    t        | j                  j                  | j                  d      S )ze Parses the ELF file header and assigns the result to attributes
            of this object.
        r   r  )r   r8   Elf_Ehdrr1   rZ   s    rD   r:   zELFFile._parse_elf_header	  s!     DLL114;;1MMrF   c                    t               }|j                  |j                                |r0t        |       }|j	                  |      }||j                  ||       t        ||j                  |d   |j                  |d         S )z Read the contents of a DWARF section from the stream and return a
            DebugSectionDescriptor. Apply relocations if asked to.
        	sh_offsetsh_addr)r1   rd   global_offsetr   address)	r   writedatar   find_relocations_for_sectionapply_section_relocationsr!   rd   	data_size)rC   ro   r   section_streamreloc_handlerreloc_sections         rD   r   zELFFile._read_dwarf_section  s    
 !W\\^,"-d3M)FFwOM(77&7 &%\\%k2&&	*, 	,rF   c                    | j                   dkD  sJ d       | j                  j                  d       | j                  j                  d      }|dk(  s
J d|z         t	        j
                  d| j                  j                  d            d   }t        j                         }t               }	 | j                  j                  t              }|sn!|j                  |j                  |             C|j                  |j                                |j                  dt        j                         |j                         }||k(  sJ d	|d
|       | j!                  ||      S )zJ Returns the uncompressed contents of the provided DWARF section.
           zUnsupported compression format.r   r  s   ZLIBzInvalid compression type: %rz>Qr   z"Wrong uncompressed size: expected z
, but got )r1   r   )r   r1   r2   r=   structunpackzlibdecompressobjr   PAGESIZEr  
decompressflushr3   r4   r5   _replace)ro   compression_typeuncompressed_sizedecompressoruncompressed_streamchunkr   s          rD   r   z!ELFFile._decompress_dwarf_section%  sP   
 ||b C"CC A #>>..q17* 	@*.>?	@* #MM$0C0CA0FGJ))+%iNN''1E%%l&=&=e&DE	 
 	!!,"4"4"67  BKK0"'') D( 	%t	(
 ':FFrF   c                 8    | j                   j                          y r  )r1   r   rZ   s    rD   r   zELFFile.closeH  s    rF   c                     | S r  r   rZ   s    rD   	__enter__zELFFile.__enter__K  s    rF   c                 $    | j                          y r  )r   )rC   rm   value	tracebacks       rD   __exit__zELFFile.__exit__N  s    

rF   r  )r	   )TT)1__name__
__module____qualname____doc__rE   classmethodrT   r[   r`   rf   ri   rp   ru   rz   r~   r   r   r   r   r   r   r   r  r  r7   r  r  rx   rY   r  r]   rb   r  r  r  r  r  r  r  r  rw   r?   r:   r   staticmethodr   r   r2  r6  r   rF   rD   r(   r(   .   s
   @+0 ' '"2
D	>
22
?3Od=
/@AD:!
A49
9
8#H)7V1
(-((((

0N,,  G  GDrF   r(   )9r3   r   rJ   r#  r%  resourcegetpagesizer'  ImportErrormmapcommon.exceptionsr   r   common.utilsr   r   r8   r
   sectionsr   r   r   r   r   r   r   r   r   r   dynamicr   r   
relocationr   r   r   gnuversionsr   r   r   segmentsr   r   r   dwarf.dwarfinfor    r!   r"   ehabi.ehabiinfor#   hashr$   r%   	constantsr&   objectr(   r   rF   rD   <module>rM     s    
  	  
#x##%H 8 3 P P P 4   : 9 L L ' 0 "af a9  == s5   B+ +C1CCC	CCCC