dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/image link.c, 1.26, 1.27 pecoff_loader.c


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/image link.c, 1.26, 1.27 pecoff_loader.c, 1.16, 1.17
Date: Thu, 28 Aug 2003 03:10:16 -0400

Update of /cvsroot/dotgnu-pnet/pnet/image
In directory subversions:/tmp/cvs-serv8815/image

Modified Files:
        link.c pecoff_loader.c 
Log Message:


Add support for gzip-compressed PE/COFF binaries.


Index: link.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/link.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -r1.26 -r1.27
*** link.c      24 Jul 2003 07:40:49 -0000      1.26
--- link.c      28 Aug 2003 07:10:13 -0000      1.27
***************
*** 219,223 ****
  
        /* Build the full pathname */
!       path = (char *)ILMalloc(fullLen);
        if(!path)
        {
--- 219,223 ----
  
        /* Build the full pathname */
!       path = (char *)ILMalloc(fullLen + 3);
        if(!path)
        {
***************
*** 293,296 ****
--- 293,305 ----
                        return path;
                }
+ 
+ #ifdef IL_CONFIG_GZIP
+               /* Try ".dll.gz" as well, in case the library was compressed */
+               strcpy(path + posn - 3, "dll.gz");
+               if(ILFileExists(path, 0))
+               {
+                       return path;
+               }
+ #endif
        }
  

Index: pecoff_loader.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/pecoff_loader.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -r1.16 -r1.17
*** pecoff_loader.c     17 Aug 2003 22:40:11 -0000      1.16
--- pecoff_loader.c     28 Aug 2003 07:10:13 -0000      1.17
***************
*** 2,6 ****
   * pecoff_loader.c - Deal with the ugly parts of loading PE/COFF images.
   *
!  * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
   *
   * This program is free software; you can redistribute it and/or modify
--- 2,6 ----
   * pecoff_loader.c - Deal with the ugly parts of loading PE/COFF images.
   *
!  * Copyright (C) 2001, 2003  Southern Storm Software, Pty Ltd.
   *
   * This program is free software; you can redistribute it and/or modify
***************
*** 20,23 ****
--- 20,29 ----
  
  #include "image.h"
+ #if defined(IL_CONFIG_GZIP) && defined(HAVE_ZLIB_H) && defined(HAVE_LIBZ)
+       #define IL_USE_GZIP     1
+ #endif
+ #ifdef IL_USE_GZIP
+       #include <zlib.h>
+ #endif
  
  #ifdef        __cplusplus
***************
*** 37,40 ****
--- 43,51 ----
        unsigned long   bufLen;
        int (*readFunc)(ILInputContext *ctx, void *buf, unsigned len);
+ #ifdef IL_USE_GZIP
+       int                             sawEOF;
+       z_streamp               gzStream;
+       ILInputContext *linked;
+ #endif
  };
  
***************
*** 73,76 ****
--- 84,312 ----
  }
  
