summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/pseudo-reloc.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2010-05-07 21:25:19 +0000
committerChristopher Faylor <me@cgf.cx>2010-05-07 21:25:19 +0000
commit27f564e9a3c8c81e95d8bfa195c0a3edadb35127 (patch)
tree5663c2caa484f99bd905192e69b634cc45c45454 /winsup/cygwin/pseudo-reloc.cc
parent186bcf2a17b1b9566853e1d3ce221109f9335ad6 (diff)
downloadcygnal-27f564e9a3c8c81e95d8bfa195c0a3edadb35127.tar.gz
cygnal-27f564e9a3c8c81e95d8bfa195c0a3edadb35127.tar.bz2
cygnal-27f564e9a3c8c81e95d8bfa195c0a3edadb35127.zip
* Makefile.in (DLL_OFILES): Add pseudo-reloc.o.
* dcrt0.cc (child_info_fork::handle_fork): Call _pei386_runtime_relocator here. (dll_crt0_1): Ditto for non-fork case. * dll_init.cc (dll::init): Complain more in comment. Clean up slightly. (dll_dllcrt0_1): Call _pei386_runtime_relocator when we know we have a filled-in per_process structure. * globals.cc (__cygwin_user_data): Accommodate new fields for _pei386_runtime_relocator. * pseudo-reloc.cc: New file adapted from old lib/pseudo-reloc.c. Include winsup.h directly. Collapse #ifdef __CYGWIN__ into one block. Perform minor whitespace code reformatting. (__report_error): Use small_printf to output error. (_pei386_runtime_relocator): Conditionalize for cygwin to take per_process pointer parameter. * winsup.h (_pei386_runtime_relocator): Declare. * include/cygwin/version.h (CYGWIN_VERSION_PER_PROCESS_API_VERSION_COMBINED): New macro. (CYGWIN_VERSION_USER_API_VERSION_COMBINED): Use above macro. (CYGWIN_VERSION_USE_PSEUDO_RELOC_IN_DLL): New macro. (CYGWIN_VERSION_API_MINOR): Bump to 227. * include/sys/cygwin.h: Remove obsolete comment. (per_process::unused2): Shorten. (per_process::pseudo_reloc_start): New field. (per_process::pseudo_reloc_end): Ditto. (per_process::image_base): Ditto. * lib/_cygwin_crt0_common.cc: Declare pseudo runtime externs needed for per_process structure. (_cygwin_crt0_common): Fill in pseudo_reloc runtime constants. * lib/pseudo-reloc-dummy.c: New file. Dummy function to satisify ld. * lib/pseudo-reloc.c: Delete.
Diffstat (limited to 'winsup/cygwin/pseudo-reloc.cc')
-rw-r--r--winsup/cygwin/pseudo-reloc.cc160
1 files changed, 71 insertions, 89 deletions
diff --git a/winsup/cygwin/pseudo-reloc.cc b/winsup/cygwin/pseudo-reloc.cc
index 77f041114..290c1a838 100644
--- a/winsup/cygwin/pseudo-reloc.cc
+++ b/winsup/cygwin/pseudo-reloc.cc
@@ -15,25 +15,23 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <windows.h>
+#ifndef __CYGWIN__
+# include "windows.h"
+# define NO_COPY
+#else
+# include "winsup.h"
+# include <wchar.h>
+# include <ntdef.h>
+# include <sys/cygwin.h>
+/* custom status code: */
+# define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269)
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <memory.h>
-#if defined(__CYGWIN__)
-#include <wchar.h>
-#include <ntdef.h>
-#include <sys/cygwin.h>
-/* copied from winsup.h */
-# define NO_COPY __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy")))
-/* custom status code: */
-#define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269)
-#define SHORT_MSG_BUF_SZ 128
-#else
-# define NO_COPY
-#endif
-
#ifdef __GNUC__
#define ATTRIBUTE_NORETURN __attribute__ ((noreturn))
#else
@@ -48,8 +46,6 @@ extern char __RUNTIME_PSEUDO_RELOC_LIST__;
extern char __RUNTIME_PSEUDO_RELOC_LIST_END__;
extern char __MINGW_LSYMBOL(_image_base__);
-void _pei386_runtime_relocator (void);
-
/* v1 relocation is basically:
* *(base + .target) += .addend
* where (base + .target) is always assumed to point
@@ -90,55 +86,32 @@ __report_error (const char *msg, ...)
* normal win32 console IO handles, redirected ones, and
* cygwin ptys.
*/
- char buf[SHORT_MSG_BUF_SZ];
+ char buf[128];
wchar_t module[MAX_PATH];
char * posix_module = NULL;
- static const char UNKNOWN_MODULE[] = "<unknown module>: ";
- static const size_t UNKNOWN_MODULE_LEN = sizeof (UNKNOWN_MODULE) - 1;
- static const char CYGWIN_FAILURE_MSG[] = "Cygwin runtime failure: ";
- static const size_t CYGWIN_FAILURE_MSG_LEN = sizeof (CYGWIN_FAILURE_MSG) - 1;
- DWORD len;
- DWORD done;
- va_list args;
+ static const char UNKNOWN_MODULE[] = "<unknown module>: ";
+ static const char CYGWIN_FAILURE_MSG[] = "Cygwin runtime failure: ";
HANDLE errh = GetStdHandle (STD_ERROR_HANDLE);
ssize_t modulelen = GetModuleFileNameW (NULL, module, sizeof (module));
+ va_list args;
+ /* FIXME: cleanup further to avoid old use of cygwin_internal */
if (errh == INVALID_HANDLE_VALUE)
- cygwin_internal (CW_EXIT_PROCESS,
- STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION,
- 1);
+ cygwin_internal (CW_EXIT_PROCESS, STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION, 1);
if (modulelen > 0)
- posix_module = cygwin_create_path (CCP_WIN_W_TO_POSIX, module);
+ posix_module = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, module);
va_start (args, msg);
- len = (DWORD) vsnprintf (buf, SHORT_MSG_BUF_SZ, msg, args);
+ vsnprintf (buf, sizeof (buf), msg, args);
va_end (args);
- buf[SHORT_MSG_BUF_SZ-1] = '\0'; /* paranoia */
+ buf[sizeof (buf) - 1] = '\0'; /* paranoia */
+ small_printf ("%s%s: %s\n", CYGWIN_FAILURE_MSG, posix_module ?: UNKNOWN_MODULE, buf);
if (posix_module)
- {
- WriteFile (errh, (PCVOID)CYGWIN_FAILURE_MSG,
- CYGWIN_FAILURE_MSG_LEN, &done, NULL);
- WriteFile (errh, (PCVOID)posix_module,
- strlen(posix_module), &done, NULL);
- WriteFile (errh, (PCVOID)": ", 2, &done, NULL);
- WriteFile (errh, (PCVOID)buf, len, &done, NULL);
- free (posix_module);
- }
- else
- {
- WriteFile (errh, (PCVOID)CYGWIN_FAILURE_MSG,
- CYGWIN_FAILURE_MSG_LEN, &done, NULL);
- WriteFile (errh, (PCVOID)UNKNOWN_MODULE,
- UNKNOWN_MODULE_LEN, &done, NULL);
- WriteFile (errh, (PCVOID)buf, len, &done, NULL);
- }
- WriteFile (errh, (PCVOID)"\n", 1, &done, NULL);
+ free (posix_module);
- cygwin_internal (CW_EXIT_PROCESS,
- STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION,
- 1);
+ cygwin_internal (CW_EXIT_PROCESS, STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION, 1);
/* not reached, but silences noreturn warning */
abort ();
#else
@@ -177,10 +150,10 @@ __write_memory (void *addr, const void *src, size_t len)
if (!len)
return;
- if (!VirtualQuery (addr, &b, sizeof(b)))
+ if (!VirtualQuery (addr, &b, sizeof (b)))
{
__report_error (" VirtualQuery failed for %d bytes at address %p",
- (int) sizeof(b), addr);
+ (int) sizeof (b), addr);
}
/* Temporarily allow write access to read-only protected memory. */
@@ -259,7 +232,7 @@ do_pseudo_reloc (void * start, void * end, void * base)
DWORD newval;
reloc_target = (ptrdiff_t) base + o->target;
newval = (*((DWORD*) reloc_target)) + o->addend;
- __write_memory ((void *) reloc_target, &newval, sizeof(DWORD));
+ __write_memory ((void *) reloc_target, &newval, sizeof (DWORD));
}
return;
}
@@ -300,33 +273,33 @@ do_pseudo_reloc (void * start, void * end, void * base)
*/
switch ((r->flags & 0xff))
{
- case 8:
- reldata = (ptrdiff_t) (*((unsigned char *)reloc_target));
- if ((reldata & 0x80) != 0)
- reldata |= ~((ptrdiff_t) 0xff);
- break;
- case 16:
- reldata = (ptrdiff_t) (*((unsigned short *)reloc_target));
- if ((reldata & 0x8000) != 0)
- reldata |= ~((ptrdiff_t) 0xffff);
- break;
- case 32:
- reldata = (ptrdiff_t) (*((unsigned int *)reloc_target));
+ case 8:
+ reldata = (ptrdiff_t) (*((unsigned char *)reloc_target));
+ if ((reldata & 0x80) != 0)
+ reldata |= ~((ptrdiff_t) 0xff);
+ break;
+ case 16:
+ reldata = (ptrdiff_t) (*((unsigned short *)reloc_target));
+ if ((reldata & 0x8000) != 0)
+ reldata |= ~((ptrdiff_t) 0xffff);
+ break;
+ case 32:
+ reldata = (ptrdiff_t) (*((unsigned int *)reloc_target));
#ifdef _WIN64
- if ((reldata & 0x80000000) != 0)
- reldata |= ~((ptrdiff_t) 0xffffffff);
+ if ((reldata & 0x80000000) != 0)
+ reldata |= ~((ptrdiff_t) 0xffffffff);
#endif
- break;
+ break;
#ifdef _WIN64
- case 64:
- reldata = (ptrdiff_t) (*((unsigned long long *)reloc_target));
- break;
+ case 64:
+ reldata = (ptrdiff_t) (*((unsigned long long *)reloc_target));
+ break;
#endif
- default:
- reldata=0;
- __report_error (" Unknown pseudo relocation bit size %d.\n",
- (int) (r->flags & 0xff));
- break;
+ default:
+ reldata=0;
+ __report_error (" Unknown pseudo relocation bit size %d.\n",
+ (int) (r->flags & 0xff));
+ break;
}
/* Adjust the relocation value */
@@ -336,25 +309,33 @@ do_pseudo_reloc (void * start, void * end, void * base)
/* Write the new relocation value back to *reloc_target */
switch ((r->flags & 0xff))
{
- case 8:
- __write_memory ((void *) reloc_target, &reldata, 1);
- break;
- case 16:
- __write_memory ((void *) reloc_target, &reldata, 2);
- break;
- case 32:
- __write_memory ((void *) reloc_target, &reldata, 4);
- break;
+ case 8:
+ __write_memory ((void *) reloc_target, &reldata, 1);
+ break;
+ case 16:
+ __write_memory ((void *) reloc_target, &reldata, 2);
+ break;
+ case 32:
+ __write_memory ((void *) reloc_target, &reldata, 4);
+ break;
#ifdef _WIN64
- case 64:
- __write_memory ((void *) reloc_target, &reldata, 8);
- break;
+ case 64:
+ __write_memory ((void *) reloc_target, &reldata, 8);
+ break;
#endif
}
}
}
+#ifdef __CYGWIN__
void
+_pei386_runtime_relocator (per_process *u)
+{
+ if (CYGWIN_VERSION_USE_PSEUDO_RELOC_IN_DLL (u))
+ do_pseudo_reloc (u->pseudo_reloc_start, u->pseudo_reloc_end, u->image_base);
+}
+#else
+extern "C" void
_pei386_runtime_relocator (void)
{
static NO_COPY int was_init = 0;
@@ -365,3 +346,4 @@ _pei386_runtime_relocator (void)
&__RUNTIME_PSEUDO_RELOC_LIST_END__,
&__MINGW_LSYMBOL(_image_base__));
}
+#endif