Do not SIGSEGV patch 'pass' functions of W32 code in non--debug-messages mode.
authorshort <>
Tue, 28 Oct 2003 18:58:46 +0000 (18:58 +0000)
committershort <>
Tue, 28 Oct 2003 18:58:46 +0000 (18:58 +0000)
 - Performance reasons.

src/libcaptive/client/init.c
src/libcaptive/include/captive/ldr_exports.h
src/libcaptive/ke/captivesym.pl
src/libcaptive/ldr/loader.c

index a2459e4..e20eda6 100644 (file)
@@ -167,14 +167,17 @@ NTSTATUS err;
                *KeNumberProcessorsp=KeNumberProcessors;
                g_assert(*KeNumberProcessorsp==1);
                }
-       /* Apply captive_kernel_patches() AFTER any symbols sanity checks above! */
-       captive_kernel_patches();
+       /* Apply AFTER any symbols sanity checks above! */
+       if (captive_options->debug_messages)
+               captive_kernel_patches_debug();
+       else
+               captive_kernel_patches_nondebug();
 
        _local_unwind2_addr=captive_Module_GetExportAddress("ntoskrnl.exe","_local_unwind2");
 
        /* Initialize 'FsRtlLegalAnsiCharacterArray'.
         * It requires 'ntoskrnl.exe' loaded by 'captive_options->load_module' above;
-        * captive_kernel_patches() should not be needed.
+        * captive_kernel_patches_debug()/captive_kernel_patches_nondebug() should not be needed.
         */
        captive_FsRtlLegalAnsiCharacterArray_init();
 
index 72c777a..280e04c 100644 (file)
@@ -49,7 +49,7 @@ gboolean captive_kernel_exports(void);
 
 
 /**
- * captive_kernel_patches:
+ * captive_kernel_patches_debug:
  *
  * Patches W32 libraries by libcaptive functions. It is done by *.def files used
  * by dlltool(1) of Mingw32 compiler suite. We use native host OS compiler and
@@ -60,11 +60,27 @@ gboolean captive_kernel_exports(void);
  * This function is generated automatically from #exports.captivesym file
  * by #captivesym.pl script.
  *
+ * This function is used in --debug-messages mode as it also patches 'pass'
+ * functions to be successfuly debug dumped.
+ *
  * Multiple calls of this function are forbidden. See also captive_kernel_exports().
  *
  * Returns: %TRUE if the export was successful.
  */
