// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** x86log.h x86/x64 code logging helpers. ***************************************************************************/ #ifndef MAME_CPU_X86LOG_H #define MAME_CPU_X86LOG_H #pragma once #include #include /*************************************************************************** CONSTANTS ***************************************************************************/ /* comment parameters */ constexpr int MAX_COMMENTS{4000}; constexpr int MAX_DATA_RANGES{1000}; constexpr int COMMENT_POOL_SIZE{MAX_COMMENTS * 40}; /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ // use x86code * to reference generated code typedef uint8_t x86code; /* code logging info */ struct log_comment { x86code* base = nullptr; const char* string = nullptr; }; /* data ranges */ struct data_range_t { x86code* base = nullptr; x86code* end = nullptr; int size = 0; }; /* the code logging context */ struct x86log_context { std::string filename; // name of the file FILE* file = nullptr; // file we are logging to data_range_t data_range[MAX_DATA_RANGES]; // list of data ranges int data_range_count = 0; // number of data ranges log_comment comment_list[MAX_COMMENTS]; // list of comments int comment_count = 0; // number of live comments char comment_pool[COMMENT_POOL_SIZE]; // string pool to hold comments char* comment_pool_next = nullptr; // 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 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 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 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(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 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(xs)...); /* flush the file */ fflush(log->file); } #endif // MAME_CPU_X86LOG_H