You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
2.6 KiB
115 lines
2.6 KiB
/*
|
|
* Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
#include <common/debug.h>
|
|
#include <common/tf_crc32.h>
|
|
#include <lib/utils.h>
|
|
#include <tf_gunzip.h>
|
|
|
|
#include "zutil.h"
|
|
|
|
/*
|
|
* memory allocated by malloc() is supposed to be aligned for any built-in type
|
|
*/
|
|
#define ZALLOC_ALIGNMENT sizeof(void *)
|
|
|
|
static uintptr_t zalloc_start;
|
|
static uintptr_t zalloc_end;
|
|
static uintptr_t zalloc_current;
|
|
|
|
static void * ZLIB_INTERNAL zcalloc(void *opaque, unsigned int items,
|
|
unsigned int size)
|
|
{
|
|
uintptr_t p, p_end;
|
|
|
|
size *= items;
|
|
|
|
p = round_up(zalloc_current, ZALLOC_ALIGNMENT);
|
|
p_end = p + size;
|
|
|
|
if (p_end > zalloc_end)
|
|
return NULL;
|
|
|
|
memset((void *)p, 0, size);
|
|
|
|
zalloc_current = p_end;
|
|
|
|
return (void *)p;
|
|
}
|
|
|
|
static void ZLIB_INTERNAL zfree(void *opaque, void *ptr)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* gunzip - decompress gzip data
|
|
* @in_buf: source of compressed input. Upon exit, the end of input.
|
|
* @in_len: length of in_buf
|
|
* @out_buf: destination of decompressed output. Upon exit, the end of output.
|
|
* @out_len: length of out_buf
|
|
* @work_buf: workspace
|
|
* @work_len: length of workspace
|
|
*/
|
|
int gunzip(uintptr_t *in_buf, size_t in_len, uintptr_t *out_buf,
|
|
size_t out_len, uintptr_t work_buf, size_t work_len)
|
|
{
|
|
z_stream stream;
|
|
int zret, ret;
|
|
|
|
zalloc_start = work_buf;
|
|
zalloc_end = work_buf + work_len;
|
|
zalloc_current = zalloc_start;
|
|
|
|
stream.next_in = (typeof(stream.next_in))*in_buf;
|
|
stream.avail_in = in_len;
|
|
stream.next_out = (typeof(stream.next_out))*out_buf;
|
|
stream.avail_out = out_len;
|
|
stream.zalloc = zcalloc;
|
|
stream.zfree = zfree;
|
|
stream.opaque = (voidpf)0;
|
|
|
|
zret = inflateInit(&stream);
|
|
if (zret != Z_OK) {
|
|
ERROR("zlib: inflate init failed (ret = %d)\n", zret);
|
|
return (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
|
|
}
|
|
|
|
zret = inflate(&stream, Z_NO_FLUSH);
|
|
if (zret == Z_STREAM_END) {
|
|
ret = 0;
|
|
} else {
|
|
if (stream.msg)
|
|
ERROR("%s\n", stream.msg);
|
|
ERROR("zlib: inflate failed (ret = %d)\n", zret);
|
|
ret = (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
|
|
}
|
|
|
|
VERBOSE("zlib: %lu byte input\n", stream.total_in);
|
|
VERBOSE("zlib: %lu byte output\n", stream.total_out);
|
|
|
|
*in_buf = (uintptr_t)stream.next_in;
|
|
*out_buf = (uintptr_t)stream.next_out;
|
|
|
|
inflateEnd(&stream);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* Wrapper function to calculate CRC
|
|
* @crc: previous accumulated CRC
|
|
* @buf: buffer base address
|
|
* @size: size of the buffer
|
|
*
|
|
* Return calculated CRC32 value
|
|
*/
|
|
uint32_t tf_crc32(uint32_t crc, const unsigned char *buf, size_t size)
|
|
{
|
|
return (uint32_t)crc32((unsigned long)crc, buf, size);
|
|
}
|
|
|