blob: 574d871b06d38129a6468b2b592036c4a6208422 [file] [log] [blame]
Masahiro Yamada55a040e2018-01-26 11:42:01 +09001/*
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
21static uintptr_t zalloc_start;
22static uintptr_t zalloc_end;
23static uintptr_t zalloc_current;
24
25static 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
45static 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 */
58int 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
Sandrine Bailleux4d8938a2018-02-07 10:32:01 +010092 VERBOSE("zlib: %lu byte input\n", stream.total_in);
93 VERBOSE("zlib: %lu byte output\n", stream.total_out);
Masahiro Yamada55a040e2018-01-26 11:42:01 +090094
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}