summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/cpu/x86log.h
blob: ac7195c99bd18213a50a0260770deb58c4baaae5 (plain) (tree)
1
2
3
4
5
6
7
8

                                





                                                                            






                                                                            

                  



                                                                            









                                                                            


                                                                            


                       

                           





                   


                      





                              

                                                          
 

                                                                             
 

                                                                             
 

                                                                                
  







                                                                            
                                                            

                       
                                                       

                                                        

                               
                                                                            

                                                     
                         
                                                                             

                                                                   
                              
                                                                               

                                                 










                                                                               
                                                                           
 
























                                                                                     










                                                                              



                                                              
 

                                                
 
                                     
 

                                                            
 

                            
 
 
                         
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    x86log.h

    x86/x64 code logging helpers.

***************************************************************************/

#pragma once

#ifndef __X86LOG_H__
#define __X86LOG_H__

#include <cstdint>
#include <cassert>
#include "x86emit.h"


/***************************************************************************
    CONSTANTS
***************************************************************************/

/* comment parameters */
constexpr int MAX_COMMENTS{4000};
constexpr int MAX_DATA_RANGES{1000};
constexpr int COMMENT_POOL_SIZE{MAX_COMMENTS * 40};


/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

/* code logging info */
struct log_comment
{
	x86code* base;
	const char* string;
};


/* data ranges */
struct data_range_t
{
	x86code* base;
	x86code* end;
	int size;
};


/* the code logging context */
struct x86log_context
{
	std::string filename; /* name of the file */
	FILE* file;           /* file we are logging to */

	data_range_t data_range[MAX_DATA_RANGES]; /* list of data ranges */
	int data_range_count;                     /* number of data ranges */

	log_comment comment_list[MAX_COMMENTS]; /* list of comments */
	int comment_count;                      /* number of live comments */

	char comment_pool[COMMENT_POOL_SIZE]; /* string pool to hold comments */
	char* comment_pool_next; /* pointer to next string pool location */
};



/***************************************************************************
    FUNCTION PROTOTYPES
***************************************************************************/

/* create a new context */
x86log_context* x86log_create_context(const char* filename);

/* release a context */
void x86log_free_context(x86log_context* log) noexcept;

/* add a comment associated with a given code pointer */
template <typename... Ts>
inline void x86log_add_comment(
	x86log_context* log, x86code* base, const char* format, Ts&&... xs);

/* mark a given range as data for logging purposes */
void x86log_mark_as_data(
	x86log_context* log, x86code* base, x86code* end, int size) noexcept;

/* disassemble a range of code and reset accumulated information */
void x86log_disasm_code_range(
	x86log_context* log, const char* label, x86code* start, x86code* stop);

/* manually printf information to the log file */
template <typename... Ts>
inline void x86log_printf(x86log_context* log, const char* format, Ts&&... xs);


/*-------------------------------------------------
    x86log_add_comment - add a comment associated
    with a given code pointer
-------------------------------------------------*/

template <typename... Ts>
inline void x86log_add_comment(
	x86log_context* log, x86code* base, const char* format, Ts&&... xs)
{
	char* string = log->comment_pool_next;
	log_comment* comment;

	assert(log->comment_count < MAX_COMMENTS);
	assert(log->comment_pool_next + strlen(format) + 256 <
			log->comment_pool + COMMENT_POOL_SIZE);

	/* we assume comments are registered in order; enforce this */
	assert(log->comment_count == 0 ||
			base >= log->comment_list[log->comment_count - 1].base);

	/* if we exceed the maxima, skip it */
	if(log->comment_count >= MAX_COMMENTS) return;
	if(log->comment_pool_next + strlen(format) + 256 >=
		log->comment_pool + COMMENT_POOL_SIZE)
		return;

	/* do the printf to the string pool */
	log->comment_pool_next +=
		sprintf(log->comment_pool_next, format, std::forward<Ts>(xs)...) + 1;

	/* fill in the new comment */
	comment = &log->comment_list[log->comment_count++];
	comment->base = base;
	comment->string = string;
}


/*-------------------------------------------------
    x86log_printf - manually printf information to
    the log file
-------------------------------------------------*/

template <typename... Ts>
inline void x86log_printf(x86log_context* log, const char* format, Ts&&... xs)
{
	/* open the file, creating it if necessary */
	if(log->file == nullptr)
	{
		log->file = fopen(log->filename.c_str(), "w");

		if(log->file == nullptr) return;
	}

	assert(log->file != nullptr);

	/* do the printf */
	fprintf(log->file, format, std::forward<Ts>(xs)...);

	/* flush the file */
	fflush(log->file);
}

#endif /* __X86LOG_H__ */