This is the mail archive of the cygwin-apps 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: More fault tolerant rebase (was Re: libtcl8.5.dll collides with Cygwin DLL by default)


Hi Jason,

On Mar 13 14:04, Corinna Vinschen wrote:
> On Mar  9 21:30, Corinna Vinschen wrote:
> > On Mar  8 10:12, Corinna Vinschen wrote:
> > > What rebase *should* do is to mark the DLLs as blocked, and keep them in
> > > the list together with their current address and size, so it can arrange
> > > the addresses of the other DLLs, taking the blocked address space into
> > > account, just like it does with the Cygwin DLL.  And of course, the DLL
> > > should not be removed from the database.
> > > 
> > > Is there anybody here who would like to tackle this?
> > 
> > After the roaring silence died down, I thought I should try myself.
> > Here's my idea how to handfle that problem.  It's not even much code.
> > 
> > I would be really grateful if somebody (Chuck? Jason? Yaakov?) could have a 
> > look if the idea is ok and maybe even test it.  With this code, the
> > DLLs are tested if they allow writing at the time, and if not, are
> > marked as not rebaseable.  If so, rebase will not try to move them,
> > and they are kept in the database nevertheless.
> > 
> > 
> > Corinna
> 
> I extended the patch a bit, so that it prints on the command line which
> DLL couldn't be rebased for what reason.  See below.  Did anybody try
> the patch except me?

I also added documentation to the README file, added a -p option to
rebaseall which skips the ash/dash-only test and created a postinstall
batch file which will be installed into a separate package called
_autorebase.  There's no `make install' for these files since the
package is only generated once.  If you are wondering why it's a .bat
file rather than a .sh file, the reason is that .sh files are run by
bash, so that would *always* block DLLs for no good reason.

Btw., I will maintain the _autorebase package, so you don't have to
care.  I'm just adding the files to the rebase repo so they are where
they belong.

Here's the full patch again.  I didn't differ between the -t and -p
option patches since that's a lot of work for no good reason.  So below
you find all patches in one go.


Corinna


    ChangeLog:

	* README: Document rebasell -p and -t options.  Document rebase
	-t option.
	* autorebase.bat: New file.
	* autorebase.hint: New file.
	* configure.ac: Bump package version to 4.1.0.
	* rebase-db.h (struct _img_info): Add cannot_rebase flag.
	* rebase.c (main): Print DLLs which couldn't be rebased to stderr.
	(save_image_info): Set cannot_rebase flag to 0 before storing
	list in DB.
	(set_cannot_rebase): New function to test if a DLL is blocked by
	another process.
	(merge_image_info): Take DLLs blocked by other processes into
	account.
	(long_options): Add --touch.
	(short_options): Add -t.
	(parse_args): Handle -t/--touch option. Set ReBaseChangeFileTime flag.
	(usage): Add text for new -t/--touch option.
	* rebaseall.in: Add -p and -t option.  Do option processing prior
	to testing for running processes.  Only test for running processes
	if -p option wasn't given.

    imagehelper/ChangeLog:

	* imagehelper.h (ReBaseChangeFileTime): Declare.
	* objectfile.h (ObjectFile::setFileTime): New method.
	* rebaseimage.cc (ReBaseChangeFileTime): Define.
	(ReBaseImage64): Call ObjectFile::setFileTime if successfully rebased
	and ReBaseChangeFileTime is true.


Index: README
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/README,v
retrieving revision 1.2
diff -u -p -r1.2 README
--- README	5 Aug 2011 15:43:23 -0000	1.2
+++ README	14 Mar 2012 20:51:45 -0000
@@ -167,16 +167,20 @@ rebaseall
 --------------------------------------------------------------------------------
 The following is the rebaseall command line syntax:
 
-    rebaseall [-b BaseAddress] [-o Offset] [-s DllSuffix] [-T FileList | -] [-4|-8] [-v]
+    rebaseall [-b BaseAddress] [-o Offset] [-s DllSuffix] [-T FileList | -] [-4|-8] [-p] [-t] [-v]
 
 where:
 
     -b => base address used by rebase (default: 0x70000000)
     -o => offset between each DLL rebased (default: 0x10000 MinGW/MSYS, 0x0 Cygwin)
