From: Jason Green To: Eli Zaretskii Cc: djgpp-workers AT delorie DOT com Subject: Re: Symify fixes Date: Tue, 29 Aug 2000 19:27:08 +0100 Message-ID: References: <226lqssqgqp6i9nk82rvrqhl9aaia029e9 AT 4ax DOT com> <7458-Mon28Aug2000203504+0300-eliz AT is DOT elta DOT co DOT il> <8011-Mon28Aug2000234727+0300-eliz AT is DOT elta DOT co DOT il> In-Reply-To: <8011-Mon28Aug2000234727+0300-eliz@is.elta.co.il> X-Mailer: Forte Agent 1.7/32.534 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id OAA07815 Reply-To: djgpp-workers AT delorie DOT com On Mon, 28 Aug 2000 23:47:27 +0200, you wrote: > > To test the robustness of symify I was going to corrupt some .exe > > file. Again, I am open to suggestions on this. > > Write a program which inserts a 0xA0000 pointer dereference at random > points of another program's source? Hmmm, I don't follow what you mean. I have added checking to the symify code so that it now exits gracefully if the program _being_ _debugged_ is corrupt, (ie nonsense values in the COFF headers). It's the new code in symify I would like to excercise. So far this is achieved by producing a garbage file, editing the first two bytes to be 4C 01, and supplying this to symify when it is run on a stack dump. The new symify will print an error message and exit, whereas the existing version will usually bomb. Attached are three patches to syms.c: 1) Replace calls to malloc() with xmalloc() 2) Fix a minor (non-bug) problem with compiler warnings 3) Introduce four new functions, these are: bail(): Prints an error message to stderr and quits. xfseek(): Wrapper for fseek(), quits upon file error. xfread(): Wrapper for fread(), quits upon file error. xmalloc_fread(): Wrapper for a combined xmalloc()/xfread() operation. Function names can change if someone will suggest better alternatives. The patches assume that the official syms.c is already fixed with the patch previously posted to c.o.m.d by Eli. Patch 1 follows: ============================================================ --- src/debug/common/syms.c~1 Sun Aug 27 19:50:32 2000 +++ src/debug/common/syms.c Sun Aug 27 19:51:36 2000 @@ -32,6 +32,8 @@ #include #include +void *xmalloc (size_t); + int undefined_symbol=0; int syms_printwhy=0; @@ -127,8 +129,7 @@ static char *symndup(char *s, int len) { char *rv; - if(!(rv = malloc(len+1))) - return (char *)NULL; + rv = xmalloc(len+1); memcpy(rv,s,len); rv[len] = 0; return rv; @@ -162,9 +163,9 @@ fseek(fd, ofs, 0); fread(&f_fh, 1, FILHSZ, fd); fread(&f_ah, 1, AOUTSZ, fd); - f_sh = (SCNHDR *)malloc(f_fh.f_nscns * SCNHSZ); - f_types = (char *)malloc(f_fh.f_nscns); - f_lnno = (LINENO **)malloc(f_fh.f_nscns * sizeof(LINENO *)); + f_sh = (SCNHDR *)xmalloc(f_fh.f_nscns * SCNHSZ); + f_types = (char *)xmalloc(f_fh.f_nscns); + f_lnno = (LINENO **)xmalloc(f_fh.f_nscns * sizeof(LINENO *)); fread(f_sh, f_fh.f_nscns, SCNHSZ, fd); for (i=0; i #include +#include + void *xmalloc (size_t); int undefined_symbol=0; @@ -151,6 +153,74 @@ return 1; } +/* bail(): Print MSG to stderr and quit */ +static void bail(const char *msg) +{ + assert(msg); + + fprintf(stderr, "SYMIFY ERROR: %s\n", msg); + exit(EXIT_FAILURE); +} + +/* xfseek(): Move the file pointer for FILE according to MODE, + * print an error message and bailout if the file operation fails. + * Return: 0 (success) always. + */ +static int xfseek(FILE *stream, long offset, int mode) +{ + assert(stream); + assert((mode==SEEK_SET) || (mode==SEEK_CUR) || (mode==SEEK_END)); + + /* Note that fseek's past the end of file will not fail in dos. */ + + if (fseek(stream, offset, mode)) + bail("fseek failed"); + + return 0; +} + +/* xfread(): Read NUMBER of objects, each of SIZE bytes, from FILE to BUFFER. + * print an error message and bailout if the file operation fails, or if less + * than NUMBER*SIZE bytes were read. + * Return: NUMBER always. + */ +static size_t xfread(void *buffer, size_t size, size_t number, FILE *stream) +{ + assert(buffer); + assert(stream); + + if (fread(buffer, size, number, stream) == number) + return number; + else if (feof(stream)) + bail("unexpected end of file"); + else if (ferror(stream)) + bail("error reading from file"); + else + bail("fread failed"); + + return 0; /* dummy return */ +} + +/* xmalloc_fread(): Allocate a memory buffer to store NUMBER of objects, + * each of SIZE bytes, then fill the buffer by reading from FILE. + * print an error message and bailout if not enough memory available to + * allocate the buffer, or if a file error occurs, or if not enough bytes + * are read to fill the buffer. + * Return: a pointer to the newly allocated buffer. + */ +static void *xmalloc_fread(size_t size, size_t number, FILE *stream) +{ + void *buffer; + + assert(stream); + + buffer = xmalloc(size * number); + + xfread(buffer, size, number, stream); + + return buffer; +} + static void process_coff(FILE *fd, long ofs) { unsigned int i; @@ -161,13 +231,12 @@ char *name; int i2_max; - fseek(fd, ofs, 0); - fread(&f_fh, 1, FILHSZ, fd); - fread(&f_ah, 1, AOUTSZ, fd); - f_sh = (SCNHDR *)xmalloc(f_fh.f_nscns * SCNHSZ); + xfseek(fd, ofs, 0); + xfread(&f_fh, FILHSZ, 1, fd); + xfread(&f_ah, AOUTSZ, 1, fd); + f_sh = xmalloc_fread(SCNHSZ, f_fh.f_nscns, fd); f_types = (char *)xmalloc(f_fh.f_nscns); f_lnno = (LINENO **)xmalloc(f_fh.f_nscns * sizeof(LINENO *)); - fread(f_sh, f_fh.f_nscns, SCNHSZ, fd); for (i=0; i