[Top][All Lists]
[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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnet/image link.c, 1.26, 1.27 pecoff_loader.c, 1.16, 1.17,
Rhys Weatherley <address@hidden> <=
- Prev by Date:
[Dotgnu-pnet-commits] CVS: pnet/profiles compact, 1.4, 1.5 compact-fp, 1.4, 1.5 full, 1.4, 1.5 kernel, 1.4, 1.5 kernel-fp, 1.4, 1.5 tiny, 1.1, 1.2
- Next by Date:
[Dotgnu-pnet-commits] CVS: pnet ChangeLog, 1.2666, 1.2667 configure.in, 1.141, 1.142
- Previous by thread:
[Dotgnu-pnet-commits] CVS: pnet/profiles compact, 1.4, 1.5 compact-fp, 1.4, 1.5 full, 1.4, 1.5 kernel, 1.4, 1.5 kernel-fp, 1.4, 1.5 tiny, 1.1, 1.2
- Next by thread:
[Dotgnu-pnet-commits] CVS: pnet ChangeLog, 1.2666, 1.2667 configure.in, 1.141, 1.142
- Index(es):