This enables more warnings on the cbfstool codebase and fixes the issues that surface as a result. A memory leak that used to occur when compressing files with lzma is also found and fixed. Finally, there are several fixes for the Makefile: - Its autodependencies used to be broken because the target for the .dependencies file was misnamed; this meant that Make didn't know how to rebuild the file, and so would silently skip the step of updating it before including it. - The ability to build to a custom output directory by defining the obj variable had bitrotted. - The default value of the obj variable was causing implicit rules not to apply when specifying a file as a target without providing a custom value for obj. - Add a distclean target for removing the .dependencies file. BUG=chromium:461875 TEST=Build an image with cbfstool both before and after. BRANCH=None Change-Id: I951919d63443f2b053c2e67c1ac9872abc0a43ca Signed-off-by: Sol Boucher <solb@chromium.org> Original-Commit-Id: 49293443b4e565ca48d284e9a66f80c9c213975d Original-Change-Id: Ia7350c2c3306905984cfa711d5fc4631f0b43d5b Original-Signed-off-by: Sol Boucher <solb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/257340 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-on: http://review.coreboot.org/9937 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
		
			
				
	
	
		
			189 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdio.h>
 | 
						|
#include <stdint.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include "../common.h"
 | 
						|
#include "C/LzmaDec.h"
 | 
						|
#include "C/LzmaEnc.h"
 | 
						|
 | 
						|
#define L (uint64_t)
 | 
						|
 | 
						|
static inline uint64_t get_64(const void *p)
 | 
						|
{
 | 
						|
	const unsigned char *data = (const unsigned char *)p;
 | 
						|
	return (L data[0]) | (L data[1] << 8) | (L data[2] << 16) |
 | 
						|
		(L data[3] << 24) | (L data [4] << 32) | (L data[5] << 40) |
 | 
						|
		(L data[6] << 48) | (L data[7] << 56);
 | 
						|
}
 | 
						|
 | 
						|
static void put_64(void *p, uint64_t value)
 | 
						|
{
 | 
						|
	unsigned char *data = (unsigned char *)p;
 | 
						|
	data[0] = value & 0xff;
 | 
						|
	data[1] = (value >> 8) & 0xff;
 | 
						|
	data[2] = (value >> 16) & 0xff;
 | 
						|
	data[3] = (value >> 24) & 0xff;
 | 
						|
	data[4] = (value >> 32) & 0xff;
 | 
						|
	data[5] = (value >> 40) & 0xff;
 | 
						|
	data[6] = (value >> 48) & 0xff;
 | 
						|
	data[7] = (value >> 56) & 0xff;
 | 
						|
}
 | 
						|
 | 
						|
/* Memory Allocation API */
 | 
						|
 | 
						|
static void *SzAlloc(unused void *u, size_t size)
 | 
						|
{
 | 
						|
	return malloc(size);
 | 
						|
}
 | 
						|
 | 
						|
static void SzFree(unused void *u, void *address)
 | 
						|
{
 | 
						|
	free(address);
 | 
						|
}
 | 
						|
 | 
						|
static struct ISzAlloc LZMAalloc = { SzAlloc, SzFree };
 | 
						|
 | 
						|
/* Streaming API */
 | 
						|
 | 
						|
struct vector_t {
 | 
						|
	char *p;
 | 
						|
	size_t pos;
 | 
						|
	size_t size;
 | 
						|
};
 | 
						|
 | 
						|
static struct vector_t instream, outstream;
 | 
						|
 | 
						|
static SRes Read(unused void *u, void *buf, size_t *size)
 | 
						|
{
 | 
						|
	if ((instream.size - instream.pos) < *size)
 | 
						|
		*size = instream.size - instream.pos;
 | 
						|
	memcpy(buf, instream.p + instream.pos, *size);
 | 
						|
	instream.pos += *size;
 | 
						|
	return SZ_OK;
 | 
						|
}
 | 
						|
 | 
						|
static size_t Write(unused void *u, const void *buf, size_t size)
 | 
						|
{
 | 
						|
	if(outstream.size - outstream.pos < size)
 | 
						|
		size = outstream.size - outstream.pos;
 | 
						|
	memcpy(outstream.p + outstream.pos, buf, size);
 | 
						|
	outstream.pos += size;
 | 
						|
	return size;
 | 
						|
}
 | 
						|
 | 
						|
static struct ISeqInStream is = { Read };
 | 
						|
static struct ISeqOutStream os = { Write };
 | 
						|
 | 
						|
/**
 | 
						|
 * Compress a buffer with lzma
 | 
						|
 * Don't copy the result back if it is too large.
 | 
						|
 * @param in a pointer to the buffer
 | 
						|
 * @param in_len the length in bytes
 | 
						|
 * @param out a pointer to a buffer of at least size in_len
 | 
						|
 * @param out_len a pointer to the compressed length of in
 | 
						|
 */
 | 
						|
 | 
						|
