xref: /rk3399_ARM-atf/lib/zlib/tf_gunzip.c (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
1 /*
2  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <debug.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <tf_gunzip.h>
12 #include <utils.h>
13 
14 #include "zutil.h"
15 
16 /*
17  * memory allocated by malloc() is supposed to be aligned for any built-in type
18  */
19 #define ZALLOC_ALIGNMENT	sizeof(void *)
20 
21 static uintptr_t zalloc_start;
22 static uintptr_t zalloc_end;
23 static uintptr_t zalloc_current;
24 
25 static void * ZLIB_INTERNAL zcalloc(void *opaque, unsigned int items,
26 				    unsigned int size)
27 {
28 	uintptr_t p, p_end;
29 
30 	size *= items;
31 
32 	p = round_up(zalloc_current, ZALLOC_ALIGNMENT);
33 	p_end = p + size;
34 
35 	if (p_end > zalloc_end)
36 		return NULL;
37 
38 	memset((void *)p, 0, size);
39 
40 	zalloc_current = p_end;
41 
42 	return (void *)p;
43 }
44 
45 static void ZLIB_INTERNAL zfree(void *opaque, void *ptr)
46 {
47 }
48 
49 /*
50  * gunzip - decompress gzip data
51  * @in_buf: source of compressed input. Upon exit, the end of input.
52  * @in_len: length of in_buf
53  * @out_buf: destination of decompressed output. Upon exit, the end of output.
54  * @out_len: length of out_buf
55  * @work_buf: workspace
56  * @work_len: length of workspace
57  */
58 int gunzip(uintptr_t *in_buf, size_t in_len, uintptr_t *out_buf,
59 	   size_t out_len, uintptr_t work_buf, size_t work_len)
60 {
61 	z_stream stream;
62 	int zret, ret;
63 
64 	zalloc_start = work_buf;
65 	zalloc_end = work_buf + work_len;
66 	zalloc_current = zalloc_start;
67 
68 	stream.next_in = (typeof(stream.next_in))*in_buf;
69 	stream.avail_in = in_len;
70 	stream.next_out = (typeof(stream.next_out))*out_buf;
71 	stream.avail_out = out_len;
72 	stream.zalloc = zcalloc;
73 	stream.zfree = zfree;
74 	stream.opaque = (voidpf)0;
75 
76 	zret = inflateInit(&stream);
77 	if (zret != Z_OK) {
78 		ERROR("zlib: inflate init failed (ret = %d)\n", zret);
79 		return (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
80 	}
81 
82 	zret = inflate(&stream, Z_NO_FLUSH);
83 	if (zret == Z_STREAM_END) {
84 		ret = 0;
85 	} else {
86 		if (stream.msg)
87 			ERROR("%s\n", stream.msg);
88 		ERROR("zlib: inflate failed (ret = %d)\n", zret);
89 		ret = (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
90 	}
91 
92 	VERBOSE("zlib: %lu byte input\n", stream.total_in);
93 	VERBOSE("zlib: %lu byte output\n", stream.total_out);
94 
95 	*in_buf = (uintptr_t)stream.next_in;
96 	*out_buf = (uintptr_t)stream.next_out;
97 
98 	inflateEnd(&stream);
99 
100 	return ret;
101 }
102