| 1 | |
| 2 | #ifdef STATIC
|
| 3 | #define PREBOOT
|
| 4 |
|
| 5 |
|
| 6 | |
| 7 | * errors about console_printk etc... on ARM
|
| 8 | #define _LINUX_KERNEL_H
|
| 9 |
|
| 10 | #include "zlib_inflate/inftrees.c"
|
| 11 | #include "zlib_inflate/inffast.c"
|
| 12 | #include "zlib_inflate/inflate.c"
|
| 13 | #ifdef CONFIG_ZLIB_DFLTCC
|
| 14 | #include "zlib_dfltcc/dfltcc.c"
|
| 15 | #include "zlib_dfltcc/dfltcc_inflate.c"
|
| 16 | #endif
|
| 17 |
|
| 18 | #else
|
| 19 |
|
| 20 |
|
| 21 | #include <linux/zutil.h>
|
| 22 |
|
| 23 | #include "zlib_inflate/inftrees.h"
|
| 24 | #include "zlib_inflate/inffast.h"
|
| 25 | #include "zlib_inflate/inflate.h"
|
| 26 |
|
| 27 | #include "zlib_inflate/infutil.h"
|
| 28 | #include <linux/decompress/inflate.h>
|
| 29 |
|
| 30 | #endif
|
| 31 |
|
| 32 | #include <linux/decompress/mm.h>
|
| 33 |
|
| 34 | #define GZIP_IOBUF_SIZE (16*1024)
|
| 35 |
|
| 36 | static long INIT nofill(void *buffer, unsigned long len)
|
| 37 | {
|
| 38 | return -1;
|
| 39 | }
|
| 40 |
|
| 41 |
|
| 42 | static int INIT __gunzip(unsigned char *buf, long len,
|
| 43 | long (*fill)(void*, unsigned long),
|
| 44 | long (*flush)(void*, unsigned long),
|
| 45 | unsigned char *out_buf, long out_len,
|
| 46 | long *pos,
|
| 47 | void(*error)(char *x)) {
|
| 48 | u8 *zbuf;
|
| 49 | struct z_stream_s *strm;
|
| 50 | int rc;
|
| 51 |
|
| 52 | rc = -1;
|
| 53 | if (flush) {
|
| 54 | out_len = 0x8000;
|
| 55 | out_buf = malloc(out_len);
|
| 56 | } else {
|
| 57 | if (!out_len)
|
| 58 | out_len = ((size_t)~0) - (size_t)out_buf;
|
| 59 | }
|
| 60 | if (!out_buf) {
|
| 61 | error("Out of memory while allocating output buffer");
|
| 62 | goto gunzip_nomem1;
|
| 63 | }
|
| 64 |
|
| 65 | if (buf)
|
| 66 | zbuf = buf;
|
| 67 | else {
|
| 68 | zbuf = malloc(GZIP_IOBUF_SIZE);
|
| 69 | len = 0;
|
| 70 | }
|
| 71 | if (!zbuf) {
|
| 72 | error("Out of memory while allocating input buffer");
|
| 73 | goto gunzip_nomem2;
|
| 74 | }
|
| 75 |
|
| 76 | strm = malloc(sizeof(*strm));
|
| 77 | if (strm == NULL) {
|
| 78 | error("Out of memory while allocating z_stream");
|
| 79 | goto gunzip_nomem3;
|
| 80 | }
|
| 81 |
|
| 82 | strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
|
| 83 | #ifdef CONFIG_ZLIB_DFLTCC
|
| 84 |
|
| 85 | zlib_inflate_workspacesize());
|
| 86 | #else
|
| 87 | sizeof(struct inflate_state));
|
| 88 | #endif
|
| 89 | if (strm->workspace == NULL) {
|
| 90 | error("Out of memory while allocating workspace");
|
| 91 | goto gunzip_nomem4;
|
| 92 | }
|
| 93 |
|
| 94 | if (!fill)
|
| 95 | fill = nofill;
|
| 96 |
|
| 97 | if (len == 0)
|
| 98 | len = fill(zbuf, GZIP_IOBUF_SIZE);
|
| 99 |
|
| 100 |
|
| 101 | if (len < 10 ||
|
| 102 | zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
|
| 103 | if (pos)
|
| 104 | *pos = 0;
|
| 105 | error("Not a gzip file");
|
| 106 | goto gunzip_5;
|
| 107 | }
|
| 108 |
|
| 109 | |
| 110 | * possible asciz filename)
|
| 111 |
|
| 112 | strm->next_in = zbuf + 10;
|
| 113 | strm->avail_in = len - 10;
|
| 114 |
|
| 115 | if (zbuf[3] & 0x8) {
|
| 116 | do {
|
| 117 | |
| 118 | * If the filename doesn't fit into the buffer,
|
| 119 | * the file is very probably corrupt. Don't try
|
| 120 | * to read more data.
|
| 121 |
|
| 122 | if (strm->avail_in == 0) {
|
| 123 | error("header error");
|
| 124 | goto gunzip_5;
|
| 125 | }
|
| 126 | --strm->avail_in;
|
| 127 | } while (*strm->next_in++);
|
| 128 | }
|
| 129 |
|
| 130 | strm->next_out = out_buf;
|
| 131 | strm->avail_out = out_len;
|
| 132 |
|
| 133 | rc = zlib_inflateInit2(strm, -MAX_WBITS);
|
| 134 |
|
| 135 | #ifdef CONFIG_ZLIB_DFLTCC
|
| 136 |
|
| 137 | #else
|
| 138 | if (!flush) {
|
| 139 | WS(strm)->inflate_state.wsize = 0;
|
| 140 | WS(strm)->inflate_state.window = NULL;
|
| 141 | }
|
| 142 | #endif
|
| 143 |
|
| 144 | while (rc == Z_OK) {
|
| 145 | if (strm->avail_in == 0) {
|
| 146 |
|
| 147 | len = fill(zbuf, GZIP_IOBUF_SIZE);
|
| 148 | if (len < 0) {
|
| 149 | rc = -1;
|
| 150 | error("read error");
|
| 151 | break;
|
| 152 | }
|
| 153 | strm->next_in = zbuf;
|
| 154 | strm->avail_in = len;
|
| 155 | }
|
| 156 | rc = zlib_inflate(strm, 0);
|
| 157 |
|
| 158 |
|
| 159 | if (flush && strm->next_out > out_buf) {
|
| 160 | long l = strm->next_out - out_buf;
|
| 161 | if (l != flush(out_buf, l)) {
|
| 162 | rc = -1;
|
| 163 | error("write error");
|
| 164 | break;
|
| 165 | }
|
| 166 | strm->next_out = out_buf;
|
| 167 | strm->avail_out = out_len;
|
| 168 | }
|
| 169 |
|
| 170 |
|
| 171 | if (rc == Z_STREAM_END) {
|
| 172 | rc = 0;
|
| 173 | break;
|
| 174 | } else if (rc != Z_OK) {
|
| 175 | error("uncompression error");
|
| 176 | rc = -1;
|
| 177 | }
|
| 178 | }
|
| 179 |
|
| 180 | zlib_inflateEnd(strm);
|
| 181 | if (pos)
|
| 182 |
|
| 183 | *pos = strm->next_in - zbuf+8;
|
| 184 |
|
| 185 | gunzip_5:
|
| 186 | free(strm->workspace);
|
| 187 | gunzip_nomem4:
|
| 188 | free(strm);
|
| 189 | gunzip_nomem3:
|
| 190 | if (!buf)
|
| 191 | free(zbuf);
|
| 192 | gunzip_nomem2:
|
| 193 | if (flush)
|
| 194 | free(out_buf);
|
| 195 | gunzip_nomem1:
|
| 196 | return rc;
|
| 197 | }
|
| 198 |
|
| 199 | #ifndef PREBOOT
|
| 200 | STATIC int INIT gunzip(unsigned char *buf, long len,
|
| 201 | long (*fill)(void*, unsigned long),
|
| 202 | long (*flush)(void*, unsigned long),
|
| 203 | unsigned char *out_buf,
|
| 204 | long *pos,
|
| 205 | void (*error)(char *x))
|
| 206 | {
|
| 207 | return __gunzip(buf, len, fill, flush, out_buf, 0, pos, error);
|
| 208 | }
|
| 209 | #else
|
| 210 | STATIC int INIT __decompress(unsigned char *buf, long len,
|
| 211 | long (*fill)(void*, unsigned long),
|
| 212 | long (*flush)(void*, unsigned long),
|
| 213 | unsigned char *out_buf, long out_len,
|
| 214 | long *pos,
|
| 215 | void (*error)(char *x))
|
| 216 | {
|
| 217 | return __gunzip(buf, len, fill, flush, out_buf, out_len, pos, error);
|
| 218 | }
|
| 219 | #endif
|