Skip to contentSkip to conversation

zlib_inflate and ppc32 changes

PATCH New Tom Rini 1 participant 4 messages Sep 3, 2004

lore
Share & tools
lore

Tom Rini

author
#0 lore raw

cover zlib_inflate and ppc32 changes

Hi. This series of patches first changes zlib_inflate/ to be more easily picked at by moving some non-core functions into their own file. Next, this switches zlib_inflate_trees_fixed(...) from using a static table, to generating that table. This can save us up to 4kB from the vmlinux (ppc32) and when used in the boot/ code, up to 8kB. Finally, we switch arch/ppc/boot/ from using it's own version of zlib to using lib/zlib_inflate. All of this should also lead the way for lib/inflate.c going away.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
author
#1 lore raw

PATCH 1/3 zlib_inflate: Move zlib_inflateSync & friends

The following patch moves zlib_inflateSync and friends, which are used by PPP and not a 'normal' gzip, into inflate_sync.c.

 lib/zlib_inflate/Makefile       |    2 
 lib/zlib_inflate/inflate.c      |  141 --------------------------------------
 lib/zlib_inflate/inflate_sync.c |  148 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 142 deletions(-)
lib/zlib_inflate/inflate_sync.c new file +148 -0
@@ -0,0 +1,148 @@
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include <linux/zutil.h>
+#include "infblock.h"
+#include "infutil.h"
+
+int zlib_inflateSync(
+	z_streamp z
+)
+{
+  uInt n;       /* number of bytes to look at */
+  Byte *p;      /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == NULL || z->state == NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != I_BAD)
+  {
+    z->state->mode = I_BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    static const Byte mark[4] = {0, 0, 0xff, 0xff};
+    if (*p == mark[m])
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  zlib_inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ * but removes the length bytes of the resulting empty stored block. When
+ * decompressing, PPP checks that at the end of input packet, inflate is
+ * waiting for these length bytes.
+ */
+int zlib_inflateSyncPoint(
+	z_streamp z
+)
+{
+  if (z == NULL || z->state == NULL || z->state->blocks == NULL)
+    return Z_STREAM_ERROR;
+  return zlib_inflate_blocks_sync_point(z->state->blocks);
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+static int zlib_inflate_addhistory(inflate_blocks_statef *s,
+				      z_stream              *z)
+{
+    uLong b;              /* bit buffer */  /* NOT USED HERE */
+    uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
+    uInt t;               /* temporary storage */
+    Byte *p;              /* input data pointer */
+    uInt n;               /* bytes available there */
+    Byte *q;              /* output window write pointer */
+    uInt m;               /* bytes to end of window or read pointer */
+
+    if (s->read != s->write)
+	return Z_STREAM_ERROR;
+    if (s->mode != TYPE)
+	return Z_DATA_ERROR;
+
+    /* we're ready to rock */
+    LOAD
+    /* while there is input ready, copy to output buffer, moving
+     * pointers as needed.
+     */
+    while (n) {
+	t = n;  /* how many to do */
+	/* is there room until end of buffer? */
+	if (t > m) t = m;
+	/* update check information */
+	if (s->checkfn != NULL)
+	    s->check = (*s->checkfn)(s->check, q, t);
+	memcpy(q, p, t);
+	q += t;
+	p += t;
+	n -= t;
+	z->total_out += t;
+	s->read = q;    /* drag read pointer forward */
+/*      WWRAP  */ 	/* expand WWRAP macro by hand to handle s->read */
+	if (q == s->end) {
+	    s->read = q = s->window;
+	    m = WAVAIL;
+	}
+    }
+    UPDATE
+    return Z_OK;
+}
+
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+
+int zlib_inflateIncomp(
+	z_stream *z
+	
+)
+{
+    if (z->state->mode != BLOCKS)
+	return Z_DATA_ERROR;
+    return zlib_inflate_addhistory(z->state->blocks, z);
+}
lib/zlib_inflate/Makefile +1 -1
@@ -16,4 +16,4 @@
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o
 
 zlib_inflate-objs := infblock.o infcodes.o inffast.o inflate.o \
-		     inftrees.o infutil.o inflate_syms.o
+		     inflate_sync.o inftrees.o infutil.o inflate_syms.o
lib/zlib_inflate/inflate.c +0 -141

144 lines not on this page · raw message

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
author
#2 lore raw

PATCH 2/3 zlib_inflate: Make zlib_inflate_trees_fixed(...) generate the table

The following changes zlib_inflate_trees_fixed(...) from using a statically defined table, to generating this table. This cuts out 4-8kB from inftrees.o (4kB on IBM 440GP, 8kB on PPC 74xx).

 lib/zlib_inflate/inffixed.h |  151 --------------------------------------------
 lib/zlib_inflate/infblock.c |    2 
 lib/zlib_inflate/inftrees.c |   34 +++++++--
 lib/zlib_inflate/inftrees.h |    1 
 4 files changed, 28 insertions(+), 160 deletions(-)
lib/zlib_inflate/infblock.c +1 -1
@@ -139,7 +139,7 @@ int zlib_inflate_blocks(
             uInt bl, bd;
             inflate_huft *tl, *td;
 
-            zlib_inflate_trees_fixed(&bl, &bd, &tl, &td, z);
+            zlib_inflate_trees_fixed(&bl, &bd, &tl, &td, s->hufts, z);
             s->sub.decode.codes = zlib_inflate_codes_new(bl, bd, tl, td, z);
             if (s->sub.decode.codes == NULL)
             {
lib/zlib_inflate/inftrees.c +26 -8
@@ -374,21 +374,39 @@ int zlib_inflate_trees_dynamic(
 }
 
 
-/* build fixed tables only once--keep them here */
-#include "inffixed.h"
-
-
 int zlib_inflate_trees_fixed(
 	uInt *bl,                /* literal desired/actual bit depth */
 	uInt *bd,                /* distance desired/actual bit depth */
 	inflate_huft **tl,       /* literal/length tree result */
 	inflate_huft **td,       /* distance tree result */
+	inflate_huft *hp,       /* space for trees */
 	z_streamp z              /* for memory allocation */
 )
 {
-  *bl = fixed_bl;
-  *bd = fixed_bd;
-  *tl = fixed_tl;
-  *td = fixed_td;
+  int i;                /* temporary variable */
+  unsigned l[288];      /* length list for huft_build */
+  uInt *v;              /* work area for huft_build */
+
+  /* set up literal table */
+  for (i = 0; i < 144; i++)
+    l[i] = 8;
+  for (; i < 256; i++)
+    l[i] = 9;
+  for (; i < 280; i++)
+    l[i] = 7;
+  for (; i < 288; i++)          /* make a complete, but wrong code set */
+    l[i] = 8;
+  *bl = 9;
+  v = WS(z)->tree_work_area_1;
+  if ((i = huft_build(l, 288, 257, cplens, cplext, tl, bl, hp,  &i, v)) != 0)
+    return i;
+
+  /* set up distance table */
+  for (i = 0; i < 30; i++)      /* make an incomplete code set */
+    l[i] = 5;
+  *bd = 5;
+  if ((i = huft_build(l, 30, 0, cpdist, cpdext, td, bd, hp, &i, v)) > 1)
+    return i;
+
   return Z_OK;
 }
lib/zlib_inflate/inffixed.h deleted +0 -151

151 lines not on this page · raw message

lib/zlib_inflate/inftrees.h +1 -0
@@ -58,6 +58,7 @@ extern int zlib_inflate_trees_fixed (
     uInt *,                     /* distance desired/actual bit depth */
     inflate_huft **,            /* literal/length tree result */
     inflate_huft **,            /* distance tree result */
+    inflate_huft *,             /* space for trees */
     z_streamp);                 /* for memory allocation */
 
 #endif /* _INFTREES_H */
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
author
#3 lore raw

PATCH 3/3 ppc32: Switch arch/ppc/boot to lib/zlib_inflate

The following patch switches arch/ppc/boot over from using its own version of zlib to the code found under lib/zlib_inflate. In conjunction with the previous two patches, the size of the resulting images isn't noticably different. But this does have the advantage of removing another copy of zlib from the kernel, and I believe this allows for lib/inflate.c to go away (as that's basically what ppc used to use).

 arch/ppc/boot/include/zlib.h          |  430 ------
 arch/ppc/boot/lib/zlib.c              | 2169 ----------------------------------
 arch/ppc/boot/common/misc-common.c    |   25 
 arch/ppc/boot/lib/Makefile            |   15 
 arch/ppc/boot/openfirmware/coffmain.c |    1 
 arch/ppc/boot/openfirmware/common.c   |  104 -
 arch/ppc/boot/simple/misc-embedded.c  |    1 
 arch/ppc/boot/simple/misc.c           |    3 
 8 files changed, 67 insertions(+), 2681 deletions(-)
arch/ppc/boot/lib/Makefile +14 -1
@@ -4,5 +4,18 @@
 
 CFLAGS_kbd.o	+= -Idrivers/char
 
-lib-y := zlib.o div64.o
+$(obj)/infblock.o: lib/zlib_inflate/infblock.c
+	$(call cmd,cc_o_c)
+$(obj)/infcodes.o: lib/zlib_inflate/infcodes.c
+	$(call cmd,cc_o_c)
+$(obj)/inffast.o: lib/zlib_inflate/inffast.c
+	$(call cmd,cc_o_c)
+$(obj)/inflate.o: lib/zlib_inflate/inflate.c
+	$(call cmd,cc_o_c)
+$(obj)/inftrees.o: lib/zlib_inflate/inftrees.c
+	$(call cmd,cc_o_c)
+$(obj)/infutil.o: lib/zlib_inflate/infutil.c
+	$(call cmd,cc_o_c)
+
+lib-y := infblock.o infcodes.o inffast.o inflate.o inftrees.o infutil.o div64.o
 lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
arch/ppc/boot/lib/zlib.c deleted +0 -2169

2,169 lines not on this page · raw message

arch/ppc/boot/common/misc-common.c +9 -16
@@ -17,7 +17,7 @@
 #include <stdarg.h>	/* for va_ bits */
 #include <linux/config.h>
 #include <linux/string.h>
-#include "zlib.h"
+#include <linux/zlib.h>
 #include "nonstdio.h"
 
 /* If we're on a PReP, assume we have a keyboard controller
@@ -202,11 +202,10 @@ void error(char *x)
 	while(1);	/* Halt */
 }
 
-void *zalloc(void *x, unsigned items, unsigned size)
+static void *zalloc(unsigned size)
 {
 	void *p = avail_ram;
 
-	size *= items;
 	size = (size + 7) & -8;
 	avail_ram += size;
 	if (avail_ram > end_avail) {
@@ -216,18 +215,12 @@ void *zalloc(void *x, unsigned items, un
 	return p;
 }
 
-void zfree(void *x, void *addr, unsigned nb)
-{
-}
-
 #define HEAD_CRC	2
 #define EXTRA_FIELD	4
 #define ORIG_NAME	8
 #define COMMENT		0x10
 #define RESERVED	0xe0
 
-#define DEFLATED	8
-
 void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
 {
 	z_stream s;
@@ -236,7 +229,7 @@ void gunzip(void *dst, int dstlen, unsig
 	/* skip header */
 	i = 10;
 	flags = src[3];
-	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+	if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
 		puts("bad gzipped data\n");
 		exit();
 	}
@@ -255,24 +248,24 @@ void gunzip(void *dst, int dstlen, unsig
 		exit();
 	}
 
-	s.zalloc = zalloc;
-	s.zfree = zfree;
-	r = inflateInit2(&s, -MAX_WBITS);
+	/* Initialize ourself. */
+	s.workspace = zalloc(zlib_inflate_workspacesize());
+	r = zlib_inflateInit2(&s, -MAX_WBITS);
 	if (r != Z_OK) {
-		puts("inflateInit2 returned "); puthex(r); puts("\n");
+		puts("zlib_inflateInit2 returned "); puthex(r); puts("\n");
 		exit();
 	}
 	s.next_in = src + i;
 	s.avail_in = *lenp - i;
 	s.next_out = dst;
 	s.avail_out = dstlen;
-	r = inflate(&s, Z_FINISH);
+	r = zlib_inflate(&s, Z_FINISH);
 	if (r != Z_OK && r != Z_STREAM_END) {
 		puts("inflate returned "); puthex(r); puts("\n");
 		exit();
 	}
 	*lenp = s.next_out - (unsigned char *) dst;
-	inflateEnd(&s);
+	zlib_inflateEnd(&s);
 }
 
 void
arch/ppc/boot/openfirmware/coffmain.c +0 -1
@@ -12,7 +12,6 @@
 
 #include "nonstdio.h"
 #include "of1275.h"
-#include "zlib.h"
 
 /* Passed from the linker */
 extern char __image_begin, __image_end;
arch/ppc/boot/simple/misc-embedded.c +0 -1
@@ -22,7 +22,6 @@
 #endif
 
 #include "nonstdio.h"
-#include "zlib.h"
 
 /* The linker tells us where the image is. */
 extern char __image_begin, __image_end;
arch/ppc/boot/openfirmware/common.c +43 -61

139 lines not on this page · raw message

arch/ppc/boot/simple/misc.c +1 -2
@@ -29,7 +29,6 @@
 #include <asm/reg.h>
 
 #include "nonstdio.h"
-#include "zlib.h"
 
 /* Default cmdline */
 #ifdef CONFIG_CMDLINE
@@ -220,7 +219,7 @@ decompress_kernel(unsigned long load_add
 	puts("\n");
 
 	puts("Uncompressing Linux...");
-	gunzip(NULL, 0x400000, zimage_start, &zimage_size);
+	gunzip(0x0, 0x400000, zimage_start, &zimage_size);
 	puts("done.\n");
 
 	/* get the bi_rec address */
arch/ppc/boot/include/zlib.h deleted +0 -430

430 lines not on this page · raw message

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/