-gboolean captive_kernel_patches(void);
+gboolean captive_kernel_patches_debug(void);
+
+
+/**
+ * captive_kernel_patches_nondebug:
+ *
+ * Function equivalent to captive_kernel_patches_debug() but it does not patch
+ * 'pass' functions as they are not needed to be traced if no --debug-messages
+ * was specified. See captive_kernel_patches_debug() for the description
+ * of this function.
+ *
+ * Returns: %TRUE if the export was successful.
+ */
+gboolean captive_kernel_patches_nondebug(void);
 
 
 struct captive_ModuleList_patchpoint {
index 5811ba4..f37f9be 100755 (executable)
@@ -108,6 +108,8 @@ print <<"HERE";
 #include <string.h>    /* for built-in: strncmp,memmove,strncpy */
 
 
+extern gboolean captive_debug_messages_disabled;
+
 HERE
 
 for my $symbol (sort keys(%symbol)) {
@@ -195,8 +197,20 @@ HERE
                                        "\tg_return_val_if_fail(${symbol}_patchpoint.orig_w32_func!=NULL,0);\n",
                                        "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n",
                                        "\t${symbol}_patchpoint.through_w32_func=TRUE;\n",
-                                       "\tr=(*(${symbol}_t_attrib *)${symbol}_patchpoint.orig_w32_func)(".join(",",@args_in).");\n",
-                                       "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n";
+                                       "\tr=(*(${symbol}_t_attrib *)${symbol}_patchpoint.orig_w32_func)(".join(",",@args_in).");\n";
+                       if (!$def->{"pass"}) {
+                               print 
+                                               "\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n";
+                               }
+                       else {
+                               print
+                                               "\tif (!captive_debug_messages_disabled)\n",
+                                               "\t\tg_assert(${symbol}_patchpoint.through_w32_func==FALSE);\n",
+                                               "\telse {\n",
+                                               "\t\tg_assert(${symbol}_patchpoint.through_w32_func==TRUE);\n",
+                                               "\t\t${symbol}_patchpoint.through_w32_func=FALSE;\n",
+                                               "\t\t}\n";
+                               }
                        }
                else {
                        print
@@ -215,7 +229,7 @@ HERE
        }
 
 # write function captive_kernel_{exports,patches}()
-for my $functype ("exports","patches") {
+for my $functype ("exports","patches_debug","patches_nondebug") {
        print <<"HERE";
 
 gboolean captive_kernel_$functype(void)
@@ -225,17 +239,20 @@ gboolean errbool;
 HERE
        for my $module (sort keys(%module)) {
                my $moduleref=$module{$module};
-               next if ($functype eq "patches") != defined $patch{$module};
+               next if ($functype=~/^patches/) != defined $patch{$module};
                print "\t\terrbool="
-                               .($functype eq "patches" ? "captive_ModuleList_patch" : "captive_ModuleList_add_builtin")
+                               .($functype=~/^patches/ ? "captive_ModuleList_patch" : "captive_ModuleList_add_builtin")
                                ."(\"$module\",\n";
                for my $symbol (sort keys(%$moduleref)) {
-                       next if $functype eq "patches" && !$def{$symbol};
+                       next if $functype=~/^patches/ && !$def{$symbol};
                        (my $symbol_outer=$symbol)=~s/^captive_reactos_//;
-                       print "\t\t\t\"$symbol_outer\",",(($functype eq "patches" && "data" eq $def{$symbol}{"type"}
-                                                                       && ($def{$symbol}{"pass"} || $def{$symbol}{"wrap"})) ? ("NULL")
+                       print "\t\t\t\"$symbol_outer\",",(($functype=~/^patches/ && "data" eq $def{$symbol}{"type"}
+                                                                                       && ($def{$symbol}{"pass"} || $def{$symbol}{"wrap"})) ? ("NULL")
                                                        : ("&${symbol}_",($def{$symbol}{"type"} || "undef"))),
-                                       (($functype ne "patches") ? () : (",".("data" eq $def{$symbol}{"type"} ? "NULL" : "&${symbol}_patchpoint"))),
+                                       (($functype!~/^patches/) ? () :
+                                                       (",".("data" eq $def{$symbol}{"type"} ? "NULL,NULL" :
+                                                                       ($functype eq "patches_nondebug" && $def{$symbol}{"pass"} ? "&${symbol}_patchpoint,NULL" :
+                                                                                       "&${symbol}_patchpoint,&${symbol}_patchpoint")))),
                                        ",\n";
                        }
                print <<"HERE";
index 8629e22..a030a1f 100644 (file)
@@ -505,7 +505,7 @@ USHORT Idx;
 PVOID ExportAddress,*ExportAddressp;
 const gchar *sym_name;
 void (*sym_val)(void);
-struct captive_ModuleList_patchpoint *patchpoint;
+struct captive_ModuleList_patchpoint *patchpoint,*patchpointpatch;
 GHashTable *exportdir_hash;
 gboolean errbool;
 
@@ -550,6 +550,7 @@ CHAR *funcname=MODULEOBJECT_BASE_OFFSET_PLUS(NameList[Idx]);
                captive_va_arg(sym_val ,ap);
                /* 'sym_val' may be NULL if 'data' type && "pass"ed */
                captive_va_arg(patchpoint,ap);  /* 'data' type if ==NULL */
+               captive_va_arg(patchpointpatch,ap);     /* 'data' type or 'pass' in non-debug mode if ==NULL */
                ExportAddressp=g_hash_table_lookup(exportdir_hash,sym_name);
                if (ExportAddressp==NULL) {
                        g_message("%s: Function not found for patchpoint (ignoring): %s",G_STRLOC,sym_name);
@@ -569,24 +570,26 @@ CHAR *funcname=MODULEOBJECT_BASE_OFFSET_PLUS(NameList[Idx]);
                if (!patchpoint) /* 'data' type && !"pass"ed => do not corrupt it by 0xF4 */
                        continue;
                patchpoint->orig_w32_func=ExportAddress;
-               if (0xF4 /* hlt */ ==*patchpoint->orig_w32_func)        /* Already patched by name-aliased function? */
+               if (!patchpointpatch)   /* 'pass' in non-debug mode */
                        continue;
-               g_assert(0xF4 /* hlt */ !=*patchpoint->orig_w32_func);
-               patchpoint->orig_w32_2ndinstr=patchpoint->orig_w32_func
-                               +instruction_length((guint8 *)patchpoint->orig_w32_func);
-               g_assert(0xF4 /* hlt */ !=*patchpoint->orig_w32_2ndinstr);
-               patchpoint->wrap_wrap_func=sym_val;
-               patchpoint->orig_w32_func_byte=*patchpoint->orig_w32_func;
-               patchpoint->orig_w32_2ndinstr_byte=*patchpoint->orig_w32_2ndinstr;
-               patchpoint->through_w32_func=FALSE;
-               g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpoint->orig_w32_func));
+               if (0xF4 /* hlt */ ==*patchpointpatch->orig_w32_func)   /* Already patched by name-aliased function? */
+                       continue;
+               g_assert(0xF4 /* hlt */ !=*patchpointpatch->orig_w32_func);
+               patchpointpatch->orig_w32_2ndinstr=patchpointpatch->orig_w32_func
+                               +instruction_length((guint8 *)patchpointpatch->orig_w32_func);
+               g_assert(0xF4 /* hlt */ !=*patchpointpatch->orig_w32_2ndinstr);
+               patchpointpatch->wrap_wrap_func=sym_val;
+               patchpointpatch->orig_w32_func_byte=*patchpointpatch->orig_w32_func;
+               patchpointpatch->orig_w32_2ndinstr_byte=*patchpointpatch->orig_w32_2ndinstr;
+               patchpointpatch->through_w32_func=FALSE;
+               g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpointpatch->orig_w32_func));
                g_hash_table_insert(captive_ModuleList_patchpoint_hash,
-                               patchpoint->orig_w32_func,      /* key */
-                               patchpoint);    /* value */
-               g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpoint->orig_w32_2ndinstr));
+                               patchpointpatch->orig_w32_func, /* key */
+                               patchpointpatch);       /* value */
+               g_assert(NULL==g_hash_table_lookup(captive_ModuleList_patchpoint_hash,patchpointpatch->orig_w32_2ndinstr));
                g_hash_table_insert(captive_ModuleList_patchpoint_hash,
-                               patchpoint->orig_w32_2ndinstr,  /* key */
-                               patchpoint);    /* value */
+                               patchpointpatch->orig_w32_2ndinstr,     /* key */
+                               patchpointpatch);       /* value */
                *(guint8 *)ExportAddress=0xF4;  /* hlt */
                }
        va_end(ap);