static int  fill_inbuf(void);
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 static char *input_data;
 static int  input_data_size;
 static ulg output_ptr;
 static ulg bytes_out;
 
-static void *malloc(int size);
-static void free(void *where);
 static void error(char *m);
 static void gzip_mark(void **);
 static void gzip_release(void **);
 
 extern int end;
 static ulg free_mem_ptr;
-static ulg free_mem_ptr_end;
+static ulg free_mem_end_ptr;
 
 #define HEAP_SIZE 0x3000
 
 #include "../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size <0) error("Malloc error");
-       if (free_mem_ptr <= 0) error("Memory error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_ptr_end)
-               error("Out of memory");
-       return p;
-}
-
-static void free(void *where)
-{ /* gzip_mark & gzip_release do the free */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (long) *ptr;
-}
-
 /* ===========================================================================
  * Fill the input buffer. This is called only when the buffer is empty
  * and at least one byte is really needed.
 
        /* FIXME FIXME FIXME */
        free_mem_ptr            = (ulg)output_start + ksize;
-       free_mem_ptr_end        = (ulg)output_start + ksize + 0x200000;
+       free_mem_end_ptr        = (ulg)output_start + ksize + 0x200000;
        /* FIXME FIXME FIXME */
 
        /* put in temp area to reduce initial footprint */
 
 static int  fill_inbuf(void);
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 extern char input_data[];
 extern char input_data_end[];
 static ulg output_ptr;
 static ulg bytes_out;
 
-static void *malloc(int size);
-static void free(void *where);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 static void putstr(const char *);
 
 extern int end;
 static ulg free_mem_ptr;
-static ulg free_mem_ptr_end;
+static ulg free_mem_end_ptr;
 
-#define HEAP_SIZE 0x3000
-
-#include "../../../../lib/inflate.c"
-
-#ifndef STANDALONE_DEBUG
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size <0) error("Malloc error");
-       if (free_mem_ptr <= 0) error("Memory error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_ptr_end)
-               error("Out of memory");
-       return p;
-}
-
-static void free(void *where)
-{ /* gzip_mark & gzip_release do the free */
-}
-
-static void gzip_mark(void **ptr)
-{
-       arch_decomp_wdog();
-       *ptr = (void *) free_mem_ptr;
-}
+#ifdef STANDALONE_DEBUG
+#define NO_INFLATE_MALLOC
+#endif
 
-static void gzip_release(void **ptr)
-{
-       arch_decomp_wdog();
-       free_mem_ptr = (long) *ptr;
-}
-#else
-static void gzip_mark(void **ptr)
-{
-}
+#define ARCH_HAS_DECOMP_WDOG
 
-static void gzip_release(void **ptr)
-{
-}
-#endif
+#include "../../../../lib/inflate.c"
 
 /* ===========================================================================
  * Fill the input buffer. This is called only when the buffer is empty
 {
        output_data             = (uch *)output_start;  /* Points to kernel start */
        free_mem_ptr            = free_mem_ptr_p;
-       free_mem_ptr_end        = free_mem_ptr_end_p;
+       free_mem_end_ptr        = free_mem_ptr_end_p;
        __machine_arch_type     = arch_id;
 
        arch_decomp_setup();
 
 static long bytes_out = 0;
 static uch *output_data;
 static unsigned long output_ptr = 0;
-
-static void *malloc(int size);
-static void free(void *where);
-static void gzip_mark(void **);
-static void gzip_release(void **);
-
 static void puts(const char *);
 
 /* the "heap" is put directly after the BSS ends, at end */
 
 extern int _end;
 static long free_mem_ptr = (long)&_end;
+static long free_mem_end_ptr;
 
 #include "../../../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size < 0)
-               error("Malloc error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       return p;
-}
-
-static void free(void *where)
-{      /* Don't care */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (long) *ptr;
-}
-
 /* decompressor info and error messages to serial console */
 
 static void
 
 
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 extern char *input_data;  /* lives in head.S */
 
-static long bytes_out = 0;
+static long bytes_out;
 static uch *output_data;
-static unsigned long output_ptr = 0;
+static unsigned long output_ptr;
 
-static void *malloc(int size);
-static void free(void *where);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 static void puts(const char *);
 
 
 extern int _end;
 static long free_mem_ptr = (long)&_end;
