1 #include <xen/errno.h>
2 #include <xen/init.h>
3 #include <xen/lib.h>
4 #include <xen/mm.h>
5 
6 #define HEAPORDER 3
7 
8 static unsigned char *__initdata window;
9 #define memptr long
10 static memptr __initdata free_mem_ptr;
11 static memptr __initdata free_mem_end_ptr;
12 
13 #define WSIZE           0x80000000
14 
15 static unsigned char *__initdata inbuf;
16 static unsigned __initdata insize;
17 
18 /* Index of next byte to be processed in inbuf: */
19 static unsigned __initdata inptr;
20 
21 /* Bytes in output buffer: */
22 static unsigned __initdata outcnt;
23 
24 #define OF(args)        args
25 #define STATIC          static
26 
27 #define memzero(s, n)   memset((s), 0, (n))
28 
29 typedef unsigned char   uch;
30 typedef unsigned short  ush;
31 typedef unsigned long   ulg;
32 
33 #define INIT            __init
34 #define INITDATA        __initdata
35 
36 #define get_byte()      (inptr < insize ? inbuf[inptr++] : fill_inbuf())
37 
38 /* Diagnostic functions */
39 #ifdef DEBUG
40 #  define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0)
41 #  define Trace(x)      do { fprintf x; } while (0)
42 #  define Tracev(x)     do { if (verbose) fprintf x ; } while (0)
43 #  define Tracevv(x)    do { if (verbose > 1) fprintf x ; } while (0)
44 #  define Tracec(c, x)  do { if (verbose && (c)) fprintf x ; } while (0)
45 #  define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0)
46 #else
47 #  define Assert(cond, msg)
48 #  define Trace(x)
49 #  define Tracev(x)
50 #  define Tracevv(x)
51 #  define Tracec(c, x)
52 #  define Tracecv(c, x)
53 #endif
54 
55 static long __initdata bytes_out;
56 static void flush_window(void);
57 
error(char * x)58 static __init void error(char *x)
59 {
60     panic("%s", x);
61 }
62 
fill_inbuf(void)63 static __init int fill_inbuf(void)
64 {
65         error("ran out of input data");
66         return 0;
67 }
68 
69 
70 #include "inflate.c"
71 
flush_window(void)72 static __init void flush_window(void)
73 {
74     /*
75      * The window is equal to the output buffer therefore only need to
76      * compute the crc.
77      */
78     unsigned long c = crc;
79     unsigned n;
80     unsigned char *in, ch;
81 
82     in = window;
83     for ( n = 0; n < outcnt; n++ )
84     {
85         ch = *in++;
86         c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
87     }
88     crc = c;
89 
90     bytes_out += (unsigned long)outcnt;
91     outcnt = 0;
92 }
93 
gzip_check(char * image,unsigned long image_len)94 __init int gzip_check(char *image, unsigned long image_len)
95 {
96     unsigned char magic0, magic1;
97 
98     if ( image_len < 2 )
99         return 0;
100 
101     magic0 = (unsigned char)image[0];
102     magic1 = (unsigned char)image[1];
103 
104     return (magic0 == 0x1f) && ((magic1 == 0x8b) || (magic1 == 0x9e));
105 }
106 
perform_gunzip(char * output,char * image,unsigned long image_len)107 __init int perform_gunzip(char *output, char *image, unsigned long image_len)
108 {
109     int rc;
110 
111     if ( !gzip_check(image, image_len) )
112         return 1;
113 
114     window = (unsigned char *)output;
115 
116     free_mem_ptr = (unsigned long)alloc_xenheap_pages(HEAPORDER, 0);
117     free_mem_end_ptr = free_mem_ptr + (PAGE_SIZE << HEAPORDER);
118 
119     inbuf = (unsigned char *)image;
120     insize = image_len;
121     inptr = 0;
122 
123     makecrc();
124 
125     if ( gunzip() < 0 )
126     {
127         rc = -EINVAL;
128     }
129     else
130     {
131         rc = 0;
132     }
133 
134     free_xenheap_pages((void *)free_mem_ptr, HEAPORDER);
135 
136     return rc;
137 }
138