
    dT                         d dl mZ ddl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 ddlmZ  G d	 d
e      Z G d de      Z G d dee      Z G d de      Z G d de      Zy)    )
namedtuple   )ELFRelocationError)
elf_assertstruct_parse   )Section)	ENUM_RELOC_TYPE_i386ENUM_RELOC_TYPE_x64ENUM_RELOC_TYPE_MIPSENUM_RELOC_TYPE_ARMENUM_RELOC_TYPE_AARCH64ENUM_RELOC_TYPE_PPC64ENUM_RELOC_TYPE_BPFENUM_RELOC_TYPE_LOONGARCH
ENUM_D_TAG)	Containerc                   .    e Zd ZdZd Zd Zd Zd Zd Zy)
Relocationz Relocation object - representing a single relocation entry. Allows
        dictionary-like access to the entry's fields.

        Can be either a REL or RELA relocation.
    c                      || _         || _        y N)entryelffile)selfr   r   s      9/usr/lib/python3/dist-packages/elftools/elf/relocation.py__init__zRelocation.__init__   s    
    c                     d| j                   v S )z6 Is this a RELA relocation? If not, it's REL.
        r_addendr   r   s    r   is_RELAzRelocation.is_RELA   s     TZZ''r   c                      | j                   |   S )z% Dict-like access to entries
        r    )r   names     r   __getitem__zRelocation.__getitem__$   s     zz$r   c                 L    d| j                         rdndd| j                  dS )Nz<Relocation (RELARELz): >)r"   r   r!   s    r   __repr__zRelocation.__repr__)   s#    ,,.e3

 	r   c                 "    | j                         S r   )r*   r!   s    r   __str__zRelocation.__str__.   s    }}r   N)	__name__
__module____qualname____doc__r   r"   r%   r*   r,    r   r   r   r      s     
(
 

r   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)RelocationTablezL Shared functionality between relocation sections and relocation tables
    c                 0   |j                   | _        || _        |j                  | _        || _        || _        || _        |r| j                  j                  | _	        n| j                  j                  | _	        | j                  j                         | _        y r   )stream_stream_elffilestructs_elfstructs_size_offset_is_relaElf_Relaentry_structElf_Relsizeof
entry_size)r   r   offsetsizeis_relas        r   r   zRelocationTable.__init__6   sv    ~~"??
 $ 0 0 9 9D $ 0 0 8 8D++224r   c                     | j                   S )z> Is this a RELA relocation section? If not, it's REL.
        )r<   r!   s    r   r"   zRelocationTable.is_RELAE   s     }}r   c                 4    | j                   | j                  z  S z. Number of relocations in the section
        )r:   rA   r!   s    r   num_relocationszRelocationTable.num_relocationsJ   s     zzT__,,r   c                     | j                   || j                  z  z   }t        | j                  | j                  |      }t        || j                        S )M Get the relocation at index #n from the section (Relocation object)
        
stream_pos)r;   rA   r   r>   r6   r   r7   )r   nentry_offsetr   s       r   get_relocationzRelocationTable.get_relocationO   sK     ||a$//&99LL#% %//r   c              #   n   K   t        | j                               D ]  }| j                  |        yw)2 Yield all the relocations in the section
        N)rangerH   rO   )r   is     r   iter_relocationsz RelocationTable.iter_relocationsY   s6      t++-. 	)A%%a((	)s   35N)	r-   r.   r/   r0   r   r"   rH   rO   rT   r1   r   r   r3   r3   2   s     5