+    -p => skip test for running ash or dash only.  This option is supposed to
+          be used by Cygwin's setup tool.  Only use it if you know what you're
+	  doing!
     -s => specify DLL suffix, use multiple if necessary (default: dll, so)
     -T => specify filelist (or stdin) to list additional files
     -4 => operate only on 32bit objects (ignore 64bit objects) (*)
     -8 => operate only on 64bit objects (ignore 32bit objects) (*)
+    -t => change modification timestamp of successfully rebased files
     -v => verbose (default: off)
 
 (*) -4 and -8 are mutually exclusive. -4 is the default if rebaseall is
@@ -242,6 +246,9 @@ The following is the rebase command line
                               With the -s option, this option is implicitly set.
       -o, --offset=OFFSET     Specify an additional offset between adjacent DLLs
                               when rebasing.  Default is no offset.
+      -t, --touch             Use this option to make sure the file's modification
+                              time is bumped if it has been successfully rebased.
+			      Usually rebase does not change the file's time.
       -T, --filelist=FILE     Also rebase the files specified in FILE.  The format
                               of FILE is one DLL per line.
       -q, --quiet             Be quiet about non-critical issues.
Index: autorebase.bat
===================================================================
RCS file: autorebase.bat
diff -N autorebase.bat
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ autorebase.bat	14 Mar 2012 20:51:45 -0000
@@ -0,0 +1,5 @@
+@echo off
+rem Postinstall scripts are always started from the Cygwin root dir
+rem so we can just call dash from here
+path .\bin;%path%
+dash -c "/bin/rebaseall -p"
Index: autorebase.hint
===================================================================
RCS file: autorebase.hint
diff -N autorebase.hint
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ autorebase.hint	14 Mar 2012 20:51:45 -0000
@@ -0,0 +1,5 @@
+sdesc: "Run rebaseall automatically"
+category: _PostInstallLast
+requires: rebase dash
+autodep: .*/[^/]*\.(?:dll|so|oct)$
+incver_ifdep: yes
Index: configure.ac
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/configure.ac,v
retrieving revision 1.6
diff -u -p -r1.6 configure.ac
--- configure.ac	24 Oct 2011 17:49:56 -0000	1.6
+++ configure.ac	14 Mar 2012 20:51:45 -0000
@@ -2,7 +2,7 @@
 # configure.ac for rebase
 
 AC_PREREQ([2.64])
-AC_INIT([rebase], [4.0.1], [cygwin@cygwin.com])
+AC_INIT([rebase], [4.1.0], [cygwin@cygwin.com])
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_SRCDIR([peflags.c])
 AC_PREFIX_DEFAULT([/usr])
Index: rebase-db.h
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/rebase-db.h,v
retrieving revision 1.3
diff -u -p -r1.3 rebase-db.h
--- rebase-db.h	5 Aug 2011 14:21:11 -0000	1.3
+++ rebase-db.h	14 Mar 2012 20:51:45 -0000
@@ -63,8 +63,10 @@ typedef struct _img_info
   ULONG   size;		/* Size of the DLL at rebased time.                  */
   ULONG   slot_size;	/* Size of the DLL rounded to allocation granularity.*/
   struct {		/* Flags                                             */
-    unsigned needs_rebasing : 1; /* Set to 0 in the database.  Used only     */
-				 /* while rebasing.                          */
+    ULONG needs_rebasing : 1; /* Set to 0 in the database.  Used only        */
+			      /* while rebasing.                             */
+    ULONG cannot_rebase  : 1; /* Set to 0 in the database.  Used only        */
+			      /* while rebasing.                             */
   } flag;
 } img_info_t;
 
