blob: 7bc0f73e095e9c5dd08de371e458669b6b28df4d [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Kees Cook5d3bca82013-08-16 07:59:11 -07002/*
3 * Copyright (c) 2013, The Chromium Authors
Kees Cook5d3bca82013-08-16 07:59:11 -07004 */
5
Kees Cook5d3bca82013-08-16 07:59:11 -07006#include <common.h>
Simon Glass6d084ce2014-12-02 13:17:35 -07007#include <bootm.h>
Kees Cook5d3bca82013-08-16 07:59:11 -07008#include <command.h>
9#include <malloc.h>
Joe Hershberger65b905b2015-03-22 17:08:59 -050010#include <mapmem.h>
Simon Glass6d084ce2014-12-02 13:17:35 -070011#include <asm/io.h>
Kees Cook5d3bca82013-08-16 07:59:11 -070012
13#include <u-boot/zlib.h>
14#include <bzlib.h>
15
16#include <lzma/LzmaTypes.h>
17#include <lzma/LzmaDec.h>
18#include <lzma/LzmaTools.h>
19
20#include <linux/lzo.h>
Simon Glass1edaed02017-11-25 11:57:33 -070021#include <test/compression.h>
22#include <test/suites.h>
23#include <test/ut.h>
Kees Cook5d3bca82013-08-16 07:59:11 -070024
25static const char plain[] =
26 "I am a highly compressable bit of text.\n"
27 "I am a highly compressable bit of text.\n"
28 "I am a highly compressable bit of text.\n"
29 "There are many like me, but this one is mine.\n"
30 "If I were any shorter, there wouldn't be much sense in\n"
31 "compressing me in the first place. At least with lzo, anyway,\n"
32 "which appears to behave poorly in the face of short text\n"
33 "messages.\n";
34
35/* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
36static const char bzip2_compressed[] =
37 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
38 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
39 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
40 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
41 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
42 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
43 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
44 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
45 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
46 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
47 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
48 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
49 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
50 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
51 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
52static const unsigned long bzip2_compressed_size = 240;
53
54/* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
55static const char lzma_compressed[] =
56 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
57 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
58 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
59 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
60 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
61 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
62 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
63 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
64 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
65 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
66 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
67 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
68 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
69 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
70 "\xfd\xf5\x50\x8d\xca";
71static const unsigned long lzma_compressed_size = 229;
72
73/* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
74static const char lzo_compressed[] =
75 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
76 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
77 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
78 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
79 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
80 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
81 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
82 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
83 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
84 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
85 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
86 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
87 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
88 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
89 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
90 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
91 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
92 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
93 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
94 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
95 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
96static const unsigned long lzo_compressed_size = 334;
97
Julius Wernerf41a3ca2015-10-06 20:03:53 -070098/* lz4 -z /tmp/plain.txt > /tmp/plain.lz4 */
99static const char lz4_compressed[] =
100 "\x04\x22\x4d\x18\x64\x70\xb9\x01\x01\x00\x00\xff\x19\x49\x20\x61"
101 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
102 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
103 "\x65\x78\x74\x2e\x0a\x28\x00\x3d\xf1\x25\x54\x68\x65\x72\x65\x20"
104 "\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d\x65"
105 "\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20\x69"
106 "\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x32\x00"
107 "\xd1\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x45\x00"
108 "\xf4\x0b\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d\x75"
109 "\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xcf\x00\x50\x69"
110 "\x6e\x67\x20\x6d\x12\x00\x00\x32\x00\xf0\x11\x20\x66\x69\x72\x73"
111 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
112 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x63\x00\xf5\x14\x77"
113 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
114 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
115 "\x6c\x79\x4e\x00\x30\x61\x63\x65\x27\x01\x01\x95\x00\x01\x2d\x01"
116 "\xb0\x0a\x6d\x65\x73\x73\x61\x67\x65\x73\x2e\x0a\x00\x00\x00\x00"
117 "\x9d\x12\x8c\x9d";
118static const unsigned long lz4_compressed_size = 276;
119
Kees Cook5d3bca82013-08-16 07:59:11 -0700120
121#define TEST_BUFFER_SIZE 512
122
Simon Glass1edaed02017-11-25 11:57:33 -0700123typedef int (*mutate_func)(struct unit_test_state *uts, void *, unsigned long,
124 void *, unsigned long, unsigned long *);
Kees Cook5d3bca82013-08-16 07:59:11 -0700125
Simon Glass1edaed02017-11-25 11:57:33 -0700126static int compress_using_gzip(struct unit_test_state *uts,
127 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700128 void *out, unsigned long out_max,
129 unsigned long *out_size)
130{
131 int ret;
132 unsigned long inout_size = out_max;
133
134 ret = gzip(out, &inout_size, in, in_size);
135 if (out_size)
136 *out_size = inout_size;
137
138 return ret;
139}
140
Simon Glass1edaed02017-11-25 11:57:33 -0700141static int uncompress_using_gzip(struct unit_test_state *uts,
142 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700143 void *out, unsigned long out_max,
144 unsigned long *out_size)
145{
146 int ret;
147 unsigned long inout_size = in_size;
148
149 ret = gunzip(out, out_max, in, &inout_size);
150 if (out_size)
151 *out_size = inout_size;
152
153 return ret;
154}
155
Simon Glass1edaed02017-11-25 11:57:33 -0700156static int compress_using_bzip2(struct unit_test_state *uts,
157 void *in, unsigned long in_size,
Wolfgang Denkec7fbf52013-10-04 17:43:24 +0200158 void *out, unsigned long out_max,
159 unsigned long *out_size)
Kees Cook5d3bca82013-08-16 07:59:11 -0700160{
161 /* There is no bzip2 compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700162 ut_asserteq(in_size, strlen(plain));
163 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook5d3bca82013-08-16 07:59:11 -0700164
165 if (bzip2_compressed_size > out_max)
166 return -1;
167
168 memcpy(out, bzip2_compressed, bzip2_compressed_size);
169 if (out_size)
170 *out_size = bzip2_compressed_size;
171
172 return 0;
173}
174
Simon Glass1edaed02017-11-25 11:57:33 -0700175static int uncompress_using_bzip2(struct unit_test_state *uts,
176 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700177 void *out, unsigned long out_max,
178 unsigned long *out_size)
179{
180 int ret;
181 unsigned int inout_size = out_max;
182
183 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
184 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
185 if (out_size)
186 *out_size = inout_size;
187
188 return (ret != BZ_OK);
189}
190
Simon Glass1edaed02017-11-25 11:57:33 -0700191static int compress_using_lzma(struct unit_test_state *uts,
192 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700193 void *out, unsigned long out_max,
194 unsigned long *out_size)
195{
196 /* There is no lzma compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700197 ut_asserteq(in_size, strlen(plain));
198 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook5d3bca82013-08-16 07:59:11 -0700199
200 if (lzma_compressed_size > out_max)
201 return -1;
202
203 memcpy(out, lzma_compressed, lzma_compressed_size);
204 if (out_size)
205 *out_size = lzma_compressed_size;
206
207 return 0;
208}
209
Simon Glass1edaed02017-11-25 11:57:33 -0700210static int uncompress_using_lzma(struct unit_test_state *uts,
211 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700212 void *out, unsigned long out_max,
213 unsigned long *out_size)
214{
215 int ret;
216 SizeT inout_size = out_max;
217
218 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
219 if (out_size)
220 *out_size = inout_size;
221
222 return (ret != SZ_OK);
223}
224
Simon Glass1edaed02017-11-25 11:57:33 -0700225static int compress_using_lzo(struct unit_test_state *uts,
226 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700227 void *out, unsigned long out_max,
228 unsigned long *out_size)
229{
230 /* There is no lzo compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700231 ut_asserteq(in_size, strlen(plain));
232 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook5d3bca82013-08-16 07:59:11 -0700233
234 if (lzo_compressed_size > out_max)
235 return -1;
236
237 memcpy(out, lzo_compressed, lzo_compressed_size);
238 if (out_size)
239 *out_size = lzo_compressed_size;
240
241 return 0;
242}
243
Simon Glass1edaed02017-11-25 11:57:33 -0700244static int uncompress_using_lzo(struct unit_test_state *uts,
245 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700246 void *out, unsigned long out_max,
247 unsigned long *out_size)
248{
249 int ret;
250 size_t input_size = in_size;
251 size_t output_size = out_max;
252
253 ret = lzop_decompress(in, input_size, out, &output_size);
254 if (out_size)
255 *out_size = output_size;
256
257 return (ret != LZO_E_OK);
258}
259
Simon Glass1edaed02017-11-25 11:57:33 -0700260static int compress_using_lz4(struct unit_test_state *uts,
261 void *in, unsigned long in_size,
Julius Wernerf41a3ca2015-10-06 20:03:53 -0700262 void *out, unsigned long out_max,
263 unsigned long *out_size)
264{
265 /* There is no lz4 compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700266 ut_asserteq(in_size, strlen(plain));
267 ut_asserteq(0, memcmp(plain, in, in_size));
Julius Wernerf41a3ca2015-10-06 20:03:53 -0700268
269 if (lz4_compressed_size > out_max)
270 return -1;
271
272 memcpy(out, lz4_compressed, lz4_compressed_size);
273 if (out_size)
274 *out_size = lz4_compressed_size;
275
276 return 0;
277}
278
Simon Glass1edaed02017-11-25 11:57:33 -0700279static int uncompress_using_lz4(struct unit_test_state *uts,
280 void *in, unsigned long in_size,
Julius Wernerf41a3ca2015-10-06 20:03:53 -0700281 void *out, unsigned long out_max,
282 unsigned long *out_size)
283{
284 int ret;
285 size_t input_size = in_size;
286 size_t output_size = out_max;
287
288 ret = ulz4fn(in, input_size, out, &output_size);
289 if (out_size)
290 *out_size = output_size;
291
292 return (ret != 0);
293}
294
Kees Cook5d3bca82013-08-16 07:59:11 -0700295#define errcheck(statement) if (!(statement)) { \
296 fprintf(stderr, "\tFailed: %s\n", #statement); \
297 ret = 1; \
298 goto out; \
299}
300
Simon Glass053f8012017-11-25 11:57:31 -0700301struct buf_state {
302 ulong orig_size;
303 ulong compressed_size;
304 ulong uncompressed_size;
Kees Cook5d3bca82013-08-16 07:59:11 -0700305 void *orig_buf;
Simon Glass053f8012017-11-25 11:57:31 -0700306 void *compressed_buf;
307 void *uncompressed_buf;
308 void *compare_buf;
309};
Kees Cook5d3bca82013-08-16 07:59:11 -0700310
Simon Glass1edaed02017-11-25 11:57:33 -0700311static int run_test_internal(struct unit_test_state *uts, char *name,
Simon Glass053f8012017-11-25 11:57:31 -0700312 mutate_func compress, mutate_func uncompress,
313 struct buf_state *buf)
314{
315 int ret;
Kees Cook5d3bca82013-08-16 07:59:11 -0700316
317 /* Compress works as expected. */
Simon Glass053f8012017-11-25 11:57:31 -0700318 printf("\torig_size:%lu\n", buf->orig_size);
319 memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700320 errcheck(compress(uts, buf->orig_buf, buf->orig_size,
321 buf->compressed_buf, buf->compressed_size,
322 &buf->compressed_size) == 0);
Simon Glass053f8012017-11-25 11:57:31 -0700323 printf("\tcompressed_size:%lu\n", buf->compressed_size);
324 errcheck(buf->compressed_size > 0);
325 errcheck(buf->compressed_size < buf->orig_size);
326 errcheck(((char *)buf->compressed_buf)[buf->compressed_size - 1] !=
327 'A');
328 errcheck(((char *)buf->compressed_buf)[buf->compressed_size] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700329
330 /* Uncompresses with space remaining. */
Simon Glass1edaed02017-11-25 11:57:33 -0700331 errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass053f8012017-11-25 11:57:31 -0700332 buf->uncompressed_buf, buf->uncompressed_size,
333 &buf->uncompressed_size) == 0);
334 printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
335 errcheck(buf->uncompressed_size == buf->orig_size);
336 errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
337 buf->orig_size) == 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700338
339 /* Uncompresses with exactly the right size output buffer. */
Simon Glass053f8012017-11-25 11:57:31 -0700340 memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700341 errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass053f8012017-11-25 11:57:31 -0700342 buf->uncompressed_buf, buf->orig_size,
343 &buf->uncompressed_size) == 0);
344 errcheck(buf->uncompressed_size == buf->orig_size);
345 errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
346 buf->orig_size) == 0);
347 errcheck(((char *)buf->uncompressed_buf)[buf->orig_size] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700348
349 /* Make sure compression does not over-run. */
Simon Glass053f8012017-11-25 11:57:31 -0700350 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700351 ret = compress(uts, buf->orig_buf, buf->orig_size,
Simon Glass053f8012017-11-25 11:57:31 -0700352 buf->compare_buf, buf->compressed_size - 1,
Kees Cook5d3bca82013-08-16 07:59:11 -0700353 NULL);
Simon Glass053f8012017-11-25 11:57:31 -0700354 errcheck(((char *)buf->compare_buf)[buf->compressed_size] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700355 errcheck(ret != 0);
356 printf("\tcompress does not overrun\n");
357
358 /* Make sure decompression does not over-run. */
Simon Glass053f8012017-11-25 11:57:31 -0700359 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700360 ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass053f8012017-11-25 11:57:31 -0700361 buf->compare_buf, buf->uncompressed_size - 1,
Kees Cook5d3bca82013-08-16 07:59:11 -0700362 NULL);
Simon Glass053f8012017-11-25 11:57:31 -0700363 errcheck(((char *)buf->compare_buf)[buf->uncompressed_size - 1] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700364 errcheck(ret != 0);
365 printf("\tuncompress does not overrun\n");
366
367 /* Got here, everything is fine. */
368 ret = 0;
369
Simon Glass053f8012017-11-25 11:57:31 -0700370out:
371 return ret;
372}
373
Simon Glass1edaed02017-11-25 11:57:33 -0700374static int run_test(struct unit_test_state *uts, char *name,
375 mutate_func compress, mutate_func uncompress)
Simon Glass053f8012017-11-25 11:57:31 -0700376{
377 struct buf_state sbuf, *buf = &sbuf;
378 int ret;
379
380 printf(" testing %s ...\n", name);
381
382 buf->orig_buf = (void *)plain;
383 buf->orig_size = strlen(buf->orig_buf); /* Trailing NUL not included */
384 errcheck(buf->orig_size > 0);
385
386 buf->compressed_size = TEST_BUFFER_SIZE;
387 buf->uncompressed_size = TEST_BUFFER_SIZE;
388 buf->compressed_buf = malloc(buf->compressed_size);
389 errcheck(buf->compressed_buf);
390 buf->uncompressed_buf = malloc(buf->uncompressed_size);
391 errcheck(buf->uncompressed_buf);
392 buf->compare_buf = malloc(buf->uncompressed_size);
393 errcheck(buf->compare_buf);
394
Simon Glass1edaed02017-11-25 11:57:33 -0700395 ret = run_test_internal(uts, name, compress, uncompress, buf);
Kees Cook5d3bca82013-08-16 07:59:11 -0700396out:
397 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
398
Simon Glass053f8012017-11-25 11:57:31 -0700399 free(buf->compare_buf);
400 free(buf->uncompressed_buf);
401 free(buf->compressed_buf);
Kees Cook5d3bca82013-08-16 07:59:11 -0700402
403 return ret;
404}
405
Simon Glass1edaed02017-11-25 11:57:33 -0700406static int compression_test_gzip(struct unit_test_state *uts)
Kees Cook5d3bca82013-08-16 07:59:11 -0700407{
Simon Glass1edaed02017-11-25 11:57:33 -0700408 return run_test(uts, "gzip", compress_using_gzip,
409 uncompress_using_gzip);
410}
411COMPRESSION_TEST(compression_test_gzip, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700412
Simon Glass1edaed02017-11-25 11:57:33 -0700413static int compression_test_bzip2(struct unit_test_state *uts)
414{
415 return run_test(uts, "bzip2", compress_using_bzip2,
416 uncompress_using_bzip2);
417}
418COMPRESSION_TEST(compression_test_bzip2, 0);
419
420static int compression_test_lzma(struct unit_test_state *uts)
421{
422 return run_test(uts, "lzma", compress_using_lzma,
423 uncompress_using_lzma);
424}
425COMPRESSION_TEST(compression_test_lzma, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700426
Simon Glass1edaed02017-11-25 11:57:33 -0700427static int compression_test_lzo(struct unit_test_state *uts)
428{
429 return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo);
430}
431COMPRESSION_TEST(compression_test_lzo, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700432
Simon Glass1edaed02017-11-25 11:57:33 -0700433static int compression_test_lz4(struct unit_test_state *uts)
434{
435 return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4);
Kees Cook5d3bca82013-08-16 07:59:11 -0700436}
Simon Glass1edaed02017-11-25 11:57:33 -0700437COMPRESSION_TEST(compression_test_lz4, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700438
Simon Glass1edaed02017-11-25 11:57:33 -0700439static int compress_using_none(struct unit_test_state *uts,
440 void *in, unsigned long in_size,
Simon Glass6d084ce2014-12-02 13:17:35 -0700441 void *out, unsigned long out_max,
442 unsigned long *out_size)
443{
444 /* Here we just copy */
445 memcpy(out, in, in_size);
446 *out_size = in_size;
447
448 return 0;
449}
450
451/**
452 * run_bootm_test() - Run tests on the bootm decopmression function
453 *
454 * @comp_type: Compression type to test
455 * @compress: Our function to compress data
456 * @return 0 if OK, non-zero on failure
457 */
Simon Glass1edaed02017-11-25 11:57:33 -0700458static int run_bootm_test(struct unit_test_state *uts, int comp_type,
459 mutate_func compress)
Simon Glass6d084ce2014-12-02 13:17:35 -0700460{
461 ulong compress_size = 1024;
462 void *compress_buff;
463 int unc_len;
464 int err = 0;
465 const ulong image_start = 0;
466 const ulong load_addr = 0x1000;
467 ulong load_end;
468
469 printf("Testing: %s\n", genimg_get_comp_name(comp_type));
470 compress_buff = map_sysmem(image_start, 0);
471 unc_len = strlen(plain);
Simon Glass1edaed02017-11-25 11:57:33 -0700472 compress(uts, (void *)plain, unc_len, compress_buff, compress_size,
Simon Glass6d084ce2014-12-02 13:17:35 -0700473 &compress_size);
474 err = bootm_decomp_image(comp_type, load_addr, image_start,
475 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
476 compress_buff, compress_size, unc_len,
477 &load_end);
Simon Glass1edaed02017-11-25 11:57:33 -0700478 ut_assertok(err);
Simon Glass6d084ce2014-12-02 13:17:35 -0700479 err = bootm_decomp_image(comp_type, load_addr, image_start,
480 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
481 compress_buff, compress_size, unc_len - 1,
482 &load_end);
Simon Glass1edaed02017-11-25 11:57:33 -0700483 ut_assert(err);
Simon Glass6d084ce2014-12-02 13:17:35 -0700484
485 /* We can't detect corruption when not decompressing */
486 if (comp_type == IH_COMP_NONE)
487 return 0;
488 memset(compress_buff + compress_size / 2, '\x49',
489 compress_size / 2);
490 err = bootm_decomp_image(comp_type, load_addr, image_start,
491 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
492 compress_buff, compress_size, 0x10000,
493 &load_end);
Simon Glass1edaed02017-11-25 11:57:33 -0700494 ut_assert(err);
Simon Glass6d084ce2014-12-02 13:17:35 -0700495
496 return 0;
497}
498
Simon Glass1edaed02017-11-25 11:57:33 -0700499static int compression_test_bootm_gzip(struct unit_test_state *uts)
Simon Glass6d084ce2014-12-02 13:17:35 -0700500{
Simon Glass1edaed02017-11-25 11:57:33 -0700501 return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip);
502}
503COMPRESSION_TEST(compression_test_bootm_gzip, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700504
Simon Glass1edaed02017-11-25 11:57:33 -0700505static int compression_test_bootm_bzip2(struct unit_test_state *uts)
506{
507 return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2);
508}
509COMPRESSION_TEST(compression_test_bootm_bzip2, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700510
Simon Glass1edaed02017-11-25 11:57:33 -0700511static int compression_test_bootm_lzma(struct unit_test_state *uts)
512{
513 return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma);
514}
515COMPRESSION_TEST(compression_test_bootm_lzma, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700516
Simon Glass1edaed02017-11-25 11:57:33 -0700517static int compression_test_bootm_lzo(struct unit_test_state *uts)
518{
519 return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo);
Simon Glass6d084ce2014-12-02 13:17:35 -0700520}
Simon Glass1edaed02017-11-25 11:57:33 -0700521COMPRESSION_TEST(compression_test_bootm_lzo, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700522
Simon Glass1edaed02017-11-25 11:57:33 -0700523static int compression_test_bootm_lz4(struct unit_test_state *uts)
524{
525 return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4);
526}
527COMPRESSION_TEST(compression_test_bootm_lz4, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700528
Simon Glass1edaed02017-11-25 11:57:33 -0700529static int compression_test_bootm_none(struct unit_test_state *uts)
530{
531 return run_bootm_test(uts, IH_COMP_NONE, compress_using_none);
532}
533COMPRESSION_TEST(compression_test_bootm_none, 0);
534
535int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
536{
537 struct unit_test *tests = ll_entry_start(struct unit_test,
538 compression_test);
539 const int n_ents = ll_entry_count(struct unit_test, compression_test);
540
541 return cmd_ut_category("compression", tests, n_ents, argc, argv);
542}