-
0)r   r3   c                       e Zd ZdZd Zy)RelocationSectionzK ELF relocation section. Serves as a collection of Relocation entries.
    c                    t        j                  | |||       t        j                  | | j                  | d   | d   |d   dk(         t	        |d   dv d       t	        |d   | j
                  k(  d|d   d	| j
                         y )
N	sh_offsetsh_sizesh_typeSHT_RELA)SHT_RELr[   zUnknown relocation type section
sh_entsizezExpected sh_entsize of z section to be )r	   r   r3   r   r   rA   r   headerr$   r   s       r   r   zRelocationSection.__init__c   s    vtW5  t||tIy0AZ0O	Q 	6)$(??-	/6,'4??:y!4??4	5r   N)r-   r.   r/   r0   r   r1   r   r   rV   rV   `   s    	5r   rV   c                   (    e Zd ZdZd Zd Zd Zd Zy)RelrRelocationSectiona   RELR compressed relocation section. This stores relative relocations
        in a compressed format. An entry with an even value serves as an
        'anchor' that defines a base address. Following this entry are one or
        more bitmaps for consecutive addresses after the anchor which determine
        if the corresponding relocation exists (if the bit is 1) or if it is
        skipped. Addends are stored at the respective addresses (as in REL
        relocations).
    c                     t        j                  | |||       | d   | _        | d   | _        | j                  j
                  j                  | _        | j                  j                         | _	        d | _
        y )NrX   rY   )r	   r   r;   r:   r   r8   Elf_Relr_relr_structr@   
_entrysize_cached_relocationsr^   s       r   r   zRelrRelocationSection.__init__w   sc    vtW5K()_
 LL0099++224#' r   c              #     K   | j                   | j                  z   }| j                   }d}||k  r!t        | j                  | j                  j
                  |      }|d   }|dz  dk(  r*|}|| j                  z  }t        || j                         nt        |dud       d}	 |dz	  }|dk(  rnB|dz  dk7  r4||| j                  z  z   }t        t        |      | j                         |dz  }M|d| j                  z  dz
  | j                  j                  j                  d	      j                         z  z  }|| j                  z  }||k  r yyw)
rQ   NrK   r_offsetr   r   z RELR bitmap without base address)rh       )r;   r:   r   rd   r   r5   re   r   r   r   r8   Elf_addrr@   )r   limitrelrbaser   rN   rS   calc_offsets           r   rT   z&RelrRelocationSection.iter_relocations   sb     tzz)|| Ul !2!2!%!4!4,02E !,Lq Q& $' 55 4t+-OP$0A$5L#q( %q(Q.&*Q-@&@(k)J)-7 7FA   T__,q0DLL4H4H4Q4QRT4U4\4\4^^^DOO#DE Uls   EEEc                     | j                   t        | j                               | _         t        | j                         S rG   )rf   listrT   lenr!   s    r   rH   z%RelrRelocationSection.num_relocations   s7     ##+'+D,A,A,C'DD$4++,,r   c                 t    | j                   t        | j                               | _         | j                   |   S )rJ   )rf   rq   rT   )r   rM   s     r   rO   z$RelrRelocationSection.get_relocation   s7     ##+'+D,A,A,C'DD$''**r   N)r-   r.   r/   r0   r   rT   rH   rO   r1   r   r   ra   ra   n   s    (*$X-+r   ra   c                      e Zd ZdZd Zd Zd Zd Z edd      Z	d>dZ
d>d	Zd>d
Zd>dZd>dZd>dZd>dZd>dZed    e	dde      ed    e	dde      iZed    e	dde      ed    e	dde      ed    e	dde      iZed    e	dde
      ed    e	dde      iZed    e	dde
      ed    e	dde      ed    e	dde      iZed    e	dde      ed    e	dde      ed    e	dde      iZed     e	dde
      ed!    e	dde      ed"    e	dde      iZed#    e	dde
      ed$    e	dde      ed%    e	dde      ed&    e	dde      ed'    e	dde      iZed(    e	dde
      ed)    e	dde
      ed*    e	dde      ed+    e	dde
      ed,    e	dde
      ed-    e	dde
      iZ e!d.    e	dde
      e!d/    e	dde      e!d0    e	dde      e!d1    e	d2de      e!d3    e	d2de      e!d4    e	d5de      e!d6    e	d5de      e!d7    e	dde      e!d8    e	dde      e!d9    e	dde      e!d:    e	dde      e!d;    e	dde      e!d<    e	dde      iZ"y=)?RelocationHandlerz4 Handles the logic of relocations in ELF files.
    c                     || _         y r   )r   )r   r   s     r   r   zRelocationHandler.__init__   s	    r   c                     d|j                   z   d|j                   z   f}| j                  j                         D ]%  }t        |t              s|j                   |v s#|c S  y)z Given a section, find the relocation section for it in the ELF
            file. Return a RelocationSection object, or None if none was
            found.
        z.relz.relaN)r$   r   iter_sections