Index: rebase.c
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/rebase.c,v
retrieving revision 1.12
diff -u -p -r1.12 rebase.c
--- rebase.c	9 Aug 2011 09:32:47 -0000	1.12
+++ rebase.c	14 Mar 2012 20:51:45 -0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2002, 2003, 2004, 2008, 2011 Jason Tishler
+ * Copyright (c) 2001, 2002, 2003, 2004, 2008, 2011, 2012 Jason Tishler
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -232,6 +232,8 @@ main (int argc, char *argv[])
   else
     {
       /* Rebase with database support. */
+      BOOL header;
+
       merge_image_info ();
       status = TRUE;
       for (i = 0; i < img_info_size; ++i)
@@ -242,6 +244,28 @@ main (int argc, char *argv[])
 	    if (status)
 	      img_info_list[i].flag.needs_rebasing = 0;
 	  }
+      for (header = FALSE, i = 0; i < img_info_size; ++i)
+	if (img_info_list[i].flag.cannot_rebase)
+	  {
+	    if (!header)
+	      {
+		fputs ("\nThe following DLLs couldn't be rebased "
+		       "because they were in use:\n", stderr);
+		header = TRUE;
+	      }
+	    fprintf (stderr, "  %s\n", img_info_list[i].name);
+	  }
+      for (header = FALSE, i = 0; i < img_info_size; ++i)
+	if (img_info_list[i].flag.needs_rebasing)
+	  {
+	    if (!header)
+	      {
+		fputs ("\nThe following DLLs couldn't be rebased "
+		       "due to errors:\n", stderr);
+		header = TRUE;
+	      }
+	    fprintf (stderr, "  %s\n", img_info_list[i].name);
+	  }
       if (save_image_info () < 0)
 	return 2;
     }
@@ -266,11 +290,14 @@ save_image_info ()
   int ret = 0;
   img_info_hdr_t hdr;
 
-  /* Remove all DLLs which couldn't be rebased from the list before storing
-     it in the database file. */
+  /* Drop cannot_rebase flag and remove all DLLs for which rebasing failed
+     from the list before storing it in the database file. */
   for (i = 0; i < img_info_size; ++i)
-    if (img_info_list[i].flag.needs_rebasing)
-      img_info_list[i--] = img_info_list[--img_info_size];
+    {
+      img_info_list[i].flag.cannot_rebase = 0;
+      if (img_info_list[i].flag.needs_rebasing)
+	img_info_list[i--] = img_info_list[--img_info_size];
+    }
   /* Create a temporary file to write to. */
   fd = mkstemp (tmp_file);
   if (fd < 0)
@@ -509,6 +536,17 @@ load_image_info ()
   return ret;
 }
 
