2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								#!/usr/bin/env python  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ESP32 core dump Utility  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  __future__  import  print_function  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  __future__  import  unicode_literals  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  __future__  import  division  
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  hashlib  import  sha256  
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  sys  
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								try :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    from  builtins  import  zip 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    from  builtins  import  str 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    from  builtins  import  range 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    from  past . utils  import  old_div 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    from  builtins  import  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								except  ImportError :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( ' Import has failed probably because of the missing  " future "  package. Please install all the packages for  ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          ' interpreter  {}  from the $IDF_PATH/requirements.txt file. ' . format ( sys . executable ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sys . exit ( 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								import  os  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  argparse  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  subprocess  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  tempfile  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  struct  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  errno  
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  base64  
						 
					
						
							
								
									
										
										
										
											2017-09-13 21:30:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  binascii  
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  logging  
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  re  
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-26 18:01:55 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								idf_path  =  os . getenv ( ' IDF_PATH ' )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  idf_path :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sys . path . insert ( 0 ,  os . path . join ( idf_path ,  ' components ' ,  ' esptool_py ' ,  ' esptool ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								try :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    import  esptool 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								except  ImportError :  
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " esptool is not found! Set proper $IDF_PATH in environment. " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-26 18:01:55 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    sys . exit ( 2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								__version__  =  " 0.4-dev "  
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								if  os . name  ==  ' nt ' :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CLOSE_FDS  =  False 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								else :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CLOSE_FDS  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								INVALID_CAUSE_VALUE  =  0xFFFF  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Exception cause dictionary to get translation of exccause register  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# From 4.4.1.5 table 4-64 Exception Causes of Xtensa  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Instruction Set Architecture (ISA) Reference Manual  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								xtensa_exception_cause_dict  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    0 :  ( " IllegalInstructionCause " ,  " Illegal instruction " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    1 :  ( " SyscallCause " ,  " SYSCALL instruction " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    2 :  ( " InstructionFetchErrorCause " ,  " Processor internal physical address or data error during instruction fetch. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    3 :  ( " LoadStoreErrorCause " ,  " Processor internal physical address or data error during load or store. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    4 :  ( " Level1InterruptCause " ,  " Level-1 interrupt as indicated by set level-1 bits in the INTERRUPT register " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    5 :  ( " AllocaCause " ,  " MOVSP instruction, if caller`s registers are not in the register file " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    6 :  ( " IntegerDivideByZeroCause " ,  " QUOS: QUOU, REMS: or REMU divisor operand is zero " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    8 :  ( " PrivilegedCause " ,  " Attempt to execute a privileged operation when CRING ? 0 " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    9 :  ( " LoadStoreAlignmentCause " ,  " Load or store to an unaligned address. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    12 :  ( " InstrPIFDataErrorCause " ,  " PIF data error during instruction fetch. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    13 :  ( " LoadStorePIFDataErrorCause " ,  " Synchronous PIF data error during LoadStore access. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    14 :  ( " InstrPIFAddrErrorCause " ,  " PIF address error during instruction fetch. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    15 :  ( " LoadStorePIFAddrErrorCause " ,  " Synchronous PIF address error during LoadStore access. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    16 :  ( " InstTLBMissCause " ,  " Error during Instruction TLB refill. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    17 :  ( " InstTLBMultiHitCause " ,  " Multiple instruction TLB entries matched. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    18 :  ( " InstFetchPrivilegeCause " ,  " An instruction fetch referenced a virtual address at a ring level less than CRING. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    20 :  ( " InstFetchProhibitedCause " ,  " An instruction fetch referenced a page mapped with an attribute that does not permit instruction fetch (EXCVADDR). " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    24 :  ( " LoadStoreTLBMissCause " ,  " Error during TLB refill for a load or store. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    25 :  ( " LoadStoreTLBMultiHitCause " ,  " Multiple TLB entries matched for a load or store. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    26 :  ( " LoadStorePrivilegeCause " ,  " A load or store referenced a virtual address at a ring level less than CRING. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    28 :  ( " LoadProhibitedCause " ,  " A load referenced a page mapped with an attribute that does not permit loads. (See EXCVADDR for more information) " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    29 :  ( " StoreProhibitedCause " ,  " A store referenced a page mapped with an attribute that does not permit stores [Region Protection Option or MMU Option]. " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    32 :  ( " Coprocessor0Disabled " ,  " Coprocessor 0 instruction when cp0 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    33 :  ( " Coprocessor1Disabled " ,  " Coprocessor 1 instruction when cp1 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    34 :  ( " Coprocessor2Disabled " ,  " Coprocessor 2 instruction when cp2 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    35 :  ( " Coprocessor3Disabled " ,  " Coprocessor 3 instruction when cp3 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    36 :  ( " Coprocessor4Disabled " ,  " Coprocessor 4 instruction when cp4 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    37 :  ( " Coprocessor5Disabled " ,  " Coprocessor 5 instruction when cp5 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    38 :  ( " Coprocessor6Disabled " ,  " Coprocessor 6 instruction when cp6 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    39 :  ( " Coprocessor7Disabled " ,  " Coprocessor 7 instruction when cp7 disabled " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    INVALID_CAUSE_VALUE :  ( " InvalidCauseRegister " ,  " Invalid EXCCAUSE register value or current task is broken and was skipped " ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ESPCoreDumpError ( RuntimeError ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Core dump runtime error class 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  message ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Constructor for core dump error 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        super ( ESPCoreDumpError ,  self ) . __init__ ( message ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  BinStruct ( object ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Binary structure representation 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								       Subclasses  must  specify  actual  structure  layout  using  ' fields '  and  ' format '  members . 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								       For  example ,  the  following  subclass  represents  structure  with  two  fields : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								       f1  of  size  2  bytes  and  4  bytes  f2 .  Little  endian . 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        class  SomeStruct ( BinStruct ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fields  =  ( " f1 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      " f2 " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            format  =  " <HL " 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Then  subclass  can  be  used  to  initialize  fields  of  underlaying  structure  and  convert  it  to  binary  representation : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        f  =  open ( ' some_struct.bin ' ,  ' wb ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        s  =  SomeStruct ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        s . f1  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        s . f2  =  10 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        f . write ( s . dump ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        f . close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  buf = None ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Base constructor for binary structure objects 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  buf  is  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            buf  =  b ' \0 '  *  self . sizeof ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        fields  =  struct . unpack ( self . __class__ . format ,  buf [ : self . sizeof ( ) ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        self . __dict__ . update ( zip ( self . __class__ . fields ,  fields ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  sizeof ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns the size of the structure represented by specific subclass 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  struct . calcsize ( self . __class__ . format ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  dump ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns binary representation of structure 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        keys  =  self . __class__ . fields 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  struct . pack ( self . __class__ . format ,  * ( self . __dict__ [ k ]  for  k  in  keys ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  Elf32FileHeader ( BinStruct ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ ELF32 file header 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    fields  =  ( " e_ident " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_type " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_machine " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_version " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_entry " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_phoff " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_shoff " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_flags " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_ehsize " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_phentsize " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_phnum " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_shentsize " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_shnum " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " e_shstrndx " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    format  =  " <16sHHLLLLLHHHHHH " 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  buf = None ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for ELF32 file header structure 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        super ( Elf32FileHeader ,  self ) . __init__ ( buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  buf  is  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # Fill in sane ELF header for LSB32 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            self . e_ident  =  b " \x7f ELF \1 \1 \1 \0 \0 \0 \0 \0 \0 \0 \0 \0 " 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            self . e_version  =  ESPCoreDumpElfFile . EV_CURRENT 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            self . e_ehsize  =  self . sizeof ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  Elf32ProgramHeader ( BinStruct ) :  
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ ELF32 program header 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fields  =  ( " p_type " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " p_offset " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " p_vaddr " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " p_paddr " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " p_filesz " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " p_memsz " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " p_flags " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " p_align " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    format  =  " <LLLLLLLL " 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  Elf32NoteDesc ( object ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ ELF32 note descriptor 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  name ,  type ,  desc ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Constructor for ELF32 note descriptor 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . name  =  name 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        self . type  =  type 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . desc  =  desc 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  dump ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns binary representation of ELF32 note descriptor 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        nm_buf  =  bytearray ( self . name ,  encoding = ' ascii ' )  +  b ' \0 ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        hdr  =  struct . pack ( " <LLL " ,  len ( nm_buf ) ,  len ( self . desc ) ,  self . type ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # pad for 4 byte alignment 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        name  =  nm_buf  +  ( ( 4  -  len ( nm_buf ) )  %  4 )  *  b ' \0 ' 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        desc  =  self . desc  +  ( ( 4  -  len ( self . desc ) )  %  4 )  *  b ' \0 ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  hdr  +  name  +  desc 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  read ( self ,  data ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Reads ELF32 note descriptor 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        hdr_sz  =  struct . calcsize ( " <LLL " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        nm_len , desc_len , self . type  =  struct . unpack ( " <LLL " ,  data [ : hdr_sz ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        nm_len_a  =  nm_len  +  ( ( 4  -  nm_len )  %  4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . name  =  struct . unpack ( " < %d s "  %  ( nm_len  -  1 ) ,  data [ hdr_sz : hdr_sz  +  nm_len  -  1 ] ) [ 0 ] . decode ( ' ascii ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . desc  =  data [ hdr_sz  +  nm_len_a : hdr_sz  +  nm_len_a  +  desc_len ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        desc_len_a  =  desc_len  +  ( ( 4  -  desc_len )  %  4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  hdr_sz  +  nm_len_a  +  desc_len_a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  XtensaPrStatus ( BinStruct ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Xtensa program status structure """ 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    fields  =  ( " si_signo " ,  " si_code " ,  " si_errno " , 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              " pr_cursig " , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								              " pr_pad0 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_sigpend " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_sighold " , 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								              " pr_pid " , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								              " pr_ppid " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_pgrp " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_sid " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_utime " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_stime " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_cutime " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " pr_cstime " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    format  =  " <3LHHLLLLLLQQQQ " 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  EspCoreDumpTaskStatus ( BinStruct ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Core dump status structure """ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # task status flags for note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TASK_STATUS_CORRECT  =  0x00 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TASK_STATUS_TCB_CORRUPTED  =  0x01 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TASK_STATUS_STACK_CORRUPTED  =  0x02 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fields  =  ( " task_index " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " task_flags " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " task_tcb_addr " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " task_stack_start " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " task_stack_len " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              " task_name " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    format  =  " <LLLLL16s " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								class  ESPCoreDumpSegment ( esptool . ImageSegment ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """  Wrapper class for a program segment in core ELF file, has a segment 
 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        type  and  flags  as  well  as  the  common  properties  of  an  ImageSegment . 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    # segment flags 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PF_X  =  0x1   # Execute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PF_W  =  0x2   # Write 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PF_R  =  0x4   # Read 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  addr ,  data ,  type ,  flags ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for program segment 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        super ( ESPCoreDumpSegment ,  self ) . __init__ ( addr ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . flags  =  flags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . type  =  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __repr__ ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns string representation of program segment 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  " %s   %s   %s "  %  ( self . type ,  self . attr_str ( ) ,  super ( ESPCoreDumpSegment ,  self ) . __repr__ ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  attr_str ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns string representation of program segment attributes 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        str  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . flags  &  self . PF_R : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  ' R ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  '   ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . flags  &  self . PF_W : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  ' W ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  '   ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . flags  &  self . PF_X : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  ' X ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  '   ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  str 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ESPCoreDumpSection ( esptool . ELFSection ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """  Wrapper class for a section in core ELF file, has a section 
 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        flags  as  well  as  the  common  properties  of  an  esptool . ELFSection . 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # section flags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SHF_WRITE        =  0x1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SHF_ALLOC        =  0x2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SHF_EXECINSTR    =  0x4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  name ,  addr ,  data ,  flags ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for section 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        super ( ESPCoreDumpSection ,  self ) . __init__ ( name ,  addr ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . flags  =  flags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __repr__ ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns string representation of section 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  " %s   %s "  %  ( super ( ESPCoreDumpSection ,  self ) . __repr__ ( ) ,  self . attr_str ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  attr_str ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns string representation of section attributes 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        str  =  " R " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . flags  &  self . SHF_WRITE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  ' W ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  '   ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . flags  &  self . SHF_EXECINSTR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  ' X ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  '   ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . flags  &  self . SHF_ALLOC : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  ' A ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            str  + =  '   ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  str 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ESPCoreDumpElfFile ( esptool . ELFFile ) :  
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """  Wrapper class for core dump ELF file 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # extra regs IDs used in EXTRA_INFO note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EXCCAUSE_IDX     =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EXCVADDR_IDX     =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPS2_IDX         =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPS3_IDX         =  3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPS4_IDX         =  4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPS5_IDX         =  5 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPS6_IDX         =  6 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPS7_IDX         =  7 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPC1_IDX         =  8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPC2_IDX         =  9 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPC3_IDX         =  10 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPC4_IDX         =  11 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPC5_IDX         =  12 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPC6_IDX         =  13 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    REG_EPC7_IDX         =  14 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    # ELF file type 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ET_NONE              =  0x0   # No file type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ET_REL               =  0x1   # Relocatable file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ET_EXEC              =  0x2   # Executable file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ET_DYN               =  0x3   # Shared object file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ET_CORE              =  0x4   # Core file 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    # ELF file version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EV_NONE              =  0x0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EV_CURRENT           =  0x1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # ELF file machine type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EM_NONE              =  0x0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EM_XTENSA            =  0x5E 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # section types 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SEC_TYPE_PROGBITS    =  0x01 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SEC_TYPE_STRTAB      =  0x03 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # special section index 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SHN_UNDEF            =  0x0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # program segment types 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PT_NULL              =  0x0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PT_LOAD              =  0x1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PT_DYNAMIC           =  0x2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PT_INTERP            =  0x3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PT_NOTE              =  0x4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PT_SHLIB             =  0x5 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PT_PHDR              =  0x6 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  name = None ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for core dump ELF file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  name : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            super ( ESPCoreDumpElfFile ,  self ) . __init__ ( name ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . sections  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . program_segments  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            self . aux_segments  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            self . e_type  =  self . ET_NONE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . e_machine  =  self . EM_NONE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  _read_elf_file ( self ,  f ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Reads core dump from ELF file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        # read the ELF file header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        LEN_FILE_HEADER  =  0x34 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            header  =  f . read ( LEN_FILE_HEADER ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            ( ident , type , machine , _version , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             self . entrypoint , phoff , shoff , _flags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             _ehsize ,  phentsize , phnum , _shentsize , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								             shnum , shstrndx )  =  struct . unpack ( " <16sHHLLLLLHHHHHH " ,  header ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        except  struct . error  as  e : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpError ( " Failed to read a valid ELF header from  %s :  %s "  %  ( f . name ,  e ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  bytearray ( [ ident [ 0 ] ] )  !=  b ' \x7f '  or  ident [ 1 : 4 ]  !=  b ' ELF ' : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpError ( " %s  has invalid ELF magic header "  %  f . name ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  machine  !=  self . EM_XTENSA : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpError ( " %s  does not appear to be an Xtensa ELF file. e_machine= %04x "  %  ( f . name ,  machine ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        self . e_type  =  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . e_machine  =  machine 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . sections  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . program_segments  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . aux_segments  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  shnum  >  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . _read_sections ( f ,  shoff ,  shstrndx ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  phnum  >  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . _read_program_segments ( f ,  phoff ,  phentsize ,  phnum ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  _read_sections ( self ,  f ,  section_header_offs ,  shstrndx ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Reads core dump sections from ELF file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        f . seek ( section_header_offs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        section_header  =  f . read ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        LEN_SEC_HEADER  =  0x28 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  len ( section_header )  ==  0 : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpError ( " No section header found at offset  %04x  in ELF file. "  %  section_header_offs ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  len ( section_header )  %  LEN_SEC_HEADER  !=  0 : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . warning ( ' Unexpected ELF section header length  %04x  is not mod- %02x '  %  ( len ( section_header ) , LEN_SEC_HEADER ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # walk through the section header and extract all sections 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        section_header_offsets  =  range ( 0 ,  len ( section_header ) ,  LEN_SEC_HEADER ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        def  read_section_header ( offs ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            name_offs , sec_type , flags , lma , sec_offs , size  =  struct . unpack_from ( " <LLLLLL " ,  section_header [ offs : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ( name_offs ,  sec_type ,  flags ,  lma ,  size ,  sec_offs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        all_sections  =  [ read_section_header ( offs )  for  offs  in  section_header_offsets ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prog_sections  =  [ s  for  s  in  all_sections  if  s [ 1 ]  ==  esptool . ELFFile . SEC_TYPE_PROGBITS ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # search for the string table section 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  shstrndx  *  LEN_SEC_HEADER  in  section_header_offsets : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpError ( " ELF file has no STRTAB section at shstrndx  %d "  %  shstrndx ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        _ , sec_type , _ , _ , sec_size , sec_offs  =  read_section_header ( shstrndx  *  LEN_SEC_HEADER ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  sec_type  !=  esptool . ELFFile . SEC_TYPE_STRTAB : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . warning ( ' ELF file has incorrect STRTAB section type 0x %02x '  %  sec_type ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        f . seek ( sec_offs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        string_table  =  f . read ( sec_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # build the real list of ELFSections by reading the actual section names from the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # string table section, and actual data for each section from the ELF file itself 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        def  lookup_string ( offs ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raw  =  string_table [ offs : ] 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  raw [ : raw . index ( b ' \x00 ' ) ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        def  read_data ( offs , size ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . seek ( offs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  f . read ( size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        prog_sections  =  [ ESPCoreDumpSection ( lookup_string ( n_offs ) ,  lma ,  read_data ( offs ,  size ) ,  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         for  ( n_offs ,  _type ,  flags ,  lma ,  size ,  offs )  in  prog_sections  if  lma  !=  0 ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        self . sections  =  prog_sections 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  _read_program_segments ( self ,  f ,  seg_table_offs ,  entsz ,  num ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Reads core dump program segments from ELF file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        f . seek ( seg_table_offs ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        seg_table  =  f . read ( entsz  *  num ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        LEN_SEG_HEADER  =  0x20 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  len ( seg_table )  ==  0 : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpError ( " No program header table found at offset  %04x  in ELF file. "  %  seg_table_offs ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  len ( seg_table )  %  LEN_SEG_HEADER  !=  0 : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . warning ( ' Unexpected ELF program header table length  %04x  is not mod- %02x '  %  ( len ( seg_table ) , LEN_SEG_HEADER ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        # walk through the program segment table and extract all segments 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        seg_table_offs  =  range ( 0 ,  len ( seg_table ) ,  LEN_SEG_HEADER ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        def  read_program_header ( offs ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            type , offset , vaddr , _paddr , filesz , _memsz , flags , _align  =  struct . unpack_from ( " <LLLLLLLL " ,  seg_table [ offs : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ( type , offset , vaddr , filesz , flags ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        prog_segments  =  [ read_program_header ( offs )  for  offs  in  seg_table_offs ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # build the real list of ImageSegment by reading actual data for each segment from the ELF file itself 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        def  read_data ( offs , size ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . seek ( offs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  f . read ( size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # read loadable segments 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . program_segments  =  [ ESPCoreDumpSegment ( vaddr ,  read_data ( offset ,  filesz ) ,  type ,  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                 for  ( type ,  offset ,  vaddr ,  filesz , flags )  in  prog_segments  if  vaddr  !=  0 ] 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . aux_segments  =  [ ESPCoreDumpSegment ( vaddr ,  read_data ( offset ,  filesz ) ,  type ,  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             for  ( type ,  offset ,  vaddr ,  filesz ,  flags )  in  prog_segments  if  type  ==  ESPCoreDumpElfFile . PT_NOTE  and  vaddr  ==  0 ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  add_program_segment ( self ,  addr ,  data ,  type ,  flags ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Adds new program segment 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # TODO: currently merging with existing segments is not supported 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        data_sz  =  len ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # check for overlapping and merge if needed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  addr  !=  0  and  data_sz  !=  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ps  in  self . program_segments : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                seg_len  =  len ( ps . data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  addr  > =  ps . addr  and  addr  <  ( ps . addr  +  seg_len ) : 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    raise  ESPCoreDumpError ( " Can not add overlapping region [ %x .. %x ] to ELF file. Conflict with existing [ %x .. %x ]. "  % 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                           ( addr ,  addr  +  data_sz  -  1 ,  ps . addr ,  ps . addr  +  seg_len  -  1 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                if  ( addr  +  data_sz )  >  ps . addr  and  ( addr  +  data_sz )  < =  ( ps . addr  +  seg_len ) : 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    raise  ESPCoreDumpError ( " Can not add overlapping region [ %x .. %x ] to ELF file. Conflict with existing [ %x .. %x ]. "  % 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                           ( addr ,  addr  +  data_sz  -  1 ,  ps . addr ,  ps . addr  +  seg_len  -  1 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        # append 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . program_segments . append ( ESPCoreDumpSegment ( addr ,  data ,  type ,  flags ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  add_aux_segment ( self ,  data ,  type ,  flags ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Adds new note segment 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . aux_segments . append ( ESPCoreDumpSegment ( 0 ,  data ,  type ,  flags ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  write_program_headers ( self ,  f ,  off ,  segs ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  seg  in  segs : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr  =  Elf32ProgramHeader ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_type  =  seg . type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_offset  =  off 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_vaddr  =  seg . addr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_paddr  =  phdr . p_vaddr   # TODO 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_filesz  =  len ( seg . data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_memsz  =  phdr . p_filesz   # TODO 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_flags  =  seg . flags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            phdr . p_align  =  0   # TODO 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . write ( phdr . dump ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            off  + =  phdr . p_filesz 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  off 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    def  dump ( self ,  f ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Write core dump contents to file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # TODO: currently dumps only program segments. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # dumping sections is not supported yet 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        # write ELF header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr  =  Elf32FileHeader ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_type  =  self . e_type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_machine  =  self . e_machine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_entry  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_phoff  =  ehdr . sizeof ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_shoff  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_flags  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_phentsize  =  Elf32ProgramHeader ( ) . sizeof ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ehdr . e_phnum  =  len ( self . program_segments )  +  len ( self . aux_segments ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        ehdr . e_shentsize  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_shnum  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ehdr . e_shstrndx  =  self . SHN_UNDEF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        f . write ( ehdr . dump ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # write program header table 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cur_off  =  ehdr . e_ehsize  +  ehdr . e_phnum  *  ehdr . e_phentsize 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        cur_off  =  self . write_program_headers ( f ,  cur_off ,  self . program_segments ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cur_off  =  self . write_program_headers ( f ,  cur_off ,  self . aux_segments ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        # write program segments 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  segment  in  self . program_segments : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . write ( segment . data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # write aux program segments 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  segment  in  self . aux_segments : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . write ( segment . data ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ESPCoreDumpLoaderError ( ESPCoreDumpError ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ Core dump loader error class 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  message ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for core dump loader error 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        super ( ESPCoreDumpLoaderError ,  self ) . __init__ ( message ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ESPCoreDumpLoader ( object ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ Core dump loader base class 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ESP32_COREDUMP_VERSION_BIN  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_VERSION_ELF_CRC32  =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_VERSION_ELF_SHA256  =  3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP_CORE_DUMP_INFO_TYPE  =  8266 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP_CORE_DUMP_TASK_INFO_TYPE  =  678 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP_CORE_DUMP_EXTRA_INFO_TYPE  =  677 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP_COREDUMP_CURR_TASK_MARKER  =  0xdeadbeef 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_HDR_FMT  =  ' <5L ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_HDR_SZ  =  struct . calcsize ( ESP32_COREDUMP_HDR_FMT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_TSK_HDR_FMT  =  ' <3L ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_TSK_HDR_SZ  =  struct . calcsize ( ESP32_COREDUMP_TSK_HDR_FMT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_MEM_SEG_HDR_FMT  =  ' <2L ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_MEM_SEG_HDR_SZ  =  struct . calcsize ( ESP32_COREDUMP_MEM_SEG_HDR_FMT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_NOTE_HDR_FMT  =  ' <3L ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_NOTE_HDR_SZ  =  struct . calcsize ( ESP32_COREDUMP_NOTE_HDR_FMT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_CRC_FMT  =  ' <L ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_CRC_SZ  =  struct . calcsize ( ESP32_COREDUMP_CRC_FMT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_SHA256_FMT  =  ' 32c ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_SHA256_SZ  =  struct . calcsize ( ESP32_COREDUMP_SHA256_FMT ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __init__ ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Base constructor for core dump loader 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . fcore  =  None 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  _get_registers_from_stack ( self ,  data ,  grows_down ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Returns list of registers (in GDB format) from xtensa stack frame 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # from "gdb/xtensa-tdep.h" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # typedef struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # 0    xtensa_elf_greg_t pc; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 1    xtensa_elf_greg_t ps; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 2    xtensa_elf_greg_t lbeg; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 3    xtensa_elf_greg_t lend; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 4    xtensa_elf_greg_t lcount; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 5    xtensa_elf_greg_t sar; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 6    xtensa_elf_greg_t windowstart; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 7    xtensa_elf_greg_t windowbase; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 8..63 xtensa_elf_greg_t reserved[8+48]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # 64   xtensa_elf_greg_t ar[64]; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # } xtensa_elf_gregset_t; 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        REG_PC_IDX  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        REG_PS_IDX  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        REG_LB_IDX  =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        REG_LE_IDX  =  3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        REG_LC_IDX  =  4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        REG_SAR_IDX  =  5 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # REG_WS_IDX = 6 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # REG_WB_IDX = 7 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        REG_AR_START_IDX  =  64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # REG_AR_NUM = 64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # FIXME: acc to xtensa_elf_gregset_t number of regs must be 128, 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        # but gdb complanis when it less then 129 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        REG_NUM  =  129 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # XT_SOL_EXIT = 0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_SOL_PC  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_SOL_PS  =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # XT_SOL_NEXT = 3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_SOL_AR_START  =  4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_SOL_AR_NUM  =  4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # XT_SOL_FRMSZ = 8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_EXIT  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_PC  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_PS  =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_AR_START  =  3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_AR_NUM  =  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_SAR  =  19 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        XT_STK_EXCCAUSE  =  20 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_EXCVADDR  =  21 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        XT_STK_LBEG  =  22 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_LEND  =  23 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_LCOUNT  =  24 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        XT_STK_FRMSZ  =  25 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        extra_regs  =  { ESPCoreDumpElfFile . REG_EPS2_IDX :  0 ,  ESPCoreDumpElfFile . REG_EPS3_IDX :  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      ESPCoreDumpElfFile . REG_EPS4_IDX :  0 ,  ESPCoreDumpElfFile . REG_EPS5_IDX :  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      ESPCoreDumpElfFile . REG_EPS6_IDX :  0 ,  ESPCoreDumpElfFile . REG_EPS7_IDX :  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      ESPCoreDumpElfFile . REG_EPC1_IDX :  0 ,  ESPCoreDumpElfFile . REG_EPC2_IDX :  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      ESPCoreDumpElfFile . REG_EPC3_IDX :  0 ,  ESPCoreDumpElfFile . REG_EPC4_IDX :  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      ESPCoreDumpElfFile . REG_EPC5_IDX :  0 ,  ESPCoreDumpElfFile . REG_EPC6_IDX :  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      ESPCoreDumpElfFile . REG_EPC7_IDX :  0 } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        regs  =  [ 0 ]  *  REG_NUM 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # TODO: support for growing up stacks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  grows_down : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpLoaderError ( " Growing up stacks are not supported for now! " ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        ex_struct  =  " < %d L "  %  XT_STK_FRMSZ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  len ( data )  <  struct . calcsize ( ex_struct ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  ESPCoreDumpLoaderError ( " Too small stack to keep frame:  %d  bytes! "  %  len ( data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        stack  =  struct . unpack ( ex_struct ,  data [ : struct . calcsize ( ex_struct ) ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # Stack frame type indicator is always the first item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rc  =  stack [ XT_STK_EXIT ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  rc  !=  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_PC_IDX ]  =  stack [ XT_STK_PC ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_PS_IDX ]  =  stack [ XT_STK_PS ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  i  in  range ( XT_STK_AR_NUM ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                regs [ REG_AR_START_IDX  +  i ]  =  stack [ XT_STK_AR_START  +  i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_SAR_IDX ]  =  stack [ XT_STK_SAR ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_LB_IDX ]  =  stack [ XT_STK_LBEG ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_LE_IDX ]  =  stack [ XT_STK_LEND ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_LC_IDX ]  =  stack [ XT_STK_LCOUNT ] 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            # FIXME: crashed and some running tasks (e.g. prvIdleTask) have EXCM bit set 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            # and GDB can not unwind callstack properly (it implies not windowed call0) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  regs [ REG_PS_IDX ]  &  ( 1  <<  5 ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                regs [ REG_PS_IDX ]  & =  ~ ( 1  <<  4 ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  stack [ XT_STK_EXCCAUSE ]  in  xtensa_exception_cause_dict : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                extra_regs [ ESPCoreDumpElfFile . REG_EXCCAUSE_IDX ]  =  stack [ XT_STK_EXCCAUSE ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                extra_regs [ ESPCoreDumpElfFile . REG_EXCCAUSE_IDX ]  =  INVALID_CAUSE_VALUE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            extra_regs [ ESPCoreDumpElfFile . REG_EXCVADDR_IDX ]  =  stack [ XT_STK_EXCVADDR ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_PC_IDX ]  =  stack [ XT_SOL_PC ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            regs [ REG_PS_IDX ]  =  stack [ XT_SOL_PS ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  i  in  range ( XT_SOL_AR_NUM ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                regs [ REG_AR_START_IDX  +  i ]  =  stack [ XT_SOL_AR_START  +  i ] 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            # nxt = stack[XT_SOL_NEXT] 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  regs , extra_regs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  tcb_is_sane ( self ,  tcb_addr ,  tcb_size ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Check tcb address if it is correct 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  not  ( tcb_addr  <  0x3ffae000  or  ( tcb_addr  +  tcb_size )  >  0x40000000 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  stack_is_sane ( self ,  sp ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Check stack address if it is correct 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  not ( sp  <  0x3ffae010  or  sp  >  0x3fffffff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  addr_is_fake ( self ,  addr ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Check if address is in fake area 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ( ( addr  <  0x3f3fffff  and  addr  > =  0x20000000 )  or  addr  > =  0x80000000 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  remove_tmp_file ( self ,  fname ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Silently removes temporary file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            os . remove ( fname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        except  OSError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  e . errno  !=  errno . ENOENT : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                logging . warning ( " Failed to remove temp file  ' %s '  ( %d )! "  %  ( fname ,  e . errno ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    def  cleanup ( self ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Cleans up loader resources 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  self . fcore : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . fcore . close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  self . fcore_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                self . remove_tmp_file ( self . fcore_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  extract_elf_corefile ( self ,  core_fname = None ,  exe_name = None ,  off = 0 ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """  Reads the ELF formatted core dump image and parse it 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        core_off  =  off 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data  =  self . read_data ( core_off ,  self . ESP32_COREDUMP_HDR_SZ ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        tot_len , coredump_ver , task_num , tcbsz , segs_num  =  struct . unpack_from ( self . ESP32_COREDUMP_HDR_FMT ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  coredump_ver  ==  self . ESP32_COREDUMP_VERSION_ELF_CRC32 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            checksum_len  =  self . ESP32_COREDUMP_CRC_SZ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  coredump_ver  ==  self . ESP32_COREDUMP_VERSION_ELF_SHA256 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            checksum_len  =  self . ESP32_COREDUMP_SHA256_SZ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  ESPCoreDumpLoaderError ( " Core dump version  ' %d '  is not supported! "  %  coredump_ver ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        core_off  + =  self . ESP32_COREDUMP_HDR_SZ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        core_elf  =  ESPCoreDumpElfFile ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        data  =  self . read_data ( core_off ,  tot_len  -  checksum_len  -  self . ESP32_COREDUMP_HDR_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        with  open ( core_fname ,  ' w+b ' )  as  fce : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            try : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                fce . write ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fce . flush ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fce . seek ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_elf . _read_elf_file ( fce ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  exe_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    exe_elf  =  ESPCoreDumpElfFile ( exe_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # Read note segments from core file which are belong to tasks (TCB or stack) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ns  in  core_elf . aux_segments : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ns . type  !=  ESPCoreDumpElfFile . PT_NOTE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    note_read  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    while  note_read  <  len ( ns . data ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        note  =  Elf32NoteDesc ( " " ,  0 ,  None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        note_read  + =  note . read ( ns . data [ note_read : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        # Check for version info note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ' ESP_CORE_DUMP_INFO '  ==  note . name  and  note . type  ==  self . ESP_CORE_DUMP_INFO_TYPE  and  exe_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            app_sha256  =  binascii . hexlify ( exe_elf . sha256 ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            n_ver_len  =  struct . calcsize ( " <L " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            n_sha256_len  =  self . ESP32_COREDUMP_SHA256_SZ  *  2   # SHA256 as hex string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            n_ver , coredump_sha256  =  struct . unpack ( " <L %d s "  %  ( n_sha256_len ) ,  note . desc [ : n_ver_len  +  n_sha256_len ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  coredump_sha256  !=  app_sha256  or  n_ver  !=  coredump_ver : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                raise  ESPCoreDumpError ( " Invalid application image for coredump: app_SHA256( %s ) != coredump_SHA256( %s ). "  % 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                       ( app_sha256 ,  coredump_sha256 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                logging . warning ( " Failed to extract ELF core dump image into file  %s . (Reason:  %s ) "  %  ( core_fname ,  e ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  core_fname 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  create_corefile ( self ,  core_fname = None ,  exe_name = None ,  rom_elf = None ,  off = 0 ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Creates core dump ELF file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        core_off  =  off 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data  =  self . read_data ( core_off ,  self . ESP32_COREDUMP_HDR_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tot_len , coredump_ver , task_num , tcbsz , segs_num  =  struct . unpack_from ( self . ESP32_COREDUMP_HDR_FMT ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  core_fname : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fce  =  tempfile . NamedTemporaryFile ( mode = ' w+b ' ,  delete = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            core_fname  =  fce . name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  coredump_ver  ==  self . ESP32_COREDUMP_VERSION_ELF_CRC32  or  coredump_ver  ==  self . ESP32_COREDUMP_VERSION_ELF_SHA256 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . extract_elf_corefile ( core_fname ,  exe_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  coredump_ver  >  self . ESP32_COREDUMP_VERSION_ELF_SHA256 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  ESPCoreDumpLoaderError ( " Core dump version  ' %d '  is not supported! Should be up to  ' %d ' . "  % 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                         ( coredump_ver ,  self . ESP32_COREDUMP_VERSION_ELF_SHA256 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        with  open ( core_fname ,  ' w+b ' )  as  fce : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tcbsz_aligned  =  tcbsz 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  tcbsz_aligned  %  4 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tcbsz_aligned  =  4  *  ( old_div ( tcbsz_aligned , 4 )  +  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # The version of core dump is ESP32_COREDUMP_VERSION_BIN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            core_off  + =  self . ESP32_COREDUMP_HDR_SZ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            core_elf  =  ESPCoreDumpElfFile ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            notes  =  b ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            core_dump_info_notes  =  b ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            task_info_notes  =  b ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            task_status  =  EspCoreDumpTaskStatus ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  i  in  range ( task_num ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_status . task_index  =  i 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_status . task_flags  =  EspCoreDumpTaskStatus . TASK_STATUS_CORRECT 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                data  =  self . read_data ( core_off ,  self . ESP32_COREDUMP_TSK_HDR_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tcb_addr , stack_top , stack_end  =  struct . unpack_from ( self . ESP32_COREDUMP_TSK_HDR_FMT ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  stack_end  >  stack_top : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    stack_len  =  stack_end  -  stack_top 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    stack_base  =  stack_top 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    stack_len  =  stack_top  -  stack_end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    stack_base  =  stack_end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                stack_len_aligned  =  stack_len 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  stack_len_aligned  %  4 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    stack_len_aligned  =  4  *  ( old_div ( stack_len_aligned , 4 )  +  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_off  + =  self . ESP32_COREDUMP_TSK_HDR_SZ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . debug ( " Read TCB  %d  bytes @ 0x %x "  %  ( tcbsz_aligned ,  tcb_addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                data  =  self . read_data ( core_off ,  tcbsz_aligned ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_status . task_tcb_addr  =  tcb_addr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  self . tcb_is_sane ( tcb_addr ,  tcbsz_aligned ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  tcbsz  !=  tcbsz_aligned : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            core_elf . add_program_segment ( tcb_addr ,  data [ : tcbsz  -  tcbsz_aligned ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                         ESPCoreDumpElfFile . PT_LOAD ,  ESPCoreDumpSegment . PF_R  |  ESPCoreDumpSegment . PF_W ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            core_elf . add_program_segment ( tcb_addr ,  data ,  ESPCoreDumpElfFile . PT_LOAD ,  ESPCoreDumpSegment . PF_R  |  ESPCoreDumpSegment . PF_W ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        # task_status.task_name = bytearray("%s\0" % task_name_str, encoding='ascii') 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    elif  tcb_addr  and  self . addr_is_fake ( tcb_addr ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        task_status . task_flags  | =  EspCoreDumpTaskStatus . TASK_STATUS_TCB_CORRUPTED 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    logging . warning ( " Skip TCB  %d  bytes @ 0x %x . (Reason:  %s ) "  %  ( tcbsz_aligned ,  tcb_addr ,  e ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_off  + =  tcbsz_aligned 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . debug ( " Read stack  %d  bytes @ 0x %x "  %  ( stack_len_aligned ,  stack_base ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                data  =  self . read_data ( core_off ,  stack_len_aligned ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  stack_len  !=  stack_len_aligned : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    data  =  data [ : stack_len  -  stack_len_aligned ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_status . task_stack_start  =  stack_base 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_status . task_stack_len  =  stack_len_aligned 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  self . stack_is_sane ( stack_base ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        core_elf . add_program_segment ( stack_base ,  data ,  ESPCoreDumpElfFile . PT_LOAD ,  ESPCoreDumpSegment . PF_R  |  ESPCoreDumpSegment . PF_W ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    elif  stack_base  and  self . addr_is_fake ( stack_base ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        task_status . task_flags  | =  EspCoreDumpTaskStatus . TASK_STATUS_STACK_CORRUPTED 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        core_elf . add_program_segment ( stack_base ,  data ,  ESPCoreDumpElfFile . PT_LOAD ,  ESPCoreDumpSegment . PF_R  |  ESPCoreDumpSegment . PF_W ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    logging . warning ( " Skip task ' s ( %x ) stack  %d  bytes @ 0x %x . (Reason:  %s ) "  %  ( tcb_addr ,  stack_len_aligned ,  stack_base ,  e ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_off  + =  stack_len_aligned 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    logging . debug ( " Stack start_end: 0x %x  @ 0x %x "  %  ( stack_top ,  stack_end ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    task_regs , extra_regs  =  self . _get_registers_from_stack ( data ,  stack_end  >  stack_top ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                except  Exception  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    logging . error ( e ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_info_notes  + =  Elf32NoteDesc ( " TASK_INFO " ,  self . ESP_CORE_DUMP_TASK_INFO_TYPE ,  task_status . dump ( ) ) . dump ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                prstatus  =  XtensaPrStatus ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                prstatus . pr_cursig  =  0   # TODO: set sig only for current/failed task 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                prstatus . pr_pid  =  tcb_addr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                note  =  Elf32NoteDesc ( " CORE " ,  1 ,  prstatus . dump ( )  +  struct . pack ( " < %d L "  %  len ( task_regs ) ,  * task_regs ) ) . dump ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                notes  + =  note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ESPCoreDumpElfFile . REG_EXCCAUSE_IDX  in  extra_regs  and  len ( core_dump_info_notes )  ==  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # actually there will be only one such note - for crashed task 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    core_dump_info_notes  + =  Elf32NoteDesc ( " ESP_CORE_DUMP_INFO " ,  self . ESP_CORE_DUMP_INFO_TYPE ,  struct . pack ( " <L " ,  coredump_ver ) ) . dump ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    exc_regs  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    for  reg_id  in  extra_regs : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        exc_regs . extend ( [ reg_id ,  extra_regs [ reg_id ] ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    core_dump_info_notes  + =  Elf32NoteDesc ( " EXTRA_INFO " ,  self . ESP_CORE_DUMP_EXTRA_INFO_TYPE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                          struct . pack ( " < %d L "  %  ( 1  +  len ( exc_regs ) ) ,  tcb_addr ,  * exc_regs ) ) . dump ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  i  in  range ( segs_num ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                data  =  self . read_data ( core_off ,  self . ESP32_COREDUMP_MEM_SEG_HDR_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_off  + =  self . ESP32_COREDUMP_MEM_SEG_HDR_SZ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                mem_start , mem_sz  =  struct . unpack_from ( self . ESP32_COREDUMP_MEM_SEG_HDR_FMT ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . debug ( " Read memory segment  %d  bytes @ 0x %x "  %  ( mem_sz ,  mem_start ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                data  =  self . read_data ( core_off ,  stack_len_aligned ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_elf . add_program_segment ( mem_start ,  data ,  ESPCoreDumpElfFile . PT_LOAD ,  ESPCoreDumpSegment . PF_R  |  ESPCoreDumpSegment . PF_W ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_off  + =  mem_sz 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # add notes 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            try : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                core_elf . add_aux_segment ( notes ,  ESPCoreDumpElfFile . PT_NOTE ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                logging . warning ( " Skip NOTES segment  %d  bytes @ 0x %x . (Reason:  %s ) "  %  ( len ( notes ) ,  0 ,  e ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # add core dump info notes 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            try : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                core_elf . add_aux_segment ( core_dump_info_notes ,  ESPCoreDumpElfFile . PT_NOTE ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . warning ( " Skip core dump info NOTES segment  %d  bytes @ 0x %x . (Reason:  %s ) "  %  ( len ( core_dump_info_notes ) ,  0 ,  e ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                core_elf . add_aux_segment ( task_info_notes ,  ESPCoreDumpElfFile . PT_NOTE ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . warning ( " Skip failed tasks info NOTES segment  %d  bytes @ 0x %x . (Reason:  %s ) "  %  ( len ( task_info_notes ) ,  0 ,  e ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # add ROM text sections 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  rom_elf : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ps  in  rom_elf . program_segments : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ps . flags  &  ESPCoreDumpSegment . PF_X : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            core_elf . add_program_segment ( ps . addr ,  ps . data ,  ESPCoreDumpElfFile . PT_LOAD ,  ps . flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            logging . warning ( " Skip ROM segment  %d  bytes @ 0x %x . (Reason:  %s ) "  %  ( len ( ps . data ) ,  ps . addr ,  e ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            core_elf . e_type  =  ESPCoreDumpElfFile . ET_CORE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            core_elf . e_machine  =  ESPCoreDumpElfFile . EM_XTENSA 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            core_elf . dump ( fce ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  core_fname 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  read_data ( self ,  off ,  sz ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Reads data from raw core dump got from flash or UART 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . fcore . seek ( off ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data  =  self . fcore . read ( sz ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ESPCoreDumpFileLoader ( ESPCoreDumpLoader ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ Core dump file loader class 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __init__ ( self ,  path ,  b64 = False ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for core dump file loader 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        super ( ESPCoreDumpFileLoader ,  self ) . __init__ ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . fcore  =  self . _load_coredump ( path ,  b64 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  _load_coredump ( self ,  path ,  b64 ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Loads core dump from (raw binary or base64-encoded) file 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        logging . debug ( " Load core dump from  ' %s ' " ,  path ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . fcore_name  =  None 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  b64 : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fhnd , self . fcore_name  =  tempfile . mkstemp ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fcore  =  os . fdopen ( fhnd ,  ' wb ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fb64  =  open ( path ,  ' rb ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                while  True : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    line  =  fb64 . readline ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  len ( line )  ==  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        break 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    data  =  base64 . standard_b64decode ( line . rstrip ( b ' \r \n ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    fcore . write ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fcore . close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                fcore  =  open ( self . fcore_name ,  ' rb ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            except  Exception  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  self . fcore_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    self . remove_tmp_file ( self . fcore_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    raise  e 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            finally : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fb64 . close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fcore  =  open ( path ,  ' rb ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  fcore 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ESPCoreDumpFlashLoader ( ESPCoreDumpLoader ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ Core dump flash loader class 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-13 21:30:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ESP32_COREDUMP_FLASH_LEN_FMT     =  ' <L ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP32_COREDUMP_FLASH_LEN_SZ      =  struct . calcsize ( ESP32_COREDUMP_FLASH_LEN_FMT ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ESP32_COREDUMP_PART_TABLE_OFF    =  0x8000 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  off ,  tool_path = None ,  chip = ' esp32 ' ,  port = None ,  baud = None ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for core dump flash loader 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        super ( ESPCoreDumpFlashLoader ,  self ) . __init__ ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . port  =  port 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . baud  =  baud 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . chip  =  chip 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . dump_sz  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . fcore  =  self . _load_coredump ( off ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  get_tool_path ( self ,  use_esptool = None ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Get tool path 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  use_esptool : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tool_path  =  os . path . join ( idf_path ,  ' components ' ,  ' esptool_py ' ,  ' esptool ' )  +  os . path . sep 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tool_path  =  os . path . join ( idf_path ,  ' components ' ,  ' partition_table ' )  +  os . path . sep 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  tool_path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  get_core_dump_partition_info ( self ,  part_off = None ,  tool_path = None ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Get core dump partition info using parttool 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        logging . info ( " Retrieving core dump partition offset and size... " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  tool_path : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tool_path  =  self . get_tool_path ( use_esptool = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  part_off : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            part_off  =  self . ESP32_COREDUMP_PART_TABLE_OFF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        size  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        offset  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tool_args  =  [ sys . executable ,  tool_path  +  ' parttool.py ' ,  " -q " ,  " --partition-table-offset " ,  str ( part_off ) ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  self . port : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tool_args . extend ( [ ' --port ' ,  self . port ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            invoke_args  =  tool_args  +  [ " get_partition_info " ,  " --partition-type " ,  " data " ,  " --partition-subtype " ,  " coredump " ,  " --info " ,  " offset " ,  " size " ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( offset_str ,  size_str )  =  subprocess . check_output ( invoke_args ) . strip ( ) . split ( b "   " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            size  =  int ( size_str ,  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            offset  =  int ( offset_str ,  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . info ( " Core dump partition offset= %d , size= %d " ,  offset ,  size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        except  subprocess . CalledProcessError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . error ( " parttool get partition info failed with err  %d "  %  e . returncode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( " Command ran:  ' %s ' "  %  e . cmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( " Command out: " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( e . output ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . error ( " Check if the coredump partition exists in partition table. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  e 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ( offset ,  size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  invoke_parttool ( self ,  tool_path = None ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Loads core dump from flash using parttool 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        part_tool_args  =  [ sys . executable ,  tool_path  +  ' parttool.py ' ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . port : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            part_tool_args . extend ( [ ' --port ' ,  self . port ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        part_tool_args . extend ( [ ' read_partition ' ,  ' --partition-type ' ,  ' data ' ,  ' --partition-subtype ' ,  ' coredump ' ,  ' --output ' ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . fcore_name  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        f  =  tempfile . NamedTemporaryFile ( mode = ' w+b ' ,  delete = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            part_tool_args . append ( f . name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . fcore_name  =  f . name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # read core dump partition 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            et_out  =  subprocess . check_output ( part_tool_args ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  len ( et_out ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . info ( et_out . decode ( ' utf-8 ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . dump_sz  =  self . _read_core_dump_length ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . seek ( self . dump_sz ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # cut free space of the partition 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . truncate ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f . seek ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        except  subprocess . CalledProcessError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . error ( " parttool script execution failed with err  %d "  %  e . returncode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( " Command ran:  ' %s ' "  %  e . cmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( " Command out: " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( e . output ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  self . fcore_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                f . close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                self . remove_tmp_file ( self . fcore_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  e 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  invoke_esptool ( self ,  tool_path = None ,  off = None ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Loads core dump from flash using elftool 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        tool_args  =  [ sys . executable ,  tool_path  +  ' esptool.py ' ,  ' -c ' ,  self . chip ] 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  self . port : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            tool_args . extend ( [ ' -p ' ,  self . port ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  self . baud : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            tool_args . extend ( [ ' -b ' ,  str ( self . baud ) ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        f  =  tempfile . NamedTemporaryFile ( mode = ' w+b ' ,  delete = False ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . fcore_name  =  None 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        try : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ( part_offset ,  part_size )  =  self . get_core_dump_partition_info ( tool_path = ' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  not  off : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                off  =  part_offset   # set default offset if not specified 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . warning ( " The core dump image offset is not specified. Use partition offset:  %d . " ,  part_offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  part_offset  !=  off : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . warning ( " Predefined image offset:  %d  does not match core dump partition offset:  %d " ,  off ,  part_offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tool_args . extend ( [ ' read_flash ' ,  str ( off ) ,  str ( self . ESP32_COREDUMP_FLASH_LEN_SZ ) ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tool_args . append ( f . name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . fcore_name  =  f . name 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            # read core dump length 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            et_out  =  subprocess . check_output ( tool_args ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  len ( et_out ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . info ( et_out . decode ( ' utf-8 ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            self . dump_sz  =  self . _read_core_dump_length ( f ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  self . dump_sz  ==  0  or  self . dump_sz  >  part_size : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . error ( " Incorrect size of core dump image:  %d , use partition size instead:  %d " ,  self . dump_sz ,  part_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                self . dump_sz  =  part_size 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # set actual size of core dump image and read it from flash 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tool_args [ - 2 ]  =  str ( self . dump_sz ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            et_out  =  subprocess . check_output ( tool_args ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  len ( et_out ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . info ( et_out . decode ( ' utf-8 ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        except  subprocess . CalledProcessError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . error ( " esptool script execution failed with err  %d "  %  e . returncode ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . debug ( " Command ran:  ' %s ' "  %  e . cmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( " Command out: " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( e . output ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  self . fcore_name : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                f . close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                self . remove_tmp_file ( self . fcore_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            raise  e 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  _load_coredump ( self ,  off = None ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Loads core dump from flash using parttool or elftool (if offset is set) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tool_path  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  off : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tool_path  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . info ( " Invoke esptool to read image. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                f  =  self . invoke_esptool ( tool_path = tool_path ,  off = off ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tool_path  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . info ( " Invoke parttool to read image. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                f  =  self . invoke_parttool ( tool_path = tool_path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        except  subprocess . CalledProcessError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  len ( e . output ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . info ( e . output ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . warning ( " System path is not set. Try to use predefined path. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  off : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tool_path  =  self . get_tool_path ( use_esptool = True ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                f  =  self . invoke_esptool ( tool_path = tool_path ,  off = off ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                tool_path  =  self . get_tool_path ( use_esptool = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                f  =  self . invoke_parttool ( tool_path = tool_path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  _read_core_dump_length ( self ,  f ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Reads core dump length 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-13 21:30:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        data  =  f . read ( self . ESP32_COREDUMP_FLASH_LEN_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tot_len ,  =  struct . unpack_from ( self . ESP32_COREDUMP_FLASH_LEN_FMT ,  data ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  tot_len 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  create_corefile ( self ,  core_fname = None ,  exe_name = None ,  rom_elf = None ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Checks flash coredump data integrity and creates ELF file 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        data  =  self . read_data ( 0 ,  self . ESP32_COREDUMP_HDR_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . checksum_len  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        _ , coredump_ver , _ , _ , _  =  struct . unpack_from ( self . ESP32_COREDUMP_HDR_FMT ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  coredump_ver  ==  self . ESP32_COREDUMP_VERSION_ELF_CRC32  or  coredump_ver  ==  self . ESP32_COREDUMP_VERSION_BIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( " Dump size =  %d , crc off = 0x %x " ,  self . dump_sz ,  self . dump_sz  -  self . ESP32_COREDUMP_CRC_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data  =  self . read_data ( self . dump_sz  -  self . ESP32_COREDUMP_CRC_SZ ,  self . ESP32_COREDUMP_CRC_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dump_crc ,  =  struct . unpack_from ( self . ESP32_COREDUMP_CRC_FMT ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data  =  self . read_data ( 0 ,  self . dump_sz  -  self . ESP32_COREDUMP_CRC_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data_crc  =  binascii . crc32 ( data )  &  0xffffffff 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  dump_crc  !=  data_crc : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                raise  ESPCoreDumpLoaderError ( " Invalid core dump CRC  %x , should be  %x "  %  ( data_crc ,  dump_crc ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  coredump_ver  ==  self . ESP32_COREDUMP_VERSION_ELF_SHA256 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dump_sha256  =  self . read_data ( self . dump_sz  -  self . ESP32_COREDUMP_SHA256_SZ ,  self . ESP32_COREDUMP_SHA256_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data  =  self . read_data ( 0 ,  self . dump_sz  -  self . ESP32_COREDUMP_SHA256_SZ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data_sha256  =  sha256 ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data_sha256_str  =  data_sha256 . hexdigest ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dump_sha256_str  =  binascii . hexlify ( dump_sha256 ) . decode ( ' ascii ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  dump_sha256_str  !=  data_sha256_str : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                raise  ESPCoreDumpLoaderError ( " Invalid core dump SHA256  ' %s ' , should be  ' %s ' "  %  ( dump_sha256_str ,  data_sha256_str ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  super ( ESPCoreDumpFlashLoader ,  self ) . create_corefile ( core_fname ,  exe_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								class  GDBMIOutRecordHandler ( object ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ GDB/MI output record handler base class 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TAG  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  f ,  verbose = False ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Base constructor for GDB/MI output record handler 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        self . verbose  =  verbose 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  execute ( self ,  ln ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Base method to execute GDB/MI output record handler function 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  self . verbose : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . debug ( " %s .execute: [[ %s ]] "  %  ( self . __class__ . __name__ ,  ln ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  GDBMIOutStreamHandler ( GDBMIOutRecordHandler ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ GDB/MI output stream handler class 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  f ,  verbose = False ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for GDB/MI output stream handler 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        super ( GDBMIOutStreamHandler ,  self ) . __init__ ( None ,  verbose ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . func  =  f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  execute ( self ,  ln ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Executes GDB/MI output stream handler function 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        GDBMIOutRecordHandler . execute ( self ,  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . func : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # remove TAG / quotes and replace c-string \n with actual NL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . func ( ln [ 1 : ] . strip ( ' " ' ) . replace ( ' \\ n ' ,  ' \n ' ) . replace ( ' \\ t ' ,  ' \t ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  GDBMIResultHandler ( GDBMIOutRecordHandler ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ GDB/MI result handler class 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TAG  =  ' ^ ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RC_DONE  =  ' done ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RC_RUNNING  =  ' running ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RC_CONNECTED  =  ' connected ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RC_ERROR  =  ' error ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RC_EXIT  =  ' exit ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  verbose = False ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Constructor for GDB/MI result handler 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        super ( GDBMIResultHandler ,  self ) . __init__ ( None ,  verbose ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . result_class  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . result_str  =  ' ' 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  _parse_rc ( self ,  ln ,  rc ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Parses result code 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        rc_str  =  " {0} {1} " . format ( self . TAG ,  rc ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  not  ln . startswith ( rc_str ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  False 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . result_class  =  rc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  len ( ln )  >  len ( rc_str ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . result_str  =  ln [ len ( rc_str ) : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  self . result_str . startswith ( ' , ' ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                self . result_str  =  self . result_str [ 1 : ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                logging . error ( " Invalid result format:  ' %s ' "  %  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . result_str  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  True 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  execute ( self ,  ln ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ Executes GDB/MI result handler function 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        GDBMIOutRecordHandler . execute ( self ,  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . _parse_rc ( ln ,  self . RC_DONE ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . _parse_rc ( ln ,  self . RC_RUNNING ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . _parse_rc ( ln ,  self . RC_CONNECTED ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . _parse_rc ( ln ,  self . RC_ERROR ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . _parse_rc ( ln ,  self . RC_EXIT ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        logging . error ( " Unknown GDB/MI result:  ' %s ' "  %  ln ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  GDBMIThreadListIdsHandler ( GDBMIResultHandler ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ GDB/MI thread-list-ids handler class 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  verbose = False ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Constructor for GDB/MI result handler 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        super ( GDBMIThreadListIdsHandler ,  self ) . __init__ ( verbose ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . threads  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . current_thread  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  execute ( self ,  ln ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Executes GDB/MI thread-list-ids handler function 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        GDBMIResultHandler . execute ( self ,  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . result_class  !=  self . RC_DONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # simple parsing method 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  re . search ( r ' thread-ids \ s*= \ s* \ { ([^ \ { \ }]*) \ } ' ,  self . result_str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  result : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  tid  in  re . finditer ( r ' thread-id= " ( \ d+) " ' ,  result . group ( 1 ) ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                self . threads . append ( tid . group ( 1 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  re . search ( r ' current-thread-id= " ( \ d+) " ' ,  self . result_str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  result : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . current_thread  =  result . group ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  GDBMIThreadSelectHandler ( GDBMIResultHandler ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ GDB/MI thread-select handler class 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  execute ( self ,  ln ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Executes GDB/MI thread-select handler function 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        GDBMIResultHandler . execute ( self ,  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . result_class  !=  self . RC_DONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  GDBMIThreadInfoHandler ( GDBMIResultHandler ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ GDB/MI thread-info handler class 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  verbose = False ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Constructor for GDB/MI result handler 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        super ( GDBMIThreadInfoHandler ,  self ) . __init__ ( verbose ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . current  =  False 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . id  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . target_id  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . details  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . name  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . frame  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . state  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . core  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  execute ( self ,  ln ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Executes GDB/MI thread-info  handler function 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        GDBMIResultHandler . execute ( self ,  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . result_class  !=  self . RC_DONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # simple parsing method 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  re . search ( r ' id= " ( \ d+) " ' ,  self . result_str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  result : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . id  =  result . group ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  re . search ( r ' current= " \ * " ' ,  self . result_str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  result : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . current  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  re . search ( r ' target-id= " ([^ " ]+) " ' ,  self . result_str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  result : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . target_id  =  result . group ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  GDBMIDataEvalHandler ( GDBMIResultHandler ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ GDB/MI data-evaluate-expression handler class 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  verbose = False ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Constructor for GDB/MI result handler 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        super ( GDBMIDataEvalHandler ,  self ) . __init__ ( verbose ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . value  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  execute ( self ,  ln ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ Executes GDB/MI data-evaluate-expression handler function 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        GDBMIResultHandler . execute ( self ,  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . result_class  !=  self . RC_DONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # simple parsing method 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  self . verbose : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            logging . debug ( " GDBMIDataEvalHandler: result  ' %s ' " ,  self . result_str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pos  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        r  =  re . compile ( r ' ([a-zA-Z_]+)=(.+) \ , ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  True : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m  =  r . search ( self . result_str ,  pos = pos ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  not  m : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  m . group ( 1 )  ==  ' value ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  self . verbose : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    logging . debug ( " GDBMIDataEvalHandler: found value =  ' %s ' " ,  m . group ( 2 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                self . value  =  self . result . group ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            pos  =  m . end ( 2 )  +  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        res_str  =  self . result_str [ pos : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        res_str  =  res_str . replace ( r ' \ " ' ,  ' \' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m  =  re . search ( r ' value= " ([^ " ]+) " ' ,  res_str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  m : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  self . verbose : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                logging . debug ( " GDBMIDataEvalHandler: found value =  ' %s ' " ,  m . group ( 1 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . value  =  m . group ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								class  GDBMIStreamConsoleHandler ( GDBMIOutStreamHandler ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ GDB/MI console stream handler class 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TAG  =  ' ~ ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  load_aux_elf ( elf_path ) :  
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """  Loads auxilary ELF file and composes GDB command to read its symbols 
 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elf  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sym_cmd  =  ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  os . path . exists ( elf_path ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elf  =  ESPCoreDumpElfFile ( elf_path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  s  in  elf . sections : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  s . name  ==  ' .text ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                sym_cmd  =  ' add-symbol-file  %s  0x %x '  %  ( elf_path ,  s . addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( elf ,  sym_cmd ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								def  dbg_corefile ( args ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """  Command to load core dump from file or flash and run GDB debug session with it 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    global  CLOSE_FDS 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    loader  =  None 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    rom_elf , rom_sym_cmd  =  load_aux_elf ( args . rom_elf ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  not  args . core : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        loader  =  ESPCoreDumpFlashLoader ( args . off ,  port = args . port ,  baud = args . baud ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        core_fname  =  loader . create_corefile ( args . save_core ,  exe_name = args . prog ,  rom_elf = rom_elf ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  not  core_fname : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . error ( " Failed to create corefile! " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            loader . cleanup ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        core_fname  =  args . core 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  args . core_format  and  args . core_format  !=  ' elf ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            loader  =  ESPCoreDumpFileLoader ( core_fname ,  args . core_format  ==  ' b64 ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            core_fname  =  loader . create_corefile ( args . save_core ,  exe_name = args . prog ,  rom_elf = rom_elf ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  not  core_fname : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                logging . error ( " Failed to create corefile! " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                loader . cleanup ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p  =  subprocess . Popen ( bufsize = 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         args = [ args . gdb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                               ' --nw ' ,   # ignore .gdbinit 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                               ' --core= %s '  %  core_fname ,   # core file, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                               ' -ex ' ,  rom_sym_cmd , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                               args . prog 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                               ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         stdin = None ,  stdout = None ,  stderr = None , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         close_fds = CLOSE_FDS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                         ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    p . wait ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  loader : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  not  args . core  and  not  args . save_core : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            loader . remove_tmp_file ( core_fname ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        loader . cleanup ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( ' Done! ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  info_corefile ( args ) :  
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """  Command to load core dump from file or flash and print it ' s data in user friendly form 
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    global  CLOSE_FDS 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    def  gdbmi_console_stream_handler ( ln ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        sys . stdout . write ( ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        sys . stdout . flush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    def  gdbmi_read2prompt ( f ,  out_handlers = None ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  True : 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ln  =  f . readline ( ) . decode ( ' utf-8 ' ) . rstrip ( '   \r \n ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ln  ==  ' (gdb) ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            elif  len ( ln )  ==  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            elif  out_handlers : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  h  in  out_handlers : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ln . startswith ( out_handlers [ h ] . TAG ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        out_handlers [ h ] . execute ( ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  gdbmi_start ( handlers ,  gdb_cmds ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gdb_args  =  [ args . gdb , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    ' --quiet ' ,   # inhibit dumping info at start-up 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ' --nx ' ,   # inhibit window interface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ' --nw ' ,   # ignore .gdbinit 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ' --interpreter=mi2 ' ,   # use GDB/MI v2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ' --core= %s '  %  core_fname ]   # core file 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  c  in  gdb_cmds : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            gdb_args  + =  [ ' -ex ' ,  c ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gdb_args . append ( args . prog ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        p  =  subprocess . Popen ( bufsize = 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             args = gdb_args , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             stdin = subprocess . PIPE ,  stdout = subprocess . PIPE ,  stderr = subprocess . STDOUT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             close_fds = CLOSE_FDS ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        gdbmi_read2prompt ( p . stdout ,  handlers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  gdbmi_cmd_exec ( p ,  handlers ,  gdbmi_cmd ) : 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  t  in  handlers : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handlers [ t ] . result_class  =  None 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        p . stdin . write ( bytearray ( " %s \n "  %  gdbmi_cmd ,  encoding = ' utf-8 ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        gdbmi_read2prompt ( p . stdout ,  handlers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  handlers [ GDBMIResultHandler . TAG ] . result_class  or  handlers [ GDBMIResultHandler . TAG ] . result_class  ==  GDBMIResultHandler . RC_EXIT : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . error ( " GDB exited ( %s  /  %s )! "  %  ( handlers [ GDBMIResultHandler . TAG ] . result_class ,  handlers [ GDBMIResultHandler . TAG ] . result_str ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            p . wait ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . error ( " Problem occured! GDB exited, restart it. " ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            p  =  gdbmi_start ( handlers ,  [ ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  handlers [ GDBMIResultHandler . TAG ] . result_class  !=  GDBMIResultHandler . RC_DONE : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . error ( " GDB/MI command failed ( %s  /  %s )! "  %  ( handlers [ GDBMIResultHandler . TAG ] . result_class ,  handlers [ GDBMIResultHandler . TAG ] . result_str ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  gdbmi_getinfo ( p ,  handlers ,  gdb_cmd ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  gdbmi_cmd_exec ( p ,  handlers ,  " -interpreter-exec console  \" %s \" "  %  gdb_cmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  gdbmi_get_thread_ids ( p ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  GDBMIThreadListIdsHandler ( verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIResultHandler . TAG ]  =  result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIStreamConsoleHandler . TAG ]  =  GDBMIStreamConsoleHandler ( None ,  verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p  =  gdbmi_cmd_exec ( p ,  handlers ,  " -thread-list-ids " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  p , result . threads , result . current_thread 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  gdbmi_switch_thread ( p ,  thr_id ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  GDBMIThreadSelectHandler ( verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIResultHandler . TAG ]  =  result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIStreamConsoleHandler . TAG ]  =  GDBMIStreamConsoleHandler ( None ,  verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  gdbmi_cmd_exec ( p ,  handlers ,  " -thread-select  %s "  %  thr_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  gdbmi_get_thread_info ( p ,  thr_id ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  GDBMIThreadInfoHandler ( verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIResultHandler . TAG ]  =  result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIStreamConsoleHandler . TAG ]  =  GDBMIStreamConsoleHandler ( None ,  verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  thr_id : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cmd  =  " -thread-info  %s "  %  thr_id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cmd  =  " -thread-info " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p  =  gdbmi_cmd_exec ( p ,  handlers ,  cmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  p , result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  gdbmi_data_evaluate_expression ( p ,  expr ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  GDBMIDataEvalHandler ( verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIResultHandler . TAG ]  =  result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handlers [ GDBMIStreamConsoleHandler . TAG ]  =  GDBMIStreamConsoleHandler ( None ,  verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p  =  gdbmi_cmd_exec ( p ,  handlers ,  " -data-evaluate-expression  \" %s \" "  %  expr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  p , result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  gdbmi_freertos_get_task_name ( p ,  tcb_addr ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p , res  =  gdbmi_data_evaluate_expression ( p ,  " (char*)((TCB_t *)0x %x )->pcTaskName "  %  tcb_addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result  =  re . match ( ' 0x[a-fA-F0-9]+[  \t ]* \' ([^ \' ]*) \' ' ,  res . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  result : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  p , result . group ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  p , ' ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  gdb2freertos_thread_id ( gdb_thread_id ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( gdb_thread_id . replace ( " process  " ,  " " ) ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    loader  =  None 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    rom_elf , rom_sym_cmd  =  load_aux_elf ( args . rom_elf ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  not  args . core : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        loader  =  ESPCoreDumpFlashLoader ( args . off ,  port = args . port ,  baud = args . baud ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        core_fname  =  loader . create_corefile ( args . save_core ,  exe_name = args . prog ,  rom_elf = rom_elf ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  not  core_fname : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            logging . error ( " Failed to create corefile! " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            loader . cleanup ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        core_fname  =  args . core 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  args . core_format  and  args . core_format  !=  ' elf ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            loader  =  ESPCoreDumpFileLoader ( core_fname ,  args . core_format  ==  ' b64 ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            core_fname  =  loader . create_corefile ( args . save_core ,  exe_name = args . prog ,  rom_elf = rom_elf ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  not  core_fname : 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                logging . error ( " Failed to create corefile! " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                loader . cleanup ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    exe_elf  =  ESPCoreDumpElfFile ( args . prog ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    core_elf  =  ESPCoreDumpElfFile ( core_fname ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    merged_segs  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    core_segs  =  core_elf . program_segments 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    for  s  in  exe_elf . sections : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        merged  =  False 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ps  in  core_segs : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ps . addr  < =  s . addr  and  ps . addr  +  len ( ps . data )  > =  s . addr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # sec:    |XXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # seg: |...XXX.............| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                seg_addr  =  ps . addr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ps . addr  +  len ( ps . data )  < =  s . addr  +  len ( s . data ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # sec:        |XXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # seg:    |XXXXXXXXXXX...| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # merged: |XXXXXXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    seg_len  =  len ( s . data )  +  ( s . addr  -  ps . addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # sec:        |XXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # seg:    |XXXXXXXXXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # merged: |XXXXXXXXXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    seg_len  =  len ( ps . data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                merged_segs . append ( ( s . name ,  seg_addr ,  seg_len ,  s . attr_str ( ) ,  True ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                core_segs . remove ( ps ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                merged  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            elif  ps . addr  > =  s . addr  and  ps . addr  < =  s . addr  +  len ( s . data ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # sec:  |XXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # seg:  |...XXX.............| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                seg_addr  =  s . addr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ps . addr  +  len ( ps . data ) )  > =  ( s . addr  +  len ( s . data ) ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # sec:    |XXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # seg:    |..XXXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # merged: |XXXXXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    seg_len  =  len ( s . data )  +  ( ps . addr  +  len ( ps . data ) )  -  ( s . addr  +  len ( s . data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # sec:    |XXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # seg:      |XXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    # merged: |XXXXXXXXXX| 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    seg_len  =  len ( s . data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                merged_segs . append ( ( s . name ,  seg_addr ,  seg_len ,  s . attr_str ( ) ,  True ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 13:06:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                core_segs . remove ( ps ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                merged  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  merged : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            merged_segs . append ( ( s . name ,  s . addr ,  len ( s . data ) ,  s . attr_str ( ) ,  False ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    handlers  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    handlers [ GDBMIResultHandler . TAG ]  =  GDBMIResultHandler ( verbose = False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    handlers [ GDBMIStreamConsoleHandler . TAG ]  =  GDBMIStreamConsoleHandler ( None ,  verbose = False ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p  =  gdbmi_start ( handlers ,  [ rom_sym_cmd ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    extra_note  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    task_info  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  seg  in  core_elf . aux_segments : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  seg . type  !=  ESPCoreDumpElfFile . PT_NOTE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        note_read  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  note_read  <  len ( seg . data ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            note  =  Elf32NoteDesc ( " " ,  0 ,  None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            note_read  + =  note . read ( seg . data [ note_read : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  note . type  ==  ESPCoreDumpLoader . ESP_CORE_DUMP_EXTRA_INFO_TYPE  and  ' EXTRA_INFO '  in  note . name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                extra_note  =  note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  note . type  ==  ESPCoreDumpLoader . ESP_CORE_DUMP_TASK_INFO_TYPE  and  ' TASK_INFO '  in  note . name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_info_struct  =  EspCoreDumpTaskStatus ( buf = note . desc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                task_info . append ( task_info_struct ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " =============================================================== " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( " ==================== ESP32 CORE DUMP START ==================== " ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    handlers [ GDBMIResultHandler . TAG ] . result_class  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    handlers [ GDBMIStreamConsoleHandler . TAG ] . func  =  gdbmi_console_stream_handler 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  extra_note : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        extra_info  =  struct . unpack ( " < %d L "  %  ( len ( extra_note . desc )  /  struct . calcsize ( " <L " ) ) ,  extra_note . desc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  extra_info [ 0 ]  ==  ESPCoreDumpLoader . ESP_COREDUMP_CURR_TASK_MARKER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print ( " \n Crashed task has been skipped. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p , task_name  =  gdbmi_freertos_get_task_name ( p ,  extra_info [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print ( " \n Crashed task handle: 0x %x , name:  ' %s ' , GDB name:  ' process  %d ' "  %  ( extra_info [ 0 ] ,  task_name ,  extra_info [ 0 ] ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " \n ================== CURRENT THREAD REGISTERS =================== " ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  extra_note : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        exccause  =  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EXCCAUSE_IDX  +  1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        exccause_str  =  xtensa_exception_cause_dict . get ( exccause ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  exccause_str : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            exccause_str  =  ( " Invalid EXCCAUSE code " ,  " Invalid EXCAUSE description or not found. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " exccause       0x %x  ( %s ) "  %  ( exccause ,  exccause_str [ 0 ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " excvaddr       0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EXCVADDR_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " epc1           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPC1_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " epc2           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPC2_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " epc3           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPC3_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " epc4           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPC4_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " epc5           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPC5_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " epc6           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPC6_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " epc7           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPC7_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " eps2           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPS2_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " eps3           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPS3_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " eps4           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPS4_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " eps5           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPS5_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " eps6           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPS6_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " eps7           0x %x "  %  extra_info [ 1  +  2  *  ESPCoreDumpElfFile . REG_EPS7_IDX  +  1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " Exception registers have not been found! " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p  =  gdbmi_getinfo ( p ,  handlers ,  " info registers " ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " \n ==================== CURRENT THREAD STACK ===================== " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p  =  gdbmi_getinfo ( p ,  handlers ,  " bt " ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  task_info  and  task_info [ 0 ] . task_flags  !=  EspCoreDumpTaskStatus . TASK_STATUS_CORRECT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " The current crashed task is corrupted. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " Task # %d  info: flags, tcb, stack ( %x ,  %x ,  %x ). "  %  ( task_info [ 0 ] . task_index , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              task_info [ 0 ] . task_flags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              task_info [ 0 ] . task_tcb_addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              task_info [ 0 ] . task_stack_start ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " \n ======================== THREADS INFO ========================= " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 12:44:14 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p  =  gdbmi_getinfo ( p ,  handlers ,  " info threads " ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # THREADS STACKS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    p , threads , cur_thread  =  gdbmi_get_thread_ids ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  thr_id  in  threads : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        task_index  =  int ( thr_id )  -  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  thr_id  ==  cur_thread : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p  =  gdbmi_switch_thread ( p ,  thr_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p , thr_info_res  =  gdbmi_get_thread_info ( p ,  thr_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tcb_addr  =  gdb2freertos_thread_id ( thr_info_res . target_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p , task_name  =  gdbmi_freertos_get_task_name ( p ,  tcb_addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " \n ==================== THREAD  %s  (TCB: 0x %x , name:  ' %s ' ) ===================== "  %  ( thr_id ,  tcb_addr ,  task_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p  =  gdbmi_getinfo ( p ,  handlers ,  " bt " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  task_info  and  task_info [ task_index ] . task_flags  !=  EspCoreDumpTaskStatus . TASK_STATUS_CORRECT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print ( " The task  ' %s '  is corrupted. "  %  thr_id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print ( " Task # %d  info: flags, tcb, stack ( %x ,  %x ,  %x ). "  %  ( task_info [ task_index ] . task_index , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  task_info [ task_index ] . task_flags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  task_info [ task_index ] . task_tcb_addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  task_info [ task_index ] . task_stack_start ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " \n ======================= ALL MEMORY REGIONS ======================== " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( " Name   Address   Size   Attrs " ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    for  ms  in  merged_segs : 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print ( " %s  0x %x  0x %x   %s "  %  ( ms [ 0 ] ,  ms [ 1 ] ,  ms [ 2 ] ,  ms [ 3 ] ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  cs  in  core_segs : 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # core dump exec segments are from ROM, other are belong to tasks (TCB or stack) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  cs . flags  &  ESPCoreDumpSegment . PF_X : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            seg_name  =  ' rom.text ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            seg_name  =  ' tasks.data ' 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print ( " .coredump. %s  0x %x  0x %x   %s "  %  ( seg_name ,  cs . addr ,  len ( cs . data ) ,  cs . attr_str ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  args . print_mem : 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print ( " \n ====================== CORE DUMP MEMORY CONTENTS ======================== " ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  cs  in  core_elf . program_segments : 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            # core dump exec segments are from ROM, other are belong to tasks (TCB or stack) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  cs . flags  &  ESPCoreDumpSegment . PF_X : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                seg_name  =  ' rom.text ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                seg_name  =  ' tasks.data ' 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            print ( " .coredump. %s  0x %x  0x %x   %s "  %  ( seg_name ,  cs . addr ,  len ( cs . data ) ,  cs . attr_str ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p  =  gdbmi_getinfo ( p ,  handlers ,  " x/ %d x 0x %x "  %  ( old_div ( len ( cs . data ) , 4 ) ,  cs . addr ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " \n ===================== ESP32 CORE DUMP END ===================== " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( " =============================================================== " ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p . stdin . write ( b ' q \n ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p . wait ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    p . stdin . close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    p . stdout . close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  loader : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  not  args . core  and  not  args . save_core : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            loader . remove_tmp_file ( core_fname ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        loader . cleanup ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( ' Done! ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  main ( ) :  
						 
					
						
							
								
									
										
										
										
											2017-01-03 22:01:40 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser  =  argparse . ArgumentParser ( description = ' espcoredump.py v %s  - ESP32 Core Dump Utility '  %  __version__ ,  prog = ' espcoredump ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . add_argument ( ' --chip ' ,  ' -c ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        help = ' Target chip type ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        choices = [ ' auto ' ,  ' esp32 ' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        default = os . environ . get ( ' ESPTOOL_CHIP ' ,  ' auto ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . add_argument ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ' --port ' ,  ' -p ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        help = ' Serial port device ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default = os . environ . get ( ' ESPTOOL_PORT ' ,  esptool . ESPLoader . DEFAULT_PORT ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . add_argument ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ' --baud ' ,  ' -b ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        help = ' Serial port baud rate used when flashing/reading ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        type = int , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default = os . environ . get ( ' ESPTOOL_BAUD ' ,  esptool . ESPLoader . ESP_ROM_BAUD ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    subparsers  =  parser . add_subparsers ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dest = ' operation ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        help = ' Run coredumper  {command}  -h for additional help ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser_debug_coredump  =  subparsers . add_parser ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ' dbg_corefile ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        help = ' Starts GDB debugging session with specified corefile ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' --debug ' ,  ' -d ' ,  help = ' Log level (0..3) ' ,  type = int ,  default = 3 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' --gdb ' ,  ' -g ' ,  help = ' Path to gdb ' ,  default = ' xtensa-esp32-elf-gdb ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' --core ' ,  ' -c ' ,  help = ' Path to core dump file (if skipped core dump will be read from flash) ' ,  type = str ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' --core-format ' ,  ' -t ' ,  help = ' (elf, raw or b64). File specified with  " -c "  is an ELF ( " elf " ),  ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                                   ' raw (raw) or base64-encoded (b64) binary ' ,  type = str ,  default = ' elf ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' --off ' ,  ' -o ' ,  help = ' Ofsset of coredump partition in flash  ' 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                           ' (type  " make partition_table "  to see). ' ,  type = int ,  default = None ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' --save-core ' ,  ' -s ' ,  help = ' Save core to file. Othwerwise temporary core file will be deleted.  ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                                 ' Ignored with  " -c " ' ,  type = str ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' --rom-elf ' ,  ' -r ' ,  help = ' Path to ROM ELF file. ' ,  type = str ,  default = ' esp32_rom.elf ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    parser_debug_coredump . add_argument ( ' prog ' ,  help = ' Path to program \' s ELF binary ' ,  type = str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser_info_coredump  =  subparsers . add_parser ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ' info_corefile ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        help = ' Print core dump info from file ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --debug ' ,  ' -d ' ,  help = ' Log level (0..3) ' ,  type = int ,  default = 3 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --gdb ' ,  ' -g ' ,  help = ' Path to gdb ' ,  default = ' xtensa-esp32-elf-gdb ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --core ' ,  ' -c ' ,  help = ' Path to core dump file (if skipped core dump will be read from flash) ' ,  type = str ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --core-format ' ,  ' -t ' ,  help = ' (elf, raw or b64). File specified with  " -c "  is an ELF ( " elf " ),  ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                                  ' raw (raw) or base64-encoded (b64) binary ' ,  type = str ,  default = ' elf ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --off ' ,  ' -o ' ,  help = ' Offset of coredump partition in flash (type  ' 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                                          ' " make partition_table "  to see). ' ,  type = int ,  default = None ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 13:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --save-core ' ,  ' -s ' ,  help = ' Save core to file. Othwerwise temporary core file will be deleted.  ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                                ' Does not work with  " -c " ' ,  type = str ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-29 15:45:31 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --rom-elf ' ,  ' -r ' ,  help = ' Path to ROM ELF file. ' ,  type = str ,  default = ' esp32_rom.elf ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 14:16:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' --print-mem ' ,  ' -m ' ,  help = ' Print memory dump ' ,  action = ' store_true ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    parser_info_coredump . add_argument ( ' prog ' ,  help = ' Path to program \' s ELF binary ' ,  type = str ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # internal sanity check - every operation matches a module function of the same name 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  operation  in  subparsers . choices : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        assert  operation  in  globals ( ) ,  " %s  should be a module function "  %  operation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    args  =  parser . parse_args ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    log_level  =  logging . CRITICAL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  args . debug  ==  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        log_level  =  logging . CRITICAL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elif  args . debug  ==  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        log_level  =  logging . ERROR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elif  args . debug  ==  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        log_level  =  logging . WARNING 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elif  args . debug  ==  3 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        log_level  =  logging . INFO 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        log_level  =  logging . DEBUG 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-22 13:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    logging . basicConfig ( format = ' %(levelname)s :  %(message)s ' ,  level = log_level ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 00:18:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( ' espcoredump.py v %s '  %  __version__ ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    operation_func  =  globals ( ) [ args . operation ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    operation_func ( args ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  ' __main__ ' :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        main ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    except  ESPCoreDumpError  as  e : 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-03 13:48:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print ( ' \n A fatal error occurred:  %s '  %  e ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-22 02:56:23 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        sys . exit ( 2 )