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