+static BOOL
+set_cannot_rebase (img_info_t *img)
+{
+  int fd = open (img->name, O_WRONLY);
+  if (fd < 0)
+    img->flag.cannot_rebase = 1;
+  else
+    close (fd);
+  return img->flag.cannot_rebase;
+}
+
 int
 merge_image_info ()
 {
@@ -541,6 +579,9 @@ merge_image_info ()
     {
       for (i = img_info_rebase_start; i < img_info_size; ++i)
 	{
+	  /* First test if we can open the DLL for writing.  If not, it's
+	     probably blocked by another process. */
+	  set_cannot_rebase (&img_info_list[i]);
 	  match = bsearch (&img_info_list[i], img_info_list,
 			   img_info_rebase_start, sizeof (img_info_t),
 			   img_info_name_cmp);
@@ -551,8 +592,10 @@ merge_image_info ()
 		 of the old file.  If so, screw the new file into the old slot.
 		 Otherwise set base to 0 to indicate that this DLL needs a new
 		 base address. */
-	      if (match->base != img_info_list[i].base
-		  || match->slot_size < img_info_list[i].slot_size)
+	      if (img_info_list[i].flag.cannot_rebase)
+		match->base = img_info_list[i].base;
+	      else if (match->base != img_info_list[i].base
+		       || match->slot_size < img_info_list[i].slot_size)
 		{
 		  /* Reuse the old address if possible. */
 		  if (match->slot_size < img_info_list[i].slot_size)
@@ -566,23 +609,24 @@ merge_image_info ()
 	      free (img_info_list[i].name);
 	      img_info_list[i--] = img_info_list[--img_info_size];
 	    }
-	  else
+	  else if (!img_info_list[i].flag.cannot_rebase)
 	    /* Not in database yet.  Set base to 0 to choose a new one. */
 	    img_info_list[i].base = 0;
 	}
-      /* After eliminating the duplicates, check if the user requested
-	 a new base address on the command line.  If so, overwrite all
-	 base addresses with 0 and set img_info_rebase_start to 0, to
-	 skip any further test. */
-      if (force_rebase_flag)
-	img_info_rebase_start = 0;
     }
-  if (!img_info_rebase_start)
+  if (!img_info_rebase_start || force_rebase_flag)
     {
       /* No database yet or enforcing a new base address.  Set base of all
-	 DLLs to 0. */
+	 DLLs to 0, if possible. */
       for (i = 0; i < img_info_size; ++i)
-	img_info_list[i].base = 0;
+	{
+	  /* Test DLLs already in database for writability. */
+	  if (i < img_info_rebase_start)
+	    set_cannot_rebase (&img_info_list[i]);
+	  if (!img_info_list[i].flag.cannot_rebase)
+	    img_info_list[i].base = 0;
+	}
+      img_info_rebase_start = 0;
     }
 
   /* Now sort the old part of the list by base address. */
@@ -596,8 +640,10 @@ merge_image_info ()
       ULONG64 cur_base;
       ULONG cur_size, slot_size;
 
-      /* Files with the needs_rebasing flag set have been checked already. */
-      if (img_info_list[i].flag.needs_rebasing)
+      /* Files with the needs_rebasing or cannot_rebase flags set have been
+	 checked already. */
+      if (img_info_list[i].flag.needs_rebasing
+      	  || img_info_list[i].flag.cannot_rebase)
 	continue;
       /* Check if the files in the old list still exist.  Drop non-existant
 	 or unaccessible files. */
@@ -613,24 +659,34 @@ merge_image_info ()
 	  continue;
 	}
       slot_size = roundup2 (cur_size, ALLOCATION_SLOT);
-      /* If the file has been reinstalled, try to rebase to the same address
-	 in the first place. */
-      if (cur_base != img_info_list[i].base)
+      if (set_cannot_rebase (&img_info_list[i]))
+	img_info_list[i].base = cur_base;
+      else
 	{
-	  img_info_list[i].flag.needs_rebasing = 1;
-	  /* Set cur_base to the old base to simplify subsequent tests. */
-	  cur_base = img_info_list[i].base;
+	  /* If the file has been reinstalled, try to rebase to the same address
+	     in the first place. */
+	  if (cur_base != img_info_list[i].base)
+	    {
+	      img_info_list[i].flag.needs_rebasing = 1;
+	      /* Set cur_base to the old base to simplify subsequent tests. */
+	      cur_base = img_info_list[i].base;
+	    }
+	  /* However, if the DLL got bigger and doesn't fit into its slot
+	     anymore, rebase this DLL from scratch. */
+	  if (i + 1 < img_info_rebase_start
+	      && cur_base + slot_size + offset >= img_info_list[i + 1].base)
+	    img_info_list[i].base = 0;
+	  /* Does the previous DLL reach into the address space of this
+	     DLL?  This happens if the previous DLL is not rebaseable. */
+	  else if (i > 0 && cur_base < img_info_list[i - 1].base
+				       + img_info_list[i + 1].slot_size)
+	    img_info_list[i].base = 0;
+	  /* Does the file match the base address requirements?  If not,
+	     rebase from scratch. */
+	  else if ((down_flag && cur_base + slot_size + offset >= image_base)
+		   || (!down_flag && cur_base < image_base))
+	    img_info_list[i].base = 0;
 	}