+ #ifdef IL_USE_GZIP
+ 
+ /*
+  * Gzip flag bits in the header.
+  */
+ #define GZ_ASCII_FLAG   0x01
+ #define GZ_HEAD_CRC     0x02
+ #define GZ_EXTRA_FIELD  0x04
+ #define GZ_ORIG_NAME    0x08
+ #define GZ_COMMENT      0x10
+ #define GZ_RESERVED     0xE0
+ 
+ /*
+  * Fill the gzip read buffer if necessary.
+  */
+ static void GzipFillRead(ILInputContext *ctx)
+ {
+       if(ctx->gzStream->avail_in == 0 && !(ctx->sawEOF))
+       {
+               int temp = (*(ctx->linked->readFunc))
+                       (ctx->linked, (void *)(ctx->buffer), BUFSIZ);
+               if(temp <= 0)
+               {
+                       ctx->gzStream->avail_in = 0;
+                       ctx->sawEOF = 1;
+               }
+               else
+               {
+                       ctx->gzStream->avail_in = (unsigned)temp;
+               }
+               ctx->gzStream->next_in = (Bytef *)(ctx->buffer);
+       }
+ }
+ 
+ /*
+  * Read a single byte from the read buffer.
+  */
+ static int GzipReadByte(ILInputContext *ctx)
+ {
+       GzipFillRead(ctx);
+       if(ctx->gzStream->avail_in > 0)
+       {
+               --(ctx->gzStream->avail_in);
+               return *(ctx->gzStream->next_in)++;
+       }
+       else
+       {
+               return -1;
+       }
+ }
+ 
+ /*
+  * Read a short value from the read buffer.
+  */
+ static int GzipReadShort(ILInputContext *ctx)
+ {
+       int b1 = GzipReadByte(ctx);
+       int b2 = GzipReadByte(ctx);
+       return (b1 | (b2 << 8));
+ }
+ 
+ /*
+  * Skip a number of bytes in the read buffer.
+  */
+ static void GzipSkip(ILInputContext *ctx, int len)
+ {
+       while(len > 0 && GzipReadByte(ctx) != -1)
+       {
+               --len;
+       }
+ }
+ 
+ /*
+  * Skip a NUL-terminated string in the read buffer.
+  */
+ static void GzipSkipString(ILInputContext *ctx)
+ {
+       int b;
+       while((b = GzipReadByte(ctx)) != -1 && b != 0)
+       {
+               /* Nothing to do here */
+       }
+ }
+ 
+ /*
+  * Gzip-based read operation.  This version doesn't check CRC's
+  * or handle concatenated gzip files.  Fix later if required.
+  */
+ static int GzipRead(ILInputContext *ctx, void *buf, unsigned len)
+ {
+       int error;
+ 
+       /* Initialize the zlib output buffer */
+       ctx->gzStream->next_out = (Bytef *)buf;
+       ctx->gzStream->avail_out = len;
+ 
+       /* Read data and write it to the output buffer */
+       while(ctx->gzStream->avail_out != 0 && !(ctx->sawEOF))
+       {
+               /* Read more data from the input stream if necessary */
+               GzipFillRead(ctx);
+ 
+               /* Inflate the input data */
+               error = inflate(ctx->gzStream, Z_NO_FLUSH);
+               if(error == Z_STREAM_END)
+               {
+                       /* We've reached the end of the gzip data: skip the CRC 
value */
+                       GzipSkip(ctx, 4);
+                       ctx->sawEOF = 1;
+               }
+               else if(error != Z_OK)
+               {
+                       /* Some kind of error occurred in the input data */
+                       ctx->sawEOF = 1;
+               }
+       }
+ 
+       /* Read the length of the uncompressed data to the caller */
+       return (int)(len - ctx->gzStream->avail_out);
+ }
+ 
+ 
+ /*
+  * Finalize gzip control structures in an input context.
+  */
+ static void GzipFinalize(ILInputContext *ctx)
+ {
+       ILInputContext *linked;
+       if(ctx->gzStream)
+       {
+               inflateEnd(ctx->gzStream);
+               ILFree(ctx->gzStream);
+               ILFree((char *)(ctx->buffer));
+               linked = ctx->linked;
+               *ctx = *linked;
+               ILFree(linked);
+       }
+ }
+ 
+ /*
+  * Gzip initialize operation.  It is assumed that the first two
+  * bytes of the gzip stream (containing the magic number) have
+  * already been read.
+  */
+ static int GzipInitialize(ILInputContext *ctx)
+ {
+       ILInputContext *linked;
+       char *buffer;
+       z_streamp gzStream;
+       int method, flags, len;
+ 
+       /* Make a copy of the context for performing linked reads */
+       linked = (ILInputContext *)ILMalloc(sizeof(ILInputContext));
+       if(!linked)
+       {
+               return 0;
+       }
+       *linked = *ctx;
+ 
+       /* Allocate a buffer for holding the gzip input data */
+       buffer = (char *)ILMalloc(BUFSIZ);
+       if(!buffer)
+       {
+               ILFree(linked);
+               return 0;
+       }
+ 
+       /* Initialize the gzip stream details */
+       gzStream = (z_streamp)ILCalloc(1, sizeof(z_stream));
+       if(!gzStream)
+       {
+               ILFree(buffer);
+               ILFree(linked);
+               return 0;
+       }
+       if(inflateInit2(gzStream, -MAX_WBITS) != Z_OK)
+       {
+               ILFree(gzStream);
+               ILFree(buffer);
+               ILFree(linked);
+               return 0;
+       }
+ 
+       /* Set up the input context for gzip-based reads */
+       ctx->stream = 0;
+       ctx->buffer = (const char *)buffer;
+       ctx->bufLen = 0;
+       ctx->readFunc = GzipRead;
+       ctx->gzStream = gzStream;
+       ctx->linked = linked;
+       ctx->sawEOF = 0;
+ 
+       /* Skip past the gzip header */
+       method = GzipReadByte(ctx);
+       flags = GzipReadByte(ctx);
+       if(method != Z_DEFLATED || (flags & GZ_RESERVED) != 0)
+       {
+               GzipFinalize(ctx);
+               return 0;
+       }
+       GzipSkip(ctx, 6);               /* Time, extra flags, and OS code */
+       if((flags & GZ_EXTRA_FIELD) != 0)
+       {
+               len = GzipReadShort(ctx);
+               GzipSkip(ctx, len);
+       }
+       if((flags & GZ_ORIG_NAME) != 0)
+       {
+               GzipSkipString(ctx);
+       }
+       if((flags & GZ_COMMENT) != 0)
+       {
+               GzipSkipString(ctx);
+       }
+       if((flags & GZ_HEAD_CRC) != 0)
+       {
+               GzipSkip(ctx, 2);
+       }
+ 
+       /* The stream is ready to go */
+       return 1;
+ }
+ 
+ #endif /* IL_USE_GZIP */
+ 
  /*
   * Seek to a particular offset within a stream by reading
***************
*** 210,213 ****
--- 446,469 ----
                return IL_LOADERR_TRUNCATED;
        }
+ #ifdef IL_USE_GZIP
+       if(buffer[0] == (char)0x1F && buffer[1] == (char)0x8B)
+       {
+               /* The image has been compressed with gzip, so layer a 
decompression
+                  object on top of the underlying input context */
+               if(!GzipInitialize(ctx))
+               {
+                       return IL_LOADERR_NOT_PE;
+               }
+ 
+               /* Suppress the use of mmap to load the stream's contents */
+               flags |= IL_LOADFLAG_NO_MAP;
+ 
+               /* Re-read the magic number bytes from the uncompressed data */
+               if((*(ctx->readFunc))(ctx, buffer, 2) != 2)
+               {
+                       return IL_LOADERR_TRUNCATED;
+               }
+       }
+ #endif
        if(buffer[0] == 'M' && buffer[1] == 'Z')
        {
***************
*** 661,669 ****
  {
        ILInputContext ctx;
        ctx.stream = file;
        ctx.buffer = 0;
        ctx.bufLen = 0;
        ctx.readFunc = StdioRead;
!       return ImageLoad(&ctx, filename, context, image, flags);
  }
  
--- 917,935 ----
  {
        ILInputContext ctx;
+       int error;
        ctx.stream = file;
        ctx.buffer = 0;
        ctx.bufLen = 0;
        ctx.readFunc = StdioRead;
! #ifdef IL_USE_GZIP
!       ctx.sawEOF = 0;
!       ctx.gzStream = 0;
!       ctx.linked = 0;
! #endif
!       error = ImageLoad(&ctx, filename, context, image, flags);
! #ifdef IL_USE_GZIP
!       GzipFinalize(&ctx);
! #endif
!       return error;
  }
  
***************
*** 724,727 ****
--- 990,994 ----
  {
        ILInputContext ctx;
+       int error;
  #ifndef REDUCED_STDIO
        ctx.stream = 0;
***************
*** 730,735 ****
        ctx.bufLen = bufLen;
        ctx.readFunc = MemoryRead;
!       return ImageLoad(&ctx, filename, context,
!                                        image, flags | IL_LOADFLAG_NO_MAP);
  }
  
--- 997,1011 ----
        ctx.bufLen = bufLen;
        ctx.readFunc = MemoryRead;
! #ifdef IL_USE_GZIP
!       ctx.sawEOF = 0;
!       ctx.gzStream = 0;
!       ctx.linked = 0;
! #endif
!       error = ImageLoad(&ctx, filename, context,
!                                         image, flags | IL_LOADFLAG_NO_MAP);
! #ifdef IL_USE_GZIP
!       GzipFinalize(&ctx);
! #endif
!       return error;
  }
  





reply via email to

[Prev in Thread] Current Thread [Next in Thread]