This is the mail archive of the cygwin-developers mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: CFA: pseudo-reloc v2


So here's another approach. It relies on the
cygwin_terminate_process/cygwin_exit_process wrapper functions, posted
here: http://cygwin.com/ml/cygwin-patches/2009-q4/msg00028.html

Attached are two patches. The first contains modifications to the cygwin
DLL.

2009-10-04  Charles Wilson  <...>

	* ntdll.h: Add custom NTSTATUS value for pseudo-reloc
	errors STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION.
	* pinfo.cc (status_exit): Map custom pseudo-reloc
	error value STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION to 127.
	* sigproc.cc (child_info::proc_retry): Return exit code when
        STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION.

The second shows the differences between winsup/mingw/pseudo-reloc.c and
winsup/cygwin/lib/pseudo-reloc.c -- that is, it assumes you've already
copied the mingw version over.  When I post this to cygwin-patches, I'll
make a traditional diff against CVS HEAD.

This one differs from previous iterations:
 1) it uses WriteFile instead of WriteConsoleW.
 2) it gets the module name and path itself, and prints error
    messages in a form similar to that used already in
    pinfo::status_exit() for STATUS_DLL_NOT_FOUND.
 3) Nor more need for write_console code copied from cygwin proper,
    which is good because that was questionable, license-wise.

Anyway, when combined with the 'TerminateProcess' wrapper patch, this
version works in every test I've thrown at it.

--
Chuck

Index: ntdll.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/ntdll.h,v
retrieving revision 1.94
diff -u -p -r1.94 ntdll.h
--- ntdll.h	14 Jul 2009 17:37:42 -0000	1.94
+++ ntdll.h	5 Oct 2009 16:58:49 -0000
@@ -46,6 +46,8 @@
 #define STATUS_ENTRYPOINT_NOT_FOUND   ((NTSTATUS) 0xc0000139)
 #define STATUS_BAD_DLL_ENTRYPOINT     ((NTSTATUS) 0xc0000251)
 #define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xc0000269)
+/* custom status code: */
+#define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269)
 
 #define PDI_MODULES 0x01
 #define PDI_HEAPS 0x04
Index: pinfo.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/pinfo.cc,v
retrieving revision 1.253
diff -u -p -r1.253 pinfo.cc
--- pinfo.cc	12 Jul 2009 21:15:47 -0000	1.253
+++ pinfo.cc	5 Oct 2009 16:58:49 -0000
@@ -128,6 +128,10 @@ status_exit (DWORD x)
 	x = 127;
       }
       break;
+    case STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION: /* custom error value */
+      /* We've already printed the error message in pseudo-reloc.c */
+      x = 127;
+      break;
     default:
       x = 127;
     }
Index: sigproc.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/sigproc.cc,v
retrieving revision 1.317
diff -u -p -r1.317 sigproc.cc
--- sigproc.cc	2 Aug 2009 21:38:40 -0000	1.317
+++ sigproc.cc	5 Oct 2009 16:58:49 -0000
@@ -923,6 +923,8 @@ child_info::proc_retry (HANDLE h)
       break;
     case STATUS_DLL_NOT_FOUND:
       return exit_code;
+    case STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION: /* pseudo-reloc.c specific */
+      return exit_code;
     case STATUS_CONTROL_C_EXIT:
       if (saw_ctrl_c ())
 	return EXITCODE_OK;
--- winsup/mingw/pseudo-reloc.c	2009-03-17 09:18:08.463300000 -0400
+++ winsup/cygwin/lib/pseudo-reloc.c	2009-10-05 14:07:10.268200000 -0400
@@ -20,6 +20,19 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+
+#if defined(__CYGWIN__)
+#include <wchar.h>
+#include <ntdef.h>
+#include <stdarg.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)
+#else
+# define NO_COPY
+#endif
  
  extern char __RUNTIME_PSEUDO_RELOC_LIST__;
  extern char __RUNTIME_PSEUDO_RELOC_LIST_END__;
@@ -42,6 +55,51 @@
   DWORD version;
 } runtime_pseudo_reloc_v2;
 
+#if defined(__CYGWIN__)
+#define SHORT_MSG_BUF_SZ 128
+static BOOL
+__print_reloc_error (const char *fmt, ...)
+{
+  char buf[SHORT_MSG_BUF_SZ];
+  wchar_t module[MAX_PATH];
+  char * posix_module = NULL;
+  BOOL rVal = FALSE;
+  static const char * UNKNOWN_MODULE = "<unknown module>: ";
+  DWORD len;
+  DWORD done;
+  va_list args;
+  HANDLE errh = GetStdHandle (STD_ERROR_HANDLE);
+  ssize_t modulelen = GetModuleFileNameW (NULL, module, sizeof (module));
+
+  if (errh == INVALID_HANDLE_VALUE)
+    return FALSE;
+
+  if (modulelen > 0)
+    posix_module = cygwin_create_path (CCP_WIN_W_TO_POSIX, module);
+
+  va_start (args, fmt);
+  len = (DWORD) vsnprintf (buf, SHORT_MSG_BUF_SZ, fmt, args);
+  va_end (args);
+  buf[SHORT_MSG_BUF_SZ-1] = '\0'; /* paranoia */
+
+  if (posix_module)
+    {
+      rVal = 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
+    {
+      rVal = WriteFile (errh, (PCVOID)UNKNOWN_MODULE,
+                        sizeof(UNKNOWN_MODULE), &done, NULL) &&
+             WriteFile (errh, (PCVOID)buf, len, &done, NULL);
+    }
+  return rVal;
+}
+#endif /* __CYGWIN__ */
+
 static void
 __write_memory (void *addr,const void *src,size_t len)
 {
@@ -49,7 +107,20 @@
   DWORD oldprot;
   if (!len)
     return;
+
+#if defined(__CYGWIN__)
+  if (!VirtualQuery (addr, &b, sizeof(b)))
+    {
+      __print_reloc_error (
+        "error while loading shared libraries: bad address specified 0x%08x.\n",
+        addr);
+      cygwin_terminate_process (GetCurrentProcess(),
+                                STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION);
+    }
+#else
   assert (VirtualQuery (addr, &b, sizeof(b)));
+#endif
+
   /* 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,
@@ -95,10 +166,18 @@
   /* Check if this is a known version.  */
   if (v2_hdr->version != RP_VERSION_V2)
     {
-#ifdef DEBUG
+#if defined(__CYGWIN__)
+      __print_reloc_error (
+        "error while loading shared libraries: invalid pseudo_reloc version %d.\n",
+        (int) v2_hdr->version);
+     cygwin_terminate_process (GetCurrentProcess(),
+                               STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION);
+#else
+# if defined(DEBUG)
       fprintf (stderr, "internal mingw runtime error:"
 	       "psuedo_reloc version %d is unknown to this runtime.\n",
 	       (int) v2_hdr->version);
+# endif
 #endif
       return;
     }
@@ -139,9 +218,15 @@
 	  default:
 	    reldata=0;
 #ifdef DEBUG
+# if defined(__CYGWIN__)
+            __print_reloc_error (
+              "error while loading shared libraries: unknown pseudo_reloc bit size %d.\n",
+              (int) (r->flags & 0xff));
+# else
     	    fprintf(stderr, "internal mingw runtime error: "
 		    "unknown pseudo_reloc bit size %d\n",
 		    (int) (r->flags & 0xff));
+# endif
 #endif
 	    break;
         }
@@ -170,7 +255,7 @@
 void
  _pei386_runtime_relocator ()
 {
-  static int was_init = 0;
+  static NO_COPY int was_init = 0;
   if (was_init)
     return;
   ++was_init;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]