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