isinstancerV   )r   sectionreloc_section_names
relsections       r   find_relocations_for_sectionz.RelocationHandler.find_relocations_for_section   se     %',,&( ,,446 	"Jz+<=OO'::!!	" r   c                     | j                   j                  |d         }|j                         D ]  }| j                  |||        y)z Apply all relocations in reloc_section (a RelocationSection object)
            to the given stream, that contains the data of the section that is
            being relocated. The stream is modified as a result.
        sh_linkN)r   get_sectionrT   _do_apply_relocation)r   r5   reloc_sectionsymtabrelocs        r   apply_section_relocationsz+RelocationHandler.apply_section_relocations   sG     ))-	*BC"335 	=E%%feV<	=r   c                    |d   |j                         k\  rt        d|d   z        |j                  |d         d   }|d   }d }| j                  j	                         dk(  r<|j                         rt        d|z        | j                  j                  |d       }nR| j                  j	                         dk(  r<|j                         st        d|z        | j                  j                  |d       }n| j                  j	                         d	k(  r~|j                         rP|t        d
   k(  r&|d   dk7  s|d   dk7  s|d   dk7  rt        d|z        | j                  j                  |d       }n|| j                  j                  |d       }n^| j                  j	                         dk(  r<|j                         rt        d|z        | j                  j                  |d       }n| j                  j	                         dk(  r| j                  j                  |d       }n| j                  j	                         dk(  r| j                  j                  |d       }n| j                  j	                         dk(  r| j                  j                  |d       }nW| j                  j	                         dk(  r:|j                         st        d|z        | j                   j                  |d       }|t        d|z        |j"                  dk(  r&| j                  j$                  j'                  d      }n|j"                  dk(  r&| j                  j$                  j)                  d      }n|j"                  dk(  r&| j                  j$                  j+                  d      }nM|j"                  dk(  r&| j                  j$                  j-                  d      }nt        d|j"                  z        t/        |||d         }|j1                  |||d   |j2                  r|d    nd!      }	|j5                  |d          |	d|j"                  dz  z  z  }	|j7                  |	|       y )"N
r_info_symz0Invalid symbol reference in relocation: index %sst_valuer_info_typex86z&Unexpected RELA relocation for x86: %sx64z%Unexpected REL relocation for x64: %sMIPS	R_MIPS_64r_type2r   r_type3r_ssymz9Multiple relocations in R_MIPS_64 are not implemented: %sARMz&Unexpected RELA relocation for ARM: %sAArch64z64-bit PowerPCz%Linux BPF - in-kernel virtual machine	LoongArchz+Unexpected REL relocation for LoongArch: %szUnsupported relocation type: %s   rj   ri   r   r   z"Invalid bytesize %s for relocationrh   rK   r   value	sym_valuerB   addend)num_symbolsr   
get_symbolr   get_machine_archr"   _RELOCATION_RECIPES_X86get_RELOCATION_RECIPES_X64r   _RELOCATION_RECIPES_MIPS_RELA_RELOCATION_RECIPES_MIPS_REL_RELOCATION_RECIPES_ARM_RELOCATION_RECIPES_AARCH64_RELOCATION_RECIPES_PPC64_RELOCATION_RECIPES_EBPF_RELOCATION_RECIPES_LOONGARCHbytesizer8   Elf_word
Elf_word64Elf_byteElf_halfr   	calc_func
has_addendseekbuild_stream)
r   r5   r   r   r   
reloc_typerecipevalue_structoriginal_valuerelocated_values
             r   r   z&RelocationHandler._do_apply_relocation   s   
 &"4"4"66$B,')* * %%eL&9::F	=)