int do_lzma_compress(char *in, int in_len, char *out, int *out_len)
 | 
						|
{
 | 
						|
	if (in_len == 0) {
 | 
						|
		ERROR("LZMA: Input length is zero.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	struct CLzmaEncProps props;
 | 
						|
	LzmaEncProps_Init(&props);
 | 
						|
	props.dictSize = in_len;
 | 
						|
	props.pb = 0; /* PosStateBits, default: 2, range: 0..4 */
 | 
						|
	props.lp = 0; /* LiteralPosStateBits, default: 0, range: 0..4 */
 | 
						|
	props.lc = 1; /* LiteralContextBits, default: 3, range: 0..8 */
 | 
						|
	props.fb = 273; /* NumFastBytes */
 | 
						|
	props.mc = 0; /* MatchFinderCycles, default: 0 */
 | 
						|
	props.algo = 1; /* AlgorithmNo, apparently, 0 and 1 are valid values. 0 = fast mode */
 | 
						|
	props.numThreads = 1;
 | 
						|
 | 
						|
	switch (props.algo) {
 | 
						|
	case 0:	// quick: HC4
 | 
						|
		props.btMode = 0;
 | 
						|
		props.level = 1;
 | 
						|
		break;
 | 
						|
	case 1:	// full: BT4
 | 
						|
	default:
 | 
						|
		props.level = 9;
 | 
						|
		props.btMode = 1;
 | 
						|
		props.numHashBytes = 4;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	CLzmaEncHandle p = LzmaEnc_Create(&LZMAalloc);
 | 
						|
 | 
						|
	int res = LzmaEnc_SetProps(p, &props);
 | 
						|
	if (res != SZ_OK) {
 | 
						|
		ERROR("LZMA: LzmaEnc_SetProps failed.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	unsigned char propsEncoded[LZMA_PROPS_SIZE + 8];
 | 
						|
	size_t propsSize = sizeof propsEncoded;
 | 
						|
	res = LzmaEnc_WriteProperties(p, propsEncoded, &propsSize);
 | 
						|
	if (res != SZ_OK) {
 | 
						|
		ERROR("LZMA: LzmaEnc_WriteProperties failed.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	instream.p = in;
 | 
						|
	instream.pos = 0;
 | 
						|
	instream.size = in_len;
 | 
						|
 | 
						|
	outstream.p = out;
 | 
						|
	outstream.pos = 0;
 | 
						|
	outstream.size = in_len;
 | 
						|
 | 
						|
	put_64(propsEncoded + LZMA_PROPS_SIZE, in_len);
 | 
						|
	Write(&os, propsEncoded, LZMA_PROPS_SIZE+8);
 | 
						|
 | 
						|
	res = LzmaEnc_Encode(p, &os, &is, 0, &LZMAalloc, &LZMAalloc);
 | 
						|
	LzmaEnc_Destroy(p, &LZMAalloc, &LZMAalloc);
 | 
						|
	if (res != SZ_OK) {
 | 
						|
		ERROR("LZMA: LzmaEnc_Encode failed %d.\n", res);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	*out_len = outstream.pos;
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int do_lzma_uncompress(char *dst, int dst_len, char *src, int src_len)
 | 
						|
{
 | 
						|
	if (src_len <= LZMA_PROPS_SIZE + 8) {
 | 
						|
		ERROR("LZMA: Input length is too small.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	uint64_t out_sizemax = get_64(&src[LZMA_PROPS_SIZE]);
 | 
						|
 | 
						|
	if (out_sizemax > (size_t) dst_len) {
 | 
						|
		ERROR("Not copying %d bytes to %d-byte buffer!\n",
 | 
						|
			(unsigned int)out_sizemax, dst_len);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	enum ELzmaStatus status;
 | 
						|
 | 
						|
	size_t destlen = out_sizemax;
 | 
						|
	size_t srclen = src_len - (LZMA_PROPS_SIZE + 8);
 | 
						|
 | 
						|
	int res = LzmaDecode((uint8_t *) dst, &destlen,
 | 
						|
			     (uint8_t *) &src[LZMA_PROPS_SIZE + 8], &srclen,
 | 
						|
			     (uint8_t *) &src[0], LZMA_PROPS_SIZE,
 | 
						|
			     LZMA_FINISH_END,
 | 
						|
			     &status,
 | 
						|
			     &LZMAalloc);
 | 
						|
 | 
						|
	if (res != SZ_OK) {
 | 
						|
		ERROR("Error while decompressing.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 |