summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2012-04-27 12:07:15 +0000
committerCorinna Vinschen <corinna@vinschen.de>2012-04-27 12:07:15 +0000
commit2d487f2dd6b3c4aa901b381b28b7539d39b19ffe (patch)
tree7767bdef0f5ab2f3f083cffea9e322954f2f4696
parent8162f580cba7facf6bdfc58286b9ac5c3a499c50 (diff)
downloadcygnal-2d487f2dd6b3c4aa901b381b28b7539d39b19ffe.tar.gz
cygnal-2d487f2dd6b3c4aa901b381b28b7539d39b19ffe.tar.bz2
cygnal-2d487f2dd6b3c4aa901b381b28b7539d39b19ffe.zip
* path.cc (find_fast_cwd_pointer): Fix for W8 CP 32 bit.
-rw-r--r--winsup/cygwin/ChangeLog4
-rw-r--r--winsup/cygwin/path.cc75
2 files changed, 58 insertions, 21 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 1300321f5..c8186e4e7 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,7 @@
+2012-04-27 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (find_fast_cwd_pointer): Fix for W8 CP 32 bit.
+
2012-04-25 Thomas Wolff <towo@towo.net>
* fhandler.h (class dev_console): Add member ext_mouse_mode5.
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 3524c0cc0..59e6de384 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3699,31 +3699,64 @@ find_fast_cwd_pointer ()
/* ...which should be followed by "mov edi, crit-sect-addr" then
"push edi", or by just a single "push crit-sect-addr". */
const uint8_t *movedi = pushedi + 1;
- if (movedi[0] == 0xbf && movedi[5] == 0x57)
- rcall = movedi + 6;
- else if (movedi[0] == 0x68)
- rcall = movedi + 5;
+ const uint8_t *mov_pfast_cwd;
+ if (movedi[0] == 0x8b && movedi[1] == 0xff) /* mov edi,edi -> W8 */
+ {
+ /* Windows 8 CP 32 bit (after a Windows Update?) does not call
+ RtlEnterCriticalSection. For some reason the function manipulates
+ the FastPebLock manually, kind of like RtlEnterCriticalSection has
+ been converted to an inline function.
+
+ Next we search for a `mov eax, some address'. This address points
+ to the LockCount member of the FastPebLock structure, so the address
+ is equal to FastPebLock + 4. */
+ const uint8_t *moveax = (const uint8_t *) memchr (movedi, 0xb8, 16);
+ if (!moveax)
+ return NULL;
+ offset = (ptrdiff_t) peek32 (moveax + 1) - 4;
+ /* Compare the address with the known PEB lock as stored in the PEB. */
+ if ((PRTL_CRITICAL_SECTION) offset != NtCurrentTeb ()->Peb->FastPebLock)
+ return NULL;
+ /* Now search for the mov instruction fetching the address of the global
+ PFAST_CWD *. */
+ mov_pfast_cwd = moveax;
+ do
+ {
+ mov_pfast_cwd = (const uint8_t *) memchr (++mov_pfast_cwd, 0x8b, 48);
+ }
+ while (mov_pfast_cwd && mov_pfast_cwd[1] != 0x1d
+ && (mov_pfast_cwd - moveax) < 48);
+ if (!mov_pfast_cwd || mov_pfast_cwd[1] != 0x1d)
+ return NULL;
+ }
else
- return NULL;
- /* Compare the address used for the critical section with the known
- PEB lock as stored in the PEB. */
- if ((PRTL_CRITICAL_SECTION) peek32 (movedi + 1)
- != NtCurrentTeb ()->Peb->FastPebLock)
- return NULL;
- /* To check we are seeing the right code, we check our expectation that
- the next instruction is a relative call into RtlEnterCriticalSection. */
- if (rcall[0] != 0xe8)
- return NULL;
- /* Check that this is a relative call to RtlEnterCriticalSection. */
- offset = (ptrdiff_t) peek32 (rcall + 1);
- if (rcall + 5 + offset != ent_crit)
- return NULL;
+ {
+ if (movedi[0] == 0xbf && movedi[5] == 0x57)
+ rcall = movedi + 6;
+ else if (movedi[0] == 0x68)
+ rcall = movedi + 5;
+ else
+ return NULL;
+ /* Compare the address used for the critical section with the known
+ PEB lock as stored in the PEB. */
+ if ((PRTL_CRITICAL_SECTION) peek32 (movedi + 1)
+ != NtCurrentTeb ()->Peb->FastPebLock)
+ return NULL;
+ /* To check we are seeing the right code, we check our expectation that
+ the next instruction is a relative call into RtlEnterCriticalSection. */
+ if (rcall[0] != 0xe8)
+ return NULL;
+ /* Check that this is a relative call to RtlEnterCriticalSection. */
+ offset = (ptrdiff_t) peek32 (rcall + 1);
+ if (rcall + 5 + offset != ent_crit)
+ return NULL;
+ mov_pfast_cwd = rcall + 5;
+ }
/* After locking the critical section, the code should read the global
PFAST_CWD * pointer that is guarded by that critical section. */
- const uint8_t *movesi = rcall + 5;
- if (movesi[0] != 0x8b)
+ if (mov_pfast_cwd[0] != 0x8b)
return NULL;
- return (fcwd_access_t **) peek32 (movesi + 2);
+ return (fcwd_access_t **) peek32 (mov_pfast_cwd + 2);
}
static fcwd_access_t **