-      /* However, if the DLL got bigger and doesn't fit into its slot
-	 anymore, rebase this DLL from scratch. */
-      if (i + 1 < img_info_rebase_start
-	  && cur_base + slot_size + offset >= img_info_list[i + 1].base)
-	img_info_list[i].base = 0;
-      /* Does the file match the base address requirements?  If not,
-	 rebase from scratch. */
-      else if ((down_flag && cur_base + slot_size + offset >= image_base)
-	       || (!down_flag && cur_base < image_base))
-	img_info_list[i].base = 0;
       /* Unconditionally overwrite old with new size. */
       img_info_list[i].size = cur_size;
       img_info_list[i].slot_size = slot_size;
@@ -1014,6 +1070,7 @@ static struct option long_options[] = {
   {"offset",	required_argument, NULL, 'o'},
   {"quiet",	no_argument,	   NULL, 'q'},
   {"database",	no_argument,	   NULL, 's'},
+  {"touch",	no_argument,	   NULL, 't'},
   {"filelist",	required_argument, NULL, 'T'},
   {"usage",	no_argument,	   NULL, 'h'},
   {"verbose",	no_argument,	   NULL, 'v'},
@@ -1021,7 +1078,7 @@ static struct option long_options[] = {
   {NULL,	no_argument,	   NULL,  0 }
 };
 
-static const char *short_options = "48b:dhio:qsT:vV";
+static const char *short_options = "48b:dhio:qstT:vV";
 
 void
 parse_args (int argc, char *argv[])
@@ -1063,6 +1120,9 @@ parse_args (int argc, char *argv[])
 	  /* FIXME: For now enforce top-down rebasing when using the database.*/
 	  down_flag = TRUE;
 	  break;
+	case 't':
+	  ReBaseChangeFileTime = TRUE;
+	  break;
 	case 'T':
 	  file_list = optarg;
 	  break;
@@ -1220,6 +1280,9 @@ Rebase PE files, usually DLLs, to a spec
                           With the -s option, this option is implicitly set.\n\
   -o, --offset=OFFSET     Specify an additional offset between adjacent DLLs\n\
                           when rebasing.  Default is no offset.\n\
+  -t, --touch             Use this option to make sure the file's modification\n\
+                          time is bumped if it has been successfully rebased.\n\
+                          Usually rebase does not change the file's time.\n\
   -T, --filelist=FILE     Also rebase the files specified in FILE.  The format\n\
                           of FILE is one DLL per line.\n\
   -q, --quiet             Be quiet about non-critical issues.\n\
Index: rebaseall.in
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/rebaseall.in,v
retrieving revision 1.6
diff -u -p -r1.6 rebaseall.in
--- rebaseall.in	24 Oct 2011 07:41:59 -0000	1.6
+++ rebaseall.in	14 Mar 2012 20:51:45 -0000
@@ -1,7 +1,7 @@
 #!/bin/@ASH@
 
 #
-# Copyright (c) 2003, 2005, 2006, 2008, 2011 Jason Tishler
+# Copyright (c) 2003, 2005, 2006, 2008, 2011, 2012 Jason Tishler
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -29,17 +29,18 @@ tp2=${tp1:-.}
 PATH=$(cd $tp2 && pwd):@bindir@:/bin
 
 ProgramName=${0##*/}
-ProgramOptions='48b:o:s:T:v'
+ProgramOptions='48b:o:ps:tT:v'
 DefaultBaseAddress=0x70000000
 DefaultOffset=@DEFAULT_OFFSET_VALUE@
+DefaultTouch=
 DefaultVerbose=
 DefaultFileList=
-DefaultSuffixes='dll|so'
+DefaultSuffixes='dll|so|oct'
 
 # Define functions
 usage()
 {
-    echo "usage: ${ProgramName} [-b BaseAddress] [-o Offset] [-s DllSuffix] [-T FileList | -] [-4|-8] [-v]"
+    echo "usage: ${ProgramName} [-b BaseAddress] [-o Offset] [-s DllSuffix] [-T FileList | -] [-4|-8] [-p] [-t] [-v]"
     exit 1
 }
 
@@ -55,11 +56,13 @@ trap cleanup 1 2 15
 # Set defaults
 BaseAddress=""
 Offset="${DefaultOffset}"
+Touch="${DefaultTouch}"
 Verbose="${DefaultVerbose}"
 FileList="${DefaultFileList}"
 Suffixes="${DefaultSuffixes}"
 db_file_i386="@sysconfdir@/rebase.db.i386"
 db_file_x86_64="@sysconfdir@/rebase.db.x86_64"
+check_for_dash_only="yes"
 case `uname -m` in
     i[3456]86)
 	db_file="${db_file_i386}";
@@ -83,45 +86,6 @@ case $Platform in
     ;;
 esac
 
-# Verify only ash or dash processes are running
-ProcessResult=0
-case $Platform in
-  mingw|msys )
-    /bin/ps -s | /bin/gawk '\
-      # Count number of running ash or dash. \
-      /\/bin\/(d)?ash(\.exe)?$/{ ash_cnt++; } \
-      # Count number of ps and gawk. \
-      /\/bin\/ps(\.exe)?$/{ cnt++; } \
-      /\/bin\/gawk(\.exe)?$/{ cnt++; } \
-      END{ \
-        # Uncomment for testing: \
-        # printf "TOTAL: %d CNT: %d ASH_CNT: %d\n", NR, cnt, ash_cnt; \
-        # Only one of ps and gawk each may run. \
-        if (cnt > 2) \
-          exit 0; \
-        # The total number of allowed processes is one less than the \
-        # number of input lines.  The extra line is the ps header output. \
-        if (NR - cnt - ash_cnt > 1) \
-          exit 0; \
-        # All is well. \
-        exit 1; \
-      }'
-    ProcessResult=$?
-    ;;
-  cygwin )
-    grep -E -q -i -v '/d?ash(.exe)?$' /proc/[0-9]*/exename
-    ProcessResult=$?
-    ;;
-esac
-if [ $ProcessResult -eq 0 -a -z "${RebaseDebug}" ]
-then
-    echo "${ProgramName}: only ash or dash processes are allowed during rebasing"
-    echo "    Exit all Cygwin processes and stop all Cygwin services."
-    echo "    Execute ash (or dash) from Start/Run... or a cmd or command window."
-    echo "    Execute '/bin/rebaseall' from ash (or dash)."
-    exit 2
-fi
-
 # Parse command line arguments
 while getopts "${ProgramOptions}" Option "$@"
 do
