diff options
author | cvs2svn <> | 2012-10-20 19:31:51 +0400 |
---|---|---|
committer | cvs2svn <> | 2012-10-20 19:31:51 +0400 |
commit | 899ce99cebcb67deca7f9b2a4f1e750a2263881e (patch) | |
tree | 49ee41a55b15ab82f82305e4849859c4a2d1cc54 /winsup/cygwin/pseudo-reloc.cc | |
parent | c0956742a74d194b9c18c7a91aa6d6010beb4cd3 (diff) |
This commit was manufactured by cvs2svn to create tag 'cygwin-cygwin-1_7_17-release
1_7_17-release'.
Sprout from cygwin-64bit-branch 2012-08-10 09:37:33 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin-64bit-'
Cherrypick from cygwin-64bit-branch 2012-10-09 12:05:52 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin-64bit-':
newlib/libc/posix/wordexp2.h
Cherrypick from master 2012-10-20 15:31:50 UTC Corinna Vinschen <corinna@vinschen.de> ' * new-features.sgml (ov-new1.7.17): Add section.':
ChangeLog
Makefile.def
Makefile.in
Makefile.tpl
compile
config.guess
config.sub
config/ChangeLog
config/cloog.m4
config/isl.m4
config/mt-sde
configure
include/ChangeLog
include/demangle.h
include/dis-asm.h
include/dwarf2.def
include/elf/ChangeLog
include/elf/aarch64.h
include/elf/arm.h
include/elf/common.h
include/elf/tilegx.h
include/mach-o/ChangeLog
include/mach-o/codesign.h
include/mach-o/external.h
include/mach-o/loader.h
include/mach-o/reloc.h
include/mach-o/x86-64.h
include/objalloc.h
include/opcode/ChangeLog
include/opcode/aarch64.h
include/opcode/arm.h
include/opcode/hppa.h
include/opcode/ia64.h
include/opcode/mips.h
include/opcode/moxie.h
include/opcode/s390.h
include/opcode/sparc.h
include/plugin-api.h
libtool.m4
ltoptions.m4
ltversion.m4
lt~obsolete.m4
newlib/ChangeLog
newlib/HOWTO
newlib/README
newlib/configure.host
newlib/doc/makedoc.c
newlib/libc/include/_ansi.h
newlib/libc/include/assert.h
newlib/libc/include/machine/_default_types.h
newlib/libc/include/machine/ieeefp.h
newlib/libc/include/machine/setjmp.h
newlib/libc/include/machine/time.h
newlib/libc/include/math.h
newlib/libc/include/stdint.h
newlib/libc/include/sys/config.h
newlib/libc/include/sys/features.h
newlib/libc/include/tgmath.h
newlib/libc/machine/configure
newlib/libc/machine/configure.in
newlib/libc/machine/rl78/Makefile.am
newlib/libc/machine/rl78/Makefile.in
newlib/libc/machine/rl78/aclocal.m4
newlib/libc/machine/rl78/configure
newlib/libc/machine/rl78/configure.in
newlib/libc/machine/rl78/setjmp.S
newlib/libc/posix/engine.c
newlib/libc/posix/wordexp.c
newlib/libc/posix/wordfree.c
newlib/libc/search/hash_buf.c
newlib/libc/stdio/fgets.c
newlib/libc/stdio/flags.c
newlib/libc/stdio/vfprintf.c
newlib/libc/stdlib/btowc.c
newlib/libc/stdlib/getopt.c
newlib/libc/string/strcasestr.c
newlib/libc/sys/sysnecv850/sbrk.c
newlib/libc/time/strftime.c
newlib/libm/machine/configure
newlib/libm/machine/configure.in
newlib/testsuite/newlib.stdio/stdio.exp
newlib/testsuite/newlib.stdio/swprintf.c
winsup/cygwin/ChangeLog
winsup/cygwin/DevNotes
winsup/cygwin/child_info.h
winsup/cygwin/cygheap.cc
winsup/cygwin/cygthread.cc
winsup/cygwin/cygtls.cc
winsup/cygwin/cygtls.h
winsup/cygwin/cygwait.cc
winsup/cygwin/cygwait.h
winsup/cygwin/dll_init.cc
winsup/cygwin/errno.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_clipboard.cc
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_floppy.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/flock.cc
winsup/cygwin/gendef
winsup/cygwin/glob.cc
winsup/cygwin/globals.cc
winsup/cygwin/gmon.c
winsup/cygwin/hookapi.cc
winsup/cygwin/include/cygwin/fs.h
winsup/cygwin/include/cygwin/in.h
winsup/cygwin/include/limits.h
winsup/cygwin/miscfuncs.cc
winsup/cygwin/mount.cc
winsup/cygwin/mount.h
winsup/cygwin/net.cc
winsup/cygwin/path.cc
winsup/cygwin/pinfo.cc
winsup/cygwin/posix_ipc.cc
winsup/cygwin/pseudo-reloc.cc
winsup/cygwin/release/1.7.10
winsup/cygwin/release/1.7.11
winsup/cygwin/release/1.7.12
winsup/cygwin/release/1.7.13
winsup/cygwin/release/1.7.14
winsup/cygwin/release/1.7.15
winsup/cygwin/release/1.7.16
winsup/cygwin/release/1.7.17
winsup/cygwin/sec_helper.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.h
winsup/cygwin/smallprint.cc
winsup/cygwin/spawn.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/tty.h
winsup/cygwin/wait.cc
winsup/doc/ChangeLog
winsup/doc/faq-what.xml
winsup/doc/new-features.sgml
winsup/utils/ChangeLog
winsup/utils/Makefile.in
winsup/utils/cygcheck.cc
winsup/w32api/ChangeLog
winsup/w32api/include/winbase.h
winsup/w32api/lib/kernel32.def
Diffstat (limited to 'winsup/cygwin/pseudo-reloc.cc')
-rw-r--r-- | winsup/cygwin/pseudo-reloc.cc | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/winsup/cygwin/pseudo-reloc.cc b/winsup/cygwin/pseudo-reloc.cc index 04d5d9862..df91e5889 100644 --- a/winsup/cygwin/pseudo-reloc.cc +++ b/winsup/cygwin/pseudo-reloc.cc @@ -126,6 +126,49 @@ __report_error (const char *msg, ...) #endif } +/* + * This function automatically sets addr as PAGE_EXECUTE_READWRITE + * by deciding whether VirtualQuery for the addr is actually needed. + * And it assumes that it is called in LdrpCallInitRoutine. + * Hence not thread safe. + */ +static void +auto_protect_for (void* addr) +{ + static MEMORY_BASIC_INFORMATION mbi; + static bool state = false; + static DWORD oldprot; + + if (!addr) + { + /* Restore original protection. */ + if (!(mbi.Protect & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE))) + VirtualProtect (mbi.BaseAddress, mbi.RegionSize, oldprot, &oldprot); + state = false; + return; + } + if (state) + { + /* We have valid region information. Are we still within this region? + If so, just leave. */ + void *ptr = ((void*) ((ptrdiff_t) mbi.BaseAddress + mbi.RegionSize)); + if (addr >= mbi.BaseAddress && addr < ptr) + return; + /* Otherwise, restore original protection and fall through to querying + and potentially changing next region. */ + if (!(mbi.Protect & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE))) + VirtualProtect (mbi.BaseAddress, mbi.RegionSize, oldprot, &oldprot); + } + else + state = true; + /* Query region and temporarily allow write access to read-only protected + memory. */ + VirtualQuery (addr, &mbi, sizeof mbi); + if (!(mbi.Protect & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE))) + VirtualProtect (mbi.BaseAddress, mbi.RegionSize, + PAGE_EXECUTE_READWRITE, &oldprot); +} + /* This function temporarily marks the page containing addr * writable, before copying len bytes from *src to *addr, and * then restores the original protection settings to the page. @@ -142,27 +185,12 @@ __report_error (const char *msg, ...) static void __write_memory (void *addr, const void *src, size_t len) { - MEMORY_BASIC_INFORMATION b; - DWORD oldprot; - if (!len) return; - - if (!VirtualQuery (addr, &b, sizeof (b))) - { - __report_error (" VirtualQuery failed for %d bytes at address %p", - (int) sizeof (b), addr); - } - - /* Temporarily allow write access to read-only protected memory. */ - if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE) - VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE, - &oldprot); + /* Fix page protection for writing. */ + auto_protect_for (addr); /* write the data. */ memcpy (addr, src, len); - /* Restore original protection. */ - if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE) - VirtualProtect (b.BaseAddress, b.RegionSize, oldprot, &oldprot); } #define RP_VERSION_V1 0 @@ -188,7 +216,7 @@ do_pseudo_reloc (void * start, void * end, void * base) * 1) With a (v2-style) version header. In this case, the * first entry in the list is a 3-DWORD structure, with * value: - * { 0, 0, RP_VERSION_V1 } + * { 0, 0, RP_VERSION_V1 } * In this case, we skip to the next entry in the list, * knowing that all elements after the head item can * be cast to runtime_pseudo_reloc_item_v1. @@ -232,6 +260,8 @@ do_pseudo_reloc (void * start, void * end, void * base) newval = (*((DWORD*) reloc_target)) + o->addend; __write_memory ((void *) reloc_target, &newval, sizeof (DWORD)); } + /* Restore original protection. */ + auto_protect_for (NULL); return; } @@ -322,7 +352,9 @@ do_pseudo_reloc (void * start, void * end, void * base) break; #endif } - } + } + /* Restore original protection. */ + auto_protect_for (NULL); } #ifdef __CYGWIN__ |