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