2019-05-29 07:18:02 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2015-07-17 19:33:39 +03:00
/*
* intel_pt_log . c : Intel Processor Trace support
* Copyright ( c ) 2013 - 2014 , Intel Corporation .
*/
# include <stdio.h>
# include <stdint.h>
# include <inttypes.h>
# include <stdarg.h>
# include <stdbool.h>
# include <string.h>
# include "intel-pt-log.h"
# include "intel-pt-insn-decoder.h"
# include "intel-pt-pkt-decoder.h"
# define MAX_LOG_NAME 256
static FILE * f ;
static char log_name [ MAX_LOG_NAME ] ;
2015-09-25 16:15:35 +03:00
bool intel_pt_enable_logging ;
2015-07-17 19:33:39 +03:00
2018-11-05 09:35:04 +02:00
void * intel_pt_log_fp ( void )
{
return f ;
}
2015-07-17 19:33:39 +03:00
void intel_pt_log_enable ( void )
{
2015-09-25 16:15:35 +03:00
intel_pt_enable_logging = true ;
2015-07-17 19:33:39 +03:00
}
void intel_pt_log_disable ( void )
{
if ( f )
fflush ( f ) ;
2015-09-25 16:15:35 +03:00
intel_pt_enable_logging = false ;
2015-07-17 19:33:39 +03:00
}
void intel_pt_log_set_name ( const char * name )
{
strncpy ( log_name , name , MAX_LOG_NAME - 5 ) ;
strcat ( log_name , " .log " ) ;
}
static void intel_pt_print_data ( const unsigned char * buf , int len , uint64_t pos ,
int indent )
{
int i ;
for ( i = 0 ; i < indent ; i + + )
fprintf ( f , " " ) ;
fprintf ( f , " %08 " PRIx64 " : " , pos ) ;
for ( i = 0 ; i < len ; i + + )
fprintf ( f , " %02x " , buf [ i ] ) ;
for ( ; i < 16 ; i + + )
fprintf ( f , " " ) ;
fprintf ( f , " " ) ;
}
static void intel_pt_print_no_data ( uint64_t pos , int indent )
{
int i ;
for ( i = 0 ; i < indent ; i + + )
fprintf ( f , " " ) ;
fprintf ( f , " %08 " PRIx64 " : " , pos ) ;
for ( i = 0 ; i < 16 ; i + + )
fprintf ( f , " " ) ;
fprintf ( f , " " ) ;
}
static int intel_pt_log_open ( void )
{
2015-09-25 16:15:35 +03:00
if ( ! intel_pt_enable_logging )
2015-07-17 19:33:39 +03:00
return - 1 ;
if ( f )
return 0 ;
if ( ! log_name [ 0 ] )
return - 1 ;
f = fopen ( log_name , " w+ " ) ;
if ( ! f ) {
2015-09-25 16:15:35 +03:00
intel_pt_enable_logging = false ;
2015-07-17 19:33:39 +03:00
return - 1 ;
}
return 0 ;
}
2015-09-25 16:15:35 +03:00
void __intel_pt_log_packet ( const struct intel_pt_pkt * packet , int pkt_len ,
uint64_t pos , const unsigned char * buf )
2015-07-17 19:33:39 +03:00
{
char desc [ INTEL_PT_PKT_DESC_MAX ] ;
if ( intel_pt_log_open ( ) )
return ;
intel_pt_print_data ( buf , pkt_len , pos , 0 ) ;
intel_pt_pkt_desc ( packet , desc , INTEL_PT_PKT_DESC_MAX ) ;
fprintf ( f , " %s \n " , desc ) ;
}
2015-09-25 16:15:35 +03:00
void __intel_pt_log_insn ( struct intel_pt_insn * intel_pt_insn , uint64_t ip )
2015-07-17 19:33:39 +03:00
{
char desc [ INTEL_PT_INSN_DESC_MAX ] ;
size_t len = intel_pt_insn - > length ;
if ( intel_pt_log_open ( ) )
return ;
2016-10-07 16:42:25 +03:00
if ( len > INTEL_PT_INSN_BUF_SZ )
len = INTEL_PT_INSN_BUF_SZ ;
2015-07-17 19:33:39 +03:00
intel_pt_print_data ( intel_pt_insn - > buf , len , ip , 8 ) ;
if ( intel_pt_insn_desc ( intel_pt_insn , desc , INTEL_PT_INSN_DESC_MAX ) > 0 )
fprintf ( f , " %s \n " , desc ) ;
else
fprintf ( f , " Bad instruction! \n " ) ;
}
2015-09-25 16:15:35 +03:00
void __intel_pt_log_insn_no_data ( struct intel_pt_insn * intel_pt_insn ,
uint64_t ip )
2015-07-17 19:33:39 +03:00
{
char desc [ INTEL_PT_INSN_DESC_MAX ] ;
if ( intel_pt_log_open ( ) )
return ;
intel_pt_print_no_data ( ip , 8 ) ;
if ( intel_pt_insn_desc ( intel_pt_insn , desc , INTEL_PT_INSN_DESC_MAX ) > 0 )
fprintf ( f , " %s \n " , desc ) ;
else
fprintf ( f , " Bad instruction! \n " ) ;
}
2015-09-25 16:15:35 +03:00
void __intel_pt_log ( const char * fmt , . . . )
2015-07-17 19:33:39 +03:00
{
va_list args ;
if ( intel_pt_log_open ( ) )
return ;
va_start ( args , fmt ) ;
vfprintf ( f , fmt , args ) ;
va_end ( args ) ;
}