<<((*e3}}(<uDF F1155j$GF\\**,5==?(;eCE E1155j$GF\\**,6}}!5k!BBY'1,i0@A0Ex\]I]0WZ__a a;;??
DQ::>>z4P\\**,5}}(<uDF F1155j$GF\\**,	95599*dKF\\**,0@@3377
DIF\\**,0WW2266z4HF\\**,;==?(AEIK K77;;JMF>$5
BD D ??a<<//88<L__!<<//::2>L__!<<//88<L__!<<//88<L$%IOO&$ % % &Z(*
 !** $(.(9(95$q	 + B 	E*%&
 *Q6??Q3F-GH!!/6:r   _RELOCATION_RECIPE_TYPEzbytesize has_addend calc_funcc                     | S r   r1   r   s       r   _reloc_calc_identityz&RelocationHandler._reloc_calc_identity?  s    r   c                     || z   |z   S r   r1   r   s       r   _reloc_calc_sym_plus_valuez,RelocationHandler._reloc_calc_sym_plus_valueB      5 6))r   c                     || z   |z
  S r   r1   r   s       r    _reloc_calc_sym_plus_value_pcrelz2RelocationHandler._reloc_calc_sym_plus_value_pcrelE  r   r   c                     ||z   S r   r1   r   s       r   _reloc_calc_sym_plus_addendz-RelocationHandler._reloc_calc_sym_plus_addendH  s    6!!r   c                     ||z   |z
  S r   r1   r   s       r   !_reloc_calc_sym_plus_addend_pcrelz3RelocationHandler._reloc_calc_sym_plus_addend_pcrelK  s    6!F**r   c                     | |z
  |z
  S r   r1   r   s       r   "_reloc_calc_value_minus_sym_addendz4RelocationHandler._reloc_calc_value_minus_sym_addendN  s    y 6))r   c                     |dz  | z   |dz  z
  S )Nr   r1   r   s       r   $_arm_reloc_calc_sym_plus_value_pcrelz6RelocationHandler._arm_reloc_calc_sym_plus_value_pcrelQ  s    A~%!33r   c                     ||z   dz  dz
  S )Nri   r   r1   r   s       r   %_bpf_64_32_reloc_calc_sym_plus_addendz7RelocationHandler._bpf_64_32_reloc_calc_sym_plus_addendT  s    F"q(1,,r   R_ARM_ABS32r   F)r   r   r   
R_ARM_CALLR_AARCH64_ABS64ri   TR_AARCH64_ABS32R_AARCH64_PREL32R_MIPS_NONE	R_MIPS_32r   R_PPC64_ADDR32R_PPC64_REL32R_PPC64_ADDR64
R_386_NONER_386_32
R_386_PC32R_X86_64_NONER_X86_64_64R_X86_64_PC32R_X86_64_32R_X86_64_32S
R_BPF_NONER_BPF_64_64R_BPF_64_32R_BPF_64_NODYLD32R_BPF_64_ABS64R_BPF_64_ABS32R_LARCH_NONE
R_LARCH_32
R_LARCH_64R_LARCH_ADD8r   R_LARCH_SUB8R_LARCH_ADD16r   R_LARCH_SUB16R_LARCH_ADD32R_LARCH_SUB32R_LARCH_ADD64R_LARCH_SUB64R_LARCH_32_PCRELR_LARCH_64_PCRELN)r   )#r-   r.   r/   r0   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r
   r   r   r   r   r   r   r   r1   r   r   ru   ru      s   "=Y;D ))B')**"+*4- 	M*,C50-2 	L)+B5:,<	 	  124K43N5P 124K43N5P 235L4769# 	]+-D54H.J[)+B50,2$  	]+-D43G.I[)+B40,2 	[)+B40,2	%! 	./1H43N2Po.0G43T1V./1H43N2P! 	\*,C54H-JZ(*A50+2 	\*,C56-8	 	O,.E43G/IM*,C43N-PO,.E47/9 	M*,C43N-PN+-D43N.P  	L)+B54H,JM*,C54H-JM*,C54Y-[/02I54H3J,-/F54H0J,-/F54H0J " 	".13J54H4J!,/1H4123 	",/1H4123 	".13J4042 	".13J484: 	"/24K4052 	"/24K485: 	"/24K4052 	"/24K485: 	"/24K4052 	"/24K485: 	""457N4789 	""457N4789I'%!r   ru   N)collectionsr   common.exceptionsr   common.utilsr   r   sectionsr	   enumsr
   r   r   r   r   r   r   r   r   	constructr   objectr   r3   rV   ra   ru   r1   r   r   <module>r      sn    # 2 3 @ @ @ " :+)f +)\5 5I+G I+V^ ^r   