This is the mail archive of the
cygwin-apps
mailing list for the Cygwin project.
Re: [patch/rebase] Make rebase 64 bit capable, take 2
Another ping.
Where are you, guys? I'm getting concerned.
Corinna
On Jul 13 14:51, Corinna Vinschen wrote:
> Jason? Chuck?
>
> Ping?
>
> On Jul 10 17:00, Corinna Vinschen wrote:
> > On Jul 10 16:00, Corinna Vinschen wrote:
> > > Here's my patch. After some brooding I decided that a -4 and -8 option
> > > is the way to go. -4 is default if rebase is a 32 bit exe, -8 is default
> > > if rebase is a 64 bit executable. While I was at it, I also added
> > > long options to rebase. The corresponding long options to -4 and -8 are,
> > > who would have guessed, --32 and --64 :)
> > >
> > > Whatever you do now, you're either running in 32 bit mode or in 64 bit
> > > mode. This implementation does not allow to mix DLLs of both types in
> > > the same call. I renamed the databases to rebase.db.i386 and
> > > rebase.db.x86_64, that should be pretty self-explanatory. Rather than
> > > using different megic numbers I decided to add a WORD which keeps the
> > > machine type as defined for the executable headers as well.
> > >
> > > I also made a couple of changes so that rebase builds on mingw64. A few
> > > more changes for mingw and msys are still required.
> > >
> > > rebaseall got another small kick, so you can specify the -4 and
> > > -8 options as well. `uname -m` is used to find out the default.
> > >
> > > Please have a look and give it a try.
> >
> > Update:
> >
> > I didn't like the way how messages about skipping files are printed.
> > That's not well covered by the --verbose option, so I decided to print
> > the "skipped because" messages, unless the --quite option is given.
> >
> >
> > Corinna
> >
> >
> > * Makefile.in (DEFS): Add define for sysconfdir.
> > (edit): Add substitute expression for sysconfdir.
> > * rebase.c: Implement rebase database.
> > (roundup): Define.
> > (roundup2): Define.
> > (machine): New global variable to keep requested machine type.
> > (image_storage_flag): New flag.
> > (force_rebase_flag): Ditto.
> > (quite): Ditto.
> > (verbose): Convert to type BOOL.
> > (progname): New variable for printing application name in error
> > output.
> > (img_info_hdr_t): New type.
> > (img_info_t): De-const name. Add name_size, slot_size, and
> > flag members.
> > (IMG_INFO_FILE_I386): Define database name for i386 systems.
> > (IMG_INFO_FILE_AMD64): Define database name for x86_64 systems.
> > (IMG_INFO_FILE): Define default database name.
> > (gen_progname): New function to initialize progname.
> > (main): Call gen_progname. Only fetch Cygwin DLL info in
> > 32 bit mode for now. Always collect file info, then rebase
> > dependent on mode. In database mode, call load_image_info,
> > collect_image_info, merge_image_info, and save_image_info.
> > (img_info_name_cmp): New comparison function.
> > (save_image_info): New function to save rebase database.
> > (load_image_info): New function to load rebase database.
> > (merge_image_info): New function to compute rebase values.
> > (collect_image_info): Fix typo in condition. Check for rebaseable
> > file here. Convert given filename to absolute pathname.
> > (print_image_info): Revamp to take database into account. Add
> > collision information.
> > (rebase): Take down_flag as parameter to allow influencing the
> > algorithm from caller. Drop call to is_rebaseable here.
> > (long_options): New option array for getopt_long.
> > (short_options): Hold short options.
> > (parse_args): Drop anOptions. Rename anOption to opt. Call
> > getopt_long. Handle all new flags.
> > (usage): Change to reflect new flags.
> > (help): New function.
> > * rebaseall.in: Use database mode. Add -4 and -8 options and
> > handle 32 and 64 bit modes.
> >
> >
> > Index: Makefile.in
> > ===================================================================
> > RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/Makefile.in,v
> > retrieving revision 1.5
> > diff -u -p -r1.5 Makefile.in
> > --- Makefile.in 7 Jul 2011 16:08:37 -0000 1.5
> > +++ Makefile.in 10 Jul 2011 14:58:58 -0000
> > @@ -1,4 +1,4 @@
> > -# $Id: Makefile.in,v 1.5 2011/07/07 16:08:37 corinna Exp $
> > +# $Id: Makefile.in,v 1.4 2011/06/28 19:43:19 corinna Exp $
> > # @configure_input@
> > # Makefile for rebase
> >
> > @@ -56,7 +56,7 @@ FGREP = @FGREP@
> > ASH = @ASH@
> >
> > DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(srcdir)/imagehelper
> > -DEFS = @DEFS@ -DVERSION='"$(PACKAGE_VERSION)"' -DLIB_VERSION='"$(LIB_VERSION)"'
> > +DEFS = @DEFS@ -DVERSION='"$(PACKAGE_VERSION)"' -DLIB_VERSION='"$(LIB_VERSION)"' -DSYSCONFDIR='"$(sysconfdir)"'
> >
> > override CFLAGS+=-Wall -Werror
> > override CXXFLAGS+=-Wall -Werror
> > @@ -109,6 +109,7 @@ getopt_long.$(O):: getopt_long.c getopt.
> > # bindir and friends in your shell scripts"
> > edit = sed \
> > -e 's|@bindir[@]|$(bindir)|g' \
> > + -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
> > -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
> > -e 's|@prefix[@]|$(prefix)|g' \
> > -e 's|@exec_prefix[@]|$(exec_prefix)|g' \
> > Index: rebase.c
> > ===================================================================
> > RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/rebase.c,v
> > retrieving revision 1.5
> > diff -u -p -r1.5 rebase.c
> > --- rebase.c 8 Jul 2011 08:22:59 -0000 1.5
> > +++ rebase.c 10 Jul 2011 14:58:58 -0000
> > @@ -19,6 +19,9 @@
> > #include <stdlib.h>
> > #include <sys/types.h>
> > #include <sys/stat.h>
> > +#if defined(__CYGWIN__) || defined(__MSYS__)
> > +#include <sys/cygwin.h>
> > +#endif
> > #include <fcntl.h>
> > #include <string.h>
> > #include <unistd.h>
> > @@ -26,125 +29,709 @@
> > #include <getopt.h>
> > #include <string.h>
> > #include <inttypes.h>
> > +#include <errno.h>
> > #include "imagehelper.h"
> >
> > +#define roundup(x,y) ((((x) + ((y) - 1)) / (y)) * (y))
> > +#define roundup2(x,y) (((x) + (y) - 1) & ~((y) - 1))
> > +
> > +BOOL save_image_info ();
> > +BOOL load_image_info ();
> > +BOOL merge_image_info ();
> > BOOL collect_image_info (const char *pathname);
> > void print_image_info ();
> > -BOOL rebase (const char *pathname, ULONG64 *new_image_base);
> > +BOOL rebase (const char *pathname, ULONG64 *new_image_base, BOOL down_flag);
> > void parse_args (int argc, char *argv[]);
> > unsigned long long string_to_ulonglong (const char *string);
> > void usage ();
> > +void help ();
> > BOOL is_rebaseable (const char *pathname);
> > FILE *file_list_fopen (const char *file_list);
> > char *file_list_fgets (char *buf, int size, FILE *file);
> > int file_list_fclose (FILE *file);
> > void version ();
> >
> > +#ifdef __x86_64__
> > +WORD machine = IMAGE_FILE_MACHINE_AMD64;
> > +#else
> > +WORD machine = IMAGE_FILE_MACHINE_I386;
> > +#endif
> > ULONG64 image_base = 0;
> > BOOL down_flag = FALSE;
> > BOOL image_info_flag = FALSE;
> > +BOOL image_storage_flag = FALSE;
> > +BOOL force_rebase_flag = FALSE;
> > ULONG offset = 0;
> > int args_index = 0;
> > -int verbose = 0;
> > +BOOL verbose = FALSE;
> > +BOOL quiet = FALSE;
> > const char *file_list = 0;
> > const char *stdin_file_list = "-";
> >
> > +const char *progname;
> > +
> > +const char IMG_INFO_MAGIC[4] = "rBiI";
> > +const ULONG IMG_INFO_VERSION = 1;
> > +
> > ULONG ALLOCATION_SLOT; /* Allocation granularity. */
> >
> > +#pragma pack (push, 4)
> > +
> > +typedef struct _img_info_hdr
> > +{
> > + CHAR magic[4]; /* Always IMG_INFO_MAGIC. */
> > + WORD machine; /* IMAGE_FILE_MACHINE_I386/IMAGE_FILE_MACHINE_AMD64 */
> > + WORD version; /* Database version, always set to IMG_INFO_VERSION. */
> > + ULONG64 base; /* Base address (-b) used to generate database. */
> > + ULONG offset; /* Offset (-o) used to generate database. */
> > + BOOL down_flag; /* Always TRUE right now. */
> > + ULONG count; /* Number of img_info_t entries following header. */
> > +} img_info_hdr_t;
> > +
> > typedef struct _img_info
> > {
> > - const char *name;
> > - ULONG64 base;
> > - ULONG size;
> > + union {
> > + PCHAR name; /* Absolute path to DLL. The strings are stored */
> > + ULONG64 _filler; /* right after the img_info_t table, in the same */
> > + }; /* order as the img_info_t entries. */
> > + ULONG name_size; /* Length of name string including trailing NUL. */
> > + ULONG64 base; /* Base address the DLL has been rebased to. */
> > + 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. */
> > + } flag;
> > } img_info_t;
> >
> > +#pragma pack (pop)
> > +
> > img_info_t *img_info_list = NULL;
> > unsigned int img_info_size = 0;
> > +unsigned int img_info_rebase_start = 0;
> > unsigned int img_info_max_size = 0;
> >
> > +#if !defined (__CYGWIN__) && !defined (__MSYS__)
> > +#undef SYSCONFDIR
> > +#define SYSCONFDIR "/../etc"
> > +#endif
> > +#define IMG_INFO_FILE_I386 SYSCONFDIR "/rebase.db.i386"
> > +#define IMG_INFO_FILE_AMD64 SYSCONFDIR "/rebase.db.x86_64"
> > +#ifdef __x86_64__
> > +#define IMG_INFO_FILE IMG_INFO_FILE_AMD64
> > +#else
> > +#define IMG_INFO_FILE IMG_INFO_FILE_I386
> > +#endif
> > +char *db_file = IMG_INFO_FILE;
> > +char tmp_file[] = SYSCONFDIR "/rebase.db.XXXXXX";
> > +
> > #ifdef __CYGWIN__
> > ULONG64 cygwin_dll_image_base = 0;
> > ULONG cygwin_dll_image_size = 0;
> > #endif
> >
> > +void
> > +gen_progname (const char *arg0)
> > +{
> > + char *p;
> > +
> > + p = strrchr (arg0, '/');
> > + if (!p)
> > + p = strrchr (arg0, '\\');
> > + progname = p ? p + 1 : arg0;
> > + if ((p = strrchr (progname, '.')) && !strcmp (p, ".exe"))
> > + *p = 0;
> > +}
> > +
> > int
> > main (int argc, char *argv[])
> > {
> > - ULONG64 new_image_base = 0;
> > int i = 0;
> > SYSTEM_INFO si;
> > BOOL status;
> >
> > setlocale (LC_ALL, "");
> > + gen_progname (argv[0]);
> > parse_args (argc, argv);
> > - new_image_base = image_base;
> > GetSystemInfo (&si);
> > ALLOCATION_SLOT = si.dwAllocationGranularity;
> >
> > + /* If database support has been requested, load database. */
> > + if (image_storage_flag)
> > + {
> > + if (load_image_info () < 0)
> > + return 2;
> > + img_info_rebase_start = img_info_size;
> > + }
> > +
> > #ifdef __CYGWIN__
> > - /* Fetch the Cygwin DLLs data to make sure that DLLs aren't rebased
> > - into the memory area taken by the Cygwin DLL. */
> > - GetImageInfos64 ("/bin/cygwin1.dll", NULL,
> > - &cygwin_dll_image_base, &cygwin_dll_image_size);
> > - /* Take the three shared memory areas preceeding the DLL into account. */
> > - cygwin_dll_image_base -= 3 * ALLOCATION_SLOT;
> > - /* Add a slack of 8 * 64K at the end of the Cygwin DLL. This leave a
> > - bit of room to install newer, bigger Cygwin DLLs, as well as room to
> > - install non-optimized DLLs for debugging purposes. Otherwise the
> > - slightest change might break fork again :-P */
> > - cygwin_dll_image_size += 3 * ALLOCATION_SLOT + 8 * ALLOCATION_SLOT;
> > + if (machine == IMAGE_FILE_MACHINE_I386)
> > + {
> > + /* Fetch the Cygwin DLLs data to make sure that DLLs aren't rebased
> > + into the memory area taken by the Cygwin DLL. */
> > + GetImageInfos64 ("/bin/cygwin1.dll", NULL,
> > + &cygwin_dll_image_base, &cygwin_dll_image_size);
> > + /* Take the three shared memory areas preceeding the DLL into account. */
> > + cygwin_dll_image_base -= 3 * ALLOCATION_SLOT;
> > + /* Add a slack of 8 * 64K at the end of the Cygwin DLL. This leave a
> > + bit of room to install newer, bigger Cygwin DLLs, as well as room to
> > + install non-optimized DLLs for debugging purposes. Otherwise the
> > + slightest change might break fork again :-P */
> > + cygwin_dll_image_size += 3 * ALLOCATION_SLOT + 8 * ALLOCATION_SLOT;
> > + }
> > #endif
> >
> > - /* Rebase file list, if specified. */
> > + /* Collect file list, if specified. */
> > if (file_list)
> > {
> > - status = TRUE;
> > char filename[MAX_PATH + 2];
> > FILE *file = file_list_fopen (file_list);
> > if (!file)
> > - exit (2);
> > + return 2;
> >
> > + status = TRUE;
> > while (file_list_fgets (filename, MAX_PATH + 2, file))
> > {
> > - status = image_info_flag ? collect_image_info (filename)
> > - : rebase (filename, &new_image_base);
> > + status = collect_image_info (filename);
> > if (!status)
> > break;
> > }
> >
> > file_list_fclose (file);
> > if (!status)
> > - exit (2);
> > + return 2;
> > }
> >
> > - /* Rebase command line arguments. */
> > + /* Collect command line arguments. */
> > for (i = args_index; i < argc; i++)
> > {
> > const char *filename = argv[i];
> > - status = image_info_flag ? collect_image_info (filename)
> > - : rebase (filename, &new_image_base);
> > + status = collect_image_info (filename);
> > if (!status)
> > - exit (2);
> > + return 2;
> > }
> >
> > + /* Nothing to do? */
> > + if (img_info_size == 0)
> > + return 0;
> > +
> > + /* Check what we have to do and do it. */
> > if (image_info_flag)
> > - print_image_info ();
> > + {
> > + /* Print. */
> > + print_image_info ();
> > + }
> > + else if (!image_storage_flag)
> > + {
> > + /* Rebase. */
> > + ULONG64 new_image_base = image_base;
> > + for (i = 0; i < img_info_size; ++i)
> > + {
> > + status = rebase (img_info_list[i].name, &new_image_base, down_flag);
> > + if (!status)
> > + return 2;
> > + }
> > + }
> > + else
> > + {
> > + /* Rebase with database support. */
> > + merge_image_info ();
> > + status = TRUE;
> > + for (i = 0; i < img_info_size; ++i)
> > + if (img_info_list[i].flag.needs_rebasing)
> > + {
> > + ULONG64 new_image_base = img_info_list[i].base;
> > + status = rebase (img_info_list[i].name, &new_image_base, FALSE);
> > + if (status)
> > + img_info_list[i].flag.needs_rebasing = 0;
> > + }
> > + if (save_image_info () < 0)
> > + return 2;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +int
> > +img_info_cmp (const void *a, const void *b)
> > +{
> > + ULONG64 abase = ((img_info_t *) a)->base;
> > + ULONG64 bbase = ((img_info_t *) b)->base;
> >
> > - exit (0);
> > + if (abase < bbase)
> > + return -1;
> > + if (abase > bbase)
> > + return 1;
> > + return strcmp (((img_info_t *) a)->name, ((img_info_t *) b)->name);
> > +}
> > +
> > +int
> > +img_info_name_cmp (const void *a, const void *b)
> > +{
> > + return strcmp (((img_info_t *) a)->name, ((img_info_t *) b)->name);
> > +}
> > +
> > +#ifndef __CYGWIN__
> > +int
> > +mkstemp (char *name)
> > +{
> > + return open (mktemp (name), O_CREAT | O_TRUNC | O_EXCL, 0600);
> > +}
> > +#endif
> > +
> > +int
> > +save_image_info ()
> > +{
> > + int i, fd;
> > + 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. */
> > + 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];
> > + /* Create a temporary file to write to. */
> > + fd = mkstemp (tmp_file);
> > + if (fd < 0)
> > + {
> > + fprintf (stderr, "%s: failed to create temporary rebase database: %s\n",
> > + progname, strerror (errno));
> > + return -1;
> > + }
> > + qsort (img_info_list, img_info_size, sizeof (img_info_t), img_info_name_cmp);
> > + /* First write the number of entries. */
> > + memcpy (hdr.magic, IMG_INFO_MAGIC, 4);
> > + hdr.machine = machine;
> > + hdr.version = IMG_INFO_VERSION;
> > + hdr.base = image_base;
> > + hdr.offset = offset;
> > + hdr.down_flag = down_flag;
> > + hdr.count = img_info_size;
> > + if (write (fd, &hdr, sizeof hdr) < 0)
> > + {
> > + fprintf (stderr, "%s: failed to write rebase database: %s\n",
> > + progname, strerror (errno));
> > + ret = -1;
> > + }
> > + /* Write the list. */
> > + else if (write (fd, img_info_list, img_info_size * sizeof (img_info_t)) < 0)
> > + {
> > + fprintf (stderr, "%s: failed to write rebase database: %s\n",
> > + progname, strerror (errno));
> > + ret = -1;
> > + }
> > + else
> > + {
> > + int i;
> > +
> > + /* Write all strings. */
> > + for (i = 0; i < img_info_size; ++i)
> > + if (write (fd, img_info_list[i].name,
> > + strlen (img_info_list[i].name) + 1) < 0)
> > + {
> > + fprintf (stderr, "%s: failed to write rebase database: %s\n",
> > + progname, strerror (errno));
> > + ret = -1;
> > + break;
> > + }
> > + }
> > +#ifdef __CYGWIN__
> > + fchmod (fd, 0660);
> > +#else
> > + chmod (tmp_file, 0660);
> > +#endif
> > + close (fd);
> > + if (ret < 0)
> > + unlink (tmp_file);
> > + else
> > + {
> > + if (unlink (db_file) < 0 && errno != ENOENT)
> > + {
> > + fprintf (stderr,
> > + "%s: failed to remove old rebase database file \"%s\":\n"
> > + "%s\n"
> > + "The new rebase database is stored in \"%s\".\n"
> > + "Manually remove \"%s\" and rename \"%s\" to \"%s\",\n"
> > + "otherwise the new rebase database will be unusable.\n",
> > + progname, db_file,
> > + strerror (errno),
> > + tmp_file,
> > + db_file, tmp_file, db_file);
> > + ret = -1;
> > + }
> > + else if (rename (tmp_file, db_file) < 0)
> > + {
> > + fprintf (stderr,
> > + "%s: failed to rename \"%s\" to \"%s\":\n"
> > + "%s\n"
> > + "Manually rename \"%s\" to \"%s\",\n"
> > + "otherwise the new rebase database will be unusable.\n",
> > + progname, tmp_file, db_file,
> > + strerror (errno),
> > + tmp_file, db_file);
> > + ret = -1;
> > + }
> > + }
> > + return ret;
> > +}
> > +
> > +int
> > +load_image_info ()
> > +{
> > + int fd;
> > + int ret = 0;
> > + int i;
> > + img_info_hdr_t hdr;
> > +
> > + fd = open (db_file, O_RDONLY);
> > + if (fd < 0)
> > + {
> > + /* It's no error if the file doesn't exist. However, in this case
> > + the -b option is mandatory. */
> > + if (errno == ENOENT && image_base)
> > + return 0;
> > + fprintf (stderr, "%s: failed to open rebase database \"%s\":\n%s\n",
> > + progname, db_file, strerror (errno));
> > + return -1;
> > + }
> > + /* First read the header. */
> > + if (read (fd, &hdr, sizeof hdr) < 0)
> > + {
> > + fprintf (stderr, "%s: failed to read rebase database \"%s\":\n%s\n",
> > + progname, db_file, strerror (errno));
> > + close (fd);
> > + return -1;
> > + }
> > + /* Check the header. */
> > + if (memcmp (hdr.magic, IMG_INFO_MAGIC, 4) != 0)
> > + {
> > + fprintf (stderr, "%s: \"%s\" is not a valid rebase database.\n",
> > + progname, db_file);
> > + close (fd);
> > + return -1;
> > + }
> > + if (hdr.machine != machine)
> > + {
> > + if (hdr.machine == IMAGE_FILE_MACHINE_I386)
> > + fprintf (stderr,
> > +"%s: \"%s\" is a database file for 32 bit DLLs but\n"
> > +"I'm started to handle 64 bit DLLs. If you want to handle 32 bit DLLs,\n"
> > +"use the -4 option.\n", progname, db_file);
> > + else if (hdr.machine == IMAGE_FILE_MACHINE_AMD64)
> > + fprintf (stderr,
> > +"%s: \"%s\" is a database file for 64 bit DLLs but\n"
> > +"I'm started to handle 32 bit DLLs. If you want to handle 64 bit DLLs,\n"
> > +"use the -8 option.\n", progname, db_file);
> > + else
> > + fprintf (stderr, "%s: \"%s\" is a database file for a machine type\n"
> > + "I don't know about.", progname, db_file);
> > + close (fd);
> > + return -1;
> > + }
> > + if (hdr.version != IMG_INFO_VERSION)
> > + {
> > + fprintf (stderr, "%s: \"%s\" is a version %u rebase database.\n"
> > + "I can only handle versions up to %lu.\n",
> > + progname, db_file, hdr.version, IMG_INFO_VERSION);
> > + close (fd);
> > + return -1;
> > + }
> > + /* If no new image base has been specified, use the one from the header. */
> > + if (image_base == 0)
> > + {
> > + image_base = hdr.base;
> > + down_flag = hdr.down_flag;
> > + }
> > + if (offset == 0)
> > + offset = hdr.offset;
> > + /* Don't enforce rebasing if address and offset are unchanged or taken from
> > + the file anyway. */
> > + if (image_base == hdr.base && offset == hdr.offset)
> > + force_rebase_flag = FALSE;
> > + img_info_size = hdr.count;
> > + /* Allocate memory for the image list. */
> > + if (ret == 0)
> > + {
> > + img_info_max_size = roundup (img_info_size, 100);
> > + img_info_list = (img_info_t *) calloc (img_info_max_size,
> > + sizeof (img_info_t));
> > + if (!img_info_list)
> > + {
> > + fprintf (stderr, "%s: Out of memory.\n", progname);
> > + ret = -1;
> > + }
> > + }
> > + /* Now read the list. */
> > + if (ret == 0
> > + && read (fd, img_info_list, img_info_size * sizeof (img_info_t)) < 0)
> > + {
> > + fprintf (stderr, "%s: failed to read rebase database \"%s\":\n%s\n",
> > + progname, db_file, strerror (errno));
> > + ret = -1;
> > + }
> > + /* Make sure all pointers are NULL. */
> > + if (ret == 0)
> > + for (i = 0; i < img_info_size; ++i)
> > + img_info_list[i].name = NULL;
> > + /* Eventually read the strings. */
> > + if (ret == 0)
> > + {
> > + for (i = 0; i < img_info_size; ++i)
> > + {
> > + img_info_list[i].name = (char *)
> > + malloc (img_info_list[i].name_size);
> > + if (!img_info_list[i].name)
> > + {
> > + fprintf (stderr, "%s: Out of memory.\n", progname);
> > + ret = -1;
> > + break;
> > + }
> > + if (read (fd, img_info_list[i].name,
> > + img_info_list[i].name_size) < 0)
> > + {
> > + fprintf (stderr, "%s: failed to read rebase database \"%s\": "
> > + "%s\n", progname, db_file, strerror (errno));
> > + ret = -1;
> > + break;
> > + }
> > + }
> > + }
> > + close (fd);
> > + /* On failure, free all allocated memory and set list pointer to NULL. */
> > + if (ret < 0)
> > + {
> > + for (i = 0; i < img_info_size && img_info_list[i].name; ++i)
> > + free (img_info_list[i].name);
> > + free (img_info_list);
> > + img_info_list = NULL;
> > + img_info_size = 0;
> > + img_info_max_size = 0;
> > + }
> > + return ret;
> > +}
> > +
> > +int
> > +merge_image_info ()
> > +{
> > + int i, end;
> > + img_info_t *match;
> > + ULONG64 floating_image_base;
> > +
> > + /* Sort new files from command line by name. */
> > + qsort (img_info_list + img_info_rebase_start,
> > + img_info_size - img_info_rebase_start, sizeof (img_info_t),
> > + img_info_name_cmp);
> > + /* Iterate through new files and eliminate duplicates. */
> > + for (i = img_info_rebase_start; i + 1 < img_info_size; ++i)
> > + if ((img_info_list[i].name_size == img_info_list[i + 1].name_size
> > + && !strcmp (img_info_list[i].name, img_info_list[i + 1].name))
> > +#ifdef __CYGWIN__
> > + || !strcmp (img_info_list[i].name, "/usr/bin/cygwin1.dll")
> > +#endif
> > + )
> > + {
> > + free (img_info_list[i].name);
> > + memmove (img_info_list + i, img_info_list + i + 1,
> > + (img_info_size - i - 1) * sizeof (img_info_t));
> > + --img_info_size;
> > + --i;
> > + }
> > + /* Iterate through new files and see if they are already available in
> > + existing database. */
> > + if (img_info_rebase_start)
> > + {
> > + for (i = img_info_rebase_start; i < img_info_size; ++i)
> > + {
> > + match = bsearch (&img_info_list[i], img_info_list,
> > + img_info_rebase_start, sizeof (img_info_t),
> > + img_info_name_cmp);
> > + if (match)
> > + {
> > + /* We found a match. Now test if the "new" file is actually
> > + the old file, or if it at least fits into the memory slot
> > + 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)
> > + {
> > + /* Reuse the old address if possible. */
> > + if (match->slot_size < img_info_list[i].slot_size)
> > + match->base = 0;
> > + match->flag.needs_rebasing = 1;
> > + }
> > + /* Unconditionally overwrite old with new size. */
> > + match->size = img_info_list[i].size;
> > + match->slot_size = img_info_list[i].slot_size;
> > + /* Remove new entry from array. */
> > + free (img_info_list[i].name);
> > + img_info_list[i--] = img_info_list[--img_info_size];
> > + }
> > + else
> > + /* 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)
> > + {
> > + /* No database yet or enforcing a new base address. Set base of all
> > + DLLs to 0. */
> > + for (i = 0; i < img_info_size; ++i)
> > + img_info_list[i].base = 0;
> > + }
> > +
> > + /* Now sort the old part of the list by base address. */
> > + if (img_info_rebase_start)
> > + qsort (img_info_list, img_info_rebase_start, sizeof (img_info_t),
> > + img_info_cmp);
> > + /* Perform several tests on the information fetched from the database
> > + to match with reality. */
> > + for (i = 0; i < img_info_rebase_start; ++i)
> > + {
> > + 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)
> > + continue;
> > + /* Check if the files in the old list still exist. Drop non-existant
> > + or unaccessible files. */
> > + if (access (img_info_list[i].name, F_OK) == -1
> > + || !GetImageInfos64 (img_info_list[i].name, NULL,
> > + &cur_base, &cur_size))
> > + {
> > + free (img_info_list[i].name);
> > + memmove (img_info_list + i, img_info_list + i + 1,
> > + (img_info_size - i - 1) * sizeof (img_info_t));
> > + --img_info_rebase_start;
> > + --img_info_size;
> > + 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)
> > + {
> > + 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 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;
> > + /* Make sure all DLLs with base address 0 have the needs_rebasing
> > + flag set. */
> > + if (img_info_list[i].base == 0)
> > + img_info_list[i].flag.needs_rebasing = 1;
> > + }
> > + /* The remainder of the function expects img_info_size to be > 0. */
> > + if (img_info_size == 0)
> > + return 0;
> > +
> > + /* Now sort entire list by base address. The files with address 0 will
> > + be first. */
> > + if (!force_rebase_flag)
> > + qsort (img_info_list, img_info_size, sizeof (img_info_t), img_info_cmp);
> > + /* Try to fit all DLLs with base address 0 into the given list. */
> > + /* FIXME: This loop only implements the top-down case. Implement a
> > + bottom-up case, too, at one point. */
> > + floating_image_base = image_base;
> > + end = img_info_size - 1;
> > + while (img_info_list[0].base == 0)
> > + {
> > + ULONG64 new_base;
> > +
> > + /* Skip trailing entries as long as there is no hole. */
> > + while (img_info_list[end].base + img_info_list[end].slot_size + offset
> > + >= floating_image_base)
> > + {
> > + floating_image_base = img_info_list[end].base;
> > + --end;
> > + }
> > + /* Test if one of the DLLs with address 0 fits into the hole. */
> > + for (i = 0, new_base = 0; img_info_list[i].base == 0; ++i, new_base = 0)
> > + {
> > + new_base = floating_image_base - img_info_list[i].slot_size - offset;
> > + if (new_base >= img_info_list[end].base
> > + + img_info_list[end].slot_size
> > +#ifdef __CYGWIN__
> > + /* Don't overlap the Cygwin DLL. */
> > + && (new_base >= cygwin_dll_image_base + cygwin_dll_image_size
> > + || new_base + img_info_list[i].slot_size
> > + <= cygwin_dll_image_base)
> > +#endif
> > + )
> > + break;
> > + }
> > + /* Found a match. Mount into list. */
> > + if (new_base)
> > + {
> > + img_info_t tmp = img_info_list[i];
> > + tmp.base = new_base;
> > + memmove (img_info_list + i, img_info_list + i + 1,
> > + (end - i) * sizeof (img_info_t));
> > + img_info_list[end] = tmp;
> > + continue;
> > + }
> > + /* Nothing matches. Set floating_image_base to the start of the
> > + uppermost DLL at this point and try again. */
> > +#ifdef __CYGWIN__
> > + if (floating_image_base >= cygwin_dll_image_base + cygwin_dll_image_size
> > + && img_info_list[end].base < cygwin_dll_image_base)
> > + floating_image_base = cygwin_dll_image_base;
> > + else
> > +#endif
> > + {
> > + floating_image_base = img_info_list[end].base;
> > + --end;
> > + }
> > + }
> > +
> > + return 0;
> > }
> >
> > BOOL
> > collect_image_info (const char *pathname)
> > {
> > + BOOL ret;
> > + WORD dll_machine;
> > +
> > /* Skip if file does not exist to prevent ReBaseImage() from using it's
> > stupid search algorithm (e.g, PATH, etc.). */
> > if (access (pathname, F_OK) == -1)
> > {
> > - fprintf (stderr, "%s: skipped because nonexistent\n", pathname);
> > + if (!quiet)
> > + fprintf (stderr, "%s: skipped because nonexistent.\n", pathname);
> > return TRUE;
> > }
> >
> > - if (img_info_size <= img_info_max_size)
> > + /* Skip if not rebaseable, but only if we're collecting for rebasing,
> > + not if we're collecting for printing only. */
> > + if (!image_info_flag && !is_rebaseable (pathname))
> > + {
> > + if (!quiet)
> > + fprintf (stderr, "%s: skipped because not rebaseable\n", pathname);
> > + return TRUE;
> > + }
> > +
> > + if (img_info_size >= img_info_max_size)
> > {
> > img_info_max_size += 100;
> > img_info_list = (img_info_t *) realloc (img_info_list,
> > @@ -152,46 +739,152 @@ collect_image_info (const char *pathname
> > * sizeof (img_info_t));
> > if (!img_info_list)
> > {
> > - fprintf (stderr, "Out of memory.\n");
> > - exit (2);
> > + fprintf (stderr, "%s: Out of memory.\n", progname);
> > + return FALSE;
> > }
> > }
> >
> > - if (GetImageInfos64 (pathname, NULL,
> > - &img_info_list[img_info_size].base,
> > - &img_info_list[img_info_size].size))
> > - img_info_list[img_info_size++].name = strdup (pathname);
> > + ret = GetImageInfos64 (pathname, &dll_machine,
> > + &img_info_list[img_info_size].base,
> > + &img_info_list[img_info_size].size);
> > + if (!ret)
> > + {
> > + if (!quiet)
> > + fprintf (stderr, "%s: skipped because file info unreadable.\n",
> > + pathname);
> > + return TRUE;
> > + }
> > + if (dll_machine != machine)
> > + {
> > + if (!quiet)
> > + fprintf (stderr, "%s: skipped because wrong machine type.\n",
> > + pathname);
> > + return TRUE;
> > + }
> > + img_info_list[img_info_size].slot_size
> > + = roundup2 (img_info_list[img_info_size].size, ALLOCATION_SLOT);
> > + img_info_list[img_info_size].flag.needs_rebasing = 1;
> > + /* This back and forth from POSIX to Win32 is a way to get a full path
> > + more thoroughly. For instance, the difference between /bin and
> > + /usr/bin will be eliminated. */
> > +#if defined (__MSYS__)
> > + {
> > + char w32_path[MAX_PATH];
> > + char full_path[MAX_PATH];
> > + cygwin_conv_to_full_win32_path (pathname, w32_path);
> > + cygwin_conv_to_full_posix_path (w32_path, full_path);
> > + img_info_list[img_info_size].name = strdup (full_path);
> > + img_info_list[img_info_size].name_size = strlen (full_path) + 1;
> > + }
> > +#elif defined (__CYGWIN__)
> > + {
> > + PWSTR w32_path = cygwin_create_path (CCP_POSIX_TO_WIN_W, pathname);
> > + if (!w32_path)
> > + {
> > + fprintf (stderr, "%s: Out of memory.\n", progname);
> > + return FALSE;
> > + }
> > + img_info_list[img_info_size].name
> > + = cygwin_create_path (CCP_WIN_W_TO_POSIX, w32_path);
> > + if (!img_info_list[img_info_size].name)
> > + {
> > + fprintf (stderr, "%s: Out of memory.\n", progname);
> > + return FALSE;
> > + }
> > + free (w32_path);
> > + img_info_list[img_info_size].name_size
> > + = strlen (img_info_list[img_info_size].name) + 1;
> > + }
> > +#else
> > + {
> > + char full_path[MAX_PATH];
> > + GetFullPathName (pathname, MAX_PATH, full_path, NULL);
> > + img_info_list[img_info_size].name = strdup (full_path);
> > + img_info_list[img_info_size].name_size = strlen (full_path) + 1;
> > + }
> > +#endif
> > + ++img_info_size;
> > return TRUE;
> > }
> >
> > -int
> > -img_info_cmp (const void *a, const void *b)
> > -{
> > - ULONG64 abase = ((img_info_t *) a)->base;
> > - ULONG64 bbase = ((img_info_t *) b)->base;
> > -
> > - if (abase < bbase)
> > - return -1;
> > - if (abase > bbase)
> > - return 1;
> > - return strcmp (((img_info_t *) a)->name, ((img_info_t *) b)->name);
> > -}
> > -
> > void
> > print_image_info ()
> > {
> > unsigned int i;
> >
> > + /* Sort list by name. */
> > + qsort (img_info_list, img_info_size, sizeof (img_info_t), img_info_name_cmp);
> > + /* Iterate through list and eliminate duplicates. */
> > + for (i = 0; i + 1 < img_info_size; ++i)
> > + if (img_info_list[i].name_size == img_info_list[i + 1].name_size
> > + && !strcmp (img_info_list[i].name, img_info_list[i + 1].name))
> > + {
> > + /* Remove duplicate, but prefer one from the command line over one
> > + from the database, because the one from the command line reflects
> > + the reality, while the database is wishful thinking. */
> > + if (img_info_list[i].flag.needs_rebasing == 0)
> > + {
> > + free (img_info_list[i].name);
> > + memmove (img_info_list + i, img_info_list + i + 1,
> > + (img_info_size - i - 1) * sizeof (img_info_t));
> > + }
> > + else
> > + {
> > + free (img_info_list[i + 1].name);
> > + if (i + 2 < img_info_size)
> > + memmove (img_info_list + i + 1, img_info_list + i + 2,
> > + (img_info_size - i - 2) * sizeof (img_info_t));
> > + }
> > + --img_info_size;
> > + --i;
> > + }
> > + /* For entries loaded from database, collect image info to reflect reality.
> > + Also, collect_image_info sets needs_rebasing to 1, so reset here. */
> > + for (i = 0; i < img_info_size; ++i)
> > + {
> > + if (img_info_list[i].flag.needs_rebasing == 0)
> > + {
> > + ULONG64 base;
> > + ULONG size;
> > +
> > + if (GetImageInfos64 (img_info_list[i].name, NULL, &base, &size))
> > + {
> > + img_info_list[i].base = base;
> > + img_info_list[i].size = size;
> > + img_info_list[i].slot_size
> > + = roundup2 (img_info_list[i].size, ALLOCATION_SLOT);
> > + }
> > + }
> > + else
> > + img_info_list[i].flag.needs_rebasing = 0;
> > + }
> > + /* Now sort by address. */
> > qsort (img_info_list, img_info_size, sizeof (img_info_t), img_info_cmp);
> > for (i = 0; i < img_info_size; ++i)
> > - printf ("%-47s base 0x%08" PRIx64 " size 0x%08lx\n",
> > - img_info_list[i].name,
> > - img_info_list[i].base,
> > - img_info_list[i].size);
> > + {
> > + int tst;
> > + ULONG64 end = img_info_list[i].base + img_info_list[i].slot_size;
> > +
> > + /* Check for overlap and mark both DLLs. */
> > + for (tst = i + 1;
> > + tst < img_info_size && img_info_list[tst].base < end;
> > + ++tst)
> > + {
> > + img_info_list[i].flag.needs_rebasing = 1;
> > + img_info_list[tst].flag.needs_rebasing = 1;
> > + }
> > + printf ("%-*s base 0x%0*" PRIx64 " size 0x%08lx %c\n",
> > + machine == IMAGE_FILE_MACHINE_I386 ? 45 : 37,
> > + img_info_list[i].name,
> > + machine == IMAGE_FILE_MACHINE_I386 ? 8 : 16,
> > + img_info_list[i].base,
> > + img_info_list[i].size,
> > + img_info_list[i].flag.needs_rebasing ? '*' : ' ');
> > + }
> > }
> >
> > BOOL
> > -rebase (const char *pathname, ULONG64 *new_image_base)
> > +rebase (const char *pathname, ULONG64 *new_image_base, BOOL down_flag)
> > {
> > ULONG64 old_image_base, prev_new_image_base;
> > ULONG old_image_size, new_image_size;
> > @@ -201,22 +894,16 @@ rebase (const char *pathname, ULONG64 *n
> > stupid search algorithm (e.g, PATH, etc.). */
> > if (access (pathname, F_OK) == -1)
> > {
> > - fprintf (stderr, "%s: skipped because nonexistent\n", pathname);
> > + if (!quiet)
> > + fprintf (stderr, "%s: skipped because nonexistent\n", pathname);
> > return TRUE;
> > }
> >
> > /* Skip if not writable. */
> > if (access (pathname, W_OK) == -1)
> > {
> > - fprintf (stderr, "%s: skipped because not writable\n", pathname);
> > - return TRUE;
> > - }
> > -
> > - /* Skip if not rebaseable. */
> > - if (!is_rebaseable (pathname))
> > - {
> > - if (verbose)
> > - fprintf (stderr, "%s: skipped because not rebaseable\n", pathname);
> > + if (!quiet)
> > + fprintf (stderr, "%s: skipped because not writable\n", pathname);
> > return TRUE;
> > }
> >
> > @@ -312,18 +999,47 @@ retry:
> > return TRUE;
> > }
> >
> > +static struct option long_options[] = {
> > + {"32", no_argument, NULL, '4'},
> > + {"64", no_argument, NULL, '8'},
> > + {"base", required_argument, NULL, 'b'},
> > + {"down", no_argument, NULL, 'd'},
> > + {"help", no_argument, NULL, 'h'},
> > + {"usage", no_argument, NULL, 'h'},
> > + {"info", no_argument, NULL, 'i'},
> > + {"offset", required_argument, NULL, 'o'},
> > + {"quiet", no_argument, NULL, 'q'},
> > + {"database", no_argument, NULL, 's'},
> > + {"filelist", required_argument, NULL, 'T'},
> > + {"usage", no_argument, NULL, 'h'},
> > + {"verbose", no_argument, NULL, 'v'},
> > + {"version", no_argument, NULL, 'V'},
> > + {NULL, no_argument, NULL, 0 }
> > +};
> > +
> > +static const char *short_options = "48b:dhioq:sT:vV";
> > +
> > void
> > parse_args (int argc, char *argv[])
> > {
> > - const char *anOptions = "b:dio:T:vV";
> > - int anOption = 0;
> > + int opt = 0;
> >
> > - while ((anOption = getopt (argc, argv, anOptions)) != -1)
> > + while ((opt = getopt_long (argc, argv, short_options, long_options, NULL))
> > + != -1)
> > {
> > - switch (anOption)
> > + switch (opt)
> > {
> > + case '4':
> > + machine = IMAGE_FILE_MACHINE_I386;
> > + db_file = IMG_INFO_FILE_I386;
> > + break;
> > + case '8':
> > + machine = IMAGE_FILE_MACHINE_AMD64;
> > + db_file = IMG_INFO_FILE_AMD64;
> > + break;
> > case 'b':
> > image_base = string_to_ulonglong (optarg);
> > + force_rebase_flag = TRUE;
> > break;
> > case 'd':
> > down_flag = TRUE;
> > @@ -333,6 +1049,15 @@ parse_args (int argc, char *argv[])
> > break;
> > case 'o':
> > offset = string_to_ulonglong (optarg);
> > + force_rebase_flag = TRUE;
> > + break;
> > + case 'q':
> > + quiet = TRUE;
> > + break;
> > + case 's':
> > + image_storage_flag = TRUE;
> > + /* FIXME: For now enforce top-down rebasing when using the database.*/
> > + down_flag = TRUE;
> > break;
> > case 'T':
> > file_list = optarg;
> > @@ -340,6 +1065,10 @@ parse_args (int argc, char *argv[])
> > case 'v':
> > verbose = TRUE;
> > break;
> > + case 'h':
> > + help ();
> > + exit (1);
> > + break;
> > case 'V':
> > version ();
> > exit (1);
> > @@ -351,7 +1080,7 @@ parse_args (int argc, char *argv[])
> > }
> > }
> >
> > - if ((image_base == 0 && !image_info_flag)
> > + if ((image_base == 0 && !image_info_flag && !image_storage_flag)
> > || (image_base && image_info_flag))
> > {
> > usage ();
> > @@ -373,9 +1102,56 @@ void
> > usage ()
> > {
> > fprintf (stderr,
> > - "usage: rebase -b BaseAddress [-Vdv] [-o Offset] "
> > - "[-T FileList | -] Files...\n"
> > - " rebase -i [-T FileList | -] Files...\n");
> > +"usage: %s [-b BaseAddress] [-o Offset] [-48dsvV] [-T FileList | -] Files...\n"
> > +" %s -i [-48s] [-T FileList | -] Files...\n"
> > +" %s --help or --usage for full help text\n",
> > + progname, progname, progname);
> > +}
> > +
> > +void
> > +help ()
> > +{
> > + printf ("\
> > +Usage: %s [OPTIONS] [FILE]...\n\
> > +Rebase PE files, usually DLLs, to a specified address or address range.\n\
> > +\n\
> > + -4, --32 Only rebase 32 bit DLLs."
> > +#ifndef __x86_64__
> > + " This is the default."
> > +#endif
> > +"\n\
> > + -8, --64 Only rebase 64 bit DLLs."
> > +#ifdef __x86_64__
> > + " This is the default."
> > +#endif
> > +"\n\
> > + -b, --base=BASEADDRESS Specifies the base address at which to start rebasing.\n\
> > + -s, --database Utilize the rebase database to find unused memory\n\
> > + slots to rebase the files on the command line to.\n\
> > + (Implies -d).\n\
> > + If -b is given, too, the database gets recreated.\n\
> > + -i, --info Rather then rebasing, just print the current base\n\
> > + address and size of the files. With -s, use the\n\
> > + database. The files are ordered by base address.\n\
> > + A '*' at the end of the line is printed if a\n\
> > + collisions with an adjacent file is detected.\n\
> > +\n\
> > + One of the options -b, -s or -i is mandatory. If no rebase database exists\n\
> > + yet, -b is required together with -s.\n\
> > +\n\
> > + -d, --down Treat the BaseAddress as upper ceiling and rebase\n\
> > + files top-down from there. Without this option the\n\
> > + files are rebased from BaseAddress bottom-up.\n\
> > + 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, --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\
> > + -v, --verbose Print some debug output.\n\
> > + -V, --version Print version info and exit.\n\
> > + -h, --help, --usage This help.\n",
> > + progname);
> > }
> >
> > BOOL
> > Index: rebaseall.in
> > ===================================================================
> > RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/rebaseall.in,v
> > retrieving revision 1.3
> > diff -u -p -r1.3 rebaseall.in
> > --- rebaseall.in 28 Jun 2011 19:43:19 -0000 1.3
> > +++ rebaseall.in 10 Jul 2011 14:58:58 -0000
> > @@ -13,7 +13,7 @@
> > #
> > # Written by Jason Tishler <jason@tishler.net>
> > #
> > -# $Id: rebaseall.in,v 1.3 2011/06/28 19:43:19 corinna Exp $
> > +# $Id: rebaseall.in,v 1.2 2011/06/21 15:40:10 corinna Exp $
> > #
> >
> > # Define constants
> > @@ -22,7 +22,7 @@ tp2=${tp1:-.}
> > PATH=$(cd $tp2 && pwd):@bindir@:/bin
> >
> > ProgramName=${0##*/}
> > -ProgramOptions='b:o:s:T:v'
> > +ProgramOptions='48b:o:s:T:v'
> > DefaultBaseAddress=0x70000000
> > DefaultOffset=@DEFAULT_OFFSET_VALUE@
> > DefaultVerbose=
> > @@ -32,31 +32,43 @@ DefaultSuffixes='dll|so'
> > # Define functions
> > usage()
> > {
> > - echo "usage: $ProgramName [-b BaseAddress] [-o Offset] [-s DllSuffix] [-T FileList | -] [-v]"
> > + echo "usage: ${ProgramName} [-b BaseAddress] [-o Offset] [-s DllSuffix] [-T FileList | -] [-4|-8] [-v]"
> > exit 1
> > }
> >
> > cleanup()
> > {
> > - rm -f "$TmpFile"
> > - exit $ExitCode
> > + rm -f "${TmpFile}"
> > + exit ${ExitCode}
> > }
> >
> > # Set traps
> > trap cleanup 1 2 15
> >
> > # Set defaults
> > -BaseAddress=$DefaultBaseAddress
> > -Offset=$DefaultOffset
> > -Verbose=$DefaultVerbose
> > -FileList=$DefaultFileList
> > -Suffixes=$DefaultSuffixes
> > +BaseAddress=""
> > +Offset="${DefaultOffset}"
> > +Verbose="${DefaultVerbose}"
> > +FileList="${DefaultFileList}"
> > +Suffixes="${DefaultSuffixes}"
> > +db_file_i386="@sysconfdir@/rebase.db.i386"
> > +db_file_x86_64="@sysconfdir@/rebase.db.x86_64"
> > +case `uname -m` in
> > + i[3456]86)
> > + db_file="${db_file_i386}";
> > + Mach="-4"
> > + ;;
> > + x86_64)
> > + Mach="-8"
> > + db_file="${db_file_x86_64}"
> > + ;;
> > +esac
> >
> > # Verify only ash or dash processes are running
> > grep -E -q -i -v '/d?ash(.exe)?$' /proc/[0-9]*/exename
> > -if [ $? -eq 0 -a -z "$RebaseDebug" ]
> > +if [ $? -eq 0 -a -z "${RebaseDebug}" ]
> > then
> > - echo "$ProgramName: only ash or dash processes are allowed during rebasing"
> > + 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)."
> > @@ -64,24 +76,43 @@ then
> > fi
> >
> > # Parse command line arguments
> > -while getopts $ProgramOptions Option "$@"
> > +while getopts "${ProgramOptions}" Option "$@"
> > do
> > - case $Option in
> > + case "${Option}" in
> > + 4)
> > + db_file="${db_file_i386}";
> > + Mach="-4"
> > + ;;
> > + 8)
> > + Mach="-8"
> > + db_file="${db_file_x86_64}"
> > + ;;
> > b)
> > - BaseAddress=$OPTARG;;
> > + BaseAddress="${OPTARG}";;
> > o)
> > - Offset=$OPTARG;;
> > + Offset="${OPTARG}";;
> > s)
> > - Suffixes="$Suffixes|$OPTARG";;
> > + Suffixes="${Suffixes}|${OPTARG}";;
> > T)
> > - FileList="$OPTARG";;
> > + FileList="${OPTARG}";;
> > v)
> > - Verbose=-v;;
> > + Verbose="-v";;
> > \?)
> > usage;;
> > esac
> > done
> >
> > +# Check if rebase database already exists.
> > +database_exists="no"
> > +[ -f "${db_file}" ] && database_exists="yes"
> > +
> > +# If BaseAddress has not been specified, and the rebase database doesn't exist
> > +# yet, set BaseAddress to default.
> > +if [ -z "${BaseAddress}" -a "${database_exists}" != "yes" ]
> > +then
> > + BaseAddress=$DefaultBaseAddress
> > +fi
> > +
> > # Set temp directory
> > TmpDir="${TMP:-${TEMP:-/tmp}}"
> >
> > @@ -112,16 +143,20 @@ find /etc/setup -name '*.lst.gz' | xargs
> > grep -E "\.($Suffixes)\$" |
> > sed -e '/cygwin1\.dll$/d' -e '/cyglsa.*\.dll$/d' \
> > -e '/sys-root\/mingw/d' \
> > - -e 's/^/\//' -e '/d?ash\.exe$/d' -e '/rebase\.exe$/d' >"$TmpFile"
> > + -e 's/^/\//' -e '/d?ash\.exe$/d' -e '/rebase\.exe$/d' >"${TmpFile}"
> >
> > # Append user supplied file list, if any
> > -if [ -n "$FileList" ]
> > +if [ -n "${FileList}" ]
> > then
> > - cat "$FileList" >>"$TmpFile"
> > + cat "${FileList}" >>"${TmpFile}"
> > fi
> >
> > -# Rebase files
> > -rebase $Verbose -d -b $BaseAddress -o $Offset -T "$TmpFile"
> > +if [ -z "${BaseAddress}" ]
> > +then
> > + ./rebase "${Verbose}" -s "${Mach}" -T "${TmpFile}"
> > +else
> > + ./rebase "${Verbose}" -s "${Mach}" -b "${BaseAddress}" -o "${Offset}" -T "${TmpFile}"
> > +fi
> > ExitCode=$?
> >
> > # Clean up
> >
> >
> > --
> > 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
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat