1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2013, The Chromium Authors 4 */ 5 6#include <common.h> 7#include <abuf.h> 8#include <bootm.h> 9#include <command.h> 10#include <gzip.h> 11#include <image.h> 12#include <log.h> 13#include <malloc.h> 14#include <mapmem.h> 15#include <asm/io.h> 16 17#include <u-boot/lz4.h> 18#include <u-boot/zlib.h> 19#include <bzlib.h> 20 21#include <lzma/LzmaTypes.h> 22#include <lzma/LzmaDec.h> 23#include <lzma/LzmaTools.h> 24 25#include <linux/lzo.h> 26#include <linux/zstd.h> 27#include <test/compression.h> 28#include <test/suites.h> 29#include <test/ut.h> 30 31static const char plain[] = 32 "I am a highly compressable bit of text.\n" 33 "I am a highly compressable bit of text.\n" 34 "I am a highly compressable bit of text.\n" 35 "There are many like me, but this one is mine.\n" 36 "If I were any shorter, there wouldn't be much sense in\n" 37 "compressing me in the first place. At least with lzo, anyway,\n" 38 "which appears to behave poorly in the face of short text\n" 39 "messages.\n"; 40 41/* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */ 42static const char bzip2_compressed[] = 43 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00" 44 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30" 45 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4" 46 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d" 47 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52" 48 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad" 49 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16" 50 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c" 51 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0" 52 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6" 53 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4" 54 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96" 55 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef" 56 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a" 57 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48"; 58static const unsigned long bzip2_compressed_size = sizeof(bzip2_compressed) - 1; 59 60/* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */ 61static const char lzma_compressed[] = 62 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88" 63 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8" 64 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15" 65 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16" 66 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57" 67 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5" 68 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d" 69 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5" 70 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b" 71 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b" 72 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b" 73 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49" 74 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3" 75 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff" 76 "\xfd\xf5\x50\x8d\xca"; 77static const unsigned long lzma_compressed_size = sizeof(lzma_compressed) - 1; 78 79/* lzop -c /tmp/plain.txt > /tmp/plain.lzo */ 80static const char lzo_compressed[] = 81 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01" 82 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00" 83 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00" 84 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61" 85 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72" 86 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74" 87 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65" 88 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d" 89 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20" 90 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84" 91 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90" 92 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d" 93 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02" 94 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73" 95 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73" 96 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77" 97 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72" 98 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72" 99 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f" 100 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73" 101 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00"; 102static const unsigned long lzo_compressed_size = sizeof(lzo_compressed) - 1; 103 104/* lz4 -z /tmp/plain.txt > /tmp/plain.lz4 */ 105static const char lz4_compressed[] = 106 "\x04\x22\x4d\x18\x64\x70\xb9\x01\x01\x00\x00\xff\x19\x49\x20\x61" 107 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72" 108 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74" 109 "\x65\x78\x74\x2e\x0a\x28\x00\x3d\xf1\x25\x54\x68\x65\x72\x65\x20" 110 "\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d\x65" 111 "\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20\x69" 112 "\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x32\x00" 113 "\xd1\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x45\x00" 114 "\xf4\x0b\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d\x75" 115 "\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xcf\x00\x50\x69" 116 "\x6e\x67\x20\x6d\x12\x00\x00\x32\x00\xf0\x11\x20\x66\x69\x72\x73" 117 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73" 118 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x63\x00\xf5\x14\x77" 119 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72" 120 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72" 121 "\x6c\x79\x4e\x00\x30\x61\x63\x65\x27\x01\x01\x95\x00\x01\x2d\x01" 122 "\xb0\x0a\x6d\x65\x73\x73\x61\x67\x65\x73\x2e\x0a\x00\x00\x00\x00" 123 "\x9d\x12\x8c\x9d"; 124static const unsigned long lz4_compressed_size = sizeof(lz4_compressed) - 1; 125 126/* zstd -19 -c /tmp/plain.txt > /tmp/plain.zst */ 127static const char zstd_compressed[] = 128 "\x28\xb5\x2f\xfd\x64\x5e\x00\xbd\x05\x00\x02\x0e\x26\x1a\x70\x17" 129 "\xb8\x0d\x0c\x53\x5c\x9d\x97\xee\xa0\x5d\x84\x89\x3f\x5c\x7a\x78" 130 "\x00\x80\x80\x0f\xe8\xdf\xaf\x06\x66\xd0\x23\xa6\x7a\x64\x8e\xf4" 131 "\x0d\x5b\x47\x65\x26\x7e\x81\xdd\x0b\xe7\x5a\x95\x3d\x49\xcc\x67" 132 "\xe0\x2d\x46\x58\xb6\xac\x64\x16\xf2\xe0\xf8\x16\x17\xaf\xda\x8f" 133 "\x37\xc0\xc3\x0d\x3b\x89\x57\x15\x1e\x46\x46\x12\x9a\x84\xbe\xa6" 134 "\xab\xcf\x50\x90\x5f\x78\x01\xd2\xc0\x51\x72\x59\x0b\xea\xab\xf2" 135 "\xd4\x2b\x2d\x26\x7c\x10\x66\x78\x42\x64\x45\x3f\xa5\x15\x6f\xbd" 136 "\x4a\x61\xe1\xc8\x27\xc0\xe3\x95\x0c\xf9\xca\x7c\xf5\x13\x30\xc3" 137 "\x1a\x7c\x7d\xa4\x17\x0b\xff\x14\xa6\x7a\x95\xa0\x34\xbc\xce\x21" 138 "\x78\x36\x23\x33\x11\x09\x00\x60\x13\x00\x63\xa3\x8e\x28\x94\x55" 139 "\x15\xb6\x26\x68\x05\x4f\x23\x12\xee\x53\x55\x2d\x44\x2f\x54\x95" 140 "\x01\xe4\xf4\x6e\xfa"; 141static const unsigned long zstd_compressed_size = sizeof(zstd_compressed) - 1; 142 143 144#define TEST_BUFFER_SIZE 512 145 146typedef int (*mutate_func)(struct unit_test_state *uts, void *, unsigned long, 147 void *, unsigned long, unsigned long *); 148 149static int compress_using_gzip(struct unit_test_state *uts, 150 void *in, unsigned long in_size, 151 void *out, unsigned long out_max, 152 unsigned long *out_size) 153{ 154 int ret; 155 unsigned long inout_size = out_max; 156 157 ret = gzip(out, &inout_size, in, in_size); 158 if (out_size) 159 *out_size = inout_size; 160 161 return ret; 162} 163 164static int uncompress_using_gzip(struct unit_test_state *uts, 165 void *in, unsigned long in_size, 166 void *out, unsigned long out_max, 167 unsigned long *out_size) 168{ 169 int ret; 170 unsigned long inout_size = in_size; 171 172 ret = gunzip(out, out_max, in, &inout_size); 173 if (out_size) 174 *out_size = inout_size; 175 176 return ret; 177} 178 179static int compress_using_bzip2(struct unit_test_state *uts, 180 void *in, unsigned long in_size, 181 void *out, unsigned long out_max, 182 unsigned long *out_size) 183{ 184 /* There is no bzip2 compression in u-boot, so fake it. */ 185 ut_asserteq(in_size, strlen(plain)); 186 ut_asserteq_mem(plain, in, in_size); 187 188 if (bzip2_compressed_size > out_max) 189 return -1; 190 191 memcpy(out, bzip2_compressed, bzip2_compressed_size); 192 if (out_size) 193 *out_size = bzip2_compressed_size; 194 195 return 0; 196} 197 198static int uncompress_using_bzip2(struct unit_test_state *uts, 199 void *in, unsigned long in_size, 200 void *out, unsigned long out_max, 201 unsigned long *out_size) 202{ 203 int ret; 204 unsigned int inout_size = out_max; 205 206 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size, 207 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); 208 if (out_size) 209 *out_size = inout_size; 210 211 return (ret != BZ_OK); 212} 213 214static int compress_using_lzma(struct unit_test_state *uts, 215 void *in, unsigned long in_size, 216 void *out, unsigned long out_max, 217 unsigned long *out_size) 218{ 219 /* There is no lzma compression in u-boot, so fake it. */ 220 ut_asserteq(in_size, strlen(plain)); 221 ut_asserteq_mem(plain, in, in_size); 222 223 if (lzma_compressed_size > out_max) 224 return -1; 225 226 memcpy(out, lzma_compressed, lzma_compressed_size); 227 if (out_size) 228 *out_size = lzma_compressed_size; 229 230 return 0; 231} 232 233static int uncompress_using_lzma(struct unit_test_state *uts, 234 void *in, unsigned long in_size, 235 void *out, unsigned long out_max, 236 unsigned long *out_size) 237{ 238 int ret; 239 SizeT inout_size = out_max; 240 241 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size); 242 if (out_size) 243 *out_size = inout_size; 244 245 return (ret != SZ_OK); 246} 247 248static int compress_using_lzo(struct unit_test_state *uts, 249 void *in, unsigned long in_size, 250 void *out, unsigned long out_max, 251 unsigned long *out_size) 252{ 253 /* There is no lzo compression in u-boot, so fake it. */ 254 ut_asserteq(in_size, strlen(plain)); 255 ut_asserteq_mem(plain, in, in_size); 256 257 if (lzo_compressed_size > out_max) 258 return -1; 259 260 memcpy(out, lzo_compressed, lzo_compressed_size); 261 if (out_size) 262 *out_size = lzo_compressed_size; 263 264 return 0; 265} 266 267static int uncompress_using_lzo(struct unit_test_state *uts, 268 void *in, unsigned long in_size, 269 void *out, unsigned long out_max, 270 unsigned long *out_size) 271{ 272 int ret; 273 size_t input_size = in_size; 274 size_t output_size = out_max; 275 276 ret = lzop_decompress(in, input_size, out, &output_size); 277 if (out_size) 278 *out_size = output_size; 279 280 return (ret != LZO_E_OK); 281} 282 283static int compress_using_lz4(struct unit_test_state *uts, 284 void *in, unsigned long in_size, 285 void *out, unsigned long out_max, 286 unsigned long *out_size) 287{ 288 /* There is no lz4 compression in u-boot, so fake it. */ 289 ut_asserteq(in_size, strlen(plain)); 290 ut_asserteq_mem(plain, in, in_size); 291 292 if (lz4_compressed_size > out_max) 293 return -1; 294 295 memcpy(out, lz4_compressed, lz4_compressed_size); 296 if (out_size) 297 *out_size = lz4_compressed_size; 298 299 return 0; 300} 301 302static int uncompress_using_lz4(struct unit_test_state *uts, 303 void *in, unsigned long in_size, 304 void *out, unsigned long out_max, 305 unsigned long *out_size) 306{ 307 int ret; 308 size_t input_size = in_size; 309 size_t output_size = out_max; 310 311 ret = ulz4fn(in, input_size, out, &output_size); 312 if (out_size) 313 *out_size = output_size; 314 315 return (ret != 0); 316} 317 318static int compress_using_zstd(struct unit_test_state *uts, 319 void *in, unsigned long in_size, 320 void *out, unsigned long out_max, 321 unsigned long *out_size) 322{ 323 /* There is no zstd compression in u-boot, so fake it. */ 324 ut_asserteq(in_size, strlen(plain)); 325 ut_asserteq_mem(plain, in, in_size); 326 327 if (zstd_compressed_size > out_max) 328 return -1; 329 330 memcpy(out, zstd_compressed, zstd_compressed_size); 331 if (out_size) 332 *out_size = zstd_compressed_size; 333 334 return 0; 335} 336 337static int uncompress_using_zstd(struct unit_test_state *uts, 338 void *in, unsigned long in_size, 339 void *out, unsigned long out_max, 340 unsigned long *out_size) 341{ 342 struct abuf in_buf, out_buf; 343 int ret; 344 345 abuf_init_set(&in_buf, in, in_size); 346 abuf_init_set(&out_buf, out, out_max); 347 348 ret = zstd_decompress(&in_buf, &out_buf); 349 if (ret >= 0) { 350 *out_size = ret; 351 ret = 0; 352 } 353 354 return ret; 355} 356 357#define errcheck(statement) if (!(statement)) { \ 358 fprintf(stderr, "\tFailed: %s\n", #statement); \ 359 ret = 1; \ 360 goto out; \ 361} 362 363struct buf_state { 364 ulong orig_size; 365 ulong compressed_size; 366 ulong uncompressed_size; 367 void *orig_buf; 368 void *compressed_buf; 369 void *uncompressed_buf; 370 void *compare_buf; 371}; 372 373static int run_test_internal(struct unit_test_state *uts, char *name, 374 mutate_func compress, mutate_func uncompress, 375 struct buf_state *buf) 376{ 377 int ret; 378 379 /* Compress works as expected. */ 380 printf("\torig_size:%lu\n", buf->orig_size); 381 memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE); 382 ut_assertok(compress(uts, buf->orig_buf, buf->orig_size, 383 buf->compressed_buf, buf->compressed_size, 384 &buf->compressed_size)); 385 printf("\tcompressed_size:%lu\n", buf->compressed_size); 386 ut_assert(buf->compressed_size > 0); 387 ut_assert(buf->compressed_size < buf->orig_size); 388 ut_assert(((char *)buf->compressed_buf)[buf->compressed_size - 1] 389 != 'A'); 390 ut_asserteq(((char *)buf->compressed_buf)[buf->compressed_size], 'A'); 391 392 /* Uncompresses with space remaining. */ 393 ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size, 394 buf->uncompressed_buf, buf->uncompressed_size, 395 &buf->uncompressed_size)); 396 printf("\tuncompressed_size:%lu\n", buf->uncompressed_size); 397 ut_asserteq(buf->uncompressed_size, buf->orig_size); 398 ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size); 399 400 /* Uncompresses with exactly the right size output buffer. */ 401 memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE); 402 ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size, 403 buf->uncompressed_buf, buf->orig_size, 404 &buf->uncompressed_size)); 405 ut_asserteq(buf->uncompressed_size, buf->orig_size); 406 ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size); 407 ut_asserteq(((char *)buf->uncompressed_buf)[buf->orig_size], 'A'); 408 409 /* Uncompresses with trailing garbage in input buffer. */ 410 memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE); 411 ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size + 4, 412 buf->uncompressed_buf, buf->uncompressed_size, 413 &buf->uncompressed_size)); 414 ut_asserteq(buf->uncompressed_size, buf->orig_size); 415 ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size); 416 417 /* Make sure compression does not over-run. */ 418 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE); 419 ret = compress(uts, buf->orig_buf, buf->orig_size, 420 buf->compare_buf, buf->compressed_size - 1, 421 NULL); 422 ut_asserteq(((char *)buf->compare_buf)[buf->compressed_size], 'A'); 423 ut_assert(ret != 0); 424 printf("\tcompress does not overrun\n"); 425 426 /* Make sure decompression does not over-run. */ 427 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE); 428 ret = uncompress(uts, buf->compressed_buf, buf->compressed_size, 429 buf->compare_buf, buf->uncompressed_size - 1, 430 NULL); 431 ut_asserteq(((char *)buf->compare_buf)[buf->uncompressed_size - 1], 'A'); 432 ut_assert(ret != 0); 433 printf("\tuncompress does not overrun\n"); 434 435 /* Got here, everything is fine. */ 436 return 0; 437} 438 439static int run_test(struct unit_test_state *uts, char *name, 440 mutate_func compress, mutate_func uncompress) 441{ 442 struct buf_state sbuf, *buf = &sbuf; 443 int ret; 444 445 printf(" testing %s ...\n", name); 446 447 buf->orig_buf = (void *)plain; 448 buf->orig_size = strlen(buf->orig_buf); /* Trailing NUL not included */ 449 errcheck(buf->orig_size > 0); 450 451 buf->compressed_size = TEST_BUFFER_SIZE; 452 buf->uncompressed_size = TEST_BUFFER_SIZE; 453 buf->compressed_buf = malloc(buf->compressed_size); 454 errcheck(buf->compressed_buf); 455 buf->uncompressed_buf = malloc(buf->uncompressed_size); 456 errcheck(buf->uncompressed_buf); 457 buf->compare_buf = malloc(buf->uncompressed_size); 458 errcheck(buf->compare_buf); 459 460 ret = run_test_internal(uts, name, compress, uncompress, buf); 461out: 462 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED"); 463 464 free(buf->compare_buf); 465 free(buf->uncompressed_buf); 466 free(buf->compressed_buf); 467 468 return ret; 469} 470 471static int compression_test_gzip(struct unit_test_state *uts) 472{ 473 return run_test(uts, "gzip", compress_using_gzip, 474 uncompress_using_gzip); 475} 476COMPRESSION_TEST(compression_test_gzip, 0); 477 478static int compression_test_bzip2(struct unit_test_state *uts) 479{ 480 return run_test(uts, "bzip2", compress_using_bzip2, 481 uncompress_using_bzip2); 482} 483COMPRESSION_TEST(compression_test_bzip2, 0); 484 485static int compression_test_lzma(struct unit_test_state *uts) 486{ 487 return run_test(uts, "lzma", compress_using_lzma, 488 uncompress_using_lzma); 489} 490COMPRESSION_TEST(compression_test_lzma, 0); 491 492static int compression_test_lzo(struct unit_test_state *uts) 493{ 494 return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo); 495} 496COMPRESSION_TEST(compression_test_lzo, 0); 497 498static int compression_test_lz4(struct unit_test_state *uts) 499{ 500 return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4); 501} 502COMPRESSION_TEST(compression_test_lz4, 0); 503 504static int compression_test_zstd(struct unit_test_state *uts) 505{ 506 return run_test(uts, "zstd", compress_using_zstd, 507 uncompress_using_zstd); 508} 509COMPRESSION_TEST(compression_test_zstd, 0); 510 511static int compress_using_none(struct unit_test_state *uts, 512 void *in, unsigned long in_size, 513 void *out, unsigned long out_max, 514 unsigned long *out_size) 515{ 516 /* Here we just copy */ 517 memcpy(out, in, in_size); 518 *out_size = in_size; 519 520 return 0; 521} 522 523/** 524 * run_bootm_test() - Run tests on the bootm decompression function 525 * 526 * @comp_type: Compression type to test 527 * @compress: Our function to compress data 528 * Return: 0 if OK, non-zero on failure 529 */ 530static int run_bootm_test(struct unit_test_state *uts, int comp_type, 531 mutate_func compress) 532{ 533 ulong compress_size = 1024; 534 void *compress_buff; 535 int unc_len; 536 int err = 0; 537 const ulong image_start = 0; 538 const ulong load_addr = 0x1000; 539 ulong load_end; 540 541 printf("Testing: %s\n", genimg_get_comp_name(comp_type)); 542 compress_buff = map_sysmem(image_start, 0); 543 unc_len = strlen(plain); 544 compress(uts, (void *)plain, unc_len, compress_buff, compress_size, 545 &compress_size); 546 err = image_decomp(comp_type, load_addr, image_start, 547 IH_TYPE_KERNEL, map_sysmem(load_addr, 0), 548 compress_buff, compress_size, unc_len, 549 &load_end); 550 ut_assertok(err); 551 err = image_decomp(comp_type, load_addr, image_start, 552 IH_TYPE_KERNEL, map_sysmem(load_addr, 0), 553 compress_buff, compress_size, unc_len - 1, 554 &load_end); 555 ut_assert(err); 556 557 /* We can't detect corruption when not decompressing */ 558 if (comp_type == IH_COMP_NONE) 559 return 0; 560 memset(compress_buff + compress_size / 2, '\x49', 561 compress_size / 2); 562 err = image_decomp(comp_type, load_addr, image_start, 563 IH_TYPE_KERNEL, map_sysmem(load_addr, 0), 564 compress_buff, compress_size, 0x10000, 565 &load_end); 566 ut_assert(err); 567 568 return 0; 569} 570 571static int compression_test_bootm_gzip(struct unit_test_state *uts) 572{ 573 return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip); 574} 575COMPRESSION_TEST(compression_test_bootm_gzip, 0); 576 577static int compression_test_bootm_bzip2(struct unit_test_state *uts) 578{ 579 return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2); 580} 581COMPRESSION_TEST(compression_test_bootm_bzip2, 0); 582 583static int compression_test_bootm_lzma(struct unit_test_state *uts) 584{ 585 return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma); 586} 587COMPRESSION_TEST(compression_test_bootm_lzma, 0); 588 589static int compression_test_bootm_lzo(struct unit_test_state *uts) 590{ 591 return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo); 592} 593COMPRESSION_TEST(compression_test_bootm_lzo, 0); 594 595static int compression_test_bootm_lz4(struct unit_test_state *uts) 596{ 597 return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4); 598} 599COMPRESSION_TEST(compression_test_bootm_lz4, 0); 600 601static int compression_test_bootm_zstd(struct unit_test_state *uts) 602{ 603 return run_bootm_test(uts, IH_COMP_ZSTD, compress_using_zstd); 604} 605COMPRESSION_TEST(compression_test_bootm_zstd, 0); 606 607static int compression_test_bootm_none(struct unit_test_state *uts) 608{ 609 return run_bootm_test(uts, IH_COMP_NONE, compress_using_none); 610} 611COMPRESSION_TEST(compression_test_bootm_none, 0); 612 613int do_ut_compression(struct cmd_tbl *cmdtp, int flag, int argc, 614 char *const argv[]) 615{ 616 struct unit_test *tests = UNIT_TEST_SUITE_START(compression_test); 617 const int n_ents = UNIT_TEST_SUITE_COUNT(compression_test); 618 619 return cmd_ut_category("compression", "compression_test_", 620 tests, n_ents, argc, argv); 621} 622