summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/utils/ssp.c224
1 files changed, 119 insertions, 105 deletions
diff --git a/winsup/utils/ssp.c b/winsup/utils/ssp.c
index 3136a9f66..c9165f3dd 100644
--- a/winsup/utils/ssp.c
+++ b/winsup/utils/ssp.c
@@ -13,20 +13,6 @@
*
*/
-#ifdef __x86_64__
-
-#include <stdio.h>
-
-int
-main (int argc, char **argv)
-{
- fprintf (stderr, "%s: This application is unsuported on x86_64 so far.\n",
- argv[0]);
- return 1;
-}
-
-#else
-
#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -56,39 +42,60 @@ static struct option longopts[] =
static char opts[] = "+cdehlstvV";
+#ifdef __x86_64__
+#define KERNEL_ADDR 0x00007FF000000000
+#define CONTEXT_SP Rsp
+#define CONTEXT_IP Rip
+typedef DWORD64 CONTEXT_REG;
+#define CONTEXT_REG_FMT "%016llx"
+#define ADDR_SSCANF_FMT "%lli"
+#else
#define KERNEL_ADDR 0x77000000
+#define CONTEXT_SP Esp
+#define CONTEXT_IP Eip
+typedef DWORD CONTEXT_REG;
+#define CONTEXT_REG_FMT "%08lx"
+#define ADDR_SSCANF_FMT "%li"
+#endif
#define TRACE_SSP 0
#define VERBOSE 1
#define TIMES 1000
-/* from winsup/gmon.h */
+/* from winsup/cygwin/gmon.h */
struct gmonhdr {
- unsigned long lpc; /* base pc address of sample buffer */
- unsigned long hpc; /* max pc address of sampled buffer */
+ size_t lpc; /* base pc address of sample buffer */
+ size_t hpc; /* max pc address of sampled buffer */
int ncnt; /* size of sample buffer (plus this header) */
int version; /* version number */
int profrate; /* profiling clock rate */
int spare[3]; /* reserved */
};
+
+struct rawarc {
+ size_t from_pc;
+ size_t to_pc;
+ long count;
+};
+
#define GMONVERSION 0x00051879
#define HISTCOUNTER unsigned short
typedef struct {
- unsigned int base_address;
+ CONTEXT_REG base_address;
int pcount;
int scount;
char *name;
} DllInfo;
typedef struct {
- unsigned int address;
+ CONTEXT_REG address;
unsigned char real_byte;
} PendingBreakpoints;
-unsigned low_pc=0, high_pc=0;
-unsigned last_pc=0, pc, last_sp=0, sp;
+CONTEXT_REG low_pc, high_pc=0;
+CONTEXT_REG last_pc=0, pc, last_sp=0, sp;
int total_cycles, count;
HANDLE hProcess;
PROCESS_INFORMATION procinfo;
@@ -98,7 +105,6 @@ HISTCOUNTER *hits=0;
struct gmonhdr hdr;
int running = 1, profiling = 1;
char dll_name[1024], *dll_ptr, *cp;
-int eip;
unsigned opcode_count = 0;
int stepping_enabled = 1;
@@ -111,8 +117,8 @@ int verbose = 0;
#define MAXTHREADS 100
DWORD active_thread_ids[MAXTHREADS];
HANDLE active_threads[MAXTHREADS];
-DWORD thread_step_flags[MAXTHREADS];
-DWORD thread_return_address[MAXTHREADS];
+int thread_step_flags[MAXTHREADS];
+CONTEXT_REG thread_return_address[MAXTHREADS];
int num_active_threads = 0;
int suspended_count=0;
@@ -125,10 +131,10 @@ PendingBreakpoints pending_breakpoints[MAXPENDS];
int num_breakpoints=0;
static void
-add_breakpoint (unsigned int address)
+add_breakpoint (CONTEXT_REG address)
{
int i;
- DWORD rv;
+ SIZE_T rv;
static char int3[] = { 0xcc };
for (i=0; i<num_breakpoints; i++)
{
@@ -141,31 +147,31 @@ add_breakpoint (unsigned int address)
return;
pending_breakpoints[i].address = address;
ReadProcessMemory (hProcess,
- (void *)address,
- &(pending_breakpoints[i].real_byte),
- 1, &rv);
+ (void *)address,
+ &(pending_breakpoints[i].real_byte),
+ 1, &rv);
WriteProcessMemory (hProcess,
- (void *)address,
- (LPVOID)int3, 1, &rv);
+ (void *)address,
+ (LPVOID)int3, 1, &rv);
if (i >= num_breakpoints)
num_breakpoints = i+1;
}
static int
-remove_breakpoint (unsigned int address)
+remove_breakpoint (CONTEXT_REG address)
{
int i;
- DWORD rv;
+ SIZE_T rv;
for (i=0; i<num_breakpoints; i++)
{
if (pending_breakpoints[i].address == address)
{
pending_breakpoints[i].address = 0;
WriteProcessMemory (hProcess,
- (void *)address,
- &(pending_breakpoints[i].real_byte),
- 1, &rv);
+ (void *)address,
+ &(pending_breakpoints[i].real_byte),
+ 1, &rv);
return 1;
}
}
@@ -231,7 +237,7 @@ dll_sort (const void *va, const void *vb)
}
static char *
-addr2dllname (unsigned int addr)
+addr2dllname (CONTEXT_REG addr)
{
int i;
for (i=num_dlls-1; i>=0; i--)
@@ -249,39 +255,44 @@ dump_registers (HANDLE thread)
{
context.ContextFlags = CONTEXT_FULL;
GetThreadContext (thread, &context);
+#ifdef __x86_64__
+ printf ("eax %016llx ebx %016llx ecx %016llx edx %016llx eip\n",
+ context.Rax, context.Rbx, context.Rcx, context.Rdx);
+ printf ("esi %016llx edi %016llx ebp %016llx esp %016llx %016llx\n",
+ context.Rsi, context.Rdi, context.Rbp, context.Rsp, context.Rip);
+#else
printf ("eax %08lx ebx %08lx ecx %08lx edx %08lx eip\n",
context.Eax, context.Ebx, context.Ecx, context.Edx);
printf ("esi %08lx edi %08lx ebp %08lx esp %08lx %08lx\n",
- context.Esi, context.Esi, context.Ebp, context.Esp, context.Eip);
+ context.Esi, context.Edi, context.Ebp, context.Esp, context.Eip);
+#endif
}
typedef struct Edge {
struct Edge *next;
- unsigned int from_pc;
- unsigned int to_pc;
- unsigned int count;
+ struct rawarc rawarc;
} Edge;
Edge *edges[4096];
void
-store_call_edge (unsigned int from_pc, unsigned int to_pc)
+store_call_edge (CONTEXT_REG from_pc, CONTEXT_REG to_pc)
{
Edge *e;
unsigned int h = ((from_pc + to_pc)>>4) & 4095;
for (e=edges[h]; e; e=e->next)
- if (e->from_pc == from_pc && e->to_pc == to_pc)
+ if (e->rawarc.from_pc == from_pc && e->rawarc.to_pc == to_pc)
break;
if (!e)
{
e = (Edge *)malloc (sizeof (Edge));
e->next = edges[h];
edges[h] = e;
- e->from_pc = from_pc;
- e->to_pc = to_pc;
- e->count = 0;
+ e->rawarc.from_pc = from_pc;
+ e->rawarc.to_pc = to_pc;
+ e->rawarc.count = 0;
}
- e->count++;
+ e->rawarc.count++;
}
void
@@ -291,7 +302,7 @@ write_call_edges (FILE *f)
Edge *e;
for (h=0; h<4096; h++)
for (e=edges[h]; e; e=e->next)
- fwrite (&(e->from_pc), 1, 3*sizeof (unsigned int), f);
+ fwrite (&(e->rawarc), 1, sizeof (struct rawarc), f);
}
char *
@@ -326,14 +337,14 @@ run_program (char *cmdline)
| DEBUG_ONLY_THIS_PROCESS,
0, 0, &startup, &procinfo))
{
- fprintf (stderr, "Can't create process: error %ld\n", GetLastError ());
+ fprintf (stderr, "Can't create process: error %u\n", (unsigned int)GetLastError ());
exit (1);
}
hProcess = procinfo.hProcess;
#if 0
- printf ("procinfo: %08x %08x %08x %08x\n",
- hProcess, procinfo.hThread, procinfo.dwProcessId, procinfo.dwThreadId);
+ printf ("procinfo: %p %p %08x %08x\n",
+ hProcess, procinfo.hThread, (int)procinfo.dwProcessId, (int)procinfo.dwThreadId);
#endif
active_threads[0] = procinfo.hThread;
@@ -369,7 +380,7 @@ run_program (char *cmdline)
while (running)
{
int src, dest;
- DWORD rv;
+ SIZE_T rv;
DEBUG_EVENT event;
int contv = DBG_CONTINUE;
@@ -382,16 +393,16 @@ run_program (char *cmdline)
hThread = lookup_thread_id (event.dwThreadId, &tix);
#if 0
- printf ("DE: %x/%d %d %d ",
- hThread, tix,
- event.dwDebugEventCode, num_active_threads);
+ printf ("DE: %p/%d %d %d ",
+ hThread, tix,
+ (int)event.dwDebugEventCode, num_active_threads);
for (src=0; src<num_active_threads; src++)
{
int sc = SuspendThread (active_threads[src]);
int rv = GetThreadContext (active_threads[src], &context);
ResumeThread (active_threads[src]);
- printf (" [%x,%x,%x]",
- active_threads[src], context.Eip, active_thread_ids[src]);
+ printf (" [%p," CONTEXT_REG_FMT ",%x]",
+ active_threads[src], context.CONTEXT_IP, (int)active_thread_ids[src]);
}
printf ("\n");
#endif
@@ -404,10 +415,10 @@ run_program (char *cmdline)
case CREATE_THREAD_DEBUG_EVENT:
if (verbose)
- printf ("create thread %08lx at %08x %s\n",
- event.dwThreadId,
- (int)event.u.CreateThread.lpStartAddress,
- addr2dllname ((unsigned int)event.u.CreateThread.lpStartAddress));
+ printf ("create thread %08x at " CONTEXT_REG_FMT " %s\n",
+ (int)event.dwThreadId,
+ (CONTEXT_REG)event.u.CreateThread.lpStartAddress,
+ addr2dllname ((CONTEXT_REG)event.u.CreateThread.lpStartAddress));
active_thread_ids[num_active_threads] = event.dwThreadId;
active_threads[num_active_threads] = event.u.CreateThread.hThread;
@@ -417,16 +428,16 @@ run_program (char *cmdline)
if (trace_all_threads && stepping_enabled)
{
thread_step_flags[num_active_threads-1] = stepping_enabled;
- add_breakpoint ((int)event.u.CreateThread.lpStartAddress);
+ add_breakpoint ((CONTEXT_REG)event.u.CreateThread.lpStartAddress);
}
break;
case EXIT_THREAD_DEBUG_EVENT:
if (verbose)
- printf ("exit thread %08lx, code=%ld\n",
- event.dwThreadId,
- event.u.ExitThread.dwExitCode);
+ printf ("exit thread %08x, code=%d\n",
+ (int)event.dwThreadId,
+ (int)event.u.ExitThread.dwExitCode);
for (src=0, dest=0; src<num_active_threads; src++)
if (active_thread_ids[src] != event.dwThreadId)
@@ -443,24 +454,24 @@ run_program (char *cmdline)
switch (event.u.Exception.ExceptionRecord.ExceptionCode)
{
case STATUS_BREAKPOINT:
- if (remove_breakpoint ((int)event.u.Exception.ExceptionRecord.ExceptionAddress))
+ if (remove_breakpoint ((CONTEXT_REG)event.u.Exception.ExceptionRecord.ExceptionAddress))
{
- context.Eip --;
+ context.CONTEXT_IP --;
if (!rv)
SetThreadContext (hThread, &context);
- if (ReadProcessMemory (hProcess, (void *)context.Esp, &rv, 4, &rv))
+ if (ReadProcessMemory (hProcess, (void *)context.CONTEXT_SP, &rv, sizeof(rv), &rv))
thread_return_address[tix] = rv;
}
set_step_threads (event.dwThreadId, stepping_enabled);
case STATUS_SINGLE_STEP:
opcode_count++;
- pc = (unsigned int)event.u.Exception.ExceptionRecord.ExceptionAddress;
- sp = (unsigned int)context.Esp;
+ pc = (CONTEXT_REG)event.u.Exception.ExceptionRecord.ExceptionAddress;
+ sp = context.CONTEXT_SP;
if (tracing_enabled)
- fprintf (tracefile, "%08x %08lx\n", pc, event.dwThreadId);
+ fprintf (tracefile, CONTEXT_REG_FMT " %08x\n", pc, (int)event.dwThreadId);
if (trace_console)
{
- printf ("%d %08x\n", tix, pc);
+ printf ("%d " CONTEXT_REG_FMT "\n", tix, pc);
fflush (stdout);
}
@@ -469,7 +480,7 @@ run_program (char *cmdline)
int i;
for (i=num_dlls-1; i>=0; i--)
{
- if (dll_info[i].base_address < context.Eip)
+ if (dll_info[i].base_address < context.CONTEXT_IP)
{
if (hThread == procinfo.hThread)
dll_info[i].pcount++;
@@ -485,23 +496,23 @@ run_program (char *cmdline)
static int ncalls=0;
static int qq=0;
if (++qq % 100 == 0)
- fprintf (stderr, " %08x %d %d \r",
+ fprintf (stderr, " " CONTEXT_REG_FMT " %d %d \r",
pc, ncalls, opcode_count);
- if (sp == last_sp-4)
+ if (sp == last_sp-sizeof(CONTEXT_REG))
{
ncalls++;
store_call_edge (last_pc, pc);
if (last_pc < KERNEL_ADDR && pc > KERNEL_ADDR)
{
- int retaddr;
- DWORD rv;
+#if 0
+ CONTEXT_REG retaddr;
+ SIZE_T rv;
ReadProcessMemory (hProcess,
(void *)sp,
(LPVOID)&(retaddr),
- 4, &rv);
-#if 0
- printf ("call last_pc = %08x pc = %08x rv = %08x\n",
+ sizeof(retaddr), &rv);
+ printf ("call last_pc = " CONTEXT_REG_FMT " pc = " CONTEXT_REG_FMT " rv = " CONTEXT_REG_FMT "\n",
last_pc, pc, retaddr);
/* experimental - try to skip kernel calls for speed */
add_breakpoint (retaddr);
@@ -520,10 +531,10 @@ run_program (char *cmdline)
default:
if (verbose)
{
- printf ("exception %ld, ", event.u.Exception.dwFirstChance);
- printf ("code: %lx flags: %lx\n",
- event.u.Exception.ExceptionRecord.ExceptionCode,
- event.u.Exception.ExceptionRecord.ExceptionFlags);
+ printf ("exception %d, ", (int)event.u.Exception.dwFirstChance);
+ printf ("code: %x flags: %x\n",
+ (int)event.u.Exception.ExceptionRecord.ExceptionCode,
+ (int)event.u.Exception.ExceptionRecord.ExceptionFlags);
if (event.u.Exception.dwFirstChance == 1)
dump_registers (hThread);
}
@@ -562,11 +573,11 @@ run_program (char *cmdline)
&rv);
if (!i)
{
- printf ("error reading memory: %ld %ld\n", rv, GetLastError ());
+ printf ("error reading memory: %zu %u\n", (size_t)rv, (unsigned int)GetLastError ());
}
if (verbose)
- printf ("ODS: %x/%d \"%s\"\n",
- (int)hThread, tix, string);
+ printf ("ODS: %p/%d \"%s\"\n",
+ hThread, tix, string);
if (strcmp (string, "ssp on") == 0)
{
@@ -585,21 +596,22 @@ run_program (char *cmdline)
case LOAD_DLL_DEBUG_EVENT:
if (verbose)
- printf ("load dll %08x:",
- (int)event.u.LoadDll.lpBaseOfDll);
+ printf ("load dll " CONTEXT_REG_FMT ":",
+ (CONTEXT_REG)event.u.LoadDll.lpBaseOfDll);
dll_ptr = (char *)"( u n k n o w n ) \0\0";
if (event.u.LoadDll.lpImageName)
{
+ void *buf;
ReadProcessMemory (hProcess,
event.u.LoadDll.lpImageName,
- (LPVOID)&src,
- sizeof (src),
+ (LPVOID)&buf,
+ sizeof (buf),
&rv);
- if (src)
+ if (buf)
{
ReadProcessMemory (hProcess,
- (void *)src,
+ buf,
(LPVOID)dll_name,
sizeof (dll_name),
&rv);
@@ -617,8 +629,7 @@ run_program (char *cmdline)
}
- dll_info[num_dlls].base_address
- = (unsigned int)event.u.LoadDll.lpBaseOfDll;
+ dll_info[num_dlls].base_address = (CONTEXT_REG)event.u.LoadDll.lpBaseOfDll;
dll_info[num_dlls].pcount = 0;
dll_info[num_dlls].scount = 0;
dll_info[num_dlls].name = wide_strdup (dll_ptr);
@@ -636,9 +647,9 @@ run_program (char *cmdline)
case EXIT_PROCESS_DEBUG_EVENT:
if (verbose)
- printf ("process %08lx %08lx exit %ld\n",
- event.dwProcessId, event.dwThreadId,
- event.u.ExitProcess.dwExitCode);
+ printf ("process %08x %08x exit %d\n",
+ (int)event.dwProcessId, (int)event.dwThreadId,
+ (int)event.u.ExitProcess.dwExitCode);
running = 0;
break;
@@ -892,8 +903,8 @@ main (int argc, char **argv)
if ( (argc - optind) < 3 )
usage (stderr);
- sscanf (argv[optind++], "%i", &low_pc);
- sscanf (argv[optind++], "%i", &high_pc);
+ sscanf (argv[optind++], ADDR_SSCANF_FMT, &low_pc);
+ sscanf (argv[optind++], ADDR_SSCANF_FMT, &high_pc);
if (low_pc > high_pc-8)
{
@@ -904,7 +915,7 @@ main (int argc, char **argv)
hits = (HISTCOUNTER *)malloc (high_pc-low_pc+4);
memset (hits, 0, high_pc-low_pc+4);
- fprintf (stderr, "prun: [%08x,%08x] Running '%s'\n",
+ fprintf (stderr, "prun: [" CONTEXT_REG_FMT "," CONTEXT_REG_FMT "] Running '%s'\n",
low_pc, high_pc, argv[optind]);
run_program (argv[optind]);
@@ -923,8 +934,13 @@ main (int argc, char **argv)
if (dll_counts)
{
- /* 1234567 123% 1234567 123% 12345678 xxxxxxxxxxx */
+#ifdef __x86_64__
+ /* 1234567 123% 1234567 123% 1234567812345678 xxxxxxxxxxx */
+ printf (" Main-Thread Other-Thread BaseAddr DLL Name\n");
+#else
+ /* 1234567 123% 1234567 123% 12345678 xxxxxxxxxxx */
printf (" Main-Thread Other-Thread BaseAddr DLL Name\n");
+#endif
total_pcount = 0;
total_scount = 0;
@@ -940,7 +956,7 @@ main (int argc, char **argv)
for (i=0; i<num_dlls; i++)
if (dll_info[i].pcount || dll_info[i].scount)
{
- printf ("%7d %3d%% %7d %3d%% %08x %s\n",
+ printf ("%7d %3d%% %7d %3d%% " CONTEXT_REG_FMT " %s\n",
dll_info[i].pcount,
(dll_info[i].pcount*100)/opcode_count,
dll_info[i].scount,
@@ -952,5 +968,3 @@ main (int argc, char **argv)
exit (0);
}
-
-#endif /* !__x86_64 */