@@ -138,8 +102,12 @@ do
 	BaseAddress="${OPTARG}";;
     o)
 	Offset="${OPTARG}";;
+    p)
+	check_for_dash_only="no";;
     s)
 	Suffixes="${Suffixes}|${OPTARG}";;
+    t)
+    	Touch="-t";;
     T)
 	FileList="${OPTARG}";;
     v)
@@ -149,6 +117,48 @@ do
     esac
 done
 
+# Verify only ash or dash processes are running
+if [ "${check_for_dash_only}" != "no" ]
+then
+  ProcessResult=0
+  case $Platform in
+    mingw|msys )
+      /bin/ps -s | /bin/gawk '\
+	# Count number of running ash or dash. \
+	/\/bin\/(d)?ash(\.exe)?$/{ ash_cnt++; } \
+	# Count number of ps and gawk. \
+	/\/bin\/ps(\.exe)?$/{ cnt++; } \
+	/\/bin\/gawk(\.exe)?$/{ cnt++; } \
+	END{ \
+	  # Uncomment for testing: \
+	  # printf "TOTAL: %d CNT: %d ASH_CNT: %d\n", NR, cnt, ash_cnt; \
+	  # Only one of ps and gawk each may run. \
+	  if (cnt > 2) \
+	    exit 0; \
+	  # The total number of allowed processes is one less than the \
+	  # number of input lines.  The extra line is the ps header output. \
+	  if (NR - cnt - ash_cnt > 1) \
+	    exit 0; \
+	  # All is well. \
+	  exit 1; \
+	}'
+      ProcessResult=$?
+      ;;
+    cygwin )
+      grep -E -q -i -v '/d?ash(.exe)?$' /proc/[0-9]*/exename
+      ProcessResult=$?
+      ;;
+  esac
+  if [ $ProcessResult -eq 0 -a -z "${RebaseDebug}" ]
+  then
+      echo "${ProgramName}: only ash or dash processes are allowed during rebasing"
+      echo "    Exit all Cygwin processes and stop all Cygwin services."
+      echo "    Execute ash (or dash) from Start/Run... or a cmd or command window."
+      echo "    Execute '/bin/rebaseall' from ash (or dash)."
+      exit 2
+  fi
+fi
+
 # Check if rebase database already exists.
 database_exists="no"
 [ -f "${db_file}" ] && database_exists="yes"
