More fault tolerant rebase (was Re: libtcl8.5.dll collides with Cygwin DLL by default)
Corinna Vinschen
corinna-cygwin@cygwin.com
Wed Mar 14 21:19:00 GMT 2012
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
More information about the Cygwin-apps
mailing list