+static long free_mem_end_ptr;
 
 #include "../../../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size <0) error("Malloc error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       return p;
-}
-
-static void free(void *where)
-{      /* Don't care */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (long) *ptr;
-}
-
 /* decompressor info and error messages to serial console */
 
 static inline void
 
 static int  fill_inbuf(void);
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 extern char input_data[];
 extern int input_len;
 static uch *output_data;
 static unsigned long output_ptr = 0;
 
-static void *malloc(int size);
-static void free(void *where);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 int puts(const char *);
 
 #define TDR *((volatile unsigned char *)0xffff8b)
 #define SSR *((volatile unsigned char *)0xffff8c)
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size <0) error("Malloc error");
-       if (free_mem_ptr == 0) error("Memory error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_end_ptr)
-               error("Out of memory");
-
-       return p;
-}
-
-static void free(void *where)
-{      /* Don't care */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (long) *ptr;
-}
-
 int puts(const char *s)
 {
        return 0;
 
 static int  fill_inbuf(void);
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 static unsigned char *input_data;
 static int input_len;
 
 #include "m32r_sio.c"
 
-static void *malloc(int size);
-static void free(void *where);
-
 static unsigned long free_mem_ptr;
 static unsigned long free_mem_end_ptr;
 
 
 #include "../../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size <0) error("Malloc error");
-       if (free_mem_ptr == 0) error("Memory error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_end_ptr)
-               error("Out of memory");
-
-       return p;
-}
-
-static void free(void *where)
-{      /* Don't care */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (long) *ptr;
-}
-
 void* memset(void* s, int c, size_t n)
 {
        int i;
 
 static unsigned long output_ptr;
 
 
-static void *malloc(int size);
-
-static inline void free(void *where)
-{      /* Don't care */
-}
-
 static unsigned long free_mem_ptr = (unsigned long) &end;
 static unsigned long free_mem_end_ptr = (unsigned long) &end + 0x90000;
 
-static inline void gzip_mark(void **ptr)
-{
-       kputs(".");
-       *ptr = (void *) free_mem_ptr;
-}
-
-static inline void gzip_release(void **ptr)
-{
-       free_mem_ptr = (unsigned long) *ptr;
-}
-
 #define INPLACE_MOVE_ROUTINE   0x1000
 #define LOW_BUFFER_START       0x2000
 #define LOW_BUFFER_END         0x90000
 
 #include "../../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size < 0)
-               error("Malloc error\n");
-       if (!free_mem_ptr)
-               error("Memory error\n");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *) free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_end_ptr)
-               error("\nOut of memory\n");
-
-       return p;
-}
-
 static inline void scroll(void)
 {
        int i;
 
 static int  fill_inbuf(void);
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 extern char input_data[];
 extern int input_len;
 static uch *output_data;
 static unsigned long output_ptr = 0;
 
-static void *malloc(int size);
-static void free(void *where);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 int puts(const char *);
 
 
 #include "../../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size <0) error("Malloc error");
-       if (free_mem_ptr == 0) error("Memory error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_end_ptr)
-               error("Out of memory");
-
-       return p;
-}
-
-static void free(void *where)
-{      /* Don't care */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (long) *ptr;
-}
-
 #ifdef CONFIG_SH_STANDARD_BIOS
 size_t strlen(const char *s)
 {
 
 static int fill_inbuf(void);
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 extern char input_data[];
 extern int input_len;
 static uch *output_data;
 static unsigned long output_ptr = 0;
 
-static void *malloc(int size);
-static void free(void *where);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 static void puts(const char *);
 
 
 #include "../../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size < 0)
-               error("Malloc error\n");
-       if (free_mem_ptr == 0)
-               error("Memory error\n");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *) free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_end_ptr)
-               error("\nOut of memory\n");
-
-       return p;
-}
-
-static void free(void *where)
-{                              /* Don't care */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (long) *ptr;
-}
-
 void puts(const char *s)
 {
 }
 
 static int  fill_inbuf(void);
 static void flush_window(void);
 static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
 
 /*
  * This is set up by the setup-routine at boot-time
 
 static long bytes_out;
 
-static void *malloc(int size);
-static void free(void *where);
-
 static void *memset(void *s, int c, unsigned n);
 static void *memcpy(void *dest, const void *src, unsigned n);
 
 
 #include "../../../../lib/inflate.c"
 
-static void *malloc(int size)
-{
-       void *p;
-
-       if (size < 0)
-               error("Malloc error");
-       if (free_mem_ptr <= 0)
-               error("Memory error");
-
-       free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
-
-       p = (void *)free_mem_ptr;
-       free_mem_ptr += size;
-
-       if (free_mem_ptr >= free_mem_end_ptr)
-               error("Out of memory");
-
-       return p;
-}
-
-static void free(void *where)
-{      /* Don't care */
-}
-
-static void gzip_mark(void **ptr)
-{
-       *ptr = (void *) free_mem_ptr;
-}
-
-static void gzip_release(void **ptr)
-{
-       free_mem_ptr = (memptr) *ptr;
-}
-
 static void scroll(void)
 {
        int i;
 
 
 static int  __init fill_inbuf(void);
 static void __init flush_window(void);
-static void __init *malloc(size_t size);
-static void __init free(void *where);
 static void __init error(char *m);
-static void __init gzip_mark(void **);
-static void __init gzip_release(void **);
 
-#include "../lib/inflate.c"
-
-static void __init *malloc(size_t size)
-{
-       return kmalloc(size, GFP_KERNEL);
-}
-
-static void __init free(void *where)
-{
-       kfree(where);
-}
-
-static void __init gzip_mark(void **ptr)
-{
-}
-
-static void __init gzip_release(void **ptr)
-{
-}
+#define NO_INFLATE_MALLOC
 
+#include "../lib/inflate.c"
 
 /* ===========================================================================
  * Fill the input buffer. This is called only when the buffer is empty
 
                message = x;
 }
 
-static void __init *malloc(size_t size)
-{
-       return kmalloc(size, GFP_KERNEL);
-}
-
-static void __init free(void *where)
-{
-       kfree(where);
-}
-
 /* link hash */
 
 #define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
 
 static void __init flush_window(void);
 static void __init error(char *m);
-static void __init gzip_mark(void **);
-static void __init gzip_release(void **);
 
-#include "../lib/inflate.c"
+#define NO_INFLATE_MALLOC
 
-static void __init gzip_mark(void **ptr)
-{
-}
-
-static void __init gzip_release(void **ptr)
-{
-}
+#include "../lib/inflate.c"
 
 /* ===========================================================================
  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 
 #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
 #define DUMPBITS(n) {b>>=(n);k-=(n);}
 
+#ifndef NO_INFLATE_MALLOC
+/* A trivial malloc implementation, adapted from
+ *  malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ */
+
+static unsigned long malloc_ptr;
+static int malloc_count;
+
+static void *malloc(int size)
+{
+       void *p;
+
+       if (size < 0)
+               error("Malloc error");
+       if (!malloc_ptr)
+               malloc_ptr = free_mem_ptr;
+
+       malloc_ptr = (malloc_ptr + 3) & ~3;     /* Align */
+
+       p = (void *)malloc_ptr;
+       malloc_ptr += size;
+
+       if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
+               error("Out of memory");
+
+       malloc_count++;
+       return p;
+}
+
+static void free(void *where)
+{
+       malloc_count--;
+       if (!malloc_count)
+               malloc_ptr = free_mem_ptr;
+}
+#else
+#define malloc(a) kmalloc(a, GFP_KERNEL)
+#define free(a) kfree(a)
+#endif
 
 /*
    Huffman code decoding is performed using a multi-level table lookup.
   int e;                /* last block flag */
   int r;                /* result code */
   unsigned h;           /* maximum struct huft's malloc'ed */
-  void *ptr;
 
   /* initialize window, bit buffer */
   wp = 0;
   h = 0;
   do {
     hufts = 0;
-    gzip_mark(&ptr);
-    if ((r = inflate_block(&e)) != 0) {
-      gzip_release(&ptr);          
-      return r;
-    }
-    gzip_release(&ptr);
+#ifdef ARCH_HAS_DECOMP_WDOG
+    arch_decomp_wdog();
+#endif
+    r = inflate_block(&e);
+    if (r)
+           return r;
     if (hufts > h)
       h = hufts;
   } while (!e);