3
^)              	   @   s6  d Z ddlZddlZddlZddlZddlZddlmZ ddlZddlm	Z	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 ddlmZ dd ZejddddddfddZejddddddddf	ddZdddZdd Z dd Z!ejdddfddZ"dd Z#e$dkr2e#  dS ) a  
CPython independent disassembly routines

There are two reasons we can't use Python's built-in routines
from dis. First, the bytecode we are extracting may be from a different
version of Python (different magic number) than the version of Python
that is doing the extraction.

Second, we need structured instruction information for the
(de)-parsing step. Python 3.4 and up provides this, but we still do
want to run on Python 2.7.
    N)deque)IS_PYPYPYTHON_VERSION)Bytecode)iscodecodeType2Portable)check_object_pathload_module)PYTHON_MAGIC_INT)format_code_info)VERSION)
op_importsc             C   sn   t | ttfkr$djdd | D } t| }|r8|d7 }|tj krLt| S |rVd}nd}td| |f d S )N.c             S   s   g | ]}t |qS  )str).0xr   r   F/home/psgendb/BIRCHDEV/python/lib/python3.6/site-packages/xdis/main.py
<listcomp>3   s    zget_opcode.<locals>.<listcomp>Zpypyz	 for pypy z)%s is not a Python version%s I know about)typelisttuplejoinr   r   keys	TypeError)versionis_pypylookupZpypy_strr   r   r   
get_opcode0   s    r   FTc
          
   C   s   |pt j}
|rd}nd}tr"d}nd}|rfd}|r:t|}|
jdt|| d| |djt jjdf  t	dk r| dkr|
jd |
jd	 |d k	rt
j
j|}|
jd
|  |
j|jd |d k	r|
jd|  |d k	r|
jd|  |	r|
jd|j  d S )NzPyPy r   zO# pydisasm version %s
# %sPython bytecode %s%s
# Disassembled from %sPython %s
z (%s)z
# 
g      @z?
## **Warning** bytecode strings will be converted to strings.
z7## To avoid loss, run this from Python 3.0 or greater

z# Timestamp in code: %dz (%Y-%m-%d %H:%M:%S)
z'# Source code size mod 2**32: %d bytes
z# SipHash:           0x%x
z# Embedded file name: %s
)sysstdoutr   r   writer   r   r   splitr   datetimefromtimestampstrftimeco_filename)bytecode_versionco	timestampoutr   	magic_intsource_sizesip_hashheadershow_filenamereal_outZco_pypy_strZrun_pypy_strZ	magic_strvaluer   r   r   show_module_header@   s@    


r4   c             C   s   t |stt| ||||||||dd
 |p0tj}|jrR|	 rR|jt|| d  t| |}|	rxt	|| ||i t
g  nt|g}t|| |||
dd dS )z:
    diassembles and deparses a given code block 'co'
    F)r1   r    T)
show_bytes	dup_linesN)r   AssertionErrorr4   r!   r"   r(   r#   r   r   disco_loop_asm_formatsetr   
disco_loop)r)   r*   r+   r,   r   r-   r.   r/   r0   
asm_formatr5   r6   r2   opcqueuer   r   r   discoz   s*    


r>   c       	      C   s   xt |dkr|j }|jdkr8|jdt|| d  t|| |d}|j|j|dd  x |jD ]}t|rd|j	| qdW qW dS )	a  Disassembles a queue of code objects. If we discover
    another code object which will be found in co_consts, we add
    the new code to the list. Note that the order of code discovery
    is in the order of first encountered which is not amenable for
    the format used by a disassembler where code objects should
    be defined before using them in other functions.
    However this is not recursive and will overall lead to less
    memory consumption at run time.
    r   <module>?r    )r6   )r5   N)r?   r@   )
lenpopleftco_namer#   r   r   dis	co_constsr   append)	r<   r   r=   r2   r6   r5   r*   bytecodecr   r   r   r:      s    

r:   c             C   s   d| t |f S )Nz%s_0x%x)id)basenameco_coder   r   r   code_uniquify   s    rL   c             C   s  t |}|j}|j||}g }x|jD ]}	t|	rt|	tjrHt |	}
n|	}
t| ||
||| t	j
dt|	}|r|jd}|dkrt||	j}||
_|
j  |j|
 q&|j|	 q&W ||_t	j
d|j}|s||kr*||kr|}n
|jd}|dkrt||j}|}||kst|||< ||_n$||krNt||j}|||< ||_|j }|j| |jdkst|jr|jdt||| d  t|| dd}|j|jdd	d  d
S )zProduces disassembly in a format more conducive to
    automatic assembly by producing inner modules before they are
    used by outer ones. Since this is recusive, we'll
    use more stack space at runtime.
    z.* object <(.+)> at   modulez^<(.+)>$z<module>r    T)r6   )r;   N)r   rC   getrE   r   
isinstancetypesCodeTyper8   rematchr   grouprL   rK   ZfreezerF   r7   addr(   r#   r   r   rD   )r<   r   r*   r2   Zfn_name_mapZall_fnsrC   Zmapped_nameZ
new_constsrH   Zc_compatmrJ   rG   r   r   r   r8      sX    






r8   c             C   s   d}y"t | }t|\}}}}	}
}}W nV   |dkr8 tj| }t| dj }t|| d}	t}
t}d}|j	}|j
}t}Y nX |} |rt||	|||
|||dd	 nt||	|||
|||||d
 | |	||||
||fS )z
    disassemble Python byte-code file (.pyc)

    If given a Python source file (".py") file, we'll
    try to find the corresponding compiled object.

    If that fails we'll compile internally for the Python version currently running
    Nrexecr   T)r1   )r;   r5   )r   r	   osstatopenreadcompiler   r
   st_sizest_mtimer   r4   r>   )filenameZ	outstreamr;   r0   r5   Zpyc_filenamer   r+   r-   r*   r   r.   r/   r[   sourcer   r   r   disassemble_file  sP    


rc   c              C   sX   t tj} | dkrB| dkr&tjr&t}qLtjjdt  tjd n
tjd }t	| dS )z*Simple test program to disassemble a file.   rM   z$usage: %s [-|CPython compiled file]
N)
rA   r!   argvxdisZPYTHON3__file__stderrr#   exitrc   )Zargcfnr   r   r   _testL  s    

rk   __main__)FF)%__doc__r%   rZ   rS   r!   rQ   collectionsr   rf   r   r   Zxdis.bytecoder   Zxdis.codetyper   r   Z	xdis.loadr   r	   Zxdis.magicsr
   Zxdis.cross_disr   Zxdis.versionr   Zxdis.op_importsr   r   r"   r4   r>   r:   rL   r8   rc   rk   __name__r   r   r   r   <module>   sF   (4&
B?
