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)


Jason?  Ping?

On Mar 14 22:18, Corinna Vinschen wrote:
> 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

-- 
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]