4343
4444#ifndef BASE_GETPC_H_
4545#define BASE_GETPC_H_
46-
47- #if ((ULONG_MAX) == (UINT_MAX))
48- # define IS32BIT
49- #else
50- # define IS64BIT
51- #endif
52-
53- #include " vmprof_config.h"
54-
5546// On many linux systems, we may need _GNU_SOURCE to get access to
5647// the defined constants that define the register we want to see (eg
5748// REG_EIP). Note this #define must come first!
6051// It will cause problems for FreeBSD though!, because it turns off
6152// the needed __BSD_VISIBLE.
6253#ifdef __APPLE__
54+ #include < limits.h>
6355#define _XOPEN_SOURCE 500
64- #endif // __APPLE__
56+ #endif
57+
58+ #include " vmprof_config.h"
6559
6660#include < string.h> // for memcmp
6761#if defined(HAVE_SYS_UCONTEXT_H)
7165#elif defined(HAVE_CYGWIN_SIGNAL_H)
7266#include < cygwin/signal.h>
7367typedef ucontext ucontext_t ;
68+ #elif defined(HAVE_SIGNAL_H)
69+ #include < signal.h>
70+ #else
71+ # error "don't know how to get the pc on this platform"
7472#endif
7573
7674
@@ -117,52 +115,8 @@ struct CallUnrollInfo {
117115// PC_FROM_UCONTEXT in config.h. The only thing we need to do here,
118116// then, is to do the magic call-unrolling for systems that support it.
119117
120- // -- Special case 1: linux x86, for which we have CallUnrollInfo
121- #if defined(__linux) && defined(__i386) && defined(__GNUC__)
122- static const struct CallUnrollInfo callunrollinfo[] = {
123- // Entry to a function: push %ebp; mov %esp,%ebp
124- // Top-of-stack contains the caller IP.
125- { 0 ,
126- {0x55 , 0x89 , 0xe5 }, 3 ,
127- 0
128- },
129- // Entry to a function, second instruction: push %ebp; mov %esp,%ebp
130- // Top-of-stack contains the old frame, caller IP is +4.
131- { -1 ,
132- {0x55 , 0x89 , 0xe5 }, 3 ,
133- 4
134- },
135- // Return from a function: RET.
136- // Top-of-stack contains the caller IP.
137- { 0 ,
138- {0xc3 }, 1 ,
139- 0
140- }
141- };
142-
143- void * GetPC (ucontext_t *signal_ucontext) {
144- // See comment above struct CallUnrollInfo. Only try instruction
145- // flow matching if both eip and esp looks reasonable.
146- const int eip = signal_ucontext->uc_mcontext .gregs [REG_EIP ];
147- const int esp = signal_ucontext->uc_mcontext .gregs [REG_ESP ];
148- if ((eip & 0xffff0000 ) != 0 && (~eip & 0xffff0000 ) != 0 &&
149- (esp & 0xffff0000 ) != 0 ) {
150- char * eip_char = (char *)(eip);
151- int i;
152- for (i = 0 ; i < sizeof (callunrollinfo)/sizeof (*callunrollinfo); ++i) {
153- if (!memcmp (eip_char + callunrollinfo[i].pc_offset ,
154- callunrollinfo[i].ins , callunrollinfo[i].ins_size )) {
155- // We have a match.
156- void **retaddr = (void **)(esp + callunrollinfo[i].return_sp_offset );
157- return *retaddr;
158- }
159- }
160- }
161- return (void *)eip;
162- }
163-
164- // Special case #2: Windows, which has to do something totally different.
165- #elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
118+ // Special case Windows, which has to do something totally different.
119+ #if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
166120// If this is ever implemented, probably the way to do it is to have
167121// profiler.cc use a high-precision timer via timeSetEvent:
168122// http://msdn2.microsoft.com/en-us/library/ms712713.aspx
@@ -172,31 +126,24 @@ void* GetPC(ucontext_t *signal_ucontext) {
172126// how we'd get the PC (using StackWalk64?)
173127// http://msdn2.microsoft.com/en-us/library/ms680650.aspx
174128
175- #include " base/logging.h" // for RAW_LOG
176- #ifndef HAVE_CYGWIN_SIGNAL_H
177- typedef int ucontext_t ;
178- #endif
129+ // #include "base/logging.h" // for RAW_LOG
130+ // #ifndef HAVE_CYGWIN_SIGNAL_H
131+ // typedef int ucontext_t;
132+ // #endif
179133
180- void * GetPC (ucontext_t *signal_ucontext) {
181- RAW_LOG (ERROR , " GetPC is not yet implemented on Windows\n " );
134+ static intptr_t GetPC (ucontext_t *signal_ucontext) {
135+ // RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n");
136+ fprintf (stderr, " GetPC is not yet implemented on Windows\n " );
182137 return NULL ;
183138}
184139
185140// Normal cases. If this doesn't compile, it's probably because
186141// PC_FROM_UCONTEXT is the empty string. You need to figure out
187142// the right value for your system, and add it to the list in
188- // configure.ac (or set it manually in your config.h).
189- #else
190- void * GetPC (ucontext_t *signal_ucontext) {
191- #ifdef __APPLE__
192- #ifdef IS32BIT
193- return (void *)(signal_ucontext->uc_mcontext ->__ss .__eip );
194- #else
195- return (void *)(signal_ucontext->uc_mcontext ->__ss .__rip );
196- #endif
143+ // vmrpof_config.h
197144#else
198- return ( void *) signal_ucontext-> PC_FROM_UCONTEXT ; // defined in config.h
199- # endif
145+ static intptr_t GetPC ( ucontext_t * signal_ucontext) {
146+ return signal_ucontext-> PC_FROM_UCONTEXT ; // defined in config.h
200147}
201148
202149#endif
0 commit comments