summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/windows/winmain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/windows/winmain.c')
-rw-r--r--src/osd/windows/winmain.c98
1 files changed, 49 insertions, 49 deletions
diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c
index ae0ba8735ab..b1a4200b0e0 100644
--- a/src/osd/windows/winmain.c
+++ b/src/osd/windows/winmain.c
@@ -105,12 +105,12 @@ public:
// bool to test if the function is NULL or not
operator bool() const { return (m_function != NULL); }
-
+
// dereference to get the underlying pointer
func_ptr operator *() const { return m_function; }
private:
- func_ptr m_function;
+ func_ptr m_function;
};
@@ -118,14 +118,14 @@ class stack_walker
{
public:
stack_walker();
-
+
FPTR ip() const { return m_stackframe.AddrPC.Offset; }
FPTR sp() const { return m_stackframe.AddrStack.Offset; }
FPTR frame() const { return m_stackframe.AddrFrame.Offset; }
-
+
void reset(CONTEXT &context, HANDLE thread);
bool unwind();
-
+
private:
HANDLE m_process;
HANDLE m_thread;
@@ -138,7 +138,7 @@ private:
dynamic_bind<BOOL (WINAPI *)(HANDLE, LPCTSTR, BOOL)> m_sym_initialize;
dynamic_bind<PVOID (WINAPI *)(HANDLE, DWORD64)> m_sym_function_table_access_64;
dynamic_bind<DWORD64 (WINAPI *)(HANDLE, DWORD64)> m_sym_get_module_base_64;
-
+
static bool s_initialized;
};
@@ -149,10 +149,10 @@ public:
// construction/destruction
symbol_manager(const char *argv0);
~symbol_manager();
-
+
// getters
FPTR last_base() const { return m_last_base; }
-
+
// core symbol lookup
const char *symbol_for_address(FPTR address);
const char *symbol_for_address(PVOID address) { return symbol_for_address(reinterpret_cast<FPTR>(address)); }
@@ -197,11 +197,11 @@ class sampling_profiler
public:
sampling_profiler(UINT32 max_seconds, UINT8 stack_depth);
~sampling_profiler();
-
+
void start();
void stop();
-// void reset();
+// void reset();
void print_results(symbol_manager &symbols);
private:
@@ -210,7 +210,7 @@ private:
static int CLIB_DECL compare_address(const void *item1, const void *item2);
static int CLIB_DECL compare_frequency(const void *item1, const void *item2);
-
+
HANDLE m_target_thread;
HANDLE m_thread;
@@ -549,7 +549,7 @@ static void osd_exit(running_machine &machine)
profiler->print_results(*symbols);
global_free(profiler);
}
-
+
// turn off our multimedia tasks
// if (av_revert_mm_thread_characteristics)
// (*av_revert_mm_thread_characteristics)(mm_task);
@@ -790,7 +790,7 @@ void stack_walker::reset(CONTEXT &initial, HANDLE thread)
m_stackframe.AddrPC.Mode = AddrModeFlat;
m_stackframe.AddrFrame.Mode = AddrModeFlat;
m_stackframe.AddrStack.Mode = AddrModeFlat;
-
+
// pull architecture-specific fields from the context
#ifdef PTR64
m_stackframe.AddrPC.Offset = m_context.Rip;
@@ -855,7 +855,7 @@ symbol_manager::symbol_manager(const char *argv0)
if (extoffs != -1)
m_mapfile.substr(0, extoffs);
m_mapfile.cat(".map");
-
+
// and the name of the symfile
extoffs = m_symfile.rchr(0, '.');
if (extoffs != -1)
@@ -905,7 +905,7 @@ const char *symbol_manager::symbol_for_address(FPTR address)
// if that fails, scan the cache if we have one
if (m_cache != NULL)
scan_cache_for_address(address);
-
+
// or else try to open a sym/map file and find it there
else
scan_file_for_address(address, false);
@@ -961,13 +961,13 @@ void symbol_manager::scan_file_for_address(FPTR address, bool create_cache)
{
bool is_symfile = false;
FILE *srcfile = NULL;
-
+
#ifdef __GNUC__
// see if we have a symbol file (gcc only)
srcfile = fopen(m_symfile, "r");
is_symfile = (srcfile != NULL);
#endif
-
+
// if not, see if we have a map file
if (srcfile == NULL)
srcfile = fopen(m_mapfile, "r");
@@ -999,7 +999,7 @@ void symbol_manager::scan_file_for_address(FPTR address, bool create_cache)
best_addr = addr;
best_symbol = symbol;
}
-
+
// also create a cache entry if we can
if (create_cache)
{
@@ -1008,10 +1008,10 @@ void symbol_manager::scan_file_for_address(FPTR address, bool create_cache)
}
}
}
-
+
// close the file
fclose(srcfile);
-
+
// format the symbol and remember the last base
format_symbol(best_symbol, address - best_addr);
m_last_base = best_addr;
@@ -1028,17 +1028,17 @@ void symbol_manager::scan_cache_for_address(FPTR address)
// reset the best info
astring best_symbol;
FPTR best_addr = 0;
-
+
// walk the cache, looking for valid entries
for (cache_entry *entry = m_cache; entry != NULL; entry = entry->m_next)
-
+
// if this is the best one so far, remember it
if (entry->m_address <= address && entry->m_address > best_addr)
{
best_addr = entry->m_address;
best_symbol = entry->m_name;
}
-
+
// format the symbol and remember the last base
format_symbol(best_symbol, address - best_addr);
m_last_base = best_addr;
@@ -1054,13 +1054,13 @@ bool symbol_manager::parse_sym_line(const char *line, FPTR &address, astring &sy
{
#ifdef __GNUC__
/*
- 32-bit gcc symbol line:
+ 32-bit gcc symbol line:
[271778](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 0) 0x007df675 line_to_symbol(char const*, unsigned int&, bool)
- 64-bit gcc symbol line:
+ 64-bit gcc symbol line:
[271775](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 0) 0x00000000008dd1e9 line_to_symbol(char const*, unsigned long long&, bool)
*/
-
+
// first look for a (ty) entry
const char *type = strstr(line, "(ty 20)");
if (type == NULL)
@@ -1075,7 +1075,7 @@ bool symbol_manager::parse_sym_line(const char *line, FPTR &address, astring &sy
in_parens = true;
else if (*chptr == ')')
in_parens = false;
-
+
// otherwise, look for an 0x address
else if (!in_parens && *chptr == '0' && chptr[1] == 'x')
{
@@ -1084,11 +1084,11 @@ bool symbol_manager::parse_sym_line(const char *line, FPTR &address, astring &sy
if (sscanf(chptr, "0x%p", &temp) != 1)
return false;
address = m_text_base + reinterpret_cast<FPTR>(temp);
-
+
// skip forward until we're past the space
while (*chptr != 0 && !isspace(*chptr))
chptr++;
-
+
// extract the symbol name
symbol.cpy(chptr).trimspace();
return (symbol.len() > 0);
@@ -1123,12 +1123,12 @@ bool symbol_manager::parse_map_line(const char *line, FPTR &address, astring &sy
if (sscanf(&line[16], "0x%p", &temp) != 1)
return false;
address = reinterpret_cast<FPTR>(temp);
-
+
// skip forward until we're past the space
const char *chptr = &line[16];
while (*chptr != 0 && !isspace(*chptr))
chptr++;
-
+
// extract the symbol name
symbol.cpy(chptr).trimspace();
return (symbol.len() > 0);
@@ -1143,7 +1143,7 @@ bool symbol_manager::parse_map_line(const char *line, FPTR &address, astring &sy
//-------------------------------------------------
void symbol_manager::format_symbol(const char *name, UINT32 displacement, const char *filename, int linenumber)
-{
+{
// start with the address and offset
m_buffer.printf(" (%s", name);
if (displacement != 0)
@@ -1156,7 +1156,7 @@ void symbol_manager::format_symbol(const char *name, UINT32 displacement, const
// close up the string
m_buffer.cat(")");
}
-
+
//-------------------------------------------------
// get_text_section_base - figure out the base
@@ -1171,20 +1171,20 @@ FPTR symbol_manager::get_text_section_base()
// start with the image base
PVOID base = reinterpret_cast<PVOID>(GetModuleHandle(NULL));
assert(base != NULL);
-
+
// make sure we have the functions we need
if (image_nt_header != NULL && image_rva_to_section != NULL)
{
// get the NT header
PIMAGE_NT_HEADERS headers = (*image_nt_header)(base);
assert(headers != NULL);
-
+
// look ourself up (assuming we are in the .text section)
PIMAGE_SECTION_HEADER section = (*image_rva_to_section)(headers, base, reinterpret_cast<FPTR>(get_text_section_base) - reinterpret_cast<FPTR>(base));
if (section != NULL)
return reinterpret_cast<FPTR>(base) + section->VirtualAddress;
}
-
+
// fallback to returning the image base (wrong)
return reinterpret_cast<FPTR>(base);
}
@@ -1255,7 +1255,7 @@ void sampling_profiler::stop()
// set the flag and wait a couple of seconds (max)
m_thread_exit = true;
WaitForSingleObject(m_thread, 2000);
-
+
// regardless, close the handle
CloseHandle(m_thread);
}
@@ -1272,18 +1272,18 @@ int CLIB_DECL sampling_profiler::compare_address(const void *item1, const void *
const FPTR *entry2 = reinterpret_cast<const FPTR *>(item2);
int mincount = MIN(entry1[0], entry2[0]);
- // sort in order of: bucket, caller, caller's caller, etc.
+ // sort in order of: bucket, caller, caller's caller, etc.
for (int index = 1; index <= mincount; index++)
if (entry1[index] != entry2[index])
return entry1[index] - entry2[index];
-
+
// if we match to the end, sort by the depth of the stack
return entry1[0] - entry2[0];
}
//-------------------------------------------------
-// compare_frequency - compare two entries by
+// compare_frequency - compare two entries by
// their frequency of occurrence
//-------------------------------------------------
@@ -1312,15 +1312,15 @@ void sampling_profiler::print_results(symbol_manager &symbols)
for (FPTR *current = m_buffer; current < m_buffer_ptr; current += m_entry_stride)
{
assert(current[0] >= 1 && current[0] < m_entry_stride);
-
+
// convert the sampled PC to its function base as a bucket
symbols.symbol_for_address(current[1]);
current[1] = symbols.last_base();
}
-
+
// step 2: sort the results
qsort(m_buffer, (m_buffer_ptr - m_buffer) / m_entry_stride, m_entry_stride * sizeof(FPTR), compare_address);
-
+
// step 3: count and collapse unique entries
UINT32 total_count = 0;
for (FPTR *current = m_buffer; current < m_buffer_ptr; )
@@ -1341,7 +1341,7 @@ void sampling_profiler::print_results(symbol_manager &symbols)
// step 4: sort the results again, this time by frequency
qsort(m_buffer, (m_buffer_ptr - m_buffer) / m_entry_stride, m_entry_stride * sizeof(FPTR), compare_frequency);
-
+
// step 5: print the results
UINT32 num_printed = 0;
for (FPTR *current = m_buffer; current < m_buffer_ptr && num_printed < 30; current += m_entry_stride)
@@ -1349,7 +1349,7 @@ void sampling_profiler::print_results(symbol_manager &symbols)
// once we hit 0 frequency, we're done
if (current[0] == 0)
break;
-
+
// output the result
printf("%4.1f%% - %6d : %p%s\n", (double)current[0] * 100.0 / (double)total_count, (UINT32)current[0], reinterpret_cast<void *>(current[1]), symbols.symbol_for_address(current[1]));
for (int index = 2; index < m_entry_stride; index++)
@@ -1392,11 +1392,11 @@ void sampling_profiler::thread_run()
SuspendThread(m_target_thread);
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(m_target_thread, &context);
-
+
// first entry is a count
FPTR *count = m_buffer_ptr++;
*count = 0;
-
+
// iterate over the frames until we run out or hit an error
walker.reset(context, m_target_thread);
int frame;
@@ -1405,11 +1405,11 @@ void sampling_profiler::thread_run()
*m_buffer_ptr++ = walker.ip();
*count += 1;
}
-
+
// fill in any missing parts with NULLs
for (; frame <= m_stack_depth; frame++)
*m_buffer_ptr++ = 0;
-
+
// resume the thread
ResumeThread(m_target_thread);