@@ -214,9 +224,9 @@ fi
 
 if [ -z "${BaseAddress}" ]
 then
-  rebase "${Verbose}" -s "${Mach}" -T "${TmpFile}"
+  rebase "${Verbose}" "${Touch}" -s "${Mach}" -T "${TmpFile}"
 else
-  rebase "${Verbose}" -s "${Mach}" -b "${BaseAddress}" -o "${Offset}" -T "${TmpFile}"
+  rebase "${Verbose}" "${Touch}" -s "${Mach}" -b "${BaseAddress}" -o "${Offset}" -T "${TmpFile}"
 fi
 ExitCode=$?
 
Index: imagehelper/imagehelper.h
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/imagehelper/imagehelper.h,v
retrieving revision 1.5
diff -u -p -r1.5 imagehelper.h
--- imagehelper/imagehelper.h	10 Jul 2011 12:26:45 -0000	1.5
+++ imagehelper/imagehelper.h	14 Mar 2012 20:51:45 -0000
@@ -27,6 +27,10 @@
 extern "C" {
 #endif
 
+/* Set to TRUE if ReBaseImage{64} should also set the files last write
+   time to TimeStamp when the file has been successfully rebased. */
+extern BOOL ReBaseChangeFileTime;
+
 BOOL ReBaseImage64(
   LPCSTR CurrentImageName,
   LPCSTR SymbolPath,       // ignored
Index: imagehelper/objectfile.h
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/imagehelper/objectfile.h,v
retrieving revision 1.5
diff -u -p -r1.5 objectfile.h
--- imagehelper/objectfile.h	10 Jul 2011 12:26:45 -0000	1.5
+++ imagehelper/objectfile.h	14 Mar 2012 20:51:45 -0000
@@ -75,6 +75,18 @@ class ObjectFile : public Base
       return sections;
     }
 
+    void setFileTime (ULONG seconds_since_epoche)
+    {
+      LARGE_INTEGER filetime;
+/* 100ns difference between Windows and UNIX timebase. */
+#define FACTOR (0x19db1ded53e8000LL)
+/* # of 100ns intervals per second. */
+#define NSPERSEC 10000000LL
+      filetime.QuadPart = seconds_since_epoche * NSPERSEC + FACTOR;
+      if (!SetFileTime (hfile, NULL, NULL, (FILETIME *) &filetime))
+        std::cerr << "SetFileTime: " << GetLastError () << std::endl;
+    }
+
     ~ObjectFile();
 
 
Index: imagehelper/rebaseimage.cc
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/imagehelper/rebaseimage.cc,v
retrieving revision 1.4
diff -u -p -r1.4 rebaseimage.cc
--- imagehelper/rebaseimage.cc	8 Jul 2011 07:18:55 -0000	1.4
+++ imagehelper/rebaseimage.cc	14 Mar 2012 20:51:45 -0000
@@ -24,6 +24,8 @@
 #include "objectfile.h"
 #include "imagehelper.h"
 
+BOOL ReBaseChangeFileTime = FALSE;
+
 BOOL ReBaseImage64 (
   LPCSTR CurrentImageName,
   LPCSTR SymbolPath,       // ignored
@@ -122,6 +124,9 @@ BOOL ReBaseImage64 (
   if (!fGoingDown)
     *NewImageBase += *NewImageSize;
 
+  if (ReBaseChangeFileTime)
+    dll.setFileTime (TimeStamp);
+
   SetLastError(NO_ERROR);
   return true;
 }


-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat


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