mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add a directory by kernel instead of a common root, add qnap-301w and rpi4 kernel 6.1 suppport
This commit is contained in:
parent
e910436a7a
commit
46837ec4c0
9459 changed files with 362648 additions and 116345 deletions
87
common/package/utils/sysupgrade-helper/src/lib/Makefile
Normal file
87
common/package/utils/sysupgrade-helper/src/lib/Makefile
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)libgeneric.o
|
||||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
COBJS-$(CONFIG_ADDR_MAP) += addr_map.o
|
||||
COBJS-$(CONFIG_BCH) += bch.o
|
||||
COBJS-$(CONFIG_AES) += aes.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib_crctable.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib_randtable.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib_huffman.o
|
||||
COBJS-$(CONFIG_USB_TTY) += circbuf.o
|
||||
COBJS-y += crc7.o
|
||||
COBJS-y += crc16.o
|
||||
COBJS-y += display_options.o
|
||||
COBJS-y += errno.o
|
||||
COBJS-$(CONFIG_OF_CONTROL) += fdtdec.o
|
||||
COBJS-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
|
||||
COBJS-$(CONFIG_GZIP) += gunzip.o
|
||||
COBJS-y += hashtable.o
|
||||
COBJS-$(CONFIG_LMB) += lmb.o
|
||||
COBJS-y += ldiv.o
|
||||
COBJS-$(CONFIG_MD5) += md5.o
|
||||
COBJS-y += net_utils.o
|
||||
COBJS-y += qsort.o
|
||||
COBJS-$(CONFIG_SHA1) += sha1.o
|
||||
COBJS-$(CONFIG_SHA256) += sha256.o
|
||||
COBJS-y += strmhz.o
|
||||
COBJS-$(CONFIG_RBTREE) += rbtree.o
|
||||
else
|
||||
COBJS-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += display_options.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
|
||||
endif
|
||||
COBJS-y += crc32.o
|
||||
COBJS-y += ctype.o
|
||||
COBJS-y += div64.o
|
||||
COBJS-y += string.o
|
||||
COBJS-y += time.o
|
||||
COBJS-$(CONFIG_BOOTP_PXE) += uuid.o
|
||||
COBJS-y += vsprintf.o
|
||||
COBJS-$(CONFIG_RANDOM_MACADDR) += rand.o
|
||||
COBJS-$(CONFIG_BOOTP_RANDOM_DELAY) += rand.o
|
||||
COBJS-$(CONFIG_CMD_LINK_LOCAL) += rand.o
|
||||
|
||||
COBJS := $(sort $(COBJS-y))
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
84
common/package/utils/sysupgrade-helper/src/lib/addr_map.c
Normal file
84
common/package/utils/sysupgrade-helper/src/lib/addr_map.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <addr_map.h>
|
||||
|
||||
static struct {
|
||||
phys_addr_t paddr;
|
||||
phys_size_t size;
|
||||
unsigned long vaddr;
|
||||
} address_map[CONFIG_SYS_NUM_ADDR_MAP];
|
||||
|
||||
phys_addr_t addrmap_virt_to_phys(void * vaddr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++) {
|
||||
u64 base, upper, addr;
|
||||
|
||||
if (address_map[i].size == 0)
|
||||
continue;
|
||||
|
||||
addr = (u64)((u32)vaddr);
|
||||
base = (u64)(address_map[i].vaddr);
|
||||
upper = (u64)(address_map[i].size) + base - 1;
|
||||
|
||||
if (addr >= base && addr <= upper) {
|
||||
return addr - address_map[i].vaddr + address_map[i].paddr;
|
||||
}
|
||||
}
|
||||
|
||||
return (phys_addr_t)(~0);
|
||||
}
|
||||
|
||||
void *addrmap_phys_to_virt(phys_addr_t paddr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++) {
|
||||
phys_addr_t base, upper;
|
||||
|
||||
if (address_map[i].size == 0)
|
||||
continue;
|
||||
|
||||
base = address_map[i].paddr;
|
||||
upper = address_map[i].size + base - 1;
|
||||
|
||||
if (paddr >= base && paddr <= upper) {
|
||||
phys_addr_t offset;
|
||||
|
||||
offset = address_map[i].paddr - address_map[i].vaddr;
|
||||
|
||||
return (void *)(unsigned long)(paddr - offset);
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)(~0);
|
||||
}
|
||||
|
||||
void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr,
|
||||
phys_size_t size, int idx)
|
||||
{
|
||||
if (idx > CONFIG_SYS_NUM_ADDR_MAP)
|
||||
return;
|
||||
|
||||
address_map[idx].vaddr = vaddr;
|
||||
address_map[idx].paddr = paddr;
|
||||
address_map[idx].size = size;
|
||||
}
|
||||
598
common/package/utils/sysupgrade-helper/src/lib/aes.c
Normal file
598
common/package/utils/sysupgrade-helper/src/lib/aes.c
Normal file
|
|
@ -0,0 +1,598 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The Chromium OS Authors.
|
||||
* (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* advanced encryption standard
|
||||
* author: karl malbrain, malbrain@yahoo.com
|
||||
*
|
||||
* This work, including the source code, documentation
|
||||
* and related data, is placed into the public domain.
|
||||
*
|
||||
* The orginal author is Karl Malbrain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
|
||||
* OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
|
||||
* MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
|
||||
* ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
|
||||
* RESULTING FROM THE USE, MODIFICATION, OR
|
||||
* REDISTRIBUTION OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include "aes.h"
|
||||
|
||||
/* forward s-box */
|
||||
static const u8 sbox[256] = {
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
||||
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
|
||||
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
|
||||
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
|
||||
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
|
||||
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
|
||||
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
||||
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
|
||||
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
|
||||
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
|
||||
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
|
||||
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
|
||||
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
|
||||
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
|
||||
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
|
||||
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
|
||||
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
|
||||
/* inverse s-box */
|
||||
static const u8 inv_sbox[256] = {
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
|
||||
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
|
||||
0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
|
||||
0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
|
||||
0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
|
||||
0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
|
||||
0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
|
||||
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
|
||||
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
|
||||
0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
|
||||
0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
|
||||
0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
|
||||
0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
|
||||
0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
|
||||
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
|
||||
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
|
||||
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||
};
|
||||
|
||||
/* combined Xtimes2[Sbox[]] */
|
||||
static const u8 x2_sbox[256] = {
|
||||
0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91,
|
||||
0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
|
||||
0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb,
|
||||
0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
|
||||
0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83,
|
||||
0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
|
||||
0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f,
|
||||
0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
|
||||
0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b,
|
||||
0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
|
||||
0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6,
|
||||
0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
|
||||
0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11,
|
||||
0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
|
||||
0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1,
|
||||
0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
|
||||
0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e,
|
||||
0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
|
||||
0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b,
|
||||
0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
|
||||
0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8,
|
||||
0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
|
||||
0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49,
|
||||
0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
|
||||
0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97,
|
||||
0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
|
||||
0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c,
|
||||
0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
|
||||
0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33,
|
||||
0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
|
||||
0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0,
|
||||
0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
|
||||
};
|
||||
|
||||
/* combined Xtimes3[Sbox[]] */
|
||||
static const u8 x3_sbox[256] = {
|
||||
0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54,
|
||||
0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
|
||||
0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b,
|
||||
0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
|
||||
0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f,
|
||||
0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
|
||||
0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5,
|
||||
0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
|
||||
0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb,
|
||||
0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
|
||||
0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed,
|
||||
0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
|
||||
0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94,
|
||||
0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
|
||||
0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04,
|
||||
0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
|
||||
0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39,
|
||||
0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
|
||||
0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83,
|
||||
0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
|
||||
0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4,
|
||||
0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
|
||||
0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0,
|
||||
0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
|
||||
0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51,
|
||||
0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
|
||||
0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12,
|
||||
0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
|
||||
0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7,
|
||||
0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
|
||||
0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8,
|
||||
0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
|
||||
};
|
||||
|
||||
/*
|
||||
* modular multiplication tables based on:
|
||||
*
|
||||
* Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
|
||||
* Xtime3[x] = x^Xtime2[x];
|
||||
*/
|
||||
static const u8 x_time_9[256] = {
|
||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
|
||||
0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
|
||||
0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
|
||||
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
|
||||
0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
|
||||
0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94,
|
||||
0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
|
||||
0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
|
||||
0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
|
||||
0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9,
|
||||
0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
|
||||
0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72,
|
||||
0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
|
||||
0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
|
||||
0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
|
||||
0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3,
|
||||
0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
|
||||
0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43,
|
||||
0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
|
||||
0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
|
||||
0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
|
||||
0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78,
|
||||
0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
|
||||
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5,
|
||||
0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
|
||||
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
|
||||
0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
|
||||
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e,
|
||||
0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
|
||||
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e,
|
||||
0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
|
||||
};
|
||||
|
||||
static const u8 x_time_b[256] = {
|
||||
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31,
|
||||
0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
|
||||
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
|
||||
0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
|
||||
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a,
|
||||
0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
|
||||
0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa,
|
||||
0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
|
||||
0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
|
||||
0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
|
||||
0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77,
|
||||
0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
|
||||
0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc,
|
||||
0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
|
||||
0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
|
||||
0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
|
||||
0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6,
|
||||
0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
|
||||
0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76,
|
||||
0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
|
||||
0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
|
||||
0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
|
||||
0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d,
|
||||
0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
|
||||
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30,
|
||||
0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
|
||||
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
|
||||
0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
|
||||
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b,
|
||||
0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
|
||||
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb,
|
||||
0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
|
||||
};
|
||||
|
||||
static const u8 x_time_d[256] = {
|
||||
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23,
|
||||
0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
|
||||
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
|
||||
0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
|
||||
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98,
|
||||
0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
|
||||
0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48,
|
||||
0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
|
||||
0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
|
||||
0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
|
||||
0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e,
|
||||
0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
|
||||
0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5,
|
||||
0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
|
||||
0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
|
||||
0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
|
||||
0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9,
|
||||
0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
|
||||
0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29,
|
||||
0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
|
||||
0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
|
||||
0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
|
||||
0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92,
|
||||
0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
|
||||
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94,
|
||||
0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
|
||||
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
|
||||
0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
|
||||
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f,
|
||||
0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
|
||||
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff,
|
||||
0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
|
||||
};
|
||||
|
||||
static const u8 x_time_e[256] = {
|
||||
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a,
|
||||
0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
|
||||
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
|
||||
0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
|
||||
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1,
|
||||
0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
|
||||
0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11,
|
||||
0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
|
||||
0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
|
||||
0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
|
||||
0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67,
|
||||
0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
|
||||
0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c,
|
||||
0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
|
||||
0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
|
||||
0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
|
||||
0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b,
|
||||
0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
|
||||
0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b,
|
||||
0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
|
||||
0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
|
||||
0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
|
||||
0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50,
|
||||
0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
|
||||
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6,
|
||||
0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
|
||||
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
|
||||
0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
|
||||
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d,
|
||||
0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
|
||||
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd,
|
||||
0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
|
||||
};
|
||||
|
||||
/*
|
||||
* Exchanges columns in each of 4 rows
|
||||
* row0 - unchanged, row1- shifted left 1,
|
||||
* row2 - shifted left 2 and row3 - shifted left 3
|
||||
*/
|
||||
static void shift_rows(u8 *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
/* just substitute row 0 */
|
||||
state[0] = sbox[state[0]];
|
||||
state[4] = sbox[state[4]];
|
||||
state[8] = sbox[state[8]];
|
||||
state[12] = sbox[state[12]];
|
||||
|
||||
/* rotate row 1 */
|
||||
tmp = sbox[state[1]];
|
||||
state[1] = sbox[state[5]];
|
||||
state[5] = sbox[state[9]];
|
||||
state[9] = sbox[state[13]];
|
||||
state[13] = tmp;
|
||||
|
||||
/* rotate row 2 */
|
||||
tmp = sbox[state[2]];
|
||||
state[2] = sbox[state[10]];
|
||||
state[10] = tmp;
|
||||
tmp = sbox[state[6]];
|
||||
state[6] = sbox[state[14]];
|
||||
state[14] = tmp;
|
||||
|
||||
/* rotate row 3 */
|
||||
tmp = sbox[state[15]];
|
||||
state[15] = sbox[state[11]];
|
||||
state[11] = sbox[state[7]];
|
||||
state[7] = sbox[state[3]];
|
||||
state[3] = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* restores columns in each of 4 rows
|
||||
* row0 - unchanged, row1- shifted right 1,
|
||||
* row2 - shifted right 2 and row3 - shifted right 3
|
||||
*/
|
||||
static void inv_shift_rows(u8 *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
/* restore row 0 */
|
||||
state[0] = inv_sbox[state[0]];
|
||||
state[4] = inv_sbox[state[4]];
|
||||
state[8] = inv_sbox[state[8]];
|
||||
state[12] = inv_sbox[state[12]];
|
||||
|
||||
/* restore row 1 */
|
||||
tmp = inv_sbox[state[13]];
|
||||
state[13] = inv_sbox[state[9]];
|
||||
state[9] = inv_sbox[state[5]];
|
||||
state[5] = inv_sbox[state[1]];
|
||||
state[1] = tmp;
|
||||
|
||||
/* restore row 2 */
|
||||
tmp = inv_sbox[state[2]];
|
||||
state[2] = inv_sbox[state[10]];
|
||||
state[10] = tmp;
|
||||
tmp = inv_sbox[state[6]];
|
||||
state[6] = inv_sbox[state[14]];
|
||||
state[14] = tmp;
|
||||
|
||||
/* restore row 3 */
|
||||
tmp = inv_sbox[state[3]];
|
||||
state[3] = inv_sbox[state[7]];
|
||||
state[7] = inv_sbox[state[11]];
|
||||
state[11] = inv_sbox[state[15]];
|
||||
state[15] = tmp;
|
||||
}
|
||||
|
||||
/* recombine and mix each row in a column */
|
||||
static void mix_sub_columns(u8 *state)
|
||||
{
|
||||
u8 tmp[4 * AES_STATECOLS];
|
||||
|
||||
/* mixing column 0 */
|
||||
tmp[0] = x2_sbox[state[0]] ^ x3_sbox[state[5]] ^
|
||||
sbox[state[10]] ^ sbox[state[15]];
|
||||
tmp[1] = sbox[state[0]] ^ x2_sbox[state[5]] ^
|
||||
x3_sbox[state[10]] ^ sbox[state[15]];
|
||||
tmp[2] = sbox[state[0]] ^ sbox[state[5]] ^
|
||||
x2_sbox[state[10]] ^ x3_sbox[state[15]];
|
||||
tmp[3] = x3_sbox[state[0]] ^ sbox[state[5]] ^
|
||||
sbox[state[10]] ^ x2_sbox[state[15]];
|
||||
|
||||
/* mixing column 1 */
|
||||
tmp[4] = x2_sbox[state[4]] ^ x3_sbox[state[9]] ^
|
||||
sbox[state[14]] ^ sbox[state[3]];
|
||||
tmp[5] = sbox[state[4]] ^ x2_sbox[state[9]] ^
|
||||
x3_sbox[state[14]] ^ sbox[state[3]];
|
||||
tmp[6] = sbox[state[4]] ^ sbox[state[9]] ^
|
||||
x2_sbox[state[14]] ^ x3_sbox[state[3]];
|
||||
tmp[7] = x3_sbox[state[4]] ^ sbox[state[9]] ^
|
||||
sbox[state[14]] ^ x2_sbox[state[3]];
|
||||
|
||||
/* mixing column 2 */
|
||||
tmp[8] = x2_sbox[state[8]] ^ x3_sbox[state[13]] ^
|
||||
sbox[state[2]] ^ sbox[state[7]];
|
||||
tmp[9] = sbox[state[8]] ^ x2_sbox[state[13]] ^
|
||||
x3_sbox[state[2]] ^ sbox[state[7]];
|
||||
tmp[10] = sbox[state[8]] ^ sbox[state[13]] ^
|
||||
x2_sbox[state[2]] ^ x3_sbox[state[7]];
|
||||
tmp[11] = x3_sbox[state[8]] ^ sbox[state[13]] ^
|
||||
sbox[state[2]] ^ x2_sbox[state[7]];
|
||||
|
||||
/* mixing column 3 */
|
||||
tmp[12] = x2_sbox[state[12]] ^ x3_sbox[state[1]] ^
|
||||
sbox[state[6]] ^ sbox[state[11]];
|
||||
tmp[13] = sbox[state[12]] ^ x2_sbox[state[1]] ^
|
||||
x3_sbox[state[6]] ^ sbox[state[11]];
|
||||
tmp[14] = sbox[state[12]] ^ sbox[state[1]] ^
|
||||
x2_sbox[state[6]] ^ x3_sbox[state[11]];
|
||||
tmp[15] = x3_sbox[state[12]] ^ sbox[state[1]] ^
|
||||
sbox[state[6]] ^ x2_sbox[state[11]];
|
||||
|
||||
memcpy(state, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
/* restore and un-mix each row in a column */
|
||||
static void inv_mix_sub_columns(u8 *state)
|
||||
{
|
||||
u8 tmp[4 * AES_STATECOLS];
|
||||
int i;
|
||||
|
||||
/* restore column 0 */
|
||||
tmp[0] = x_time_e[state[0]] ^ x_time_b[state[1]] ^
|
||||
x_time_d[state[2]] ^ x_time_9[state[3]];
|
||||
tmp[5] = x_time_9[state[0]] ^ x_time_e[state[1]] ^
|
||||
x_time_b[state[2]] ^ x_time_d[state[3]];
|
||||
tmp[10] = x_time_d[state[0]] ^ x_time_9[state[1]] ^
|
||||
x_time_e[state[2]] ^ x_time_b[state[3]];
|
||||
tmp[15] = x_time_b[state[0]] ^ x_time_d[state[1]] ^
|
||||
x_time_9[state[2]] ^ x_time_e[state[3]];
|
||||
|
||||
/* restore column 1 */
|
||||
tmp[4] = x_time_e[state[4]] ^ x_time_b[state[5]] ^
|
||||
x_time_d[state[6]] ^ x_time_9[state[7]];
|
||||
tmp[9] = x_time_9[state[4]] ^ x_time_e[state[5]] ^
|
||||
x_time_b[state[6]] ^ x_time_d[state[7]];
|
||||
tmp[14] = x_time_d[state[4]] ^ x_time_9[state[5]] ^
|
||||
x_time_e[state[6]] ^ x_time_b[state[7]];
|
||||
tmp[3] = x_time_b[state[4]] ^ x_time_d[state[5]] ^
|
||||
x_time_9[state[6]] ^ x_time_e[state[7]];
|
||||
|
||||
/* restore column 2 */
|
||||
tmp[8] = x_time_e[state[8]] ^ x_time_b[state[9]] ^
|
||||
x_time_d[state[10]] ^ x_time_9[state[11]];
|
||||
tmp[13] = x_time_9[state[8]] ^ x_time_e[state[9]] ^
|
||||
x_time_b[state[10]] ^ x_time_d[state[11]];
|
||||
tmp[2] = x_time_d[state[8]] ^ x_time_9[state[9]] ^
|
||||
x_time_e[state[10]] ^ x_time_b[state[11]];
|
||||
tmp[7] = x_time_b[state[8]] ^ x_time_d[state[9]] ^
|
||||
x_time_9[state[10]] ^ x_time_e[state[11]];
|
||||
|
||||
/* restore column 3 */
|
||||
tmp[12] = x_time_e[state[12]] ^ x_time_b[state[13]] ^
|
||||
x_time_d[state[14]] ^ x_time_9[state[15]];
|
||||
tmp[1] = x_time_9[state[12]] ^ x_time_e[state[13]] ^
|
||||
x_time_b[state[14]] ^ x_time_d[state[15]];
|
||||
tmp[6] = x_time_d[state[12]] ^ x_time_9[state[13]] ^
|
||||
x_time_e[state[14]] ^ x_time_b[state[15]];
|
||||
tmp[11] = x_time_b[state[12]] ^ x_time_d[state[13]] ^
|
||||
x_time_9[state[14]] ^ x_time_e[state[15]];
|
||||
|
||||
for (i = 0; i < 4 * AES_STATECOLS; i++)
|
||||
state[i] = inv_sbox[tmp[i]];
|
||||
}
|
||||
|
||||
/*
|
||||
* encrypt/decrypt columns of the key
|
||||
* n.b. you can replace this with byte-wise xor if you wish.
|
||||
*/
|
||||
static void add_round_key(u32 *state, u32 *key)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < 4; idx++)
|
||||
state[idx] ^= key[idx];
|
||||
}
|
||||
|
||||
static u8 rcon[11] = {
|
||||
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
|
||||
};
|
||||
|
||||
/* produce AES_STATECOLS bytes for each round */
|
||||
void aes_expand_key(u8 *key, u8 *expkey)
|
||||
{
|
||||
u8 tmp0, tmp1, tmp2, tmp3, tmp4;
|
||||
u32 idx;
|
||||
|
||||
memcpy(expkey, key, AES_KEYCOLS * 4);
|
||||
|
||||
for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
|
||||
tmp0 = expkey[4*idx - 4];
|
||||
tmp1 = expkey[4*idx - 3];
|
||||
tmp2 = expkey[4*idx - 2];
|
||||
tmp3 = expkey[4*idx - 1];
|
||||
if (!(idx % AES_KEYCOLS)) {
|
||||
tmp4 = tmp3;
|
||||
tmp3 = sbox[tmp0];
|
||||
tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
|
||||
tmp1 = sbox[tmp2];
|
||||
tmp2 = sbox[tmp4];
|
||||
} else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
|
||||
tmp0 = sbox[tmp0];
|
||||
tmp1 = sbox[tmp1];
|
||||
tmp2 = sbox[tmp2];
|
||||
tmp3 = sbox[tmp3];
|
||||
}
|
||||
|
||||
expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
|
||||
expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
|
||||
expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
|
||||
expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt one 128 bit block */
|
||||
void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
|
||||
{
|
||||
u8 state[AES_STATECOLS * 4];
|
||||
u32 round;
|
||||
|
||||
memcpy(state, in, AES_STATECOLS * 4);
|
||||
add_round_key((u32 *)state, (u32 *)expkey);
|
||||
|
||||
for (round = 1; round < AES_ROUNDS + 1; round++) {
|
||||
if (round < AES_ROUNDS)
|
||||
mix_sub_columns(state);
|
||||
else
|
||||
shift_rows(state);
|
||||
|
||||
add_round_key((u32 *)state,
|
||||
(u32 *)expkey + round * AES_STATECOLS);
|
||||
}
|
||||
|
||||
memcpy(out, state, sizeof(state));
|
||||
}
|
||||
|
||||
void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
|
||||
{
|
||||
u8 state[AES_STATECOLS * 4];
|
||||
int round;
|
||||
|
||||
memcpy(state, in, sizeof(state));
|
||||
|
||||
add_round_key((u32 *)state,
|
||||
(u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
|
||||
inv_shift_rows(state);
|
||||
|
||||
for (round = AES_ROUNDS; round--; ) {
|
||||
add_round_key((u32 *)state,
|
||||
(u32 *)expkey + round * AES_STATECOLS);
|
||||
if (round)
|
||||
inv_mix_sub_columns(state);
|
||||
}
|
||||
|
||||
memcpy(out, state, sizeof(state));
|
||||
}
|
||||
32
common/package/utils/sysupgrade-helper/src/lib/asm-offsets.c
Normal file
32
common/package/utils/sysupgrade-helper/src/lib/asm-offsets.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c
|
||||
*
|
||||
* This program is used to generate definitions needed by
|
||||
* assembly language modules.
|
||||
*
|
||||
* We use the technique used in the OSF Mach kernel code:
|
||||
* generate asm statements containing #defines,
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <linux/kbuild.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Round up to make sure size gives nice stack alignment */
|
||||
DEFINE(GENERATED_GBL_DATA_SIZE,
|
||||
(sizeof(struct global_data) + 15) & ~15);
|
||||
|
||||
DEFINE(GENERATED_BD_INFO_SIZE,
|
||||
(sizeof(struct bd_info) + 15) & ~15);
|
||||
|
||||
return 0;
|
||||
}
|
||||
1358
common/package/utils/sysupgrade-helper/src/lib/bch.c
Normal file
1358
common/package/utils/sysupgrade-helper/src/lib/bch.c
Normal file
File diff suppressed because it is too large
Load diff
1601
common/package/utils/sysupgrade-helper/src/lib/bzlib.c
Normal file
1601
common/package/utils/sysupgrade-helper/src/lib/bzlib.c
Normal file
File diff suppressed because it is too large
Load diff
145
common/package/utils/sysupgrade-helper/src/lib/bzlib_crctable.c
Normal file
145
common/package/utils/sysupgrade-helper/src/lib/bzlib_crctable.c
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#include <config.h>
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for doing CRCs ---*/
|
||||
/*--- crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*--
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
David Wheeler
|
||||
Peter Fenwick
|
||||
Alistair Moffat
|
||||
Radford Neal
|
||||
Ian H. Witten
|
||||
Robert Sedgewick
|
||||
Jon L. Bentley
|
||||
|
||||
For more information on these sources, see the manual.
|
||||
--*/
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*--
|
||||
I think this is an implementation of the AUTODIN-II,
|
||||
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
|
||||
from code by Rob Warnock, in Section 51 of the
|
||||
comp.compression FAQ.
|
||||
--*/
|
||||
|
||||
UInt32 BZ2_crc32Table[256] = {
|
||||
|
||||
/*-- Ugly, innit? --*/
|
||||
|
||||
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
|
||||
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
|
||||
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
|
||||
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
|
||||
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
|
||||
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
|
||||
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
|
||||
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
|
||||
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
|
||||
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
|
||||
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
|
||||
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
|
||||
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
|
||||
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
|
||||
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
|
||||
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
|
||||
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
|
||||
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
|
||||
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
|
||||
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
|
||||
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
|
||||
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
|
||||
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
|
||||
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
|
||||
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
|
||||
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
|
||||
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
|
||||
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
|
||||
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
|
||||
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
|
||||
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
|
||||
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
|
||||
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
|
||||
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
|
||||
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
|
||||
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
|
||||
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
|
||||
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
|
||||
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
|
||||
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
|
||||
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
|
||||
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
|
||||
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
|
||||
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
|
||||
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
|
||||
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
|
||||
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
|
||||
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
|
||||
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
|
||||
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
|
||||
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
|
||||
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
|
||||
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
|
||||
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
|
||||
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
|
||||
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
|
||||
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
|
||||
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
|
||||
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
|
||||
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
|
||||
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
|
||||
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
|
||||
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
|
||||
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
|
@ -0,0 +1,674 @@
|
|||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Decompression machinery ---*/
|
||||
/*--- decompress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*--
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
David Wheeler
|
||||
Peter Fenwick
|
||||
Alistair Moffat
|
||||
Radford Neal
|
||||
Ian H. Witten
|
||||
Robert Sedgewick
|
||||
Jon L. Bentley
|
||||
|
||||
For more information on these sources, see the manual.
|
||||
--*/
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void makeMaps_d ( DState* s )
|
||||
{
|
||||
Int32 i;
|
||||
s->nInUse = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (s->inUse[i]) {
|
||||
s->seqToUnseq[s->nInUse] = i;
|
||||
s->nInUse++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define RETURN(rrr) \
|
||||
{ retVal = rrr; goto save_state_and_return; };
|
||||
|
||||
#define GET_BITS(lll,vvv,nnn) \
|
||||
case lll: s->state = lll; \
|
||||
while (True) { \
|
||||
if (s->bsLive >= nnn) { \
|
||||
UInt32 v; \
|
||||
v = (s->bsBuff >> \
|
||||
(s->bsLive-nnn)) & ((1 << nnn)-1); \
|
||||
s->bsLive -= nnn; \
|
||||
vvv = v; \
|
||||
break; \
|
||||
} \
|
||||
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
|
||||
s->bsBuff \
|
||||
= (s->bsBuff << 8) | \
|
||||
((UInt32) \
|
||||
(*((UChar*)(s->strm->next_in)))); \
|
||||
s->bsLive += 8; \
|
||||
s->strm->next_in++; \
|
||||
s->strm->avail_in--; \
|
||||
s->strm->total_in_lo32++; \
|
||||
if (s->strm->total_in_lo32 == 0) \
|
||||
s->strm->total_in_hi32++; \
|
||||
}
|
||||
|
||||
#define GET_UCHAR(lll,uuu) \
|
||||
GET_BITS(lll,uuu,8)
|
||||
|
||||
#define GET_BIT(lll,uuu) \
|
||||
GET_BITS(lll,uuu,1)
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define GET_MTF_VAL(label1,label2,lval) \
|
||||
{ \
|
||||
if (groupPos == 0) { \
|
||||
groupNo++; \
|
||||
if (groupNo >= nSelectors) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
groupPos = BZ_G_SIZE; \
|
||||
gSel = s->selector[groupNo]; \
|
||||
gMinlen = s->minLens[gSel]; \
|
||||
gLimit = &(s->limit[gSel][0]); \
|
||||
gPerm = &(s->perm[gSel][0]); \
|
||||
gBase = &(s->base[gSel][0]); \
|
||||
} \
|
||||
groupPos--; \
|
||||
zn = gMinlen; \
|
||||
GET_BITS(label1, zvec, zn); \
|
||||
while (1) { \
|
||||
if (zn > 20 /* the longest code */) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
if (zvec <= gLimit[zn]) break; \
|
||||
zn++; \
|
||||
GET_BIT(label2, zj); \
|
||||
zvec = (zvec << 1) | zj; \
|
||||
}; \
|
||||
if (zvec - gBase[zn] < 0 \
|
||||
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
lval = gPerm[zvec - gBase[zn]]; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
Int32 BZ2_decompress ( DState* s )
|
||||
{
|
||||
UChar uc;
|
||||
Int32 retVal;
|
||||
Int32 minLen, maxLen;
|
||||
bz_stream* strm = s->strm;
|
||||
|
||||
/* stuff that needs to be saved/restored */
|
||||
Int32 i;
|
||||
Int32 j;
|
||||
Int32 t;
|
||||
Int32 alphaSize;
|
||||
Int32 nGroups;
|
||||
Int32 nSelectors;
|
||||
Int32 EOB;
|
||||
Int32 groupNo;
|
||||
Int32 groupPos;
|
||||
Int32 nextSym;
|
||||
Int32 nblockMAX;
|
||||
Int32 nblock;
|
||||
Int32 es;
|
||||
Int32 N;
|
||||
Int32 curr;
|
||||
Int32 zt;
|
||||
Int32 zn;
|
||||
Int32 zvec;
|
||||
Int32 zj;
|
||||
Int32 gSel;
|
||||
Int32 gMinlen;
|
||||
Int32* gLimit;
|
||||
Int32* gBase;
|
||||
Int32* gPerm;
|
||||
|
||||
if (s->state == BZ_X_MAGIC_1) {
|
||||
/*initialise the save area*/
|
||||
s->save_i = 0;
|
||||
s->save_j = 0;
|
||||
s->save_t = 0;
|
||||
s->save_alphaSize = 0;
|
||||
s->save_nGroups = 0;
|
||||
s->save_nSelectors = 0;
|
||||
s->save_EOB = 0;
|
||||
s->save_groupNo = 0;
|
||||
s->save_groupPos = 0;
|
||||
s->save_nextSym = 0;
|
||||
s->save_nblockMAX = 0;
|
||||
s->save_nblock = 0;
|
||||
s->save_es = 0;
|
||||
s->save_N = 0;
|
||||
s->save_curr = 0;
|
||||
s->save_zt = 0;
|
||||
s->save_zn = 0;
|
||||
s->save_zvec = 0;
|
||||
s->save_zj = 0;
|
||||
s->save_gSel = 0;
|
||||
s->save_gMinlen = 0;
|
||||
s->save_gLimit = NULL;
|
||||
s->save_gBase = NULL;
|
||||
s->save_gPerm = NULL;
|
||||
}
|
||||
|
||||
/*restore from the save area*/
|
||||
i = s->save_i;
|
||||
j = s->save_j;
|
||||
t = s->save_t;
|
||||
alphaSize = s->save_alphaSize;
|
||||
nGroups = s->save_nGroups;
|
||||
nSelectors = s->save_nSelectors;
|
||||
EOB = s->save_EOB;
|
||||
groupNo = s->save_groupNo;
|
||||
groupPos = s->save_groupPos;
|
||||
nextSym = s->save_nextSym;
|
||||
nblockMAX = s->save_nblockMAX;
|
||||
nblock = s->save_nblock;
|
||||
es = s->save_es;
|
||||
N = s->save_N;
|
||||
curr = s->save_curr;
|
||||
zt = s->save_zt;
|
||||
zn = s->save_zn;
|
||||
zvec = s->save_zvec;
|
||||
zj = s->save_zj;
|
||||
gSel = s->save_gSel;
|
||||
gMinlen = s->save_gMinlen;
|
||||
gLimit = s->save_gLimit;
|
||||
gBase = s->save_gBase;
|
||||
gPerm = s->save_gPerm;
|
||||
|
||||
retVal = BZ_OK;
|
||||
|
||||
switch (s->state) {
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_1, uc);
|
||||
if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_2, uc);
|
||||
if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_3, uc)
|
||||
if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
|
||||
if (s->blockSize100k < (BZ_HDR_0 + 1) ||
|
||||
s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
s->blockSize100k -= BZ_HDR_0;
|
||||
|
||||
if (s->smallDecompress) {
|
||||
s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
|
||||
s->ll4 = BZALLOC(
|
||||
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
|
||||
);
|
||||
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
|
||||
} else {
|
||||
s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
|
||||
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
|
||||
}
|
||||
|
||||
GET_UCHAR(BZ_X_BLKHDR_1, uc);
|
||||
|
||||
if (uc == 0x17) goto endhdr_2;
|
||||
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_2, uc);
|
||||
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_3, uc);
|
||||
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_4, uc);
|
||||
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_5, uc);
|
||||
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_6, uc);
|
||||
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->currBlockNo++;
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
|
||||
|
||||
s->storedBlockCRC = 0;
|
||||
GET_UCHAR(BZ_X_BCRC_1, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_2, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_3, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_4, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
|
||||
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
|
||||
|
||||
s->origPtr = 0;
|
||||
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
|
||||
if (s->origPtr < 0)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
if (s->origPtr > 10 + 100000*s->blockSize100k)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*--- Receive the mapping table ---*/
|
||||
for (i = 0; i < 16; i++) {
|
||||
GET_BIT(BZ_X_MAPPING_1, uc);
|
||||
if (uc == 1)
|
||||
s->inUse16[i] = True; else
|
||||
s->inUse16[i] = False;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) s->inUse[i] = False;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (s->inUse16[i])
|
||||
for (j = 0; j < 16; j++) {
|
||||
GET_BIT(BZ_X_MAPPING_2, uc);
|
||||
if (uc == 1) s->inUse[i * 16 + j] = True;
|
||||
}
|
||||
makeMaps_d ( s );
|
||||
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
|
||||
alphaSize = s->nInUse+2;
|
||||
|
||||
/*--- Now the selectors ---*/
|
||||
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
|
||||
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
|
||||
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
|
||||
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
j = 0;
|
||||
while (True) {
|
||||
GET_BIT(BZ_X_SELECTOR_3, uc);
|
||||
if (uc == 0) break;
|
||||
j++;
|
||||
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
|
||||
/*--- Undo the MTF values for the selectors. ---*/
|
||||
{
|
||||
UChar pos[BZ_N_GROUPS], tmp, v;
|
||||
for (v = 0; v < nGroups; v++) pos[v] = v;
|
||||
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
v = s->selectorMtf[i];
|
||||
tmp = pos[v];
|
||||
while (v > 0) { pos[v] = pos[v-1]; v--; }
|
||||
pos[0] = tmp;
|
||||
s->selector[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Now the coding tables ---*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
GET_BITS(BZ_X_CODING_1, curr, 5);
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
while (True) {
|
||||
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
|
||||
GET_BIT(BZ_X_CODING_2, uc);
|
||||
if (uc == 0) break;
|
||||
GET_BIT(BZ_X_CODING_3, uc);
|
||||
if (uc == 0) curr++; else curr--;
|
||||
}
|
||||
s->len[t][i] = curr;
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Create the Huffman decoding tables ---*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
minLen = 32;
|
||||
maxLen = 0;
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
BZ2_hbCreateDecodeTables (
|
||||
&(s->limit[t][0]),
|
||||
&(s->base[t][0]),
|
||||
&(s->perm[t][0]),
|
||||
&(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize
|
||||
);
|
||||
s->minLens[t] = minLen;
|
||||
}
|
||||
|
||||
/*--- Now the MTF values ---*/
|
||||
|
||||
EOB = s->nInUse+1;
|
||||
nblockMAX = 100000 * s->blockSize100k;
|
||||
groupNo = -1;
|
||||
groupPos = 0;
|
||||
|
||||
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
|
||||
|
||||
/*-- MTF init --*/
|
||||
{
|
||||
Int32 ii, jj, kk;
|
||||
kk = MTFA_SIZE-1;
|
||||
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
|
||||
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
|
||||
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
|
||||
kk--;
|
||||
}
|
||||
s->mtfbase[ii] = kk + 1;
|
||||
}
|
||||
}
|
||||
/*-- end MTF init --*/
|
||||
|
||||
nblock = 0;
|
||||
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
|
||||
|
||||
while (True) {
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
WATCHDOG_RESET();
|
||||
#endif
|
||||
if (nextSym == EOB) break;
|
||||
|
||||
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
|
||||
|
||||
es = -1;
|
||||
N = 1;
|
||||
do {
|
||||
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
|
||||
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
|
||||
N = N * 2;
|
||||
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
|
||||
}
|
||||
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
|
||||
|
||||
es++;
|
||||
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
|
||||
s->unzftab[uc] += es;
|
||||
|
||||
if (s->smallDecompress)
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->ll16[nblock] = (UInt16)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
}
|
||||
else
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->tt[nblock] = (UInt32)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
};
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*-- uc = MTF ( nextSym-1 ) --*/
|
||||
{
|
||||
Int32 ii, jj, kk, pp, lno, off;
|
||||
UInt32 nn;
|
||||
nn = (UInt32)(nextSym - 1);
|
||||
|
||||
if (nn < MTFL_SIZE) {
|
||||
/* avoid general-case expense */
|
||||
pp = s->mtfbase[0];
|
||||
uc = s->mtfa[pp+nn];
|
||||
while (nn > 3) {
|
||||
Int32 z = pp+nn;
|
||||
s->mtfa[(z) ] = s->mtfa[(z)-1];
|
||||
s->mtfa[(z)-1] = s->mtfa[(z)-2];
|
||||
s->mtfa[(z)-2] = s->mtfa[(z)-3];
|
||||
s->mtfa[(z)-3] = s->mtfa[(z)-4];
|
||||
nn -= 4;
|
||||
}
|
||||
while (nn > 0) {
|
||||
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
|
||||
};
|
||||
s->mtfa[pp] = uc;
|
||||
} else {
|
||||
/* general case */
|
||||
lno = nn / MTFL_SIZE;
|
||||
off = nn % MTFL_SIZE;
|
||||
pp = s->mtfbase[lno] + off;
|
||||
uc = s->mtfa[pp];
|
||||
while (pp > s->mtfbase[lno]) {
|
||||
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
|
||||
};
|
||||
s->mtfbase[lno]++;
|
||||
while (lno > 0) {
|
||||
s->mtfbase[lno]--;
|
||||
s->mtfa[s->mtfbase[lno]]
|
||||
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
|
||||
lno--;
|
||||
}
|
||||
s->mtfbase[0]--;
|
||||
s->mtfa[s->mtfbase[0]] = uc;
|
||||
if (s->mtfbase[0] == 0) {
|
||||
kk = MTFA_SIZE-1;
|
||||
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
WATCHDOG_RESET();
|
||||
#endif
|
||||
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
|
||||
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
|
||||
kk--;
|
||||
}
|
||||
s->mtfbase[ii] = kk + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-- end uc = MTF ( nextSym-1 ) --*/
|
||||
|
||||
s->unzftab[s->seqToUnseq[uc]]++;
|
||||
if (s->smallDecompress)
|
||||
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
|
||||
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
|
||||
nblock++;
|
||||
|
||||
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we know what nblock is, we can do a better sanity
|
||||
check on s->origPtr.
|
||||
*/
|
||||
if (s->origPtr < 0 || s->origPtr >= nblock)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->state_out_len = 0;
|
||||
s->state_out_ch = 0;
|
||||
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
|
||||
s->state = BZ_X_OUTPUT;
|
||||
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
|
||||
|
||||
/*-- Set up cftab to facilitate generation of T^(-1) --*/
|
||||
s->cftab[0] = 0;
|
||||
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
|
||||
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
|
||||
|
||||
if (s->smallDecompress) {
|
||||
|
||||
/*-- Make a copy of cftab, used in generation of T --*/
|
||||
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
|
||||
|
||||
/*-- compute the T vector --*/
|
||||
for (i = 0; i < nblock; i++) {
|
||||
uc = (UChar)(s->ll16[i]);
|
||||
SET_LL(i, s->cftabCopy[uc]);
|
||||
s->cftabCopy[uc]++;
|
||||
}
|
||||
|
||||
/*-- Compute T^(-1) by pointer reversal on T --*/
|
||||
i = s->origPtr;
|
||||
j = GET_LL(i);
|
||||
do {
|
||||
Int32 tmp = GET_LL(j);
|
||||
SET_LL(j, i);
|
||||
i = j;
|
||||
j = tmp;
|
||||
}
|
||||
while (i != s->origPtr);
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
WATCHDOG_RESET();
|
||||
#endif
|
||||
s->tPos = s->origPtr;
|
||||
s->nblock_used = 0;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_SMALL(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
BZ_GET_SMALL(s->k0); s->nblock_used++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
WATCHDOG_RESET();
|
||||
#endif
|
||||
/*-- compute the T^(-1) vector --*/
|
||||
for (i = 0; i < nblock; i++) {
|
||||
uc = (UChar)(s->tt[i] & 0xff);
|
||||
s->tt[s->cftab[uc]] |= (i << 8);
|
||||
s->cftab[uc]++;
|
||||
}
|
||||
|
||||
s->tPos = s->tt[s->origPtr] >> 8;
|
||||
s->nblock_used = 0;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_FAST(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
BZ_GET_FAST(s->k0); s->nblock_used++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RETURN(BZ_OK);
|
||||
|
||||
|
||||
endhdr_2:
|
||||
|
||||
GET_UCHAR(BZ_X_ENDHDR_2, uc);
|
||||
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_3, uc);
|
||||
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_4, uc);
|
||||
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_5, uc);
|
||||
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_6, uc);
|
||||
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->storedCombinedCRC = 0;
|
||||
GET_UCHAR(BZ_X_CCRC_1, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_2, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_3, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_4, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
|
||||
s->state = BZ_X_IDLE;
|
||||
RETURN(BZ_STREAM_END);
|
||||
|
||||
default: AssertH ( False, 4001 );
|
||||
}
|
||||
|
||||
AssertH ( False, 4002 );
|
||||
|
||||
save_state_and_return:
|
||||
|
||||
s->save_i = i;
|
||||
s->save_j = j;
|
||||
s->save_t = t;
|
||||
s->save_alphaSize = alphaSize;
|
||||
s->save_nGroups = nGroups;
|
||||
s->save_nSelectors = nSelectors;
|
||||
s->save_EOB = EOB;
|
||||
s->save_groupNo = groupNo;
|
||||
s->save_groupPos = groupPos;
|
||||
s->save_nextSym = nextSym;
|
||||
s->save_nblockMAX = nblockMAX;
|
||||
s->save_nblock = nblock;
|
||||
s->save_es = es;
|
||||
s->save_N = N;
|
||||
s->save_curr = curr;
|
||||
s->save_zt = zt;
|
||||
s->save_zn = zn;
|
||||
s->save_zvec = zvec;
|
||||
s->save_zj = zj;
|
||||
s->save_gSel = gSel;
|
||||
s->save_gMinlen = gMinlen;
|
||||
s->save_gLimit = gLimit;
|
||||
s->save_gBase = gBase;
|
||||
s->save_gPerm = gPerm;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end decompress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
229
common/package/utils/sysupgrade-helper/src/lib/bzlib_huffman.c
Normal file
229
common/package/utils/sysupgrade-helper/src/lib/bzlib_huffman.c
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
#include <config.h>
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Huffman coding low-level stuff ---*/
|
||||
/*--- huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*--
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
David Wheeler
|
||||
Peter Fenwick
|
||||
Alistair Moffat
|
||||
Radford Neal
|
||||
Ian H. Witten
|
||||
Robert Sedgewick
|
||||
Jon L. Bentley
|
||||
|
||||
For more information on these sources, see the manual.
|
||||
--*/
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
|
||||
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
|
||||
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
|
||||
|
||||
#define ADDWEIGHTS(zw1,zw2) \
|
||||
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
|
||||
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
|
||||
|
||||
#define UPHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (weight[tmp] < weight[heap[zz >> 1]]) { \
|
||||
heap[zz] = heap[zz >> 1]; \
|
||||
zz >>= 1; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
#define DOWNHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, yy, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (True) { \
|
||||
yy = zz << 1; \
|
||||
if (yy > nHeap) break; \
|
||||
if (yy < nHeap && \
|
||||
weight[heap[yy+1]] < weight[heap[yy]]) \
|
||||
yy++; \
|
||||
if (weight[tmp] < weight[heap[yy]]) break; \
|
||||
heap[zz] = heap[yy]; \
|
||||
zz = yy; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbMakeCodeLengths ( UChar *len,
|
||||
Int32 *freq,
|
||||
Int32 alphaSize,
|
||||
Int32 maxLen )
|
||||
{
|
||||
/*--
|
||||
Nodes and heap entries run from 1. Entry 0
|
||||
for both the heap and nodes is a sentinel.
|
||||
--*/
|
||||
Int32 nNodes, nHeap, n1, n2, i, j, k;
|
||||
Bool tooLong;
|
||||
|
||||
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
|
||||
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
|
||||
|
||||
while (True) {
|
||||
|
||||
nNodes = alphaSize;
|
||||
nHeap = 0;
|
||||
|
||||
heap[0] = 0;
|
||||
weight[0] = 0;
|
||||
parent[0] = -2;
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
parent[i] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = i;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
|
||||
|
||||
while (nHeap > 1) {
|
||||
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
nNodes++;
|
||||
parent[n1] = parent[n2] = nNodes;
|
||||
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
|
||||
parent[nNodes] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = nNodes;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
|
||||
|
||||
tooLong = False;
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = 0;
|
||||
k = i;
|
||||
while (parent[k] >= 0) { k = parent[k]; j++; }
|
||||
len[i-1] = j;
|
||||
if (j > maxLen) tooLong = True;
|
||||
}
|
||||
|
||||
if (! tooLong) break;
|
||||
|
||||
for (i = 1; i < alphaSize; i++) {
|
||||
j = weight[i] >> 8;
|
||||
j = 1 + (j / 2);
|
||||
weight[i] = j << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbAssignCodes ( Int32 *code,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 n, vec, i;
|
||||
|
||||
vec = 0;
|
||||
for (n = minLen; n <= maxLen; n++) {
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
if (length[i] == n) { code[i] = vec; vec++; };
|
||||
vec <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbCreateDecodeTables ( Int32 *limit,
|
||||
Int32 *base,
|
||||
Int32 *perm,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 pp, i, j, vec;
|
||||
|
||||
pp = 0;
|
||||
for (i = minLen; i <= maxLen; i++)
|
||||
for (j = 0; j < alphaSize; j++)
|
||||
if (length[j] == i) { perm[pp] = j; pp++; };
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
|
||||
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
|
||||
|
||||
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
|
||||
vec = 0;
|
||||
|
||||
for (i = minLen; i <= maxLen; i++) {
|
||||
vec += (base[i+1] - base[i]);
|
||||
limit[i] = vec-1;
|
||||
vec <<= 1;
|
||||
}
|
||||
for (i = minLen + 1; i <= maxLen; i++)
|
||||
base[i] = ((limit[i-1] + 1) << 1) - base[i];
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
530
common/package/utils/sysupgrade-helper/src/lib/bzlib_private.h
Normal file
530
common/package/utils/sysupgrade-helper/src/lib/bzlib_private.h
Normal file
|
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
* This file is a modified version of bzlib_private.h from the bzip2-1.0.2
|
||||
* distribution which can be found at http://sources.redhat.com/bzip2/
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Private header file for the library. ---*/
|
||||
/*--- bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*--
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
David Wheeler
|
||||
Peter Fenwick
|
||||
Alistair Moffat
|
||||
Radford Neal
|
||||
Ian H. Witten
|
||||
Robert Sedgewick
|
||||
Jon L. Bentley
|
||||
|
||||
For more information on these sources, see the manual.
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef _BZLIB_PRIVATE_H
|
||||
#define _BZLIB_PRIVATE_H
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*-- General stuff. --*/
|
||||
|
||||
#define BZ_VERSION "1.0.2, 30-Dec-2001"
|
||||
|
||||
typedef char Char;
|
||||
typedef unsigned char Bool;
|
||||
typedef unsigned char UChar;
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#define True ((Bool)1)
|
||||
#define False ((Bool)0)
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __inline__ /* */
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
extern void BZ2_bz__AssertH__fail ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
|
||||
#if BZ_DEBUG
|
||||
#define AssertD(cond,msg) \
|
||||
{ if (!(cond)) { \
|
||||
fprintf ( stderr, \
|
||||
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
|
||||
exit(1); \
|
||||
}}
|
||||
#else
|
||||
#define AssertD(cond,msg) /* */
|
||||
#endif
|
||||
#define VPrintf0(zf) \
|
||||
fprintf(stderr,zf)
|
||||
#define VPrintf1(zf,za1) \
|
||||
fprintf(stderr,zf,za1)
|
||||
#define VPrintf2(zf,za1,za2) \
|
||||
fprintf(stderr,zf,za1,za2)
|
||||
#define VPrintf3(zf,za1,za2,za3) \
|
||||
fprintf(stderr,zf,za1,za2,za3)
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4)
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4,za5)
|
||||
#else
|
||||
extern void bz_internal_error ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) bz_internal_error ( errcode ); }
|
||||
#define AssertD(cond,msg) /* */
|
||||
#define VPrintf0(zf) /* */
|
||||
#define VPrintf1(zf,za1) /* */
|
||||
#define VPrintf2(zf,za1,za2) /* */
|
||||
#define VPrintf3(zf,za1,za2,za3) /* */
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) /* */
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) /* */
|
||||
#endif
|
||||
|
||||
|
||||
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
|
||||
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
|
||||
|
||||
|
||||
/*-- Header bytes. --*/
|
||||
|
||||
#define BZ_HDR_B 0x42 /* 'B' */
|
||||
#define BZ_HDR_Z 0x5a /* 'Z' */
|
||||
#define BZ_HDR_h 0x68 /* 'h' */
|
||||
#define BZ_HDR_0 0x30 /* '0' */
|
||||
|
||||
/*-- Constants for the back end. --*/
|
||||
|
||||
#define BZ_MAX_ALPHA_SIZE 258
|
||||
#define BZ_MAX_CODE_LEN 23
|
||||
|
||||
#define BZ_RUNA 0
|
||||
#define BZ_RUNB 1
|
||||
|
||||
#define BZ_N_GROUPS 6
|
||||
#define BZ_G_SIZE 50
|
||||
#define BZ_N_ITERS 4
|
||||
|
||||
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
|
||||
|
||||
|
||||
/*-- Stuff for randomising repetitive blocks. --*/
|
||||
|
||||
extern Int32 BZ2_rNums[512];
|
||||
|
||||
#define BZ_RAND_DECLS \
|
||||
Int32 rNToGo; \
|
||||
Int32 rTPos \
|
||||
|
||||
#define BZ_RAND_INIT_MASK \
|
||||
s->rNToGo = 0; \
|
||||
s->rTPos = 0 \
|
||||
|
||||
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
|
||||
|
||||
#define BZ_RAND_UPD_MASK \
|
||||
if (s->rNToGo == 0) { \
|
||||
s->rNToGo = BZ2_rNums[s->rTPos]; \
|
||||
s->rTPos++; \
|
||||
if (s->rTPos == 512) s->rTPos = 0; \
|
||||
} \
|
||||
s->rNToGo--;
|
||||
|
||||
|
||||
/*-- Stuff for doing CRCs. --*/
|
||||
|
||||
extern UInt32 BZ2_crc32Table[256];
|
||||
|
||||
#define BZ_INITIALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = 0xffffffffL; \
|
||||
}
|
||||
|
||||
#define BZ_FINALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = ~(crcVar); \
|
||||
}
|
||||
|
||||
#define BZ_UPDATE_CRC(crcVar,cha) \
|
||||
{ \
|
||||
crcVar = (crcVar << 8) ^ \
|
||||
BZ2_crc32Table[(crcVar >> 24) ^ \
|
||||
((UChar)cha)]; \
|
||||
}
|
||||
|
||||
|
||||
/*-- States and modes for compression. --*/
|
||||
|
||||
#define BZ_M_IDLE 1
|
||||
#define BZ_M_RUNNING 2
|
||||
#define BZ_M_FLUSHING 3
|
||||
#define BZ_M_FINISHING 4
|
||||
|
||||
#define BZ_S_OUTPUT 1
|
||||
#define BZ_S_INPUT 2
|
||||
|
||||
#define BZ_N_RADIX 2
|
||||
#define BZ_N_QSORT 12
|
||||
#define BZ_N_SHELL 18
|
||||
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
|
||||
|
||||
|
||||
/*-- Structure holding all the compression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* mode this stream is in, and whether inputting */
|
||||
/* or outputting data */
|
||||
Int32 mode;
|
||||
Int32 state;
|
||||
|
||||
/* remembers avail_in when flush/finish requested */
|
||||
UInt32 avail_in_expect;
|
||||
|
||||
/* for doing the block sorting */
|
||||
UInt32* arr1;
|
||||
UInt32* arr2;
|
||||
UInt32* ftab;
|
||||
Int32 origPtr;
|
||||
|
||||
/* aliases for arr1 and arr2 */
|
||||
UInt32* ptr;
|
||||
UChar* block;
|
||||
UInt16* mtfv;
|
||||
UChar* zbits;
|
||||
|
||||
/* for deciding when to use the fallback sorting algorithm */
|
||||
Int32 workFactor;
|
||||
|
||||
/* run-length-encoding of the input */
|
||||
UInt32 state_in_ch;
|
||||
Int32 state_in_len;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* input and output limits and current posns */
|
||||
Int32 nblock;
|
||||
Int32 nblockMAX;
|
||||
Int32 numZ;
|
||||
Int32 state_out_pos;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
UChar unseqToSeq[256];
|
||||
|
||||
/* the buffer for bit stream creation */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* block and combined CRCs */
|
||||
UInt32 blockCRC;
|
||||
UInt32 combinedCRC;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 verbosity;
|
||||
Int32 blockNo;
|
||||
Int32 blockSize100k;
|
||||
|
||||
/* stuff for coding the MTF values */
|
||||
Int32 nMTF;
|
||||
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
/* second dimension: only 3 needed; 4 makes index calculations faster */
|
||||
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
|
||||
|
||||
}
|
||||
EState;
|
||||
|
||||
|
||||
/*-- externs for compression. --*/
|
||||
|
||||
extern void
|
||||
BZ2_blockSort ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_compressBlock ( EState*, Bool );
|
||||
|
||||
extern void
|
||||
BZ2_bsInitWrite ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
|
||||
|
||||
extern void
|
||||
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
|
||||
|
||||
|
||||
/*-- states for decompression. --*/
|
||||
|
||||
#define BZ_X_IDLE 1
|
||||
#define BZ_X_OUTPUT 2
|
||||
|
||||
#define BZ_X_MAGIC_1 10
|
||||
#define BZ_X_MAGIC_2 11
|
||||
#define BZ_X_MAGIC_3 12
|
||||
#define BZ_X_MAGIC_4 13
|
||||
#define BZ_X_BLKHDR_1 14
|
||||
#define BZ_X_BLKHDR_2 15
|
||||
#define BZ_X_BLKHDR_3 16
|
||||
#define BZ_X_BLKHDR_4 17
|
||||
#define BZ_X_BLKHDR_5 18
|
||||
#define BZ_X_BLKHDR_6 19
|
||||
#define BZ_X_BCRC_1 20
|
||||
#define BZ_X_BCRC_2 21
|
||||
#define BZ_X_BCRC_3 22
|
||||
#define BZ_X_BCRC_4 23
|
||||
#define BZ_X_RANDBIT 24
|
||||
#define BZ_X_ORIGPTR_1 25
|
||||
#define BZ_X_ORIGPTR_2 26
|
||||
#define BZ_X_ORIGPTR_3 27
|
||||
#define BZ_X_MAPPING_1 28
|
||||
#define BZ_X_MAPPING_2 29
|
||||
#define BZ_X_SELECTOR_1 30
|
||||
#define BZ_X_SELECTOR_2 31
|
||||
#define BZ_X_SELECTOR_3 32
|
||||
#define BZ_X_CODING_1 33
|
||||
#define BZ_X_CODING_2 34
|
||||
#define BZ_X_CODING_3 35
|
||||
#define BZ_X_MTF_1 36
|
||||
#define BZ_X_MTF_2 37
|
||||
#define BZ_X_MTF_3 38
|
||||
#define BZ_X_MTF_4 39
|
||||
#define BZ_X_MTF_5 40
|
||||
#define BZ_X_MTF_6 41
|
||||
#define BZ_X_ENDHDR_2 42
|
||||
#define BZ_X_ENDHDR_3 43
|
||||
#define BZ_X_ENDHDR_4 44
|
||||
#define BZ_X_ENDHDR_5 45
|
||||
#define BZ_X_ENDHDR_6 46
|
||||
#define BZ_X_CCRC_1 47
|
||||
#define BZ_X_CCRC_2 48
|
||||
#define BZ_X_CCRC_3 49
|
||||
#define BZ_X_CCRC_4 50
|
||||
|
||||
|
||||
/*-- Constants for the fast MTF decoder. --*/
|
||||
|
||||
#define MTFA_SIZE 4096
|
||||
#define MTFL_SIZE 16
|
||||
|
||||
|
||||
/*-- Structure holding all the decompression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* state indicator for this stream */
|
||||
Int32 state;
|
||||
|
||||
/* for doing the final run-length decoding */
|
||||
UChar state_out_ch;
|
||||
Int32 state_out_len;
|
||||
Bool blockRandomised;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* the buffer for bit stream reading */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 blockSize100k;
|
||||
Bool smallDecompress;
|
||||
Int32 currBlockNo;
|
||||
Int32 verbosity;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform */
|
||||
Int32 origPtr;
|
||||
UInt32 tPos;
|
||||
Int32 k0;
|
||||
Int32 unzftab[256];
|
||||
Int32 nblock_used;
|
||||
Int32 cftab[257];
|
||||
Int32 cftabCopy[257];
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (FAST) */
|
||||
UInt32 *tt;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (SMALL) */
|
||||
UInt16 *ll16;
|
||||
UChar *ll4;
|
||||
|
||||
/* stored and calculated CRCs */
|
||||
UInt32 storedBlockCRC;
|
||||
UInt32 storedCombinedCRC;
|
||||
UInt32 calculatedBlockCRC;
|
||||
UInt32 calculatedCombinedCRC;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
Bool inUse16[16];
|
||||
UChar seqToUnseq[256];
|
||||
|
||||
/* for decoding the MTF values */
|
||||
UChar mtfa [MTFA_SIZE];
|
||||
Int32 mtfbase[256 / MTFL_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
|
||||
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 minLens[BZ_N_GROUPS];
|
||||
|
||||
/* save area for scalars in the main decompress code */
|
||||
Int32 save_i;
|
||||
Int32 save_j;
|
||||
Int32 save_t;
|
||||
Int32 save_alphaSize;
|
||||
Int32 save_nGroups;
|
||||
Int32 save_nSelectors;
|
||||
Int32 save_EOB;
|
||||
Int32 save_groupNo;
|
||||
Int32 save_groupPos;
|
||||
Int32 save_nextSym;
|
||||
Int32 save_nblockMAX;
|
||||
Int32 save_nblock;
|
||||
Int32 save_es;
|
||||
Int32 save_N;
|
||||
Int32 save_curr;
|
||||
Int32 save_zt;
|
||||
Int32 save_zn;
|
||||
Int32 save_zvec;
|
||||
Int32 save_zj;
|
||||
Int32 save_gSel;
|
||||
Int32 save_gMinlen;
|
||||
Int32* save_gLimit;
|
||||
Int32* save_gBase;
|
||||
Int32* save_gPerm;
|
||||
|
||||
}
|
||||
DState;
|
||||
|
||||
|
||||
/*-- Macros for decompression. --*/
|
||||
|
||||
#define BZ_GET_FAST(cccc) \
|
||||
s->tPos = s->tt[s->tPos]; \
|
||||
cccc = (UChar)(s->tPos & 0xff); \
|
||||
s->tPos >>= 8;
|
||||
|
||||
#define BZ_GET_FAST_C(cccc) \
|
||||
c_tPos = c_tt[c_tPos]; \
|
||||
cccc = (UChar)(c_tPos & 0xff); \
|
||||
c_tPos >>= 8;
|
||||
|
||||
#define SET_LL4(i,n) \
|
||||
{ if (((i) & 0x1) == 0) \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
|
||||
}
|
||||
|
||||
#define GET_LL4(i) \
|
||||
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
|
||||
|
||||
#define SET_LL(i,n) \
|
||||
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
|
||||
SET_LL4(i, n >> 16); \
|
||||
}
|
||||
|
||||
#define GET_LL(i) \
|
||||
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
|
||||
|
||||
#define BZ_GET_SMALL(cccc) \
|
||||
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
|
||||
s->tPos = GET_LL(s->tPos);
|
||||
|
||||
|
||||
/*-- externs for decompression. --*/
|
||||
|
||||
extern Int32
|
||||
BZ2_indexIntoF ( Int32, Int32* );
|
||||
|
||||
extern Int32
|
||||
BZ2_decompress ( DState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
|
||||
Int32, Int32, Int32 );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
|
||||
|
||||
#ifdef BZ_NO_STDIO
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
125
common/package/utils/sysupgrade-helper/src/lib/bzlib_randtable.c
Normal file
125
common/package/utils/sysupgrade-helper/src/lib/bzlib_randtable.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#include <config.h>
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for randomising repetitive blocks ---*/
|
||||
/*--- randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*--
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
David Wheeler
|
||||
Peter Fenwick
|
||||
Alistair Moffat
|
||||
Radford Neal
|
||||
Ian H. Witten
|
||||
Robert Sedgewick
|
||||
Jon L. Bentley
|
||||
|
||||
For more information on these sources, see the manual.
|
||||
--*/
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------*/
|
||||
Int32 BZ2_rNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
110
common/package/utils/sysupgrade-helper/src/lib/circbuf.c
Normal file
110
common/package/utils/sysupgrade-helper/src/lib/circbuf.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* (C) Copyright 2003
|
||||
* Gerry Hamel, geh@ti.com, Texas Instruments
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <circbuf.h>
|
||||
|
||||
|
||||
int buf_init (circbuf_t * buf, unsigned int size)
|
||||
{
|
||||
assert (buf != NULL);
|
||||
|
||||
buf->size = 0;
|
||||
buf->totalsize = size;
|
||||
buf->data = (char *) malloc (sizeof (char) * size);
|
||||
assert (buf->data != NULL);
|
||||
|
||||
buf->top = buf->data;
|
||||
buf->tail = buf->data;
|
||||
buf->end = &(buf->data[size]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int buf_free (circbuf_t * buf)
|
||||
{
|
||||
assert (buf != NULL);
|
||||
assert (buf->data != NULL);
|
||||
|
||||
free (buf->data);
|
||||
memset (buf, 0, sizeof (circbuf_t));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int buf_pop (circbuf_t * buf, char *dest, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
char *p = buf->top;
|
||||
|
||||
assert (buf != NULL);
|
||||
assert (dest != NULL);
|
||||
|
||||
/* Cap to number of bytes in buffer */
|
||||
if (len > buf->size)
|
||||
len = buf->size;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
dest[i] = *p++;
|
||||
/* Bounds check. */
|
||||
if (p == buf->end) {
|
||||
p = buf->data;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update 'top' pointer */
|
||||
buf->top = p;
|
||||
buf->size -= len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int buf_push (circbuf_t * buf, const char *src, unsigned int len)
|
||||
{
|
||||
/* NOTE: this function allows push to overwrite old data. */
|
||||
unsigned int i;
|
||||
char *p = buf->tail;
|
||||
|
||||
assert (buf != NULL);
|
||||
assert (src != NULL);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
*p++ = src[i];
|
||||
if (p == buf->end) {
|
||||
p = buf->data;
|
||||
}
|
||||
/* Make sure pushing too much data just replaces old data */
|
||||
if (buf->size < buf->totalsize) {
|
||||
buf->size++;
|
||||
} else {
|
||||
buf->top++;
|
||||
if (buf->top == buf->end) {
|
||||
buf->top = buf->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update 'tail' pointer */
|
||||
buf->tail = p;
|
||||
|
||||
return len;
|
||||
}
|
||||
107
common/package/utils/sysupgrade-helper/src/lib/crc16.c
Normal file
107
common/package/utils/sysupgrade-helper/src/lib/crc16.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
*==========================================================================
|
||||
*
|
||||
* crc16.c
|
||||
*
|
||||
* 16 bit CRC with polynomial x^16+x^12+x^5+1
|
||||
*
|
||||
*==========================================================================
|
||||
*####ECOSGPLCOPYRIGHTBEGIN####
|
||||
* -------------------------------------------
|
||||
* This file is part of eCos, the Embedded Configurable Operating System.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2002 Gary Thomas
|
||||
*
|
||||
* eCos is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 or (at your option) any later version.
|
||||
*
|
||||
* eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with eCos; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*
|
||||
* As a special exception, if other files instantiate templates or use macros
|
||||
* or inline functions from this file, or you compile this file and link it
|
||||
* with other works to produce a work based on this file, this file does not
|
||||
* by itself cause the resulting work to be covered by the GNU General Public
|
||||
* License. However the source code for this file must still be made available
|
||||
* in accordance with section (3) of the GNU General Public License.
|
||||
*
|
||||
* This exception does not invalidate any other reasons why a work based on
|
||||
* this file might be covered by the GNU General Public License.
|
||||
*
|
||||
* Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
||||
* at http: *sources.redhat.com/ecos/ecos-license/
|
||||
* -------------------------------------------
|
||||
*####ECOSGPLCOPYRIGHTEND####
|
||||
*==========================================================================
|
||||
*#####DESCRIPTIONBEGIN####
|
||||
*
|
||||
* Author(s): gthomas
|
||||
* Contributors: gthomas,asl
|
||||
* Date: 2001-01-31
|
||||
* Purpose:
|
||||
* Description:
|
||||
*
|
||||
* This code is part of eCos (tm).
|
||||
*
|
||||
*####DESCRIPTIONEND####
|
||||
*
|
||||
*==========================================================================
|
||||
*/
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
/* Table of CRC constants - implements x^16+x^12+x^5+1 */
|
||||
static const uint16_t crc16_tab[] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
|
||||
};
|
||||
|
||||
uint16_t
|
||||
cyg_crc16(unsigned char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
uint16_t cksum;
|
||||
|
||||
cksum = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xFF] ^ (cksum << 8);
|
||||
}
|
||||
return cksum;
|
||||
}
|
||||
251
common/package/utils/sysupgrade-helper/src/lib/crc32.c
Normal file
251
common/package/utils/sysupgrade-helper/src/lib/crc32.c
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* This file is derived from crc32.c from the zlib-1.1.3 distribution
|
||||
* by Jean-loup Gailly and Mark Adler.
|
||||
*/
|
||||
|
||||
/* crc32.c -- compute the CRC-32 of a data stream
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <common.h>
|
||||
#endif
|
||||
#include <compiler.h>
|
||||
#include <u-boot/crc.h>
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
#include <watchdog.h>
|
||||
#endif
|
||||
#include "u-boot/zlib.h"
|
||||
|
||||
#define local static
|
||||
#define ZEXPORT /* empty */
|
||||
|
||||
#define tole(x) cpu_to_le32(x)
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
|
||||
local int crc_table_empty = 1;
|
||||
local uint32_t crc_table[256];
|
||||
local void make_crc_table OF((void));
|
||||
|
||||
/*
|
||||
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
|
||||
|
||||
Polynomials over GF(2) are represented in binary, one bit per coefficient,
|
||||
with the lowest powers in the most significant bit. Then adding polynomials
|
||||
is just exclusive-or, and multiplying a polynomial by x is a right shift by
|
||||
one. If we call the above polynomial p, and represent a byte as the
|
||||
polynomial q, also with the lowest power in the most significant bit (so the
|
||||
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
|
||||
where a mod b means the remainder after dividing a by b.
|
||||
|
||||
This calculation is done using the shift-register method of multiplying and
|
||||
taking the remainder. The register is initialized to zero, and for each
|
||||
incoming bit, x^32 is added mod p to the register if the bit is a one (where
|
||||
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
|
||||
x (which is shifting right by one and adding x^32 mod p if the bit shifted
|
||||
out is a one). We start with the highest power (least significant bit) of
|
||||
q and repeat for all eight bits of q.
|
||||
|
||||
The table is simply the CRC of all possible eight bit values. This is all
|
||||
the information needed to generate CRC's on data a byte at a time for all
|
||||
combinations of CRC register values and incoming bytes.
|
||||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
uint32_t c;
|
||||
int n, k;
|
||||
uLong poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320L) */
|
||||
poly = 0L;
|
||||
for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
|
||||
poly |= 1L << (31 - p[n]);
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
{
|
||||
c = (uLong)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[n] = tole(c);
|
||||
}
|
||||
crc_table_empty = 0;
|
||||
}
|
||||
#else
|
||||
/* ========================================================================
|
||||
* Table of CRC-32's of all single-byte values (made by make_crc_table)
|
||||
*/
|
||||
|
||||
local const uint32_t crc_table[256] = {
|
||||
tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
|
||||
tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
|
||||
tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
|
||||
tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
|
||||
tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
|
||||
tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
|
||||
tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
|
||||
tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
|
||||
tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
|
||||
tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
|
||||
tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
|
||||
tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
|
||||
tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
|
||||
tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
|
||||
tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
|
||||
tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
|
||||
tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
|
||||
tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
|
||||
tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
|
||||
tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
|
||||
tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
|
||||
tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
|
||||
tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
|
||||
tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
|
||||
tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
|
||||
tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
|
||||
tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
|
||||
tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
|
||||
tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
|
||||
tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
|
||||
tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
|
||||
tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
|
||||
tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
|
||||
tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
|
||||
tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
|
||||
tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
|
||||
tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
|
||||
tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
|
||||
tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
|
||||
tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
|
||||
tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
|
||||
tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
|
||||
tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
|
||||
tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
|
||||
tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
|
||||
tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
|
||||
tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
|
||||
tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
|
||||
tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
|
||||
tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
|
||||
tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
|
||||
tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
|
||||
tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
|
||||
tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
|
||||
tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
|
||||
tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
|
||||
tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
|
||||
tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
|
||||
tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
|
||||
tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
|
||||
tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
|
||||
tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
|
||||
tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
|
||||
tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
const uint32_t * ZEXPORT get_crc_table()
|
||||
{
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty) make_crc_table();
|
||||
#endif
|
||||
return (const uint32_t *)crc_table;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define DO_CRC(x) crc = tab[(crc ^ (x)) & 255] ^ (crc >> 8)
|
||||
# else
|
||||
# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
|
||||
# endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
/* No ones complement version. JFFS2 (and other things ?)
|
||||
* don't use ones compliment in their CRC calculations.
|
||||
*/
|
||||
uint32_t ZEXPORT crc32_no_comp(uint32_t crc, const Bytef *buf, uInt len)
|
||||
{
|
||||
const uint32_t *tab = crc_table;
|
||||
const uint32_t *b =(const uint32_t *)buf;
|
||||
size_t rem_len;
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif
|
||||
crc = cpu_to_le32(crc);
|
||||
/* Align it */
|
||||
if (((long)b) & 3 && len) {
|
||||
uint8_t *p = (uint8_t *)b;
|
||||
do {
|
||||
DO_CRC(*p++);
|
||||
} while ((--len) && ((long)p)&3);
|
||||
b = (uint32_t *)p;
|
||||
}
|
||||
|
||||
rem_len = len & 3;
|
||||
len = len >> 2;
|
||||
for (--b; len; --len) {
|
||||
/* load data 32 bits wide, xor data 32 bits wide. */
|
||||
crc ^= *++b; /* use pre increment for speed */
|
||||
DO_CRC(0);
|
||||
DO_CRC(0);
|
||||
DO_CRC(0);
|
||||
DO_CRC(0);
|
||||
}
|
||||
len = rem_len;
|
||||
/* And the last few bytes */
|
||||
if (len) {
|
||||
uint8_t *p = (uint8_t *)(b + 1) - 1;
|
||||
do {
|
||||
DO_CRC(*++p); /* use pre increment for speed */
|
||||
} while (--len);
|
||||
}
|
||||
|
||||
return le32_to_cpu(crc);
|
||||
}
|
||||
#undef DO_CRC
|
||||
|
||||
uint32_t ZEXPORT crc32 (uint32_t crc, const Bytef *p, uInt len)
|
||||
{
|
||||
return crc32_no_comp(crc ^ 0xffffffffL, p, len) ^ 0xffffffffL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes
|
||||
* of input.
|
||||
*/
|
||||
uint32_t ZEXPORT crc32_wd (uint32_t crc,
|
||||
const unsigned char *buf,
|
||||
uInt len, uInt chunk_sz)
|
||||
{
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
const unsigned char *end, *curr;
|
||||
int chunk;
|
||||
|
||||
curr = buf;
|
||||
end = buf + len;
|
||||
while (curr < end) {
|
||||
chunk = end - curr;
|
||||
if (chunk > chunk_sz)
|
||||
chunk = chunk_sz;
|
||||
crc = crc32 (crc, curr, chunk);
|
||||
curr += chunk;
|
||||
WATCHDOG_RESET ();
|
||||
}
|
||||
#else
|
||||
crc = crc32 (crc, buf, len);
|
||||
#endif
|
||||
|
||||
return crc;
|
||||
}
|
||||
62
common/package/utils/sysupgrade-helper/src/lib/crc7.c
Normal file
62
common/package/utils/sysupgrade-helper/src/lib/crc7.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* crc7.c
|
||||
*
|
||||
* This source code is licensed under the GNU General Public License,
|
||||
* Version 2. See the file COPYING for more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/crc7.h>
|
||||
|
||||
|
||||
/* Table for CRC-7 (polynomial x^7 + x^3 + 1) */
|
||||
const u8 crc7_syndrome_table[256] = {
|
||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
|
||||
0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||
0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
|
||||
0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
|
||||
0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
|
||||
0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
|
||||
0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
|
||||
0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
|
||||
0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
|
||||
0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
|
||||
0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
|
||||
0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
|
||||
0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
|
||||
0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
|
||||
0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
|
||||
0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
|
||||
0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
|
||||
0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
|
||||
0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
|
||||
0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
|
||||
0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
|
||||
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
|
||||
0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
|
||||
0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
|
||||
0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
|
||||
0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
|
||||
0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
|
||||
0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
|
||||
0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
|
||||
0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
|
||||
0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
|
||||
0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
|
||||
};
|
||||
|
||||
/**
|
||||
* crc7 - update the CRC7 for the data buffer
|
||||
* @crc: previous CRC7 value
|
||||
* @buffer: data pointer
|
||||
* @len: number of bytes in the buffer
|
||||
* Context: any
|
||||
*
|
||||
* Returns the updated CRC7 value.
|
||||
*/
|
||||
u8 crc7(u8 crc, const u8 *buffer, size_t len)
|
||||
{
|
||||
while (len--)
|
||||
crc = crc7_byte(crc, *buffer++);
|
||||
return crc;
|
||||
}
|
||||
56
common/package/utils/sysupgrade-helper/src/lib/ctype.c
Normal file
56
common/package/utils/sysupgrade-helper/src/lib/ctype.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* linux/lib/ctype.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <linux/ctype.h>
|
||||
|
||||
const unsigned char _ctype[] = {
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
|
||||
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
|
||||
_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
|
||||
_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
|
||||
_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
|
||||
_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
|
||||
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
|
||||
_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
|
||||
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
|
||||
_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
|
||||
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
|
||||
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
|
||||
153
common/package/utils/sysupgrade-helper/src/lib/display_options.c
Normal file
153
common/package/utils/sysupgrade-helper/src/lib/display_options.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* (C) Copyright 2000-2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <version.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
int display_options (void)
|
||||
{
|
||||
#if defined(BUILD_TAG)
|
||||
printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
|
||||
#else
|
||||
printf ("\n\n%s\n\n", version_string);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* print sizes as "xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB",
|
||||
* xxx GiB, xxx.y GiB, etc as needed; allow for optional trailing string
|
||||
* (like "\n")
|
||||
*/
|
||||
void print_size(unsigned long long size, const char *s)
|
||||
{
|
||||
unsigned long m = 0, n;
|
||||
unsigned long long f;
|
||||
static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'};
|
||||
unsigned long d = 10 * ARRAY_SIZE(names);
|
||||
char c = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) {
|
||||
if (size >> d) {
|
||||
c = names[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
printf("%llu Bytes%s", size, s);
|
||||
return;
|
||||
}
|
||||
|
||||
n = size >> d;
|
||||
f = size & ((1ULL << d) - 1);
|
||||
|
||||
/* If there's a remainder, deal with it */
|
||||
if (f) {
|
||||
m = (10ULL * f + (1ULL << (d - 1))) >> d;
|
||||
|
||||
if (m >= 10) {
|
||||
m -= 10;
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("%lu", n);
|
||||
if (m) {
|
||||
printf (".%ld", m);
|
||||
}
|
||||
printf (" %ciB%s", c, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print data buffer in hex and ascii form to the terminal.
|
||||
*
|
||||
* data reads are buffered so that each memory address is only read once.
|
||||
* Useful when displaying the contents of volatile registers.
|
||||
*
|
||||
* parameters:
|
||||
* addr: Starting address to display at start of line
|
||||
* data: pointer to data buffer
|
||||
* width: data value width. May be 1, 2, or 4.
|
||||
* count: number of values to display
|
||||
* linelen: Number of values to print per line; specify 0 for default length
|
||||
*/
|
||||
#define MAX_LINE_LENGTH_BYTES (64)
|
||||
#define DEFAULT_LINE_LENGTH_BYTES (16)
|
||||
int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen)
|
||||
{
|
||||
/* linebuf as a union causes proper alignment */
|
||||
union linebuf {
|
||||
uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1];
|
||||
uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1];
|
||||
uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1];
|
||||
} lb;
|
||||
int i;
|
||||
|
||||
if (linelen*width > MAX_LINE_LENGTH_BYTES)
|
||||
linelen = MAX_LINE_LENGTH_BYTES / width;
|
||||
if (linelen < 1)
|
||||
linelen = DEFAULT_LINE_LENGTH_BYTES / width;
|
||||
|
||||
while (count) {
|
||||
printf("%08lx:", addr);
|
||||
|
||||
/* check for overflow condition */
|
||||
if (count < linelen)
|
||||
linelen = count;
|
||||
|
||||
/* Copy from memory into linebuf and print hex values */
|
||||
for (i = 0; i < linelen; i++) {
|
||||
uint32_t x;
|
||||
if (width == 4)
|
||||
x = lb.ui[i] = *(volatile uint32_t *)data;
|
||||
else if (width == 2)
|
||||
x = lb.us[i] = *(volatile uint16_t *)data;
|
||||
else
|
||||
x = lb.uc[i] = *(volatile uint8_t *)data;
|
||||
printf(" %0*x", width * 2, x);
|
||||
data += width;
|
||||
}
|
||||
|
||||
/* Print data in ASCII characters */
|
||||
for (i = 0; i < linelen * width; i++) {
|
||||
if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
|
||||
lb.uc[i] = '.';
|
||||
}
|
||||
lb.uc[i] = '\0';
|
||||
printf(" %s\n", lb.uc);
|
||||
|
||||
/* update references */
|
||||
addr += linelen * width;
|
||||
count -= linelen;
|
||||
|
||||
if (ctrlc())
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
52
common/package/utils/sysupgrade-helper/src/lib/div64.c
Normal file
52
common/package/utils/sysupgrade-helper/src/lib/div64.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
|
||||
*
|
||||
* Based on former do_div() implementation from asm-parisc/div64.h:
|
||||
* Copyright (C) 1999 Hewlett-Packard Co
|
||||
* Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
*
|
||||
*
|
||||
* Generic C version of 64bit/32bit division and modulo, with
|
||||
* 64bit result and 32bit remainder.
|
||||
*
|
||||
* The fast case for (n>>32 == 0) is handled inline by do_div().
|
||||
*
|
||||
* Code generated for this function might be very inefficient
|
||||
* for some CPUs. __div64_32() can be overridden by linking arch-specific
|
||||
* assembly versions such as arch/powerpc/lib/div64.S and arch/sh/lib/div64.S.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
uint32_t __div64_32(uint64_t *n, uint32_t base)
|
||||
{
|
||||
uint64_t rem = *n;
|
||||
uint64_t b = base;
|
||||
uint64_t res, d = 1;
|
||||
uint32_t high = rem >> 32;
|
||||
|
||||
/* Reduce the thing a bit first */
|
||||
res = 0;
|
||||
if (high >= base) {
|
||||
high /= base;
|
||||
res = (uint64_t) high << 32;
|
||||
rem -= (uint64_t) (high*base) << 32;
|
||||
}
|
||||
|
||||
while ((int64_t)b > 0 && b < rem) {
|
||||
b = b+b;
|
||||
d = d+d;
|
||||
}
|
||||
|
||||
do {
|
||||
if (rem >= b) {
|
||||
rem -= b;
|
||||
res += d;
|
||||
}
|
||||
b >>= 1;
|
||||
d >>= 1;
|
||||
} while (d);
|
||||
|
||||
*n = res;
|
||||
return rem;
|
||||
}
|
||||
1
common/package/utils/sysupgrade-helper/src/lib/errno.c
Normal file
1
common/package/utils/sysupgrade-helper/src/lib/errno.c
Normal file
|
|
@ -0,0 +1 @@
|
|||
int errno = 0;
|
||||
503
common/package/utils/sysupgrade-helper/src/lib/fdtdec.c
Normal file
503
common/package/utils/sysupgrade-helper/src/lib/fdtdec.c
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The Chromium OS Authors.
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <serial.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdtdec.h>
|
||||
|
||||
/* we need the generic GPIO interface here */
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Here are the type we know about. One day we might allow drivers to
|
||||
* register. For now we just put them here. The COMPAT macro allows us to
|
||||
* turn this into a sparse list later, and keeps the ID with the name.
|
||||
*/
|
||||
#define COMPAT(id, name) name
|
||||
static const char * const compat_names[COMPAT_COUNT] = {
|
||||
COMPAT(UNKNOWN, "<none>"),
|
||||
COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"),
|
||||
COMPAT(NVIDIA_TEGRA20_I2C, "nvidia,tegra20-i2c"),
|
||||
COMPAT(NVIDIA_TEGRA20_DVC, "nvidia,tegra20-i2c-dvc"),
|
||||
COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"),
|
||||
COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
|
||||
COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
|
||||
};
|
||||
|
||||
const char *fdtdec_get_compatible(enum fdt_compat_id id)
|
||||
{
|
||||
/* We allow reading of the 'unknown' ID for testing purposes */
|
||||
assert(id >= 0 && id < COMPAT_COUNT);
|
||||
return compat_names[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Look in the FDT for an alias with the given name and return its node.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param name alias name to look up
|
||||
* @return node offset if found, or an error code < 0 otherwise
|
||||
*/
|
||||
static int find_alias_node(const void *blob, const char *name)
|
||||
{
|
||||
const char *path;
|
||||
int alias_node;
|
||||
|
||||
debug("find_alias_node: %s\n", name);
|
||||
alias_node = fdt_path_offset(blob, "/aliases");
|
||||
if (alias_node < 0)
|
||||
return alias_node;
|
||||
path = fdt_getprop(blob, alias_node, name, NULL);
|
||||
if (!path)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
return fdt_path_offset(blob, path);
|
||||
}
|
||||
|
||||
fdt_addr_t fdtdec_get_addr(const void *blob, int node,
|
||||
const char *prop_name)
|
||||
{
|
||||
const fdt_addr_t *cell;
|
||||
int len;
|
||||
|
||||
debug("get_addr: %s\n", prop_name);
|
||||
cell = fdt_getprop(blob, node, prop_name, &len);
|
||||
if (cell && (len == sizeof(fdt_addr_t) ||
|
||||
len == sizeof(fdt_addr_t) * 2))
|
||||
return fdt_addr_to_cpu(*cell);
|
||||
return FDT_ADDR_T_NONE;
|
||||
}
|
||||
|
||||
s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
|
||||
s32 default_val)
|
||||
{
|
||||
const s32 *cell;
|
||||
int len;
|
||||
|
||||
debug("get_size: %s\n", prop_name);
|
||||
cell = fdt_getprop(blob, node, prop_name, &len);
|
||||
if (cell && len >= sizeof(s32))
|
||||
return fdt32_to_cpu(cell[0]);
|
||||
return default_val;
|
||||
}
|
||||
|
||||
int fdtdec_get_is_enabled(const void *blob, int node)
|
||||
{
|
||||
const char *cell;
|
||||
|
||||
/*
|
||||
* It should say "okay", so only allow that. Some fdts use "ok" but
|
||||
* this is a bug. Please fix your device tree source file. See here
|
||||
* for discussion:
|
||||
*
|
||||
* http://www.mail-archive.com/u-boot@lists.denx.de/msg71598.html
|
||||
*/
|
||||
cell = fdt_getprop(blob, node, "status", NULL);
|
||||
if (cell)
|
||||
return 0 == strcmp(cell, "okay");
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum fdt_compat_id fd_dec_lookup(const void *blob, int node)
|
||||
{
|
||||
enum fdt_compat_id id;
|
||||
|
||||
/* Search our drivers */
|
||||
for (id = COMPAT_UNKNOWN; id < COMPAT_COUNT; id++)
|
||||
if (0 == fdt_node_check_compatible(blob, node,
|
||||
compat_names[id]))
|
||||
return id;
|
||||
return COMPAT_UNKNOWN;
|
||||
}
|
||||
|
||||
int fdtdec_next_compatible(const void *blob, int node,
|
||||
enum fdt_compat_id id)
|
||||
{
|
||||
return fdt_node_offset_by_compatible(blob, node, compat_names[id]);
|
||||
}
|
||||
|
||||
int fdtdec_next_compatible_subnode(const void *blob, int node,
|
||||
enum fdt_compat_id id, int *depthp)
|
||||
{
|
||||
do {
|
||||
node = fdt_next_node(blob, node, depthp);
|
||||
} while (*depthp > 1);
|
||||
|
||||
/* If this is a direct subnode, and compatible, return it */
|
||||
if (*depthp == 1 && 0 == fdt_node_check_compatible(
|
||||
blob, node, compat_names[id]))
|
||||
return node;
|
||||
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
}
|
||||
|
||||
int fdtdec_next_alias(const void *blob, const char *name,
|
||||
enum fdt_compat_id id, int *upto)
|
||||
{
|
||||
#define MAX_STR_LEN 20
|
||||
char str[MAX_STR_LEN + 20];
|
||||
int node, err;
|
||||
|
||||
/* snprintf() is not available */
|
||||
assert(strlen(name) < MAX_STR_LEN);
|
||||
sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto);
|
||||
node = find_alias_node(blob, str);
|
||||
if (node < 0)
|
||||
return node;
|
||||
err = fdt_node_check_compatible(blob, node, compat_names[id]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (err)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
(*upto)++;
|
||||
return node;
|
||||
}
|
||||
|
||||
int fdtdec_find_aliases_for_id(const void *blob, const char *name,
|
||||
enum fdt_compat_id id, int *node_list, int maxcount)
|
||||
{
|
||||
memset(node_list, '\0', sizeof(*node_list) * maxcount);
|
||||
|
||||
return fdtdec_add_aliases_for_id(blob, name, id, node_list, maxcount);
|
||||
}
|
||||
|
||||
/* TODO: Can we tighten this code up a little? */
|
||||
int fdtdec_add_aliases_for_id(const void *blob, const char *name,
|
||||
enum fdt_compat_id id, int *node_list, int maxcount)
|
||||
{
|
||||
int name_len = strlen(name);
|
||||
int nodes[maxcount];
|
||||
int num_found = 0;
|
||||
int offset, node;
|
||||
int alias_node;
|
||||
int count;
|
||||
int i, j;
|
||||
|
||||
/* find the alias node if present */
|
||||
alias_node = fdt_path_offset(blob, "/aliases");
|
||||
|
||||
/*
|
||||
* start with nothing, and we can assume that the root node can't
|
||||
* match
|
||||
*/
|
||||
memset(nodes, '\0', sizeof(nodes));
|
||||
|
||||
/* First find all the compatible nodes */
|
||||
for (node = count = 0; node >= 0 && count < maxcount;) {
|
||||
node = fdtdec_next_compatible(blob, node, id);
|
||||
if (node >= 0)
|
||||
nodes[count++] = node;
|
||||
}
|
||||
if (node >= 0)
|
||||
debug("%s: warning: maxcount exceeded with alias '%s'\n",
|
||||
__func__, name);
|
||||
|
||||
/* Now find all the aliases */
|
||||
for (offset = fdt_first_property_offset(blob, alias_node);
|
||||
offset > 0;
|
||||
offset = fdt_next_property_offset(blob, offset)) {
|
||||
const struct fdt_property *prop;
|
||||
const char *path;
|
||||
int number;
|
||||
int found;
|
||||
|
||||
node = 0;
|
||||
prop = fdt_get_property_by_offset(blob, offset, NULL);
|
||||
path = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
|
||||
if (prop->len && 0 == strncmp(path, name, name_len))
|
||||
node = fdt_path_offset(blob, prop->data);
|
||||
if (node <= 0)
|
||||
continue;
|
||||
|
||||
/* Get the alias number */
|
||||
number = simple_strtoul(path + name_len, NULL, 10);
|
||||
if (number < 0 || number >= maxcount) {
|
||||
debug("%s: warning: alias '%s' is out of range\n",
|
||||
__func__, path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make sure the node we found is actually in our list! */
|
||||
found = -1;
|
||||
for (j = 0; j < count; j++)
|
||||
if (nodes[j] == node) {
|
||||
found = j;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found == -1) {
|
||||
debug("%s: warning: alias '%s' points to a node "
|
||||
"'%s' that is missing or is not compatible "
|
||||
" with '%s'\n", __func__, path,
|
||||
fdt_get_name(blob, node, NULL),
|
||||
compat_names[id]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add this node to our list in the right place, and mark
|
||||
* it as done.
|
||||
*/
|
||||
if (fdtdec_get_is_enabled(blob, node)) {
|
||||
if (node_list[number]) {
|
||||
debug("%s: warning: alias '%s' requires that "
|
||||
"a node be placed in the list in a "
|
||||
"position which is already filled by "
|
||||
"node '%s'\n", __func__, path,
|
||||
fdt_get_name(blob, node, NULL));
|
||||
continue;
|
||||
}
|
||||
node_list[number] = node;
|
||||
if (number >= num_found)
|
||||
num_found = number + 1;
|
||||
}
|
||||
nodes[found] = 0;
|
||||
}
|
||||
|
||||
/* Add any nodes not mentioned by an alias */
|
||||
for (i = j = 0; i < maxcount; i++) {
|
||||
if (!node_list[i]) {
|
||||
for (; j < maxcount; j++)
|
||||
if (nodes[j] &&
|
||||
fdtdec_get_is_enabled(blob, nodes[j]))
|
||||
break;
|
||||
|
||||
/* Have we run out of nodes to add? */
|
||||
if (j == maxcount)
|
||||
break;
|
||||
|
||||
assert(!node_list[i]);
|
||||
node_list[i] = nodes[j++];
|
||||
if (i >= num_found)
|
||||
num_found = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return num_found;
|
||||
}
|
||||
|
||||
int fdtdec_check_fdt(void)
|
||||
{
|
||||
/*
|
||||
* We must have an FDT, but we cannot panic() yet since the console
|
||||
* is not ready. So for now, just assert(). Boards which need an early
|
||||
* FDT (prior to console ready) will need to make their own
|
||||
* arrangements and do their own checks.
|
||||
*/
|
||||
assert(!fdtdec_prepare_fdt());
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is a little odd in that it accesses global data. At some
|
||||
* point if the architecture board.c files merge this will make more sense.
|
||||
* Even now, it is common code.
|
||||
*/
|
||||
int fdtdec_prepare_fdt(void)
|
||||
{
|
||||
if (((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) {
|
||||
printf("No valid FDT found - please append one to U-Boot "
|
||||
"binary, use u-boot-dtb.bin or define "
|
||||
"CONFIG_OF_EMBED\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name)
|
||||
{
|
||||
const u32 *phandle;
|
||||
int lookup;
|
||||
|
||||
phandle = fdt_getprop(blob, node, prop_name, NULL);
|
||||
if (!phandle)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
|
||||
lookup = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*phandle));
|
||||
return lookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a property in a node and check that it has a minimum length.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param node node to examine
|
||||
* @param prop_name name of property to find
|
||||
* @param min_len minimum property length in bytes
|
||||
* @param err 0 if ok, or -FDT_ERR_NOTFOUND if the property is not
|
||||
found, or -FDT_ERR_BADLAYOUT if not enough data
|
||||
* @return pointer to cell, which is only valid if err == 0
|
||||
*/
|
||||
static const void *get_prop_check_min_len(const void *blob, int node,
|
||||
const char *prop_name, int min_len, int *err)
|
||||
{
|
||||
const void *cell;
|
||||
int len;
|
||||
|
||||
debug("%s: %s\n", __func__, prop_name);
|
||||
cell = fdt_getprop(blob, node, prop_name, &len);
|
||||
if (!cell)
|
||||
*err = -FDT_ERR_NOTFOUND;
|
||||
else if (len < min_len)
|
||||
*err = -FDT_ERR_BADLAYOUT;
|
||||
else
|
||||
*err = 0;
|
||||
return cell;
|
||||
}
|
||||
|
||||
int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
|
||||
u32 *array, int count)
|
||||
{
|
||||
const u32 *cell;
|
||||
int i, err = 0;
|
||||
|
||||
debug("%s: %s\n", __func__, prop_name);
|
||||
cell = get_prop_check_min_len(blob, node, prop_name,
|
||||
sizeof(u32) * count, &err);
|
||||
if (!err) {
|
||||
for (i = 0; i < count; i++)
|
||||
array[i] = fdt32_to_cpu(cell[i]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
const u32 *fdtdec_locate_array(const void *blob, int node,
|
||||
const char *prop_name, int count)
|
||||
{
|
||||
const u32 *cell;
|
||||
int err;
|
||||
|
||||
cell = get_prop_check_min_len(blob, node, prop_name,
|
||||
sizeof(u32) * count, &err);
|
||||
return err ? NULL : cell;
|
||||
}
|
||||
|
||||
int fdtdec_get_bool(const void *blob, int node, const char *prop_name)
|
||||
{
|
||||
const s32 *cell;
|
||||
int len;
|
||||
|
||||
debug("%s: %s\n", __func__, prop_name);
|
||||
cell = fdt_getprop(blob, node, prop_name, &len);
|
||||
return cell != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no
|
||||
* terminating item.
|
||||
*
|
||||
* @param blob FDT blob to use
|
||||
* @param node Node to look at
|
||||
* @param prop_name Node property name
|
||||
* @param gpio Array of gpio elements to fill from FDT. This will be
|
||||
* untouched if either 0 or an error is returned
|
||||
* @param max_count Maximum number of elements allowed
|
||||
* @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would
|
||||
* be exceeded, or -FDT_ERR_NOTFOUND if the property is missing.
|
||||
*/
|
||||
static int fdtdec_decode_gpios(const void *blob, int node,
|
||||
const char *prop_name, struct fdt_gpio_state *gpio,
|
||||
int max_count)
|
||||
{
|
||||
const struct fdt_property *prop;
|
||||
const u32 *cell;
|
||||
const char *name;
|
||||
int len, i;
|
||||
|
||||
debug("%s: %s\n", __func__, prop_name);
|
||||
assert(max_count > 0);
|
||||
prop = fdt_get_property(blob, node, prop_name, &len);
|
||||
if (!prop) {
|
||||
debug("FDT: %s: property '%s' missing\n", __func__, prop_name);
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
}
|
||||
|
||||
/* We will use the name to tag the GPIO */
|
||||
name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
|
||||
cell = (u32 *)prop->data;
|
||||
len /= sizeof(u32) * 3; /* 3 cells per GPIO record */
|
||||
if (len > max_count) {
|
||||
debug("FDT: %s: too many GPIOs / cells for "
|
||||
"property '%s'\n", __func__, prop_name);
|
||||
return -FDT_ERR_BADLAYOUT;
|
||||
}
|
||||
|
||||
/* Read out the GPIO data from the cells */
|
||||
for (i = 0; i < len; i++, cell += 3) {
|
||||
gpio[i].gpio = fdt32_to_cpu(cell[1]);
|
||||
gpio[i].flags = fdt32_to_cpu(cell[2]);
|
||||
gpio[i].name = name;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
|
||||
struct fdt_gpio_state *gpio)
|
||||
{
|
||||
int err;
|
||||
|
||||
debug("%s: %s\n", __func__, prop_name);
|
||||
gpio->gpio = FDT_GPIO_NONE;
|
||||
gpio->name = NULL;
|
||||
err = fdtdec_decode_gpios(blob, node, prop_name, gpio, 1);
|
||||
return err == 1 ? 0 : err;
|
||||
}
|
||||
|
||||
int fdtdec_setup_gpio(struct fdt_gpio_state *gpio)
|
||||
{
|
||||
/*
|
||||
* Return success if there is no GPIO defined. This is used for
|
||||
* optional GPIOs)
|
||||
*/
|
||||
if (!fdt_gpio_isvalid(gpio))
|
||||
return 0;
|
||||
|
||||
if (gpio_request(gpio->gpio, gpio->name))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name,
|
||||
u8 *array, int count)
|
||||
{
|
||||
const u8 *cell;
|
||||
int err;
|
||||
|
||||
cell = get_prop_check_min_len(blob, node, prop_name, count, &err);
|
||||
if (!err)
|
||||
memcpy(array, cell, count);
|
||||
return err;
|
||||
}
|
||||
|
||||
const u8 *fdtdec_locate_byte_array(const void *blob, int node,
|
||||
const char *prop_name, int count)
|
||||
{
|
||||
const u8 *cell;
|
||||
int err;
|
||||
|
||||
cell = get_prop_check_min_len(blob, node, prop_name, count, &err);
|
||||
if (err)
|
||||
return NULL;
|
||||
return cell;
|
||||
}
|
||||
226
common/package/utils/sysupgrade-helper/src/lib/fdtdec_test.c
Normal file
226
common/package/utils/sysupgrade-helper/src/lib/fdtdec_test.c
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Some very basic tests for fdtdec, accessed through test_fdtdec command.
|
||||
* They are easiest to use with sandbox.
|
||||
*
|
||||
* Copyright (c) 2011 The Chromium OS Authors.
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <libfdt.h>
|
||||
#include <malloc.h>
|
||||
#include <os.h>
|
||||
|
||||
/* The size of our test fdt blob */
|
||||
#define FDT_SIZE (16 * 1024)
|
||||
|
||||
/**
|
||||
* Check if an operation failed, and if so, print an error
|
||||
*
|
||||
* @param oper_name Name of operation
|
||||
* @param err Error code to check
|
||||
*
|
||||
* @return 0 if ok, -1 if there was an error
|
||||
*/
|
||||
static int fdt_checkerr(const char *oper_name, int err)
|
||||
{
|
||||
if (err) {
|
||||
printf("%s: %s: %s\n", __func__, oper_name, fdt_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the result of an operation and if incorrect, print an error
|
||||
*
|
||||
* @param oper_name Name of operation
|
||||
* @param expected Expected value
|
||||
* @param value Actual value
|
||||
*
|
||||
* @return 0 if ok, -1 if there was an error
|
||||
*/
|
||||
static int checkval(const char *oper_name, int expected, int value)
|
||||
{
|
||||
if (expected != value) {
|
||||
printf("%s: %s: expected %d, but returned %d\n", __func__,
|
||||
oper_name, expected, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CHECK(op) if (fdt_checkerr(#op, op)) return -1
|
||||
#define CHECKVAL(op, expected) \
|
||||
if (checkval(#op, expected, op)) \
|
||||
return -1
|
||||
#define CHECKOK(op) CHECKVAL(op, 0)
|
||||
|
||||
/* maximum number of nodes / aliases to generate */
|
||||
#define MAX_NODES 20
|
||||
|
||||
/*
|
||||
* Make a test fdt
|
||||
*
|
||||
* @param fdt Device tree pointer
|
||||
* @param size Size of device tree blob
|
||||
* @param aliases Specifies alias assignments. Format is a list of items
|
||||
* separated by space. Items are #a where
|
||||
* # is the alias number
|
||||
* a is the node to point to
|
||||
* @param nodes Specifies nodes to generate (a=0, b=1), upper case
|
||||
* means to create a disabled node
|
||||
*/
|
||||
static int make_fdt(void *fdt, int size, const char *aliases,
|
||||
const char *nodes)
|
||||
{
|
||||
char name[20], value[20];
|
||||
const char *s;
|
||||
int fd;
|
||||
|
||||
CHECK(fdt_create(fdt, size));
|
||||
CHECK(fdt_finish_reservemap(fdt));
|
||||
CHECK(fdt_begin_node(fdt, ""));
|
||||
|
||||
CHECK(fdt_begin_node(fdt, "aliases"));
|
||||
for (s = aliases; *s;) {
|
||||
sprintf(name, "i2c%c", *s);
|
||||
sprintf(value, "/i2c%d@0", s[1] - 'a');
|
||||
CHECK(fdt_property_string(fdt, name, value));
|
||||
s += 2 + (s[2] != '\0');
|
||||
}
|
||||
CHECK(fdt_end_node(fdt));
|
||||
|
||||
for (s = nodes; *s; s++) {
|
||||
sprintf(value, "i2c%d@0", (*s & 0xdf) - 'A');
|
||||
CHECK(fdt_begin_node(fdt, value));
|
||||
CHECK(fdt_property_string(fdt, "compatible",
|
||||
fdtdec_get_compatible(COMPAT_UNKNOWN)));
|
||||
if (*s <= 'Z')
|
||||
CHECK(fdt_property_string(fdt, "status", "disabled"));
|
||||
CHECK(fdt_end_node(fdt));
|
||||
}
|
||||
|
||||
CHECK(fdt_end_node(fdt));
|
||||
CHECK(fdt_finish(fdt));
|
||||
CHECK(fdt_pack(fdt));
|
||||
#if defined(DEBUG) && defined(CONFIG_SANDBOX)
|
||||
fd = os_open("/tmp/fdtdec-text.dtb", OS_O_CREAT | OS_O_WRONLY);
|
||||
if (fd == -1) {
|
||||
printf("Could not open .dtb file to write\n");
|
||||
return -1;
|
||||
}
|
||||
os_write(fd, fdt, size);
|
||||
os_close(fd);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run_test(const char *aliases, const char *nodes, const char *expect)
|
||||
{
|
||||
int list[MAX_NODES];
|
||||
const char *s;
|
||||
void *blob;
|
||||
int i;
|
||||
|
||||
blob = malloc(FDT_SIZE);
|
||||
if (!blob) {
|
||||
printf("%s: out of memory\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("aliases=%s, nodes=%s, expect=%s: ", aliases, nodes, expect);
|
||||
CHECKVAL(make_fdt(blob, FDT_SIZE, aliases, nodes), 0);
|
||||
CHECKVAL(fdtdec_find_aliases_for_id(blob, "i2c",
|
||||
COMPAT_UNKNOWN,
|
||||
list, ARRAY_SIZE(list)), strlen(expect));
|
||||
|
||||
/* Check we got the right ones */
|
||||
for (i = 0, s = expect; *s; s++, i++) {
|
||||
int want = *s;
|
||||
const char *name;
|
||||
int got = ' ';
|
||||
|
||||
name = list[i] ? fdt_get_name(blob, list[i], NULL) : NULL;
|
||||
if (name)
|
||||
got = name[3] + 'a' - '0';
|
||||
|
||||
if (got != want) {
|
||||
printf("Position %d: Expected '%c', got '%c' ('%s')\n",
|
||||
i, want, got, name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("pass\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
/* basic tests */
|
||||
CHECKOK(run_test("", "", ""));
|
||||
CHECKOK(run_test("1e 3d", "", ""));
|
||||
|
||||
/*
|
||||
* 'a' represents 0, 'b' represents 1, etc.
|
||||
* The first character is the alias number, the second is the node
|
||||
* number. So the params mean:
|
||||
* 0a 1b : point alias 0 to node 0 (a), alias 1 to node 1(b)
|
||||
* ab : to create nodes 0 and 1 (a and b)
|
||||
* ab : we expect the function to return two nodes, in
|
||||
* the order 0, 1
|
||||
*/
|
||||
CHECKOK(run_test("0a 1b", "ab", "ab"));
|
||||
|
||||
CHECKOK(run_test("0a 1c", "ab", "ab"));
|
||||
CHECKOK(run_test("1c", "ab", "ab"));
|
||||
CHECKOK(run_test("1b", "ab", "ab"));
|
||||
CHECKOK(run_test("0b", "ab", "ba"));
|
||||
CHECKOK(run_test("0b 2d", "dbc", "bcd"));
|
||||
CHECKOK(run_test("0d 3a 1c 2b", "dbac", "dcba"));
|
||||
|
||||
/* things with holes */
|
||||
CHECKOK(run_test("1b 3d", "dbc", "cb d"));
|
||||
CHECKOK(run_test("1e 3d", "dbc", "bc d"));
|
||||
|
||||
/* no aliases */
|
||||
CHECKOK(run_test("", "dbac", "dbac"));
|
||||
|
||||
/* disabled nodes */
|
||||
CHECKOK(run_test("0d 3a 1c 2b", "dBac", "dc a"));
|
||||
CHECKOK(run_test("0b 2d", "DBc", "c"));
|
||||
CHECKOK(run_test("0b 4d 2c", "DBc", " c"));
|
||||
|
||||
/* conflicting aliases - first one gets it */
|
||||
CHECKOK(run_test("2a 1a 0a", "a", " a"));
|
||||
CHECKOK(run_test("0a 1a 2a", "a", "a"));
|
||||
|
||||
printf("Test passed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
test_fdtdec, 3, 1, do_test_fdtdec,
|
||||
"test_fdtdec",
|
||||
"Run tests for fdtdec library");
|
||||
120
common/package/utils/sysupgrade-helper/src/lib/gunzip.c
Normal file
120
common/package/utils/sysupgrade-helper/src/lib/gunzip.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* (C) Copyright 2000-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <malloc.h>
|
||||
#include <u-boot/zlib.h>
|
||||
|
||||
#define ZALLOC_ALIGNMENT 16
|
||||
#define HEAD_CRC 2
|
||||
#define EXTRA_FIELD 4
|
||||
#define ORIG_NAME 8
|
||||
#define COMMENT 0x10
|
||||
#define RESERVED 0xe0
|
||||
#define DEFLATED 8
|
||||
|
||||
void *gzalloc(void *x, unsigned items, unsigned size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
size *= items;
|
||||
size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
|
||||
|
||||
p = malloc (size);
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
void gzfree(void *x, void *addr, unsigned nb)
|
||||
{
|
||||
free (addr);
|
||||
}
|
||||
|
||||
int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
|
||||
{
|
||||
int i, flags;
|
||||
|
||||
/* skip header */
|
||||
i = 10;
|
||||
flags = src[3];
|
||||
if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
|
||||
puts ("Error: Bad gzipped data\n");
|
||||
return (-1);
|
||||
}
|
||||
if ((flags & EXTRA_FIELD) != 0)
|
||||
i = 12 + src[10] + (src[11] << 8);
|
||||
if ((flags & ORIG_NAME) != 0)
|
||||
while (src[i++] != 0)
|
||||
;
|
||||
if ((flags & COMMENT) != 0)
|
||||
while (src[i++] != 0)
|
||||
;
|
||||
if ((flags & HEAD_CRC) != 0)
|
||||
i += 2;
|
||||
if (i >= *lenp) {
|
||||
puts ("Error: gunzip out of data in header\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return zunzip(dst, dstlen, src, lenp, 1, i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Uncompress blocks compressed with zlib without headers
|
||||
*/
|
||||
int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
|
||||
int stoponerr, int offset)
|
||||
{
|
||||
z_stream s;
|
||||
int r;
|
||||
|
||||
s.zalloc = gzalloc;
|
||||
s.zfree = gzfree;
|
||||
|
||||
r = inflateInit2(&s, -MAX_WBITS);
|
||||
if (r != Z_OK) {
|
||||
printf ("Error: inflateInit2() returned %d\n", r);
|
||||
return -1;
|
||||
}
|
||||
s.next_in = src + offset;
|
||||
s.avail_in = *lenp - offset;
|
||||
s.next_out = dst;
|
||||
s.avail_out = dstlen;
|
||||
do {
|
||||
r = inflate(&s, Z_FINISH);
|
||||
if (r != Z_STREAM_END && r != Z_BUF_ERROR && stoponerr == 1) {
|
||||
printf("Error: inflate() returned %d\n", r);
|
||||
inflateEnd(&s);
|
||||
return -1;
|
||||
}
|
||||
s.avail_in = *lenp - offset - (int)(s.next_out - (unsigned char*)dst);
|
||||
s.avail_out = dstlen;
|
||||
} while (r == Z_BUF_ERROR);
|
||||
*lenp = s.next_out - (unsigned char *) dst;
|
||||
inflateEnd(&s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
767
common/package/utils/sysupgrade-helper/src/lib/hashtable.c
Normal file
767
common/package/utils/sysupgrade-helper/src/lib/hashtable.c
Normal file
|
|
@ -0,0 +1,767 @@
|
|||
/*
|
||||
* This implementation is based on code from uClibc-0.9.30.3 but was
|
||||
* modified and extended for use within U-Boot.
|
||||
*
|
||||
* Copyright (C) 2010 Wolfgang Denk <wd@denx.de>
|
||||
*
|
||||
* Original license header:
|
||||
*
|
||||
* Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
|
||||
* This file is part of the GNU C Library.
|
||||
* Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1993.
|
||||
*
|
||||
* The GNU C Library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* The GNU C Library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with the GNU C Library; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef USE_HOSTCC /* HOST build */
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include <ctype.h>
|
||||
|
||||
# ifndef debug
|
||||
# ifdef DEBUG
|
||||
# define debug(fmt,args...) printf(fmt ,##args)
|
||||
# else
|
||||
# define debug(fmt,args...)
|
||||
# endif
|
||||
# endif
|
||||
#else /* U-Boot build */
|
||||
# include <common.h>
|
||||
# include <linux/string.h>
|
||||
# include <linux/ctype.h>
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ENV_MIN_ENTRIES /* minimum number of entries */
|
||||
#define CONFIG_ENV_MIN_ENTRIES 64
|
||||
#endif
|
||||
#ifndef CONFIG_ENV_MAX_ENTRIES /* maximum number of entries */
|
||||
#define CONFIG_ENV_MAX_ENTRIES 512
|
||||
#endif
|
||||
|
||||
#include "search.h"
|
||||
|
||||
/*
|
||||
* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
|
||||
* [Knuth] The Art of Computer Programming, part 3 (6.4)
|
||||
*/
|
||||
|
||||
/*
|
||||
* The reentrant version has no static variables to maintain the state.
|
||||
* Instead the interface of all functions is extended to take an argument
|
||||
* which describes the current status.
|
||||
*/
|
||||
typedef struct _ENTRY {
|
||||
int used;
|
||||
ENTRY entry;
|
||||
} _ENTRY;
|
||||
|
||||
|
||||
/*
|
||||
* hcreate()
|
||||
*/
|
||||
|
||||
/*
|
||||
* For the used double hash method the table size has to be a prime. To
|
||||
* correct the user given table size we need a prime test. This trivial
|
||||
* algorithm is adequate because
|
||||
* a) the code is (most probably) called a few times per program run and
|
||||
* b) the number is small because the table must fit in the core
|
||||
* */
|
||||
static int isprime(unsigned int number)
|
||||
{
|
||||
/* no even number will be passed */
|
||||
unsigned int div = 3;
|
||||
|
||||
while (div * div < number && number % div != 0)
|
||||
div += 2;
|
||||
|
||||
return number % div != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before using the hash table we must allocate memory for it.
|
||||
* Test for an existing table are done. We allocate one element
|
||||
* more as the found prime number says. This is done for more effective
|
||||
* indexing as explained in the comment for the hsearch function.
|
||||
* The contents of the table is zeroed, especially the field used
|
||||
* becomes zero.
|
||||
*/
|
||||
|
||||
int hcreate_r(size_t nel, struct hsearch_data *htab)
|
||||
{
|
||||
/* Test for correct arguments. */
|
||||
if (htab == NULL) {
|
||||
__set_errno(EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* There is still another table active. Return with error. */
|
||||
if (htab->table != NULL)
|
||||
return 0;
|
||||
|
||||
/* Change nel to the first prime number not smaller as nel. */
|
||||
nel |= 1; /* make odd */
|
||||
while (!isprime(nel))
|
||||
nel += 2;
|
||||
|
||||
htab->size = nel;
|
||||
htab->filled = 0;
|
||||
|
||||
/* allocate memory and zero out */
|
||||
htab->table = (_ENTRY *) calloc(htab->size + 1, sizeof(_ENTRY));
|
||||
if (htab->table == NULL)
|
||||
return 0;
|
||||
|
||||
/* everything went alright */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hdestroy()
|
||||
*/
|
||||
|
||||
/*
|
||||
* After using the hash table it has to be destroyed. The used memory can
|
||||
* be freed and the local static variable can be marked as not used.
|
||||
*/
|
||||
|
||||
void hdestroy_r(struct hsearch_data *htab)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Test for correct arguments. */
|
||||
if (htab == NULL) {
|
||||
__set_errno(EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* free used memory */
|
||||
for (i = 1; i <= htab->size; ++i) {
|
||||
if (htab->table[i].used > 0) {
|
||||
ENTRY *ep = &htab->table[i].entry;
|
||||
|
||||
free((void *)ep->key);
|
||||
free(ep->data);
|
||||
}
|
||||
}
|
||||
free(htab->table);
|
||||
|
||||
/* the sign for an existing table is an value != NULL in htable */
|
||||
htab->table = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* hsearch()
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the search function. It uses double hashing with open addressing.
|
||||
* The argument item.key has to be a pointer to an zero terminated, most
|
||||
* probably strings of chars. The function for generating a number of the
|
||||
* strings is simple but fast. It can be replaced by a more complex function
|
||||
* like ajw (see [Aho,Sethi,Ullman]) if the needs are shown.
|
||||
*
|
||||
* We use an trick to speed up the lookup. The table is created by hcreate
|
||||
* with one more element available. This enables us to use the index zero
|
||||
* special. This index will never be used because we store the first hash
|
||||
* index in the field used where zero means not used. Every other value
|
||||
* means used. The used field can be used as a first fast comparison for
|
||||
* equality of the stored and the parameter value. This helps to prevent
|
||||
* unnecessary expensive calls of strcmp.
|
||||
*
|
||||
* This implementation differs from the standard library version of
|
||||
* this function in a number of ways:
|
||||
*
|
||||
* - While the standard version does not make any assumptions about
|
||||
* the type of the stored data objects at all, this implementation
|
||||
* works with NUL terminated strings only.
|
||||
* - Instead of storing just pointers to the original objects, we
|
||||
* create local copies so the caller does not need to care about the
|
||||
* data any more.
|
||||
* - The standard implementation does not provide a way to update an
|
||||
* existing entry. This version will create a new entry or update an
|
||||
* existing one when both "action == ENTER" and "item.data != NULL".
|
||||
* - Instead of returning 1 on success, we return the index into the
|
||||
* internal hash table, which is also guaranteed to be positive.
|
||||
* This allows us direct access to the found hash table slot for
|
||||
* example for functions like hdelete().
|
||||
*/
|
||||
|
||||
/*
|
||||
* hstrstr_r - return index to entry whose key and/or data contains match
|
||||
*/
|
||||
int hstrstr_r(const char *match, int last_idx, ENTRY ** retval,
|
||||
struct hsearch_data *htab)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
for (idx = last_idx + 1; idx < htab->size; ++idx) {
|
||||
if (htab->table[idx].used <= 0)
|
||||
continue;
|
||||
if (strstr(htab->table[idx].entry.key, match) ||
|
||||
strstr(htab->table[idx].entry.data, match)) {
|
||||
*retval = &htab->table[idx].entry;
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
__set_errno(ESRCH);
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
|
||||
struct hsearch_data *htab)
|
||||
{
|
||||
unsigned int idx;
|
||||
size_t key_len = strlen(match);
|
||||
|
||||
for (idx = last_idx + 1; idx < htab->size; ++idx) {
|
||||
if (htab->table[idx].used <= 0)
|
||||
continue;
|
||||
if (!strncmp(match, htab->table[idx].entry.key, key_len)) {
|
||||
*retval = &htab->table[idx].entry;
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
__set_errno(ESRCH);
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
|
||||
struct hsearch_data *htab)
|
||||
{
|
||||
unsigned int hval;
|
||||
unsigned int count;
|
||||
unsigned int len = strlen(item.key);
|
||||
unsigned int idx;
|
||||
unsigned int first_deleted = 0;
|
||||
|
||||
/* Compute an value for the given string. Perhaps use a better method. */
|
||||
hval = len;
|
||||
count = len;
|
||||
while (count-- > 0) {
|
||||
hval <<= 4;
|
||||
hval += item.key[count];
|
||||
}
|
||||
|
||||
/*
|
||||
* First hash function:
|
||||
* simply take the modul but prevent zero.
|
||||
*/
|
||||
hval %= htab->size;
|
||||
if (hval == 0)
|
||||
++hval;
|
||||
|
||||
/* The first index tried. */
|
||||
idx = hval;
|
||||
|
||||
if (htab->table[idx].used) {
|
||||
/*
|
||||
* Further action might be required according to the
|
||||
* action value.
|
||||
*/
|
||||
unsigned hval2;
|
||||
|
||||
if (htab->table[idx].used == -1
|
||||
&& !first_deleted)
|
||||
first_deleted = idx;
|
||||
|
||||
if (htab->table[idx].used == hval
|
||||
&& strcmp(item.key, htab->table[idx].entry.key) == 0) {
|
||||
/* Overwrite existing value? */
|
||||
if ((action == ENTER) && (item.data != NULL)) {
|
||||
free(htab->table[idx].entry.data);
|
||||
htab->table[idx].entry.data =
|
||||
strdup(item.data);
|
||||
if (!htab->table[idx].entry.data) {
|
||||
__set_errno(ENOMEM);
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* return found entry */
|
||||
*retval = &htab->table[idx].entry;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Second hash function:
|
||||
* as suggested in [Knuth]
|
||||
*/
|
||||
hval2 = 1 + hval % (htab->size - 2);
|
||||
|
||||
do {
|
||||
/*
|
||||
* Because SIZE is prime this guarantees to
|
||||
* step through all available indices.
|
||||
*/
|
||||
if (idx <= hval2)
|
||||
idx = htab->size + idx - hval2;
|
||||
else
|
||||
idx -= hval2;
|
||||
|
||||
/*
|
||||
* If we visited all entries leave the loop
|
||||
* unsuccessfully.
|
||||
*/
|
||||
if (idx == hval)
|
||||
break;
|
||||
|
||||
/* If entry is found use it. */
|
||||
if ((htab->table[idx].used == hval)
|
||||
&& strcmp(item.key, htab->table[idx].entry.key) == 0) {
|
||||
/* Overwrite existing value? */
|
||||
if ((action == ENTER) && (item.data != NULL)) {
|
||||
free(htab->table[idx].entry.data);
|
||||
htab->table[idx].entry.data =
|
||||
strdup(item.data);
|
||||
if (!htab->table[idx].entry.data) {
|
||||
__set_errno(ENOMEM);
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* return found entry */
|
||||
*retval = &htab->table[idx].entry;
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
while (htab->table[idx].used);
|
||||
}
|
||||
|
||||
/* An empty bucket has been found. */
|
||||
if (action == ENTER) {
|
||||
/*
|
||||
* If table is full and another entry should be
|
||||
* entered return with error.
|
||||
*/
|
||||
if (htab->filled == htab->size) {
|
||||
__set_errno(ENOMEM);
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create new entry;
|
||||
* create copies of item.key and item.data
|
||||
*/
|
||||
if (first_deleted)
|
||||
idx = first_deleted;
|
||||
|
||||
htab->table[idx].used = hval;
|
||||
htab->table[idx].entry.key = strdup(item.key);
|
||||
htab->table[idx].entry.data = strdup(item.data);
|
||||
if (!htab->table[idx].entry.key ||
|
||||
!htab->table[idx].entry.data) {
|
||||
__set_errno(ENOMEM);
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
++htab->filled;
|
||||
|
||||
/* return new entry */
|
||||
*retval = &htab->table[idx].entry;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__set_errno(ESRCH);
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hdelete()
|
||||
*/
|
||||
|
||||
/*
|
||||
* The standard implementation of hsearch(3) does not provide any way
|
||||
* to delete any entries from the hash table. We extend the code to
|
||||
* do that.
|
||||
*/
|
||||
|
||||
int hdelete_r(const char *key, struct hsearch_data *htab)
|
||||
{
|
||||
ENTRY e, *ep;
|
||||
int idx;
|
||||
|
||||
debug("hdelete: DELETE key \"%s\"\n", key);
|
||||
|
||||
e.key = (char *)key;
|
||||
|
||||
if ((idx = hsearch_r(e, FIND, &ep, htab)) == 0) {
|
||||
__set_errno(ESRCH);
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
/* free used ENTRY */
|
||||
debug("hdelete: DELETING key \"%s\"\n", key);
|
||||
|
||||
free((void *)ep->key);
|
||||
free(ep->data);
|
||||
htab->table[idx].used = -1;
|
||||
|
||||
--htab->filled;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* hexport()
|
||||
*/
|
||||
|
||||
/*
|
||||
* Export the data stored in the hash table in linearized form.
|
||||
*
|
||||
* Entries are exported as "name=value" strings, separated by an
|
||||
* arbitrary (non-NUL, of course) separator character. This allows to
|
||||
* use this function both when formatting the U-Boot environment for
|
||||
* external storage (using '\0' as separator), but also when using it
|
||||
* for the "printenv" command to print all variables, simply by using
|
||||
* as '\n" as separator. This can also be used for new features like
|
||||
* exporting the environment data as text file, including the option
|
||||
* for later re-import.
|
||||
*
|
||||
* The entries in the result list will be sorted by ascending key
|
||||
* values.
|
||||
*
|
||||
* If the separator character is different from NUL, then any
|
||||
* separator characters and backslash characters in the values will
|
||||
* be escaped by a preceeding backslash in output. This is needed for
|
||||
* example to enable multi-line values, especially when the output
|
||||
* shall later be parsed (for example, for re-import).
|
||||
*
|
||||
* There are several options how the result buffer is handled:
|
||||
*
|
||||
* *resp size
|
||||
* -----------
|
||||
* NULL 0 A string of sufficient length will be allocated.
|
||||
* NULL >0 A string of the size given will be
|
||||
* allocated. An error will be returned if the size is
|
||||
* not sufficient. Any unused bytes in the string will
|
||||
* be '\0'-padded.
|
||||
* !NULL 0 The user-supplied buffer will be used. No length
|
||||
* checking will be performed, i. e. it is assumed that
|
||||
* the buffer size will always be big enough. DANGEROUS.
|
||||
* !NULL >0 The user-supplied buffer will be used. An error will
|
||||
* be returned if the size is not sufficient. Any unused
|
||||
* bytes in the string will be '\0'-padded.
|
||||
*/
|
||||
|
||||
static int cmpkey(const void *p1, const void *p2)
|
||||
{
|
||||
ENTRY *e1 = *(ENTRY **) p1;
|
||||
ENTRY *e2 = *(ENTRY **) p2;
|
||||
|
||||
return (strcmp(e1->key, e2->key));
|
||||
}
|
||||
|
||||
ssize_t hexport_r(struct hsearch_data *htab, const char sep,
|
||||
char **resp, size_t size,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
ENTRY *list[htab->size];
|
||||
char *res, *p;
|
||||
size_t totlen;
|
||||
int i, n;
|
||||
|
||||
/* Test for correct arguments. */
|
||||
if ((resp == NULL) || (htab == NULL)) {
|
||||
__set_errno(EINVAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
debug("EXPORT table = %p, htab.size = %d, htab.filled = %d, "
|
||||
"size = %zu\n", htab, htab->size, htab->filled, size);
|
||||
/*
|
||||
* Pass 1:
|
||||
* search used entries,
|
||||
* save addresses and compute total length
|
||||
*/
|
||||
for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
|
||||
|
||||
if (htab->table[i].used > 0) {
|
||||
ENTRY *ep = &htab->table[i].entry;
|
||||
int arg, found = 0;
|
||||
|
||||
for (arg = 0; arg < argc; ++arg) {
|
||||
if (strcmp(argv[arg], ep->key) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((argc > 0) && (found == 0))
|
||||
continue;
|
||||
|
||||
list[n++] = ep;
|
||||
|
||||
totlen += strlen(ep->key) + 2;
|
||||
|
||||
if (sep == '\0') {
|
||||
totlen += strlen(ep->data);
|
||||
} else { /* check if escapes are needed */
|
||||
char *s = ep->data;
|
||||
|
||||
while (*s) {
|
||||
++totlen;
|
||||
/* add room for needed escape chars */
|
||||
if ((*s == sep) || (*s == '\\'))
|
||||
++totlen;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
totlen += 2; /* for '=' and 'sep' char */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Pass 1a: print unsorted list */
|
||||
printf("Unsorted: n=%d\n", n);
|
||||
for (i = 0; i < n; ++i) {
|
||||
printf("\t%3d: %p ==> %-10s => %s\n",
|
||||
i, list[i], list[i]->key, list[i]->data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Sort list by keys */
|
||||
qsort(list, n, sizeof(ENTRY *), cmpkey);
|
||||
|
||||
/* Check if the user supplied buffer size is sufficient */
|
||||
if (size) {
|
||||
if (size < totlen + 1) { /* provided buffer too small */
|
||||
printf("Env export buffer too small: %zu, "
|
||||
"but need %zu\n", size, totlen + 1);
|
||||
__set_errno(ENOMEM);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
size = totlen + 1;
|
||||
}
|
||||
|
||||
/* Check if the user provided a buffer */
|
||||
if (*resp) {
|
||||
/* yes; clear it */
|
||||
res = *resp;
|
||||
memset(res, '\0', size);
|
||||
} else {
|
||||
/* no, allocate and clear one */
|
||||
*resp = res = calloc(1, size);
|
||||
if (res == NULL) {
|
||||
__set_errno(ENOMEM);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Pass 2:
|
||||
* export sorted list of result data
|
||||
*/
|
||||
for (i = 0, p = res; i < n; ++i) {
|
||||
const char *s;
|
||||
|
||||
s = list[i]->key;
|
||||
while (*s)
|
||||
*p++ = *s++;
|
||||
*p++ = '=';
|
||||
|
||||
s = list[i]->data;
|
||||
|
||||
while (*s) {
|
||||
if ((*s == sep) || (*s == '\\'))
|
||||
*p++ = '\\'; /* escape */
|
||||
*p++ = *s++;
|
||||
}
|
||||
*p++ = sep;
|
||||
}
|
||||
*p = '\0'; /* terminate result */
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* himport()
|
||||
*/
|
||||
|
||||
/*
|
||||
* Import linearized data into hash table.
|
||||
*
|
||||
* This is the inverse function to hexport(): it takes a linear list
|
||||
* of "name=value" pairs and creates hash table entries from it.
|
||||
*
|
||||
* Entries without "value", i. e. consisting of only "name" or
|
||||
* "name=", will cause this entry to be deleted from the hash table.
|
||||
*
|
||||
* The "flag" argument can be used to control the behaviour: when the
|
||||
* H_NOCLEAR bit is set, then an existing hash table will kept, i. e.
|
||||
* new data will be added to an existing hash table; otherwise, old
|
||||
* data will be discarded and a new hash table will be created.
|
||||
*
|
||||
* The separator character for the "name=value" pairs can be selected,
|
||||
* so we both support importing from externally stored environment
|
||||
* data (separated by NUL characters) and from plain text files
|
||||
* (entries separated by newline characters).
|
||||
*
|
||||
* To allow for nicely formatted text input, leading white space
|
||||
* (sequences of SPACE and TAB chars) is ignored, and entries starting
|
||||
* (after removal of any leading white space) with a '#' character are
|
||||
* considered comments and ignored.
|
||||
*
|
||||
* [NOTE: this means that a variable name cannot start with a '#'
|
||||
* character.]
|
||||
*
|
||||
* When using a non-NUL separator character, backslash is used as
|
||||
* escape character in the value part, allowing for example for
|
||||
* multi-line values.
|
||||
*
|
||||
* In theory, arbitrary separator characters can be used, but only
|
||||
* '\0' and '\n' have really been tested.
|
||||
*/
|
||||
|
||||
int himport_r(struct hsearch_data *htab,
|
||||
const char *env, size_t size, const char sep, int flag)
|
||||
{
|
||||
char *data, *sp, *dp, *name, *value;
|
||||
|
||||
/* Test for correct arguments. */
|
||||
if (htab == NULL) {
|
||||
__set_errno(EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we allocate new space to make sure we can write to the array */
|
||||
if ((data = malloc(size)) == NULL) {
|
||||
debug("himport_r: can't malloc %zu bytes\n", size);
|
||||
__set_errno(ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
memcpy(data, env, size);
|
||||
dp = data;
|
||||
|
||||
if ((flag & H_NOCLEAR) == 0) {
|
||||
/* Destroy old hash table if one exists */
|
||||
debug("Destroy Hash Table: %p table = %p\n", htab,
|
||||
htab->table);
|
||||
if (htab->table)
|
||||
hdestroy_r(htab);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create new hash table (if needed). The computation of the hash
|
||||
* table size is based on heuristics: in a sample of some 70+
|
||||
* existing systems we found an average size of 39+ bytes per entry
|
||||
* in the environment (for the whole key=value pair). Assuming a
|
||||
* size of 8 per entry (= safety factor of ~5) should provide enough
|
||||
* safety margin for any existing environment definitions and still
|
||||
* allow for more than enough dynamic additions. Note that the
|
||||
* "size" argument is supposed to give the maximum enviroment size
|
||||
* (CONFIG_ENV_SIZE). This heuristics will result in
|
||||
* unreasonably large numbers (and thus memory footprint) for
|
||||
* big flash environments (>8,000 entries for 64 KB
|
||||
* envrionment size), so we clip it to a reasonable value.
|
||||
* On the other hand we need to add some more entries for free
|
||||
* space when importing very small buffers. Both boundaries can
|
||||
* be overwritten in the board config file if needed.
|
||||
*/
|
||||
|
||||
if (!htab->table) {
|
||||
int nent = CONFIG_ENV_MIN_ENTRIES + size / 8;
|
||||
|
||||
if (nent > CONFIG_ENV_MAX_ENTRIES)
|
||||
nent = CONFIG_ENV_MAX_ENTRIES;
|
||||
|
||||
debug("Create Hash Table: N=%d\n", nent);
|
||||
|
||||
if (hcreate_r(nent, htab) == 0) {
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse environment; allow for '\0' and 'sep' as separators */
|
||||
do {
|
||||
ENTRY e, *rv;
|
||||
|
||||
/* skip leading white space */
|
||||
while (isblank(*dp))
|
||||
++dp;
|
||||
|
||||
/* skip comment lines */
|
||||
if (*dp == '#') {
|
||||
while (*dp && (*dp != sep))
|
||||
++dp;
|
||||
++dp;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* parse name */
|
||||
for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp)
|
||||
;
|
||||
|
||||
/* deal with "name" and "name=" entries (delete var) */
|
||||
if (*dp == '\0' || *(dp + 1) == '\0' ||
|
||||
*dp == sep || *(dp + 1) == sep) {
|
||||
if (*dp == '=')
|
||||
*dp++ = '\0';
|
||||
*dp++ = '\0'; /* terminate name */
|
||||
|
||||
debug("DELETE CANDIDATE: \"%s\"\n", name);
|
||||
|
||||
if (hdelete_r(name, htab) == 0)
|
||||
debug("DELETE ERROR ##############################\n");
|
||||
|
||||
continue;
|
||||
}
|
||||
*dp++ = '\0'; /* terminate name */
|
||||
|
||||
/* parse value; deal with escapes */
|
||||
for (value = sp = dp; *dp && (*dp != sep); ++dp) {
|
||||
if ((*dp == '\\') && *(dp + 1))
|
||||
++dp;
|
||||
*sp++ = *dp;
|
||||
}
|
||||
*sp++ = '\0'; /* terminate value */
|
||||
++dp;
|
||||
|
||||
/* enter into hash table */
|
||||
e.key = name;
|
||||
e.data = value;
|
||||
|
||||
hsearch_r(e, ENTER, &rv, htab);
|
||||
if (rv == NULL) {
|
||||
printf("himport_r: can't insert \"%s=%s\" into hash table\n",
|
||||
name, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n",
|
||||
htab, htab->filled, htab->size,
|
||||
rv, name, value);
|
||||
} while ((dp < data + size) && *dp); /* size check needed for text */
|
||||
/* without '\0' termination */
|
||||
debug("INSERT: free(data = %p)\n", data);
|
||||
free(data);
|
||||
|
||||
debug("INSERT: done\n");
|
||||
return 1; /* everything OK */
|
||||
}
|
||||
55
common/package/utils/sysupgrade-helper/src/lib/ldiv.c
Normal file
55
common/package/utils/sysupgrade-helper/src/lib/ldiv.c
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
typedef struct {
|
||||
long quot;
|
||||
long rem;
|
||||
} ldiv_t;
|
||||
/* Return the `ldiv_t' representation of NUMER over DENOM. */
|
||||
ldiv_t
|
||||
ldiv (long int numer, long int denom)
|
||||
{
|
||||
ldiv_t result;
|
||||
|
||||
result.quot = numer / denom;
|
||||
result.rem = numer % denom;
|
||||
|
||||
/* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where
|
||||
NUMER / DENOM is to be computed in infinite precision. In
|
||||
other words, we should always truncate the quotient towards
|
||||
zero, never -infinity. Machine division and remainer may
|
||||
work either way when one or both of NUMER or DENOM is
|
||||
negative. If only one is negative and QUOT has been
|
||||
truncated towards -infinity, REM will have the same sign as
|
||||
DENOM and the opposite sign of NUMER; if both are negative
|
||||
and QUOT has been truncated towards -infinity, REM will be
|
||||
positive (will have the opposite sign of NUMER). These are
|
||||
considered `wrong'. If both are NUM and DENOM are positive,
|
||||
RESULT will always be positive. This all boils down to: if
|
||||
NUMER >= 0, but REM < 0, we got the wrong answer. In that
|
||||
case, to get the right answer, add 1 to QUOT and subtract
|
||||
DENOM from REM. */
|
||||
|
||||
if (numer >= 0 && result.rem < 0)
|
||||
{
|
||||
++result.quot;
|
||||
result.rem -= denom;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (C) Copyright 2000-2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)libfdt.o
|
||||
|
||||
SOBJS =
|
||||
|
||||
COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
|
||||
|
||||
COBJS-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt)
|
||||
COBJS-$(CONFIG_FIT) += $(COBJS-libfdt)
|
||||
|
||||
|
||||
COBJS := $(sort $(COBJS-y))
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
23
common/package/utils/sysupgrade-helper/src/lib/libfdt/README
Normal file
23
common/package/utils/sysupgrade-helper/src/lib/libfdt/README
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
The libfdt functionality was written by David Gibson. The original
|
||||
source came from the git repository:
|
||||
|
||||
URL: git://ozlabs.org/home/dgibson/git/libfdt.git
|
||||
|
||||
author David Gibson <dgibson@sneetch.(none)>
|
||||
Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
|
||||
committer David Gibson <dgibson@sneetch.(none)>
|
||||
Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
|
||||
commit 857f54e79f74429af20c2b5ecc00ee98af6a3b8b
|
||||
tree 2f648f0f88225a51ded452968d28b4402df8ade0
|
||||
parent 07a12a08005f3b5cd9337900a6551e450c07b515
|
||||
|
||||
To adapt for u-boot usage, only the applicable files were copied and
|
||||
imported into the u-boot git repository.
|
||||
Omitted:
|
||||
* GPL - u-boot comes with a copy of the GPL license
|
||||
* test subdirectory - not directly useful for u-boot
|
||||
|
||||
After importing, other customizations were performed. See the git log
|
||||
for details.
|
||||
|
||||
Jerry Van Baren
|
||||
240
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt.c
Normal file
240
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt.c
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
#define UINT_MAX (~0U)
|
||||
|
||||
int fdt_check_header(const void *fdt)
|
||||
{
|
||||
if (fdt_magic(fdt) == FDT_MAGIC) {
|
||||
/* Complete tree */
|
||||
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
|
||||
return -FDT_ERR_BADVERSION;
|
||||
if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
|
||||
return -FDT_ERR_BADVERSION;
|
||||
} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
|
||||
/* Unfinished sequential-write blob */
|
||||
if (fdt_size_dt_struct(fdt) == 0)
|
||||
return -FDT_ERR_BADSTATE;
|
||||
} else {
|
||||
return -FDT_ERR_BADMAGIC;
|
||||
}
|
||||
|
||||
if (fdt_off_dt_struct(fdt) > (UINT_MAX - fdt_size_dt_struct(fdt)))
|
||||
return FDT_ERR_BADOFFSET;
|
||||
|
||||
if (fdt_off_dt_strings(fdt) > (UINT_MAX - fdt_size_dt_strings(fdt)))
|
||||
return FDT_ERR_BADOFFSET;
|
||||
|
||||
if ((fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt)) > fdt_totalsize(fdt))
|
||||
return FDT_ERR_BADOFFSET;
|
||||
|
||||
if ((fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)) > fdt_totalsize(fdt))
|
||||
return FDT_ERR_BADOFFSET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (fdt_version(fdt) >= 0x11)
|
||||
if (((offset + len) < offset)
|
||||
|| ((offset + len) > fdt_size_dt_struct(fdt)))
|
||||
return NULL;
|
||||
|
||||
p = _fdt_offset_ptr(fdt, offset);
|
||||
|
||||
if (p + len < p)
|
||||
return NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
|
||||
{
|
||||
const uint32_t *tagp, *lenp;
|
||||
uint32_t tag;
|
||||
int offset = startoffset;
|
||||
const char *p;
|
||||
|
||||
*nextoffset = -FDT_ERR_TRUNCATED;
|
||||
tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
|
||||
if (!tagp)
|
||||
return FDT_END; /* premature end */
|
||||
tag = fdt32_to_cpu(*tagp);
|
||||
offset += FDT_TAGSIZE;
|
||||
|
||||
*nextoffset = -FDT_ERR_BADSTRUCTURE;
|
||||
switch (tag) {
|
||||
case FDT_BEGIN_NODE:
|
||||
/* skip name */
|
||||
do {
|
||||
p = fdt_offset_ptr(fdt, offset++, 1);
|
||||
} while (p && (*p != '\0'));
|
||||
if (!p)
|
||||
return FDT_END; /* premature end */
|
||||
break;
|
||||
|
||||
case FDT_PROP:
|
||||
lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
|
||||
if (!lenp)
|
||||
return FDT_END; /* premature end */
|
||||
/* skip-name offset, length and value */
|
||||
offset += sizeof(struct fdt_property) - FDT_TAGSIZE
|
||||
+ fdt32_to_cpu(*lenp);
|
||||
break;
|
||||
|
||||
case FDT_END:
|
||||
case FDT_END_NODE:
|
||||
case FDT_NOP:
|
||||
break;
|
||||
|
||||
default:
|
||||
return FDT_END;
|
||||
}
|
||||
|
||||
if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
|
||||
return FDT_END; /* premature end */
|
||||
|
||||
*nextoffset = FDT_TAGALIGN(offset);
|
||||
return tag;
|
||||
}
|
||||
|
||||
int _fdt_check_node_offset(const void *fdt, int offset)
|
||||
{
|
||||
if ((offset < 0) || (offset % FDT_TAGSIZE)
|
||||
|| (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
|
||||
return -FDT_ERR_BADOFFSET;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
int _fdt_check_prop_offset(const void *fdt, int offset)
|
||||
{
|
||||
if ((offset < 0) || (offset % FDT_TAGSIZE)
|
||||
|| (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
|
||||
return -FDT_ERR_BADOFFSET;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
int fdt_next_node(const void *fdt, int offset, int *depth)
|
||||
{
|
||||
int nextoffset = 0;
|
||||
uint32_t tag;
|
||||
|
||||
if (offset >= 0)
|
||||
if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
|
||||
return nextoffset;
|
||||
|
||||
do {
|
||||
offset = nextoffset;
|
||||
tag = fdt_next_tag(fdt, offset, &nextoffset);
|
||||
|
||||
switch (tag) {
|
||||
case FDT_PROP:
|
||||
case FDT_NOP:
|
||||
break;
|
||||
|
||||
case FDT_BEGIN_NODE:
|
||||
if (depth)
|
||||
(*depth)++;
|
||||
break;
|
||||
|
||||
case FDT_END_NODE:
|
||||
if (depth && ((--(*depth)) < 0))
|
||||
return nextoffset;
|
||||
break;
|
||||
|
||||
case FDT_END:
|
||||
if ((nextoffset >= 0)
|
||||
|| ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
else
|
||||
return nextoffset;
|
||||
}
|
||||
} while (tag != FDT_BEGIN_NODE);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
|
||||
{
|
||||
int len = strlen(s) + 1;
|
||||
const char *last = strtab + tabsize - len;
|
||||
const char *p;
|
||||
|
||||
for (p = strtab; p <= last; p++)
|
||||
if (memcmp(p, s, len) == 0)
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fdt_move(const void *fdt, void *buf, int bufsize)
|
||||
{
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
if (fdt_totalsize(fdt) > bufsize)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
memmove(buf, fdt, fdt_totalsize(fdt));
|
||||
return 0;
|
||||
}
|
||||
578
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_ro.c
Normal file
578
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_ro.c
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
static int _fdt_nodename_eq(const void *fdt, int offset,
|
||||
const char *s, int len)
|
||||
{
|
||||
const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
|
||||
|
||||
if (! p)
|
||||
/* short match */
|
||||
return 0;
|
||||
|
||||
if (memcmp(p, s, len) != 0)
|
||||
return 0;
|
||||
|
||||
if (p[len] == '\0')
|
||||
return 1;
|
||||
else if (!memchr(s, '@', len) && (p[len] == '@'))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *fdt_string(const void *fdt, int stroffset)
|
||||
{
|
||||
return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
|
||||
}
|
||||
|
||||
static int _fdt_string_eq(const void *fdt, int stroffset,
|
||||
const char *s, int len)
|
||||
{
|
||||
const char *p = fdt_string(fdt, stroffset);
|
||||
|
||||
return (strlen(p) == len) && (memcmp(p, s, len) == 0);
|
||||
}
|
||||
|
||||
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
|
||||
{
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
|
||||
*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_num_mem_rsv(const void *fdt)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int _nextprop(const void *fdt, int offset)
|
||||
{
|
||||
uint32_t tag;
|
||||
int nextoffset;
|
||||
|
||||
do {
|
||||
tag = fdt_next_tag(fdt, offset, &nextoffset);
|
||||
|
||||
switch (tag) {
|
||||
case FDT_END:
|
||||
if (nextoffset >= 0)
|
||||
return -FDT_ERR_BADSTRUCTURE;
|
||||
else
|
||||
return nextoffset;
|
||||
|
||||
case FDT_PROP:
|
||||
return offset;
|
||||
}
|
||||
offset = nextoffset;
|
||||
} while (tag == FDT_NOP);
|
||||
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
}
|
||||
|
||||
int fdt_subnode_offset_namelen(const void *fdt, int offset,
|
||||
const char *name, int namelen)
|
||||
{
|
||||
int depth;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
for (depth = 0;
|
||||
(offset >= 0) && (depth >= 0);
|
||||
offset = fdt_next_node(fdt, offset, &depth))
|
||||
if ((depth == 1)
|
||||
&& _fdt_nodename_eq(fdt, offset, name, namelen))
|
||||
return offset;
|
||||
|
||||
if (depth < 0)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
return offset; /* error */
|
||||
}
|
||||
|
||||
int fdt_subnode_offset(const void *fdt, int parentoffset,
|
||||
const char *name)
|
||||
{
|
||||
return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
|
||||
}
|
||||
|
||||
int fdt_path_offset(const void *fdt, const char *path)
|
||||
{
|
||||
const char *end = path + strlen(path);
|
||||
const char *p = path;
|
||||
int offset = 0;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
/* see if we have an alias */
|
||||
if (*path != '/') {
|
||||
const char *q = strchr(path, '/');
|
||||
|
||||
if (!q)
|
||||
q = end;
|
||||
|
||||
p = fdt_get_alias_namelen(fdt, p, q - p);
|
||||
if (!p)
|
||||
return -FDT_ERR_BADPATH;
|
||||
offset = fdt_path_offset(fdt, p);
|
||||
|
||||
p = q;
|
||||
}
|
||||
|
||||
while (*p) {
|
||||
const char *q;
|
||||
|
||||
while (*p == '/')
|
||||
p++;
|
||||
if (! *p)
|
||||
return offset;
|
||||
q = strchr(p, '/');
|
||||
if (! q)
|
||||
q = end;
|
||||
|
||||
offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
|
||||
p = q;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
|
||||
{
|
||||
const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
|
||||
int err;
|
||||
|
||||
if (((err = fdt_check_header(fdt)) != 0)
|
||||
|| ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
|
||||
goto fail;
|
||||
|
||||
if (len)
|
||||
*len = strlen(nh->name);
|
||||
|
||||
return nh->name;
|
||||
|
||||
fail:
|
||||
if (len)
|
||||
*len = err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fdt_first_property_offset(const void *fdt, int nodeoffset)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
|
||||
return offset;
|
||||
|
||||
return _nextprop(fdt, offset);
|
||||
}
|
||||
|
||||
int fdt_next_property_offset(const void *fdt, int offset)
|
||||
{
|
||||
if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
|
||||
return offset;
|
||||
|
||||
return _nextprop(fdt, offset);
|
||||
}
|
||||
|
||||
const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
|
||||
int offset,
|
||||
int *lenp)
|
||||
{
|
||||
int err;
|
||||
const struct fdt_property *prop;
|
||||
|
||||
if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
|
||||
if (lenp)
|
||||
*lenp = err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = _fdt_offset_ptr(fdt, offset);
|
||||
|
||||
if (lenp)
|
||||
*lenp = fdt32_to_cpu(prop->len);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
const struct fdt_property *fdt_get_property_namelen(const void *fdt,
|
||||
int offset,
|
||||
const char *name,
|
||||
int namelen, int *lenp)
|
||||
{
|
||||
for (offset = fdt_first_property_offset(fdt, offset);
|
||||
(offset >= 0);
|
||||
(offset = fdt_next_property_offset(fdt, offset))) {
|
||||
const struct fdt_property *prop;
|
||||
|
||||
if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
|
||||
offset = -FDT_ERR_INTERNAL;
|
||||
break;
|
||||
}
|
||||
if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
|
||||
name, namelen))
|
||||
return prop;
|
||||
}
|
||||
|
||||
if (lenp)
|
||||
*lenp = offset;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct fdt_property *fdt_get_property(const void *fdt,
|
||||
int nodeoffset,
|
||||
const char *name, int *lenp)
|
||||
{
|
||||
return fdt_get_property_namelen(fdt, nodeoffset, name,
|
||||
strlen(name), lenp);
|
||||
}
|
||||
|
||||
const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
|
||||
const char *name, int namelen, int *lenp)
|
||||
{
|
||||
const struct fdt_property *prop;
|
||||
|
||||
prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
|
||||
if (! prop)
|
||||
return NULL;
|
||||
|
||||
return prop->data;
|
||||
}
|
||||
|
||||
const void *fdt_getprop_by_offset(const void *fdt, int offset,
|
||||
const char **namep, int *lenp)
|
||||
{
|
||||
const struct fdt_property *prop;
|
||||
|
||||
prop = fdt_get_property_by_offset(fdt, offset, lenp);
|
||||
if (!prop)
|
||||
return NULL;
|
||||
if (namep)
|
||||
*namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
|
||||
return prop->data;
|
||||
}
|
||||
|
||||
const void *fdt_getprop(const void *fdt, int nodeoffset,
|
||||
const char *name, int *lenp)
|
||||
{
|
||||
return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
|
||||
}
|
||||
|
||||
uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
|
||||
{
|
||||
const uint32_t *php;
|
||||
int len;
|
||||
|
||||
/* FIXME: This is a bit sub-optimal, since we potentially scan
|
||||
* over all the properties twice. */
|
||||
php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
|
||||
if (!php || (len != sizeof(*php))) {
|
||||
php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
|
||||
if (!php || (len != sizeof(*php)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fdt32_to_cpu(*php);
|
||||
}
|
||||
|
||||
const char *fdt_get_alias_namelen(const void *fdt,
|
||||
const char *name, int namelen)
|
||||
{
|
||||
int aliasoffset;
|
||||
|
||||
aliasoffset = fdt_path_offset(fdt, "/aliases");
|
||||
if (aliasoffset < 0)
|
||||
return NULL;
|
||||
|
||||
return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
|
||||
}
|
||||
|
||||
const char *fdt_get_alias(const void *fdt, const char *name)
|
||||
{
|
||||
return fdt_get_alias_namelen(fdt, name, strlen(name));
|
||||
}
|
||||
|
||||
int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
|
||||
{
|
||||
int pdepth = 0, p = 0;
|
||||
int offset, depth, namelen;
|
||||
const char *name;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
if (buflen < 2)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
for (offset = 0, depth = 0;
|
||||
(offset >= 0) && (offset <= nodeoffset);
|
||||
offset = fdt_next_node(fdt, offset, &depth)) {
|
||||
while (pdepth > depth) {
|
||||
do {
|
||||
p--;
|
||||
} while (buf[p-1] != '/');
|
||||
pdepth--;
|
||||
}
|
||||
|
||||
if (pdepth >= depth) {
|
||||
name = fdt_get_name(fdt, offset, &namelen);
|
||||
if (!name)
|
||||
return namelen;
|
||||
if ((p + namelen + 1) <= buflen) {
|
||||
memcpy(buf + p, name, namelen);
|
||||
p += namelen;
|
||||
buf[p++] = '/';
|
||||
pdepth++;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset == nodeoffset) {
|
||||
if (pdepth < (depth + 1))
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
if (p > 1) /* special case so that root path is "/", not "" */
|
||||
p--;
|
||||
buf[p] = '\0';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
|
||||
return -FDT_ERR_BADOFFSET;
|
||||
else if (offset == -FDT_ERR_BADOFFSET)
|
||||
return -FDT_ERR_BADSTRUCTURE;
|
||||
|
||||
return offset; /* error from fdt_next_node() */
|
||||
}
|
||||
|
||||
int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
|
||||
int supernodedepth, int *nodedepth)
|
||||
{
|
||||
int offset, depth;
|
||||
int supernodeoffset = -FDT_ERR_INTERNAL;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
if (supernodedepth < 0)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
|
||||
for (offset = 0, depth = 0;
|
||||
(offset >= 0) && (offset <= nodeoffset);
|
||||
offset = fdt_next_node(fdt, offset, &depth)) {
|
||||
if (depth == supernodedepth)
|
||||
supernodeoffset = offset;
|
||||
|
||||
if (offset == nodeoffset) {
|
||||
if (nodedepth)
|
||||
*nodedepth = depth;
|
||||
|
||||
if (supernodedepth > depth)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
else
|
||||
return supernodeoffset;
|
||||
}
|
||||
}
|
||||
|
||||
if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
|
||||
return -FDT_ERR_BADOFFSET;
|
||||
else if (offset == -FDT_ERR_BADOFFSET)
|
||||
return -FDT_ERR_BADSTRUCTURE;
|
||||
|
||||
return offset; /* error from fdt_next_node() */
|
||||
}
|
||||
|
||||
int fdt_node_depth(const void *fdt, int nodeoffset)
|
||||
{
|
||||
int nodedepth;
|
||||
int err;
|
||||
|
||||
err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
|
||||
if (err)
|
||||
return (err < 0) ? err : -FDT_ERR_INTERNAL;
|
||||
return nodedepth;
|
||||
}
|
||||
|
||||
int fdt_parent_offset(const void *fdt, int nodeoffset)
|
||||
{
|
||||
int nodedepth = fdt_node_depth(fdt, nodeoffset);
|
||||
|
||||
if (nodedepth < 0)
|
||||
return nodedepth;
|
||||
return fdt_supernode_atdepth_offset(fdt, nodeoffset,
|
||||
nodedepth - 1, NULL);
|
||||
}
|
||||
|
||||
int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
|
||||
const char *propname,
|
||||
const void *propval, int proplen)
|
||||
{
|
||||
int offset;
|
||||
const void *val;
|
||||
int len;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
/* FIXME: The algorithm here is pretty horrible: we scan each
|
||||
* property of a node in fdt_getprop(), then if that didn't
|
||||
* find what we want, we scan over them again making our way
|
||||
* to the next node. Still it's the easiest to implement
|
||||
* approach; performance can come later. */
|
||||
for (offset = fdt_next_node(fdt, startoffset, NULL);
|
||||
offset >= 0;
|
||||
offset = fdt_next_node(fdt, offset, NULL)) {
|
||||
val = fdt_getprop(fdt, offset, propname, &len);
|
||||
if (val && (len == proplen)
|
||||
&& (memcmp(val, propval, len) == 0))
|
||||
return offset;
|
||||
}
|
||||
|
||||
return offset; /* error from fdt_next_node() */
|
||||
}
|
||||
|
||||
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
|
||||
{
|
||||
int offset;
|
||||
|
||||
if ((phandle == 0) || (phandle == -1))
|
||||
return -FDT_ERR_BADPHANDLE;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
/* FIXME: The algorithm here is pretty horrible: we
|
||||
* potentially scan each property of a node in
|
||||
* fdt_get_phandle(), then if that didn't find what
|
||||
* we want, we scan over them again making our way to the next
|
||||
* node. Still it's the easiest to implement approach;
|
||||
* performance can come later. */
|
||||
for (offset = fdt_next_node(fdt, -1, NULL);
|
||||
offset >= 0;
|
||||
offset = fdt_next_node(fdt, offset, NULL)) {
|
||||
if (fdt_get_phandle(fdt, offset) == phandle)
|
||||
return offset;
|
||||
}
|
||||
|
||||
return offset; /* error from fdt_next_node() */
|
||||
}
|
||||
|
||||
static int _fdt_stringlist_contains(const char *strlist, int listlen,
|
||||
const char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
const char *p;
|
||||
|
||||
while (listlen >= len) {
|
||||
if (memcmp(str, strlist, len+1) == 0)
|
||||
return 1;
|
||||
p = memchr(strlist, '\0', listlen);
|
||||
if (!p)
|
||||
return 0; /* malformed strlist.. */
|
||||
listlen -= (p-strlist) + 1;
|
||||
strlist = p + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_node_check_compatible(const void *fdt, int nodeoffset,
|
||||
const char *compatible)
|
||||
{
|
||||
const void *prop;
|
||||
int len;
|
||||
|
||||
prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
|
||||
if (!prop)
|
||||
return len;
|
||||
if (_fdt_stringlist_contains(prop, len, compatible))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
|
||||
const char *compatible)
|
||||
{
|
||||
int offset, err;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
/* FIXME: The algorithm here is pretty horrible: we scan each
|
||||
* property of a node in fdt_node_check_compatible(), then if
|
||||
* that didn't find what we want, we scan over them again
|
||||
* making our way to the next node. Still it's the easiest to
|
||||
* implement approach; performance can come later. */
|
||||
for (offset = fdt_next_node(fdt, startoffset, NULL);
|
||||
offset >= 0;
|
||||
offset = fdt_next_node(fdt, offset, NULL)) {
|
||||
err = fdt_node_check_compatible(fdt, offset, compatible);
|
||||
if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
|
||||
return err;
|
||||
else if (err == 0)
|
||||
return offset;
|
||||
}
|
||||
|
||||
return offset; /* error from fdt_next_node() */
|
||||
}
|
||||
469
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_rw.c
Normal file
469
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_rw.c
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
static int _fdt_blocks_misordered(const void *fdt,
|
||||
int mem_rsv_size, int struct_size)
|
||||
{
|
||||
return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
|
||||
|| (fdt_off_dt_struct(fdt) <
|
||||
(fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
|
||||
|| (fdt_off_dt_strings(fdt) <
|
||||
(fdt_off_dt_struct(fdt) + struct_size))
|
||||
|| (fdt_totalsize(fdt) <
|
||||
(fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
|
||||
}
|
||||
|
||||
static int _fdt_rw_check_header(void *fdt)
|
||||
{
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
if (fdt_version(fdt) < 17)
|
||||
return -FDT_ERR_BADVERSION;
|
||||
if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
|
||||
fdt_size_dt_struct(fdt)))
|
||||
return -FDT_ERR_BADLAYOUT;
|
||||
if (fdt_version(fdt) > 17)
|
||||
fdt_set_version(fdt, 17);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FDT_RW_CHECK_HEADER(fdt) \
|
||||
{ \
|
||||
int err; \
|
||||
if ((err = _fdt_rw_check_header(fdt)) != 0) \
|
||||
return err; \
|
||||
}
|
||||
|
||||
static inline int _fdt_data_size(void *fdt)
|
||||
{
|
||||
return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
|
||||
}
|
||||
|
||||
static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
|
||||
{
|
||||
char *p = splicepoint;
|
||||
char *end = (char *)fdt + _fdt_data_size(fdt);
|
||||
|
||||
if (((p + oldlen) < p) || ((p + oldlen) > end))
|
||||
return -FDT_ERR_BADOFFSET;
|
||||
if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
|
||||
return -FDT_ERR_NOSPACE;
|
||||
memmove(p + newlen, p + oldlen, end - p - oldlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
|
||||
int oldn, int newn)
|
||||
{
|
||||
int delta = (newn - oldn) * sizeof(*p);
|
||||
int err;
|
||||
err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
|
||||
if (err)
|
||||
return err;
|
||||
fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
|
||||
fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fdt_splice_struct(void *fdt, void *p,
|
||||
int oldlen, int newlen)
|
||||
{
|
||||
int delta = newlen - oldlen;
|
||||
int err;
|
||||
|
||||
if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
|
||||
return err;
|
||||
|
||||
fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
|
||||
fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fdt_splice_string(void *fdt, int newlen)
|
||||
{
|
||||
void *p = (char *)fdt
|
||||
+ fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
|
||||
int err;
|
||||
|
||||
if ((err = _fdt_splice(fdt, p, 0, newlen)))
|
||||
return err;
|
||||
|
||||
fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fdt_find_add_string(void *fdt, const char *s)
|
||||
{
|
||||
char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
|
||||
const char *p;
|
||||
char *new;
|
||||
int len = strlen(s) + 1;
|
||||
int err;
|
||||
|
||||
p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
|
||||
if (p)
|
||||
/* found it */
|
||||
return (p - strtab);
|
||||
|
||||
new = strtab + fdt_size_dt_strings(fdt);
|
||||
err = _fdt_splice_string(fdt, len);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memcpy(new, s, len);
|
||||
return (new - strtab);
|
||||
}
|
||||
|
||||
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
|
||||
{
|
||||
struct fdt_reserve_entry *re;
|
||||
int err;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
|
||||
err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
re->address = cpu_to_fdt64(address);
|
||||
re->size = cpu_to_fdt64(size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_del_mem_rsv(void *fdt, int n)
|
||||
{
|
||||
struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
|
||||
int err;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
if (n >= fdt_num_mem_rsv(fdt))
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
|
||||
err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
|
||||
if (err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
|
||||
int len, struct fdt_property **prop)
|
||||
{
|
||||
int oldlen;
|
||||
int err;
|
||||
|
||||
*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
|
||||
if (! (*prop))
|
||||
return oldlen;
|
||||
|
||||
if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
|
||||
FDT_TAGALIGN(len))))
|
||||
return err;
|
||||
|
||||
(*prop)->len = cpu_to_fdt32(len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
|
||||
int len, struct fdt_property **prop)
|
||||
{
|
||||
int proplen;
|
||||
int nextoffset;
|
||||
int namestroff;
|
||||
int err;
|
||||
|
||||
if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
|
||||
return nextoffset;
|
||||
|
||||
namestroff = _fdt_find_add_string(fdt, name);
|
||||
if (namestroff < 0)
|
||||
return namestroff;
|
||||
|
||||
*prop = _fdt_offset_ptr_w(fdt, nextoffset);
|
||||
proplen = sizeof(**prop) + FDT_TAGALIGN(len);
|
||||
|
||||
err = _fdt_splice_struct(fdt, *prop, 0, proplen);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
(*prop)->tag = cpu_to_fdt32(FDT_PROP);
|
||||
(*prop)->nameoff = cpu_to_fdt32(namestroff);
|
||||
(*prop)->len = cpu_to_fdt32(len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_set_name(void *fdt, int nodeoffset, const char *name)
|
||||
{
|
||||
char *namep;
|
||||
int oldlen, newlen;
|
||||
int err;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
|
||||
if (!namep)
|
||||
return oldlen;
|
||||
|
||||
newlen = strlen(name);
|
||||
|
||||
err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
|
||||
FDT_TAGALIGN(newlen+1));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memcpy(namep, name, newlen+1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
int err;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
|
||||
if (err == -FDT_ERR_NOTFOUND)
|
||||
err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memcpy(prop->data, val, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_delprop(void *fdt, int nodeoffset, const char *name)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
int len, proplen;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
|
||||
if (! prop)
|
||||
return len;
|
||||
|
||||
proplen = sizeof(*prop) + FDT_TAGALIGN(len);
|
||||
return _fdt_splice_struct(fdt, prop, proplen, 0);
|
||||
}
|
||||
|
||||
int fdt_add_subnode_namelen(void *fdt, int parentoffset,
|
||||
const char *name, int namelen)
|
||||
{
|
||||
struct fdt_node_header *nh;
|
||||
int offset, nextoffset;
|
||||
int nodelen;
|
||||
int err;
|
||||
uint32_t tag;
|
||||
uint32_t *endtag;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
|
||||
if (offset >= 0)
|
||||
return -FDT_ERR_EXISTS;
|
||||
else if (offset != -FDT_ERR_NOTFOUND)
|
||||
return offset;
|
||||
|
||||
/* Try to place the new node after the parent's properties */
|
||||
fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
|
||||
do {
|
||||
offset = nextoffset;
|
||||
tag = fdt_next_tag(fdt, offset, &nextoffset);
|
||||
} while ((tag == FDT_PROP) || (tag == FDT_NOP));
|
||||
|
||||
nh = _fdt_offset_ptr_w(fdt, offset);
|
||||
nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
|
||||
|
||||
err = _fdt_splice_struct(fdt, nh, 0, nodelen);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
|
||||
memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
|
||||
memcpy(nh->name, name, namelen);
|
||||
endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
|
||||
*endtag = cpu_to_fdt32(FDT_END_NODE);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
|
||||
{
|
||||
return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
|
||||
}
|
||||
|
||||
int fdt_del_node(void *fdt, int nodeoffset)
|
||||
{
|
||||
int endoffset;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
endoffset = _fdt_node_end_offset(fdt, nodeoffset);
|
||||
if (endoffset < 0)
|
||||
return endoffset;
|
||||
|
||||
return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
|
||||
endoffset - nodeoffset, 0);
|
||||
}
|
||||
|
||||
static void _fdt_packblocks(const char *old, char *new,
|
||||
int mem_rsv_size, int struct_size)
|
||||
{
|
||||
uint32_t mem_rsv_off, struct_off, strings_off;
|
||||
|
||||
mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
|
||||
struct_off = mem_rsv_off + mem_rsv_size;
|
||||
strings_off = struct_off + struct_size;
|
||||
|
||||
memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
|
||||
fdt_set_off_mem_rsvmap(new, mem_rsv_off);
|
||||
|
||||
memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
|
||||
fdt_set_off_dt_struct(new, struct_off);
|
||||
fdt_set_size_dt_struct(new, struct_size);
|
||||
|
||||
memmove(new + strings_off, old + fdt_off_dt_strings(old),
|
||||
fdt_size_dt_strings(old));
|
||||
fdt_set_off_dt_strings(new, strings_off);
|
||||
fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
|
||||
}
|
||||
|
||||
int fdt_open_into(const void *fdt, void *buf, int bufsize)
|
||||
{
|
||||
int err;
|
||||
int mem_rsv_size, struct_size;
|
||||
int newsize;
|
||||
const char *fdtstart = fdt;
|
||||
const char *fdtend = fdtstart + fdt_totalsize(fdt);
|
||||
char *tmp;
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
|
||||
* sizeof(struct fdt_reserve_entry);
|
||||
|
||||
if (fdt_version(fdt) >= 17) {
|
||||
struct_size = fdt_size_dt_struct(fdt);
|
||||
} else {
|
||||
struct_size = 0;
|
||||
while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
|
||||
;
|
||||
if (struct_size < 0)
|
||||
return struct_size;
|
||||
}
|
||||
|
||||
if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
|
||||
/* no further work necessary */
|
||||
err = fdt_move(fdt, buf, bufsize);
|
||||
if (err)
|
||||
return err;
|
||||
fdt_set_version(buf, 17);
|
||||
fdt_set_size_dt_struct(buf, struct_size);
|
||||
fdt_set_totalsize(buf, bufsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Need to reorder */
|
||||
newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
|
||||
+ struct_size + fdt_size_dt_strings(fdt);
|
||||
|
||||
if (bufsize < newsize)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
/* First attempt to build converted tree at beginning of buffer */
|
||||
tmp = buf;
|
||||
/* But if that overlaps with the old tree... */
|
||||
if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
|
||||
/* Try right after the old tree instead */
|
||||
tmp = (char *)(uintptr_t)fdtend;
|
||||
if ((tmp + newsize) > ((char *)buf + bufsize))
|
||||
return -FDT_ERR_NOSPACE;
|
||||
}
|
||||
|
||||
_fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
|
||||
memmove(buf, tmp, newsize);
|
||||
|
||||
fdt_set_magic(buf, FDT_MAGIC);
|
||||
fdt_set_totalsize(buf, bufsize);
|
||||
fdt_set_version(buf, 17);
|
||||
fdt_set_last_comp_version(buf, 16);
|
||||
fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_pack(void *fdt)
|
||||
{
|
||||
int mem_rsv_size;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
|
||||
* sizeof(struct fdt_reserve_entry);
|
||||
_fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
|
||||
fdt_set_totalsize(fdt, _fdt_data_size(fdt));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
struct fdt_errtabent {
|
||||
const char *str;
|
||||
};
|
||||
|
||||
#define FDT_ERRTABENT(val) \
|
||||
[(val)] = { .str = #val, }
|
||||
|
||||
static struct fdt_errtabent fdt_errtable[] = {
|
||||
FDT_ERRTABENT(FDT_ERR_NOTFOUND),
|
||||
FDT_ERRTABENT(FDT_ERR_EXISTS),
|
||||
FDT_ERRTABENT(FDT_ERR_NOSPACE),
|
||||
|
||||
FDT_ERRTABENT(FDT_ERR_BADOFFSET),
|
||||
FDT_ERRTABENT(FDT_ERR_BADPATH),
|
||||
FDT_ERRTABENT(FDT_ERR_BADSTATE),
|
||||
|
||||
FDT_ERRTABENT(FDT_ERR_TRUNCATED),
|
||||
FDT_ERRTABENT(FDT_ERR_BADMAGIC),
|
||||
FDT_ERRTABENT(FDT_ERR_BADVERSION),
|
||||
FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
|
||||
FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
|
||||
};
|
||||
#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
|
||||
|
||||
const char *fdt_strerror(int errval)
|
||||
{
|
||||
if (errval > 0)
|
||||
return "<valid offset/length>";
|
||||
else if (errval == 0)
|
||||
return "<no error>";
|
||||
else if (errval > -FDT_ERRTABSIZE) {
|
||||
const char *s = fdt_errtable[-errval].str;
|
||||
|
||||
if (s)
|
||||
return s;
|
||||
}
|
||||
|
||||
return "<unknown error>";
|
||||
}
|
||||
256
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_sw.c
Normal file
256
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_sw.c
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
static int _fdt_sw_check_header(void *fdt)
|
||||
{
|
||||
if (fdt_magic(fdt) != FDT_SW_MAGIC)
|
||||
return -FDT_ERR_BADMAGIC;
|
||||
/* FIXME: should check more details about the header state */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FDT_SW_CHECK_HEADER(fdt) \
|
||||
{ \
|
||||
int err; \
|
||||
if ((err = _fdt_sw_check_header(fdt)) != 0) \
|
||||
return err; \
|
||||
}
|
||||
|
||||
static void *_fdt_grab_space(void *fdt, size_t len)
|
||||
{
|
||||
int offset = fdt_size_dt_struct(fdt);
|
||||
int spaceleft;
|
||||
|
||||
spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
|
||||
- fdt_size_dt_strings(fdt);
|
||||
|
||||
if ((offset + len < offset) || (offset + len > spaceleft))
|
||||
return NULL;
|
||||
|
||||
fdt_set_size_dt_struct(fdt, offset + len);
|
||||
return _fdt_offset_ptr_w(fdt, offset);
|
||||
}
|
||||
|
||||
int fdt_create(void *buf, int bufsize)
|
||||
{
|
||||
void *fdt = buf;
|
||||
|
||||
if (bufsize < sizeof(struct fdt_header))
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
memset(buf, 0, bufsize);
|
||||
|
||||
fdt_set_magic(fdt, FDT_SW_MAGIC);
|
||||
fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
|
||||
fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
|
||||
fdt_set_totalsize(fdt, bufsize);
|
||||
|
||||
fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
|
||||
sizeof(struct fdt_reserve_entry)));
|
||||
fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
|
||||
fdt_set_off_dt_strings(fdt, bufsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
|
||||
{
|
||||
struct fdt_reserve_entry *re;
|
||||
int offset;
|
||||
|
||||
FDT_SW_CHECK_HEADER(fdt);
|
||||
|
||||
if (fdt_size_dt_struct(fdt))
|
||||
return -FDT_ERR_BADSTATE;
|
||||
|
||||
offset = fdt_off_dt_struct(fdt);
|
||||
if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
re = (struct fdt_reserve_entry *)((char *)fdt + offset);
|
||||
re->address = cpu_to_fdt64(addr);
|
||||
re->size = cpu_to_fdt64(size);
|
||||
|
||||
fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_finish_reservemap(void *fdt)
|
||||
{
|
||||
return fdt_add_reservemap_entry(fdt, 0, 0);
|
||||
}
|
||||
|
||||
int fdt_begin_node(void *fdt, const char *name)
|
||||
{
|
||||
struct fdt_node_header *nh;
|
||||
int namelen = strlen(name) + 1;
|
||||
|
||||
FDT_SW_CHECK_HEADER(fdt);
|
||||
|
||||
nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
|
||||
if (! nh)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
|
||||
memcpy(nh->name, name, namelen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_end_node(void *fdt)
|
||||
{
|
||||
uint32_t *en;
|
||||
|
||||
FDT_SW_CHECK_HEADER(fdt);
|
||||
|
||||
en = _fdt_grab_space(fdt, FDT_TAGSIZE);
|
||||
if (! en)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
*en = cpu_to_fdt32(FDT_END_NODE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _fdt_find_add_string(void *fdt, const char *s)
|
||||
{
|
||||
char *strtab = (char *)fdt + fdt_totalsize(fdt);
|
||||
const char *p;
|
||||
int strtabsize = fdt_size_dt_strings(fdt);
|
||||
int len = strlen(s) + 1;
|
||||
int struct_top, offset;
|
||||
|
||||
p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
|
||||
if (p)
|
||||
return p - strtab;
|
||||
|
||||
/* Add it */
|
||||
offset = -strtabsize - len;
|
||||
struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
|
||||
if (fdt_totalsize(fdt) + offset < struct_top)
|
||||
return 0; /* no more room :( */
|
||||
|
||||
memcpy(strtab + offset, s, len);
|
||||
fdt_set_size_dt_strings(fdt, strtabsize + len);
|
||||
return offset;
|
||||
}
|
||||
|
||||
int fdt_property(void *fdt, const char *name, const void *val, int len)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
int nameoff;
|
||||
|
||||
FDT_SW_CHECK_HEADER(fdt);
|
||||
|
||||
nameoff = _fdt_find_add_string(fdt, name);
|
||||
if (nameoff == 0)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
|
||||
if (! prop)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
prop->tag = cpu_to_fdt32(FDT_PROP);
|
||||
prop->nameoff = cpu_to_fdt32(nameoff);
|
||||
prop->len = cpu_to_fdt32(len);
|
||||
memcpy(prop->data, val, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_finish(void *fdt)
|
||||
{
|
||||
char *p = (char *)fdt;
|
||||
uint32_t *end;
|
||||
int oldstroffset, newstroffset;
|
||||
uint32_t tag;
|
||||
int offset, nextoffset;
|
||||
|
||||
FDT_SW_CHECK_HEADER(fdt);
|
||||
|
||||
/* Add terminator */
|
||||
end = _fdt_grab_space(fdt, sizeof(*end));
|
||||
if (! end)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
*end = cpu_to_fdt32(FDT_END);
|
||||
|
||||
/* Relocate the string table */
|
||||
oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
|
||||
newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
|
||||
memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
|
||||
fdt_set_off_dt_strings(fdt, newstroffset);
|
||||
|
||||
/* Walk the structure, correcting string offsets */
|
||||
offset = 0;
|
||||
while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
|
||||
if (tag == FDT_PROP) {
|
||||
struct fdt_property *prop =
|
||||
_fdt_offset_ptr_w(fdt, offset);
|
||||
int nameoff;
|
||||
|
||||
nameoff = fdt32_to_cpu(prop->nameoff);
|
||||
nameoff += fdt_size_dt_strings(fdt);
|
||||
prop->nameoff = cpu_to_fdt32(nameoff);
|
||||
}
|
||||
offset = nextoffset;
|
||||
}
|
||||
if (nextoffset < 0)
|
||||
return nextoffset;
|
||||
|
||||
/* Finally, adjust the header */
|
||||
fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
|
||||
fdt_set_magic(fdt, FDT_MAGIC);
|
||||
return 0;
|
||||
}
|
||||
122
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_wip.c
Normal file
122
common/package/utils/sysupgrade-helper/src/lib/libfdt/fdt_wip.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
#else
|
||||
#include "fdt_host.h"
|
||||
#endif
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len)
|
||||
{
|
||||
void *propval;
|
||||
int proplen;
|
||||
|
||||
propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
|
||||
if (! propval)
|
||||
return proplen;
|
||||
|
||||
if (proplen != len)
|
||||
return -FDT_ERR_NOSPACE;
|
||||
|
||||
memcpy(propval, val, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _fdt_nop_region(void *start, int len)
|
||||
{
|
||||
uint32_t *p;
|
||||
|
||||
for (p = start; (char *)p < ((char *)start + len); p++)
|
||||
*p = cpu_to_fdt32(FDT_NOP);
|
||||
}
|
||||
|
||||
int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
int len;
|
||||
|
||||
prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
|
||||
if (! prop)
|
||||
return len;
|
||||
|
||||
_fdt_nop_region(prop, len + sizeof(*prop));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _fdt_node_end_offset(void *fdt, int offset)
|
||||
{
|
||||
int depth = 0;
|
||||
|
||||
while ((offset >= 0) && (depth >= 0))
|
||||
offset = fdt_next_node(fdt, offset, &depth);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
int fdt_nop_node(void *fdt, int nodeoffset)
|
||||
{
|
||||
int endoffset;
|
||||
|
||||
endoffset = _fdt_node_end_offset(fdt, nodeoffset);
|
||||
if (endoffset < 0)
|
||||
return endoffset;
|
||||
|
||||
_fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
|
||||
endoffset - nodeoffset);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
#ifndef _LIBFDT_INTERNAL_H
|
||||
#define _LIBFDT_INTERNAL_H
|
||||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <fdt.h>
|
||||
|
||||
#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||||
#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
|
||||
|
||||
#define FDT_CHECK_HEADER(fdt) \
|
||||
{ \
|
||||
int err; \
|
||||
if ((err = fdt_check_header(fdt)) != 0) \
|
||||
return err; \
|
||||
}
|
||||
|
||||
int _fdt_check_node_offset(const void *fdt, int offset);
|
||||
int _fdt_check_prop_offset(const void *fdt, int offset);
|
||||
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
|
||||
int _fdt_node_end_offset(void *fdt, int nodeoffset);
|
||||
|
||||
static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
|
||||
{
|
||||
return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
|
||||
}
|
||||
|
||||
static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
|
||||
{
|
||||
return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
|
||||
}
|
||||
|
||||
static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
|
||||
{
|
||||
const struct fdt_reserve_entry *rsv_table =
|
||||
(const struct fdt_reserve_entry *)
|
||||
((const char *)fdt + fdt_off_mem_rsvmap(fdt));
|
||||
|
||||
return rsv_table + n;
|
||||
}
|
||||
static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
|
||||
{
|
||||
return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
|
||||
}
|
||||
|
||||
#define FDT_SW_MAGIC (~FDT_MAGIC)
|
||||
|
||||
#endif /* _LIBFDT_INTERNAL_H */
|
||||
348
common/package/utils/sysupgrade-helper/src/lib/lmb.c
Normal file
348
common/package/utils/sysupgrade-helper/src/lib/lmb.c
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* Procedures for maintaining information about logical memory blocks.
|
||||
*
|
||||
* Peter Bergner, IBM Corp. June 2001.
|
||||
* Copyright (C) 2001 Peter Bergner.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <lmb.h>
|
||||
|
||||
#define LMB_ALLOC_ANYWHERE 0
|
||||
|
||||
void lmb_dump_all(struct lmb *lmb)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
unsigned long i;
|
||||
|
||||
debug("lmb_dump_all:\n");
|
||||
debug(" memory.cnt = 0x%lx\n", lmb->memory.cnt);
|
||||
debug(" memory.size = 0x%llx\n",
|
||||
(unsigned long long)lmb->memory.size);
|
||||
for (i=0; i < lmb->memory.cnt ;i++) {
|
||||
debug(" memory.reg[0x%lx].base = 0x%llx\n", i,
|
||||
(long long unsigned)lmb->memory.region[i].base);
|
||||
debug(" .size = 0x%llx\n",
|
||||
(long long unsigned)lmb->memory.region[i].size);
|
||||
}
|
||||
|
||||
debug("\n reserved.cnt = 0x%lx\n",
|
||||
lmb->reserved.cnt);
|
||||
debug(" reserved.size = 0x%llx\n",
|
||||
(long long unsigned)lmb->reserved.size);
|
||||
for (i=0; i < lmb->reserved.cnt ;i++) {
|
||||
debug(" reserved.reg[0x%lx].base = 0x%llx\n", i,
|
||||
(long long unsigned)lmb->reserved.region[i].base);
|
||||
debug(" .size = 0x%llx\n",
|
||||
(long long unsigned)lmb->reserved.region[i].size);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
static long lmb_addrs_overlap(phys_addr_t base1,
|
||||
phys_size_t size1, phys_addr_t base2, phys_size_t size2)
|
||||
{
|
||||
return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
|
||||
}
|
||||
|
||||
static long lmb_addrs_adjacent(phys_addr_t base1, phys_size_t size1,
|
||||
phys_addr_t base2, phys_size_t size2)
|
||||
{
|
||||
if (base2 == base1 + size1)
|
||||
return 1;
|
||||
else if (base1 == base2 + size2)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long lmb_regions_adjacent(struct lmb_region *rgn,
|
||||
unsigned long r1, unsigned long r2)
|
||||
{
|
||||
phys_addr_t base1 = rgn->region[r1].base;
|
||||
phys_size_t size1 = rgn->region[r1].size;
|
||||
phys_addr_t base2 = rgn->region[r2].base;
|
||||
phys_size_t size2 = rgn->region[r2].size;
|
||||
|
||||
return lmb_addrs_adjacent(base1, size1, base2, size2);
|
||||
}
|
||||
|
||||
static void lmb_remove_region(struct lmb_region *rgn, unsigned long r)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = r; i < rgn->cnt - 1; i++) {
|
||||
rgn->region[i].base = rgn->region[i + 1].base;
|
||||
rgn->region[i].size = rgn->region[i + 1].size;
|
||||
}
|
||||
rgn->cnt--;
|
||||
}
|
||||
|
||||
/* Assumption: base addr of region 1 < base addr of region 2 */
|
||||
static void lmb_coalesce_regions(struct lmb_region *rgn,
|
||||
unsigned long r1, unsigned long r2)
|
||||
{
|
||||
rgn->region[r1].size += rgn->region[r2].size;
|
||||
lmb_remove_region(rgn, r2);
|
||||
}
|
||||
|
||||
void lmb_init(struct lmb *lmb)
|
||||
{
|
||||
/* Create a dummy zero size LMB which will get coalesced away later.
|
||||
* This simplifies the lmb_add() code below...
|
||||
*/
|
||||
lmb->memory.region[0].base = 0;
|
||||
lmb->memory.region[0].size = 0;
|
||||
lmb->memory.cnt = 1;
|
||||
lmb->memory.size = 0;
|
||||
|
||||
/* Ditto. */
|
||||
lmb->reserved.region[0].base = 0;
|
||||
lmb->reserved.region[0].size = 0;
|
||||
lmb->reserved.cnt = 1;
|
||||
lmb->reserved.size = 0;
|
||||
}
|
||||
|
||||
/* This routine called with relocation disabled. */
|
||||
static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size)
|
||||
{
|
||||
unsigned long coalesced = 0;
|
||||
long adjacent, i;
|
||||
|
||||
if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) {
|
||||
rgn->region[0].base = base;
|
||||
rgn->region[0].size = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First try and coalesce this LMB with another. */
|
||||
for (i=0; i < rgn->cnt; i++) {
|
||||
phys_addr_t rgnbase = rgn->region[i].base;
|
||||
phys_size_t rgnsize = rgn->region[i].size;
|
||||
|
||||
if ((rgnbase == base) && (rgnsize == size))
|
||||
/* Already have this region, so we're done */
|
||||
return 0;
|
||||
|
||||
adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
|
||||
if ( adjacent > 0 ) {
|
||||
rgn->region[i].base -= size;
|
||||
rgn->region[i].size += size;
|
||||
coalesced++;
|
||||
break;
|
||||
}
|
||||
else if ( adjacent < 0 ) {
|
||||
rgn->region[i].size += size;
|
||||
coalesced++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
|
||||
lmb_coalesce_regions(rgn, i, i+1);
|
||||
coalesced++;
|
||||
}
|
||||
|
||||
if (coalesced)
|
||||
return coalesced;
|
||||
if (rgn->cnt >= MAX_LMB_REGIONS)
|
||||
return -1;
|
||||
|
||||
/* Couldn't coalesce the LMB, so add it to the sorted table. */
|
||||
for (i = rgn->cnt-1; i >= 0; i--) {
|
||||
if (base < rgn->region[i].base) {
|
||||
rgn->region[i+1].base = rgn->region[i].base;
|
||||
rgn->region[i+1].size = rgn->region[i].size;
|
||||
} else {
|
||||
rgn->region[i+1].base = base;
|
||||
rgn->region[i+1].size = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (base < rgn->region[0].base) {
|
||||
rgn->region[0].base = base;
|
||||
rgn->region[0].size = size;
|
||||
}
|
||||
|
||||
rgn->cnt++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This routine may be called with relocation disabled. */
|
||||
long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||
{
|
||||
struct lmb_region *_rgn = &(lmb->memory);
|
||||
|
||||
return lmb_add_region(_rgn, base, size);
|
||||
}
|
||||
|
||||
long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||
{
|
||||
struct lmb_region *rgn = &(lmb->reserved);
|
||||
phys_addr_t rgnbegin, rgnend;
|
||||
phys_addr_t end = base + size;
|
||||
int i;
|
||||
|
||||
rgnbegin = rgnend = 0; /* supress gcc warnings */
|
||||
|
||||
/* Find the region where (base, size) belongs to */
|
||||
for (i=0; i < rgn->cnt; i++) {
|
||||
rgnbegin = rgn->region[i].base;
|
||||
rgnend = rgnbegin + rgn->region[i].size;
|
||||
|
||||
if ((rgnbegin <= base) && (end <= rgnend))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Didn't find the region */
|
||||
if (i == rgn->cnt)
|
||||
return -1;
|
||||
|
||||
/* Check to see if we are removing entire region */
|
||||
if ((rgnbegin == base) && (rgnend == end)) {
|
||||
lmb_remove_region(rgn, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check to see if region is matching at the front */
|
||||
if (rgnbegin == base) {
|
||||
rgn->region[i].base = end;
|
||||
rgn->region[i].size -= size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check to see if the region is matching at the end */
|
||||
if (rgnend == end) {
|
||||
rgn->region[i].size -= size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to split the entry - adjust the current one to the
|
||||
* beginging of the hole and add the region after hole.
|
||||
*/
|
||||
rgn->region[i].size = base - rgn->region[i].base;
|
||||
return lmb_add_region(rgn, end, rgnend - end);
|
||||
}
|
||||
|
||||
long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||
{
|
||||
struct lmb_region *_rgn = &(lmb->reserved);
|
||||
|
||||
return lmb_add_region(_rgn, base, size);
|
||||
}
|
||||
|
||||
long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base,
|
||||
phys_size_t size)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i=0; i < rgn->cnt; i++) {
|
||||
phys_addr_t rgnbase = rgn->region[i].base;
|
||||
phys_size_t rgnsize = rgn->region[i].size;
|
||||
if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (i < rgn->cnt) ? i : -1;
|
||||
}
|
||||
|
||||
phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align)
|
||||
{
|
||||
return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE);
|
||||
}
|
||||
|
||||
phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr)
|
||||
{
|
||||
phys_addr_t alloc;
|
||||
|
||||
alloc = __lmb_alloc_base(lmb, size, align, max_addr);
|
||||
|
||||
if (alloc == 0)
|
||||
printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
|
||||
(ulong)size, (ulong)max_addr);
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size)
|
||||
{
|
||||
return addr & ~(size - 1);
|
||||
}
|
||||
|
||||
static phys_addr_t lmb_align_up(phys_addr_t addr, ulong size)
|
||||
{
|
||||
return (addr + (size - 1)) & ~(size - 1);
|
||||
}
|
||||
|
||||
phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr)
|
||||
{
|
||||
long i, j;
|
||||
phys_addr_t base = 0;
|
||||
phys_addr_t res_base;
|
||||
|
||||
for (i = lmb->memory.cnt-1; i >= 0; i--) {
|
||||
phys_addr_t lmbbase = lmb->memory.region[i].base;
|
||||
phys_size_t lmbsize = lmb->memory.region[i].size;
|
||||
|
||||
if (lmbsize < size)
|
||||
continue;
|
||||
if (max_addr == LMB_ALLOC_ANYWHERE)
|
||||
base = lmb_align_down(lmbbase + lmbsize - size, align);
|
||||
else if (lmbbase < max_addr) {
|
||||
base = min(lmbbase + lmbsize, max_addr);
|
||||
base = lmb_align_down(base - size, align);
|
||||
} else
|
||||
continue;
|
||||
|
||||
while (base && lmbbase <= base) {
|
||||
j = lmb_overlaps_region(&lmb->reserved, base, size);
|
||||
if (j < 0) {
|
||||
/* This area isn't reserved, take it */
|
||||
if (lmb_add_region(&lmb->reserved, base,
|
||||
lmb_align_up(size,
|
||||
align)) < 0)
|
||||
return 0;
|
||||
return base;
|
||||
}
|
||||
res_base = lmb->reserved.region[j].base;
|
||||
if (res_base < size)
|
||||
break;
|
||||
base = lmb_align_down(res_base - size, align);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lmb->reserved.cnt; i++) {
|
||||
phys_addr_t upper = lmb->reserved.region[i].base +
|
||||
lmb->reserved.region[i].size - 1;
|
||||
if ((addr >= lmb->reserved.region[i].base) && (addr <= upper))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __board_lmb_reserve(struct lmb *lmb)
|
||||
{
|
||||
/* please define platform specific board_lmb_reserve() */
|
||||
}
|
||||
void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve")));
|
||||
|
||||
void __arch_lmb_reserve(struct lmb *lmb)
|
||||
{
|
||||
/* please define platform specific arch_lmb_reserve() */
|
||||
}
|
||||
void arch_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__arch_lmb_reserve")));
|
||||
1033
common/package/utils/sysupgrade-helper/src/lib/lzma/LzmaDec.c
Normal file
1033
common/package/utils/sysupgrade-helper/src/lib/lzma/LzmaDec.c
Normal file
File diff suppressed because it is too large
Load diff
223
common/package/utils/sysupgrade-helper/src/lib/lzma/LzmaDec.h
Normal file
223
common/package/utils/sysupgrade-helper/src/lib/lzma/LzmaDec.h
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
/* LzmaDec.h -- LZMA Decoder
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMADEC_H
|
||||
#define __LZMADEC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
/* #define _LZMA_PROB32 */
|
||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CLzmaProb UInt32
|
||||
#else
|
||||
#define CLzmaProb UInt16
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- LZMA Properties ---------- */
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaProps
|
||||
{
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
/* LzmaProps_Decode - decodes properties
|
||||
Returns:
|
||||
SZ_OK
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
} CLzmaDec;
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
} ELzmaFinishMode;
|
||||
|
||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||
|
||||
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||
|
||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||
and output value of destLen will be less than output buffer size limit.
|
||||
You can check status result also.
|
||||
|
||||
You can use multiple checks to test data integrity after full decompression:
|
||||
1) Check Result and "status" variable.
|
||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||
} ELzmaStatus;
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
|
||||
/* ---------- Interfaces ---------- */
|
||||
|
||||
/* There are 3 levels of interfaces:
|
||||
1) Dictionary Interface
|
||||
2) Buffer Interface
|
||||
3) One Call Interface
|
||||
You can select any of these interfaces, but don't mix functions from different
|
||||
groups for same object. */
|
||||
|
||||
|
||||
/* There are two variants to allocate state for Dictionary Interface:
|
||||
1) LzmaDec_Allocate / LzmaDec_Free
|
||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
You can use variant 2, if you set dictionary buffer manually.
|
||||
For Buffer Interface you must always use variant 1.
|
||||
|
||||
LzmaDec_Allocate* can return:
|
||||
SZ_OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||
|
||||
/* ---------- Dictionary Interface ---------- */
|
||||
|
||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||
dictionary to some other external buffer.
|
||||
You must work with CLzmaDec variables directly in this interface.
|
||||
|
||||
STEPS:
|
||||
LzmaDec_Constr()
|
||||
LzmaDec_Allocate()
|
||||
for (each new stream)
|
||||
{
|
||||
LzmaDec_Init()
|
||||
while (it needs more decompression)
|
||||
{
|
||||
LzmaDec_DecodeToDic()
|
||||
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||
}
|
||||
}
|
||||
LzmaDec_Free()
|
||||
*/
|
||||
|
||||
/* LzmaDec_DecodeToDic
|
||||
|
||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- Buffer Interface ---------- */
|
||||
|
||||
/* It's zlib-like interface.
|
||||
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||
to work with CLzmaDec variables manually.
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaDecode
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#endif
|
||||
133
common/package/utils/sysupgrade-helper/src/lib/lzma/LzmaTools.c
Normal file
133
common/package/utils/sysupgrade-helper/src/lib/lzma/LzmaTools.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.65
|
||||
*
|
||||
* Copyright (C) 2007-2009 Industrie Dial Face S.p.A.
|
||||
* Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com)
|
||||
*
|
||||
* Copyright (C) 1999-2005 Igor Pavlov
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* LZMA_Alone stream format:
|
||||
*
|
||||
* uchar Properties[5]
|
||||
* uint64 Uncompressed size
|
||||
* uchar data[*]
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#ifdef CONFIG_LZMA
|
||||
|
||||
#define LZMA_PROPERTIES_OFFSET 0
|
||||
#define LZMA_SIZE_OFFSET LZMA_PROPS_SIZE
|
||||
#define LZMA_DATA_OFFSET LZMA_SIZE_OFFSET+sizeof(uint64_t)
|
||||
|
||||
#include "LzmaTools.h"
|
||||
#include "LzmaDec.h"
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
|
||||
static void SzFree(void *p, void *address) { p = p; free(address); }
|
||||
|
||||
int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize,
|
||||
unsigned char *inStream, SizeT length)
|
||||
{
|
||||
int res = SZ_ERROR_DATA;
|
||||
int i;
|
||||
ISzAlloc g_Alloc;
|
||||
|
||||
SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */
|
||||
SizeT outProcessed;
|
||||
SizeT outSize;
|
||||
SizeT outSizeHigh;
|
||||
ELzmaStatus state;
|
||||
SizeT compressedSize = (SizeT)(length - LZMA_PROPS_SIZE);
|
||||
|
||||
debug ("LZMA: Image address............... 0x%p\n", inStream);
|
||||
debug ("LZMA: Properties address.......... 0x%p\n", inStream + LZMA_PROPERTIES_OFFSET);
|
||||
debug ("LZMA: Uncompressed size address... 0x%p\n", inStream + LZMA_SIZE_OFFSET);
|
||||
debug ("LZMA: Compressed data address..... 0x%p\n", inStream + LZMA_DATA_OFFSET);
|
||||
debug ("LZMA: Destination address......... 0x%p\n", outStream);
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
|
||||
outSize = 0;
|
||||
outSizeHigh = 0;
|
||||
/* Read the uncompressed size */
|
||||
for (i = 0; i < 8; i++) {
|
||||
unsigned char b = inStream[LZMA_SIZE_OFFSET + i];
|
||||
if (i < 4) {
|
||||
outSize += (UInt32)(b) << (i * 8);
|
||||
} else {
|
||||
outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
|
||||
}
|
||||
}
|
||||
|
||||
outSizeFull = (SizeT)outSize;
|
||||
if (sizeof(SizeT) >= 8) {
|
||||
/*
|
||||
* SizeT is a 64 bit uint => We can manage files larger than 4GB!
|
||||
*
|
||||
*/
|
||||
outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
|
||||
} else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) {
|
||||
/*
|
||||
* SizeT is a 32 bit uint => We cannot manage files larger than
|
||||
* 4GB! Assume however that all 0xf values is "unknown size" and
|
||||
* not actually a file of 2^64 bits.
|
||||
*
|
||||
*/
|
||||
if (outSizeHigh != (SizeT)-1 || outSize != (SizeT)-1) {
|
||||
debug ("LZMA: 64bit support not enabled.\n");
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
debug("LZMA: Uncompresed size............ 0x%zx\n", outSizeFull);
|
||||
debug("LZMA: Compresed size.............. 0x%zx\n", compressedSize);
|
||||
|
||||
g_Alloc.Alloc = SzAlloc;
|
||||
g_Alloc.Free = SzFree;
|
||||
|
||||
/* Decompress */
|
||||
outProcessed = outSizeFull;
|
||||
|
||||
WATCHDOG_RESET();
|
||||
|
||||
res = LzmaDecode(
|
||||
outStream, &outProcessed,
|
||||
inStream + LZMA_DATA_OFFSET, &compressedSize,
|
||||
inStream, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &state, &g_Alloc);
|
||||
*uncompressedSize = outProcessed;
|
||||
if (res != SZ_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.65
|
||||
*
|
||||
* Copyright (C) 2007-2008 Industrie Dial Face S.p.A.
|
||||
* Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com)
|
||||
*
|
||||
* Copyright (C) 1999-2005 Igor Pavlov
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __LZMA_TOOL_H__
|
||||
#define __LZMA_TOOL_H__
|
||||
|
||||
#include <lzma/LzmaTypes.h>
|
||||
|
||||
extern int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize,
|
||||
unsigned char *inStream, SizeT length);
|
||||
#endif
|
||||
51
common/package/utils/sysupgrade-helper/src/lib/lzma/Makefile
Normal file
51
common/package/utils/sysupgrade-helper/src/lib/lzma/Makefile
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# Copyright (C) 2007-2008 Industrie Dial Face S.p.A.
|
||||
# Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com)
|
||||
#
|
||||
# (C) Copyright 2003-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)liblzma.o
|
||||
|
||||
SOBJS =
|
||||
|
||||
CFLAGS += -D_LZMA_PROB32
|
||||
|
||||
COBJS-$(CONFIG_LZMA) += LzmaDec.o LzmaTools.o
|
||||
|
||||
COBJS = $(COBJS-y)
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
The lib_lzma functionality was written by Igor Pavlov.
|
||||
The original source cames from the LZMA SDK web page:
|
||||
|
||||
URL: http://www.7-zip.org/sdk.html
|
||||
Author: Igor Pavlov
|
||||
|
||||
The import is made using the import_lzmasdk.sh script that:
|
||||
|
||||
* untars the lzmaXYY.tar.bz2 file (from the download web page)
|
||||
* copies the files LzmaDec.h, Types.h, LzmaDec.c, history.txt,
|
||||
and lzma.txt from source archive into the lib_lzma directory (pwd).
|
||||
|
||||
Example:
|
||||
|
||||
. import_lzmasdk.sh ~/lzma465.tar.bz2
|
||||
|
||||
Notice: The files from lzma sdk are _not modified_ by this script!
|
||||
|
||||
The files LzmaTools.{c,h} are provided to export the lzmaBuffToBuffDecompress()
|
||||
function that wraps the complex LzmaDecode() function from the LZMA SDK. The
|
||||
do_bootm() function uses the lzmaBuffToBuffDecopress() function to expand the
|
||||
compressed image.
|
||||
|
||||
The directory U-BOOT/include/lzma contains stubs files that permit to use the
|
||||
library directly from U-BOOT code without touching the original LZMA SDK's
|
||||
files.
|
||||
|
||||
Luigi 'Comio' Mantellini <luigi.mantellini@idf-hit.com>
|
||||
208
common/package/utils/sysupgrade-helper/src/lib/lzma/Types.h
Normal file
208
common/package/utils/sysupgrade-helper/src/lib/lzma/Types.h
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/* Types.h -- Basic types
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
#define SZ_ERROR_DATA 1
|
||||
#define SZ_ERROR_MEM 2
|
||||
#define SZ_ERROR_CRC 3
|
||||
#define SZ_ERROR_UNSUPPORTED 4
|
||||
#define SZ_ERROR_PARAM 5
|
||||
#define SZ_ERROR_INPUT_EOF 6
|
||||
#define SZ_ERROR_OUTPUT_EOF 7
|
||||
#define SZ_ERROR_READ 8
|
||||
#define SZ_ERROR_WRITE 9
|
||||
#define SZ_ERROR_PROGRESS 10
|
||||
#define SZ_ERROR_FAIL 11
|
||||
#define SZ_ERROR_THREAD 12
|
||||
|
||||
#define SZ_ERROR_ARCHIVE 16
|
||||
#define SZ_ERROR_NO_ARCHIVE 17
|
||||
|
||||
typedef int SRes;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef DWORD WRes;
|
||||
#else
|
||||
typedef int WRes;
|
||||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#ifdef _LZMA_UINT32_IS_ULONG
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
#else
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _SZ_NO_INT_64
|
||||
|
||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||
NOTES: Some code will work incorrectly in that case! */
|
||||
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
typedef size_t SizeT;
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define MY_NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define MY_NO_INLINE
|
||||
#endif
|
||||
|
||||
#define MY_CDECL __cdecl
|
||||
#define MY_STD_CALL __stdcall
|
||||
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
||||
|
||||
#else
|
||||
|
||||
#define MY_CDECL
|
||||
#define MY_STD_CALL
|
||||
#define MY_FAST_CALL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
} ISeqInStream;
|
||||
|
||||
/* it can return SZ_ERROR_INPUT_EOF */
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
} ISeqOutStream;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SZ_SEEK_SET = 0,
|
||||
SZ_SEEK_CUR = 1,
|
||||
SZ_SEEK_END = 2
|
||||
} ESzSeek;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ISeekInStream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ILookInStream;
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||
|
||||
/* reads via ILookInStream::Read */
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||
|
||||
#define LookToRead_BUF_SIZE (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
} CLookToRead;
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||
void LookToRead_Init(CLookToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToLook;
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToRead;
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
} ICompressProgress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#endif
|
||||
236
common/package/utils/sysupgrade-helper/src/lib/lzma/history.txt
Normal file
236
common/package/utils/sysupgrade-helper/src/lib/lzma/history.txt
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
HISTORY of the LZMA SDK
|
||||
-----------------------
|
||||
|
||||
4.65 2009-02-03
|
||||
-------------------------
|
||||
- Some minor fixes
|
||||
|
||||
|
||||
4.63 2008-12-31
|
||||
-------------------------
|
||||
- Some minor fixes
|
||||
|
||||
|
||||
4.61 beta 2008-11-23
|
||||
-------------------------
|
||||
- The bug in ANSI-C LZMA Decoder was fixed:
|
||||
If encoded stream was corrupted, decoder could access memory
|
||||
outside of allocated range.
|
||||
- Some changes in ANSI-C 7z Decoder interfaces.
|
||||
- LZMA SDK is placed in the public domain.
|
||||
|
||||
|
||||
4.60 beta 2008-08-19
|
||||
-------------------------
|
||||
- Some minor fixes.
|
||||
|
||||
|
||||
4.59 beta 2008-08-13
|
||||
-------------------------
|
||||
- The bug was fixed:
|
||||
LZMA Encoder in fast compression mode could access memory outside of
|
||||
allocated range in some rare cases.
|
||||
|
||||
|
||||
4.58 beta 2008-05-05
|
||||
-------------------------
|
||||
- ANSI-C LZMA Decoder was rewritten for speed optimizations.
|
||||
- ANSI-C LZMA Encoder was included to LZMA SDK.
|
||||
- C++ LZMA code now is just wrapper over ANSI-C code.
|
||||
|
||||
|
||||
4.57 2007-12-12
|
||||
-------------------------
|
||||
- Speed optimizations in Ñ++ LZMA Decoder.
|
||||
- Small changes for more compatibility with some C/C++ compilers.
|
||||
|
||||
|
||||
4.49 beta 2007-07-05
|
||||
-------------------------
|
||||
- .7z ANSI-C Decoder:
|
||||
- now it supports BCJ and BCJ2 filters
|
||||
- now it supports files larger than 4 GB.
|
||||
- now it supports "Last Write Time" field for files.
|
||||
- C++ code for .7z archives compressing/decompressing from 7-zip
|
||||
was included to LZMA SDK.
|
||||
|
||||
|
||||
4.43 2006-06-04
|
||||
-------------------------
|
||||
- Small changes for more compatibility with some C/C++ compilers.
|
||||
|
||||
|
||||
4.42 2006-05-15
|
||||
-------------------------
|
||||
- Small changes in .h files in ANSI-C version.
|
||||
|
||||
|
||||
4.39 beta 2006-04-14
|
||||
-------------------------
|
||||
- The bug in versions 4.33b:4.38b was fixed:
|
||||
C++ version of LZMA encoder could not correctly compress
|
||||
files larger than 2 GB with HC4 match finder (-mfhc4).
|
||||
|
||||
|
||||
4.37 beta 2005-04-06
|
||||
-------------------------
|
||||
- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
|
||||
|
||||
|
||||
4.35 beta 2005-03-02
|
||||
-------------------------
|
||||
- The bug was fixed in C++ version of LZMA Decoder:
|
||||
If encoded stream was corrupted, decoder could access memory
|
||||
outside of allocated range.
|
||||
|
||||
|
||||
4.34 beta 2006-02-27
|
||||
-------------------------
|
||||
- Compressing speed and memory requirements for compressing were increased
|
||||
- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
|
||||
|
||||
|
||||
4.32 2005-12-09
|
||||
-------------------------
|
||||
- Java version of LZMA SDK was included
|
||||
|
||||
|
||||
4.30 2005-11-20
|
||||
-------------------------
|
||||
- Compression ratio was improved in -a2 mode
|
||||
- Speed optimizations for compressing in -a2 mode
|
||||
- -fb switch now supports values up to 273
|
||||
- The bug in 7z_C (7zIn.c) was fixed:
|
||||
It used Alloc/Free functions from different memory pools.
|
||||
So if program used two memory pools, it worked incorrectly.
|
||||
- 7z_C: .7z format supporting was improved
|
||||
- LZMA# SDK (C#.NET version) was included
|
||||
|
||||
|
||||
4.27 (Updated) 2005-09-21
|
||||
-------------------------
|
||||
- Some GUIDs/interfaces in C++ were changed.
|
||||
IStream.h:
|
||||
ISequentialInStream::Read now works as old ReadPart
|
||||
ISequentialOutStream::Write now works as old WritePart
|
||||
|
||||
|
||||
4.27 2005-08-07
|
||||
-------------------------
|
||||
- The bug in LzmaDecodeSize.c was fixed:
|
||||
if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
|
||||
decompressing worked incorrectly.
|
||||
|
||||
|
||||
4.26 2005-08-05
|
||||
-------------------------
|
||||
- Fixes in 7z_C code and LzmaTest.c:
|
||||
previous versions could work incorrectly,
|
||||
if malloc(0) returns 0
|
||||
|
||||
|
||||
4.23 2005-06-29
|
||||
-------------------------
|
||||
- Small fixes in C++ code
|
||||
|
||||
|
||||
4.22 2005-06-10
|
||||
-------------------------
|
||||
- Small fixes
|
||||
|
||||
|
||||
4.21 2005-06-08
|
||||
-------------------------
|
||||
- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
|
||||
- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
|
||||
- LzmaStateDecode.h
|
||||
- LzmaStateDecode.c
|
||||
- LzmaStateTest.c
|
||||
- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
|
||||
|
||||
|
||||
4.17 2005-04-18
|
||||
-------------------------
|
||||
- New example for RAM->RAM compressing/decompressing:
|
||||
LZMA + BCJ (filter for x86 code):
|
||||
- LzmaRam.h
|
||||
- LzmaRam.cpp
|
||||
- LzmaRamDecode.h
|
||||
- LzmaRamDecode.c
|
||||
- -f86 switch for lzma.exe
|
||||
|
||||
|
||||
4.16 2005-03-29
|
||||
-------------------------
|
||||
- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
|
||||
If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
|
||||
decoder could access memory outside of allocated range.
|
||||
- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
|
||||
Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
|
||||
LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
|
||||
- Small speed optimization in LZMA C++ code
|
||||
- filter for SPARC's code was added
|
||||
- Simplified version of .7z ANSI-C Decoder was included
|
||||
|
||||
|
||||
4.06 2004-09-05
|
||||
-------------------------
|
||||
- The bug in v4.05 was fixed:
|
||||
LZMA-Encoder didn't release output stream in some cases.
|
||||
|
||||
|
||||
4.05 2004-08-25
|
||||
-------------------------
|
||||
- Source code of filters for x86, IA-64, ARM, ARM-Thumb
|
||||
and PowerPC code was included to SDK
|
||||
- Some internal minor changes
|
||||
|
||||
|
||||
4.04 2004-07-28
|
||||
-------------------------
|
||||
- More compatibility with some C++ compilers
|
||||
|
||||
|
||||
4.03 2004-06-18
|
||||
-------------------------
|
||||
- "Benchmark" command was added. It measures compressing
|
||||
and decompressing speed and shows rating values.
|
||||
Also it checks hardware errors.
|
||||
|
||||
|
||||
4.02 2004-06-10
|
||||
-------------------------
|
||||
- C++ LZMA Encoder/Decoder code now is more portable
|
||||
and it can be compiled by GCC on Linux.
|
||||
|
||||
|
||||
4.01 2004-02-15
|
||||
-------------------------
|
||||
- Some detection of data corruption was enabled.
|
||||
LzmaDecode.c / RangeDecoderReadByte
|
||||
.....
|
||||
{
|
||||
rd->ExtraBytes = 1;
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
||||
4.00 2004-02-13
|
||||
-------------------------
|
||||
- Original version of LZMA SDK
|
||||
|
||||
|
||||
|
||||
HISTORY of the LZMA
|
||||
-------------------
|
||||
2001-2008: Improvements to LZMA compressing/decompressing code,
|
||||
keeping compatibility with original LZMA format
|
||||
1996-2001: Development of LZMA compression format
|
||||
|
||||
Some milestones:
|
||||
|
||||
2001-08-30: LZMA compression was added to 7-Zip
|
||||
1999-01-02: First version of 7-Zip was released
|
||||
|
||||
|
||||
End of document
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 lzmaVERSION.tar.bz2" >&2
|
||||
echo >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "$1" = "" ] ; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ ! -f $1 ] ; then
|
||||
echo "$1 doesn't exist!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BASENAME=`basename $1 .tar.bz2`
|
||||
TMPDIR=/tmp/tmp_lib_$BASENAME
|
||||
FILES="C/LzmaDec.h
|
||||
C/Types.h
|
||||
C/LzmaDec.c
|
||||
history.txt
|
||||
lzma.txt"
|
||||
|
||||
mkdir -p $TMPDIR
|
||||
echo "Untar $1 -> $TMPDIR"
|
||||
tar -jxf $1 -C $TMPDIR
|
||||
|
||||
for i in $FILES; do
|
||||
echo Copying $TMPDIR/$i \-\> `basename $i`
|
||||
cp $TMPDIR/$i .
|
||||
chmod -x `basename $i`
|
||||
done
|
||||
|
||||
echo "done!"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
License
|
||||
|
||||
LZMA SDK is placed in the public domain.
|
||||
594
common/package/utils/sysupgrade-helper/src/lib/lzma/lzma.txt
Normal file
594
common/package/utils/sysupgrade-helper/src/lib/lzma/lzma.txt
Normal file
|
|
@ -0,0 +1,594 @@
|
|||
LZMA SDK 4.65
|
||||
-------------
|
||||
|
||||
LZMA SDK provides the documentation, samples, header files, libraries,
|
||||
and tools you need to develop applications that use LZMA compression.
|
||||
|
||||
LZMA is default and general compression method of 7z format
|
||||
in 7-Zip compression program (www.7-zip.org). LZMA provides high
|
||||
compression ratio and very fast decompression.
|
||||
|
||||
LZMA is an improved version of famous LZ77 compression algorithm.
|
||||
It was improved in way of maximum increasing of compression ratio,
|
||||
keeping high decompression speed and low memory requirements for
|
||||
decompressing.
|
||||
|
||||
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
|
||||
LZMA SDK is written and placed in the public domain by Igor Pavlov.
|
||||
|
||||
|
||||
LZMA SDK Contents
|
||||
-----------------
|
||||
|
||||
LZMA SDK includes:
|
||||
|
||||
- ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing
|
||||
- Compiled file->file LZMA compressing/decompressing program for Windows system
|
||||
|
||||
|
||||
UNIX/Linux version
|
||||
------------------
|
||||
To compile C++ version of file->file LZMA encoding, go to directory
|
||||
C++/7zip/Compress/LZMA_Alone
|
||||
and call make to recompile it:
|
||||
make -f makefile.gcc clean all
|
||||
|
||||
In some UNIX/Linux versions you must compile LZMA with static libraries.
|
||||
To compile with static libraries, you can use
|
||||
LIB = -lm -static
|
||||
|
||||
|
||||
Files
|
||||
---------------------
|
||||
lzma.txt - LZMA SDK description (this file)
|
||||
7zFormat.txt - 7z Format description
|
||||
7zC.txt - 7z ANSI-C Decoder description
|
||||
methods.txt - Compression method IDs for .7z
|
||||
lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
|
||||
history.txt - history of the LZMA SDK
|
||||
|
||||
|
||||
Source code structure
|
||||
---------------------
|
||||
|
||||
C/ - C files
|
||||
7zCrc*.* - CRC code
|
||||
Alloc.* - Memory allocation functions
|
||||
Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
|
||||
LzFind.* - Match finder for LZ (LZMA) encoders
|
||||
LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding
|
||||
LzHash.h - Additional file for LZ match finder
|
||||
LzmaDec.* - LZMA decoding
|
||||
LzmaEnc.* - LZMA encoding
|
||||
LzmaLib.* - LZMA Library for DLL calling
|
||||
Types.h - Basic types for another .c files
|
||||
Threads.* - The code for multithreading.
|
||||
|
||||
LzmaLib - LZMA Library (.DLL for Windows)
|
||||
|
||||
LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).
|
||||
|
||||
Archive - files related to archiving
|
||||
7z - 7z ANSI-C Decoder
|
||||
|
||||
CPP/ -- CPP files
|
||||
|
||||
Common - common files for C++ projects
|
||||
Windows - common files for Windows related code
|
||||
|
||||
7zip - files related to 7-Zip Project
|
||||
|
||||
Common - common files for 7-Zip
|
||||
|
||||
Compress - files related to compression/decompression
|
||||
|
||||
Copy - Copy coder
|
||||
RangeCoder - Range Coder (special code of compression/decompression)
|
||||
LZMA - LZMA compression/decompression on C++
|
||||
LZMA_Alone - file->file LZMA compression/decompression
|
||||
Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
|
||||
|
||||
Archive - files related to archiving
|
||||
|
||||
Common - common files for archive handling
|
||||
7z - 7z C++ Encoder/Decoder
|
||||
|
||||
Bundles - Modules that are bundles of other modules
|
||||
|
||||
Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
|
||||
Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
|
||||
Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
|
||||
|
||||
UI - User Interface files
|
||||
|
||||
Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
|
||||
Common - Common UI files
|
||||
Console - Code for console archiver
|
||||
|
||||
|
||||
|
||||
CS/ - C# files
|
||||
7zip
|
||||
Common - some common files for 7-Zip
|
||||
Compress - files related to compression/decompression
|
||||
LZ - files related to LZ (Lempel-Ziv) compression algorithm
|
||||
LZMA - LZMA compression/decompression
|
||||
LzmaAlone - file->file LZMA compression/decompression
|
||||
RangeCoder - Range Coder (special code of compression/decompression)
|
||||
|
||||
Java/ - Java files
|
||||
SevenZip
|
||||
Compression - files related to compression/decompression
|
||||
LZ - files related to LZ (Lempel-Ziv) compression algorithm
|
||||
LZMA - LZMA compression/decompression
|
||||
RangeCoder - Range Coder (special code of compression/decompression)
|
||||
|
||||
|
||||
C/C++ source code of LZMA SDK is part of 7-Zip project.
|
||||
7-Zip source code can be downloaded from 7-Zip's SourceForge page:
|
||||
|
||||
http://sourceforge.net/projects/sevenzip/
|
||||
|
||||
|
||||
|
||||
LZMA features
|
||||
-------------
|
||||
- Variable dictionary size (up to 1 GB)
|
||||
- Estimated compressing speed: about 2 MB/s on 2 GHz CPU
|
||||
- Estimated decompressing speed:
|
||||
- 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64
|
||||
- 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC
|
||||
- Small memory requirements for decompressing (16 KB + DictionarySize)
|
||||
- Small code size for decompressing: 5-8 KB
|
||||
|
||||
LZMA decoder uses only integer operations and can be
|
||||
implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
|
||||
|
||||
Some critical operations that affect the speed of LZMA decompression:
|
||||
1) 32*16 bit integer multiply
|
||||
2) Misspredicted branches (penalty mostly depends from pipeline length)
|
||||
3) 32-bit shift and arithmetic operations
|
||||
|
||||
The speed of LZMA decompressing mostly depends from CPU speed.
|
||||
Memory speed has no big meaning. But if your CPU has small data cache,
|
||||
overall weight of memory speed will slightly increase.
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
|
||||
Using LZMA encoder/decoder executable
|
||||
--------------------------------------
|
||||
|
||||
Usage: LZMA <e|d> inputFile outputFile [<switches>...]
|
||||
|
||||
e: encode file
|
||||
|
||||
d: decode file
|
||||
|
||||
b: Benchmark. There are two tests: compressing and decompressing
|
||||
with LZMA method. Benchmark shows rating in MIPS (million
|
||||
instructions per second). Rating value is calculated from
|
||||
measured speed and it is normalized with Intel's Core 2 results.
|
||||
Also Benchmark checks possible hardware errors (RAM
|
||||
errors in most cases). Benchmark uses these settings:
|
||||
(-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
|
||||
Also you can change the number of iterations. Example for 30 iterations:
|
||||
LZMA b 30
|
||||
Default number of iterations is 10.
|
||||
|
||||
<Switches>
|
||||
|
||||
|
||||
-a{N}: set compression mode 0 = fast, 1 = normal
|
||||
default: 1 (normal)
|
||||
|
||||
d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
|
||||
The maximum value for dictionary size is 1 GB = 2^30 bytes.
|
||||
Dictionary size is calculated as DictionarySize = 2^N bytes.
|
||||
For decompressing file compressed by LZMA method with dictionary
|
||||
size D = 2^N you need about D bytes of memory (RAM).
|
||||
|
||||
-fb{N}: set number of fast bytes - [5, 273], default: 128
|
||||
Usually big number gives a little bit better compression ratio
|
||||
and slower compression process.
|
||||
|
||||
-lc{N}: set number of literal context bits - [0, 8], default: 3
|
||||
Sometimes lc=4 gives gain for big files.
|
||||
|
||||
-lp{N}: set number of literal pos bits - [0, 4], default: 0
|
||||
lp switch is intended for periodical data when period is
|
||||
equal 2^N. For example, for 32-bit (4 bytes)
|
||||
periodical data you can use lp=2. Often it's better to set lc0,
|
||||
if you change lp switch.
|
||||
|
||||
-pb{N}: set number of pos bits - [0, 4], default: 2
|
||||
pb switch is intended for periodical data
|
||||
when period is equal 2^N.
|
||||
|
||||
-mf{MF_ID}: set Match Finder. Default: bt4.
|
||||
Algorithms from hc* group doesn't provide good compression
|
||||
ratio, but they often works pretty fast in combination with
|
||||
fast mode (-a0).
|
||||
|
||||
Memory requirements depend from dictionary size
|
||||
(parameter "d" in table below).
|
||||
|
||||
MF_ID Memory Description
|
||||
|
||||
bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
|
||||
bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
|
||||
bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
|
||||
hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
|
||||
|
||||
-eos: write End Of Stream marker. By default LZMA doesn't write
|
||||
eos marker, since LZMA decoder knows uncompressed size
|
||||
stored in .lzma file header.
|
||||
|
||||
-si: Read data from stdin (it will write End Of Stream marker).
|
||||
-so: Write data to stdout
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
1) LZMA e file.bin file.lzma -d16 -lc0
|
||||
|
||||
compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
|
||||
and 0 literal context bits. -lc0 allows to reduce memory requirements
|
||||
for decompression.
|
||||
|
||||
|
||||
2) LZMA e file.bin file.lzma -lc0 -lp2
|
||||
|
||||
compresses file.bin to file.lzma with settings suitable
|
||||
for 32-bit periodical data (for example, ARM or MIPS code).
|
||||
|
||||
3) LZMA d file.lzma file.bin
|
||||
|
||||
decompresses file.lzma to file.bin.
|
||||
|
||||
|
||||
Compression ratio hints
|
||||
-----------------------
|
||||
|
||||
Recommendations
|
||||
---------------
|
||||
|
||||
To increase the compression ratio for LZMA compressing it's desirable
|
||||
to have aligned data (if it's possible) and also it's desirable to locate
|
||||
data in such order, where code is grouped in one place and data is
|
||||
grouped in other place (it's better than such mixing: code, data, code,
|
||||
data, ...).
|
||||
|
||||
|
||||
Filters
|
||||
-------
|
||||
You can increase the compression ratio for some data types, using
|
||||
special filters before compressing. For example, it's possible to
|
||||
increase the compression ratio on 5-10% for code for those CPU ISAs:
|
||||
x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
|
||||
|
||||
You can find C source code of such filters in C/Bra*.* files
|
||||
|
||||
You can check the compression ratio gain of these filters with such
|
||||
7-Zip commands (example for ARM code):
|
||||
No filter:
|
||||
7z a a1.7z a.bin -m0=lzma
|
||||
|
||||
With filter for little-endian ARM code:
|
||||
7z a a2.7z a.bin -m0=arm -m1=lzma
|
||||
|
||||
It works in such manner:
|
||||
Compressing = Filter_encoding + LZMA_encoding
|
||||
Decompressing = LZMA_decoding + Filter_decoding
|
||||
|
||||
Compressing and decompressing speed of such filters is very high,
|
||||
so it will not increase decompressing time too much.
|
||||
Moreover, it reduces decompression time for LZMA_decoding,
|
||||
since compression ratio with filtering is higher.
|
||||
|
||||
These filters convert CALL (calling procedure) instructions
|
||||
from relative offsets to absolute addresses, so such data becomes more
|
||||
compressible.
|
||||
|
||||
For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
|
||||
|
||||
|
||||
LZMA compressed file format
|
||||
---------------------------
|
||||
Offset Size Description
|
||||
0 1 Special LZMA properties (lc,lp, pb in encoded form)
|
||||
1 4 Dictionary size (little endian)
|
||||
5 8 Uncompressed size (little endian). -1 means unknown size
|
||||
13 Compressed data
|
||||
|
||||
|
||||
ANSI-C LZMA Decoder
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
|
||||
If you want to use old interfaces you can download previous version of LZMA SDK
|
||||
from sourceforge.net site.
|
||||
|
||||
To use ANSI-C LZMA Decoder you need the following files:
|
||||
1) LzmaDec.h + LzmaDec.c + Types.h
|
||||
LzmaUtil/LzmaUtil.c is example application that uses these files.
|
||||
|
||||
|
||||
Memory requirements for LZMA decoding
|
||||
-------------------------------------
|
||||
|
||||
Stack usage of LZMA decoding function for local variables is not
|
||||
larger than 200-400 bytes.
|
||||
|
||||
LZMA Decoder uses dictionary buffer and internal state structure.
|
||||
Internal state structure consumes
|
||||
state_size = (4 + (1.5 << (lc + lp))) KB
|
||||
by default (lc=3, lp=0), state_size = 16 KB.
|
||||
|
||||
|
||||
How To decompress data
|
||||
----------------------
|
||||
|
||||
LZMA Decoder (ANSI-C version) now supports 2 interfaces:
|
||||
1) Single-call Decompressing
|
||||
2) Multi-call State Decompressing (zlib-like interface)
|
||||
|
||||
You must use external allocator:
|
||||
Example:
|
||||
void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
|
||||
void SzFree(void *p, void *address) { p = p; free(address); }
|
||||
ISzAlloc alloc = { SzAlloc, SzFree };
|
||||
|
||||
You can use p = p; operator to disable compiler warnings.
|
||||
|
||||
|
||||
Single-call Decompressing
|
||||
-------------------------
|
||||
When to use: RAM->RAM decompressing
|
||||
Compile files: LzmaDec.h + LzmaDec.c + Types.h
|
||||
Compile defines: no defines
|
||||
Memory Requirements:
|
||||
- Input buffer: compressed size
|
||||
- Output buffer: uncompressed size
|
||||
- LZMA Internal Structures: state_size (16 KB for default settings)
|
||||
|
||||
Interface:
|
||||
int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
In:
|
||||
dest - output data
|
||||
destLen - output data size
|
||||
src - input data
|
||||
srcLen - input data size
|
||||
propData - LZMA properties (5 bytes)
|
||||
propSize - size of propData buffer (5 bytes)
|
||||
finishMode - It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
You can use LZMA_FINISH_END, when you know that
|
||||
current output buffer covers last bytes of stream.
|
||||
alloc - Memory allocator.
|
||||
|
||||
Out:
|
||||
destLen - processed output size
|
||||
srcLen - processed input size
|
||||
|
||||
Output:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
|
||||
If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
|
||||
and output value of destLen will be less than output buffer size limit.
|
||||
|
||||
You can use multiple checks to test data integrity after full decompression:
|
||||
1) Check Result and "status" variable.
|
||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
|
||||
Multi-call State Decompressing (zlib-like interface)
|
||||
----------------------------------------------------
|
||||
|
||||
When to use: file->file decompressing
|
||||
Compile files: LzmaDec.h + LzmaDec.c + Types.h
|
||||
|
||||
Memory Requirements:
|
||||
- Buffer for input stream: any size (for example, 16 KB)
|
||||
- Buffer for output stream: any size (for example, 16 KB)
|
||||
- LZMA Internal Structures: state_size (16 KB for default settings)
|
||||
- LZMA dictionary (dictionary size is encoded in LZMA properties header)
|
||||
|
||||
1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
|
||||
unsigned char header[LZMA_PROPS_SIZE + 8];
|
||||
ReadFile(inFile, header, sizeof(header)
|
||||
|
||||
2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
|
||||
|
||||
CLzmaDec state;
|
||||
LzmaDec_Constr(&state);
|
||||
res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
|
||||
if (res != SZ_OK)
|
||||
return res;
|
||||
|
||||
3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
|
||||
|
||||
LzmaDec_Init(&state);
|
||||
for (;;)
|
||||
{
|
||||
...
|
||||
int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
4) Free all allocated structures
|
||||
LzmaDec_Free(&state, &g_Alloc);
|
||||
|
||||
For full code example, look at C/LzmaUtil/LzmaUtil.c code.
|
||||
|
||||
|
||||
How To compress data
|
||||
--------------------
|
||||
|
||||
Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
|
||||
LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h
|
||||
|
||||
Memory Requirements:
|
||||
- (dictSize * 11.5 + 6 MB) + state_size
|
||||
|
||||
Lzma Encoder can use two memory allocators:
|
||||
1) alloc - for small arrays.
|
||||
2) allocBig - for big arrays.
|
||||
|
||||
For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
|
||||
better compression speed. Note that Windows has bad implementation for
|
||||
Large RAM Pages.
|
||||
It's OK to use same allocator for alloc and allocBig.
|
||||
|
||||
|
||||
Single-call Compression with callbacks
|
||||
--------------------------------------
|
||||
|
||||
Check C/LzmaUtil/LzmaUtil.c as example,
|
||||
|
||||
When to use: file->file decompressing
|
||||
|
||||
1) you must implement callback structures for interfaces:
|
||||
ISeqInStream
|
||||
ISeqOutStream
|
||||
ICompressProgress
|
||||
ISzAlloc
|
||||
|
||||
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
CFileSeqInStream inStream;
|
||||
CFileSeqOutStream outStream;
|
||||
|
||||
inStream.funcTable.Read = MyRead;
|
||||
inStream.file = inFile;
|
||||
outStream.funcTable.Write = MyWrite;
|
||||
outStream.file = outFile;
|
||||
|
||||
|
||||
2) Create CLzmaEncHandle object;
|
||||
|
||||
CLzmaEncHandle enc;
|
||||
|
||||
enc = LzmaEnc_Create(&g_Alloc);
|
||||
if (enc == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
|
||||
|
||||
3) initialize CLzmaEncProps properties;
|
||||
|
||||
LzmaEncProps_Init(&props);
|
||||
|
||||
Then you can change some properties in that structure.
|
||||
|
||||
4) Send LZMA properties to LZMA Encoder
|
||||
|
||||
res = LzmaEnc_SetProps(enc, &props);
|
||||
|
||||
5) Write encoded properties to header
|
||||
|
||||
Byte header[LZMA_PROPS_SIZE + 8];
|
||||
size_t headerSize = LZMA_PROPS_SIZE;
|
||||
UInt64 fileSize;
|
||||
int i;
|
||||
|
||||
res = LzmaEnc_WriteProperties(enc, header, &headerSize);
|
||||
fileSize = MyGetFileLength(inFile);
|
||||
for (i = 0; i < 8; i++)
|
||||
header[headerSize++] = (Byte)(fileSize >> (8 * i));
|
||||
MyWriteFileAndCheck(outFile, header, headerSize)
|
||||
|
||||
6) Call encoding function:
|
||||
res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
|
||||
NULL, &g_Alloc, &g_Alloc);
|
||||
|
||||
7) Destroy LZMA Encoder Object
|
||||
LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
|
||||
|
||||
|
||||
If callback function return some error code, LzmaEnc_Encode also returns that code.
|
||||
|
||||
|
||||
Single-call RAM->RAM Compression
|
||||
--------------------------------
|
||||
|
||||
Single-call RAM->RAM Compression is similar to Compression with callbacks,
|
||||
but you provide pointers to buffers instead of pointers to stream callbacks:
|
||||
|
||||
HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
|
||||
|
||||
|
||||
LZMA Defines
|
||||
------------
|
||||
|
||||
_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
|
||||
|
||||
_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
|
||||
some structures will be doubled in that case.
|
||||
|
||||
_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
|
||||
|
||||
_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
|
||||
|
||||
|
||||
C++ LZMA Encoder/Decoder
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
C++ LZMA code use COM-like interfaces. So if you want to use it,
|
||||
you can study basics of COM/OLE.
|
||||
C++ LZMA code is just wrapper over ANSI-C code.
|
||||
|
||||
|
||||
C++ Notes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
|
||||
you must check that you correctly work with "new" operator.
|
||||
7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
|
||||
So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
|
||||
operator new(size_t size)
|
||||
{
|
||||
void *p = ::malloc(size);
|
||||
if (p == 0)
|
||||
throw CNewException();
|
||||
return p;
|
||||
}
|
||||
If you use MSCV that throws exception for "new" operator, you can compile without
|
||||
"NewHandler.cpp". So standard exception will be used. Actually some code of
|
||||
7-Zip catches any exception in internal code and converts it to HRESULT code.
|
||||
So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
|
||||
|
||||
---
|
||||
|
||||
http://www.7-zip.org
|
||||
http://www.7-zip.org/sdk.html
|
||||
http://www.7-zip.org/support.html
|
||||
46
common/package/utils/sysupgrade-helper/src/lib/lzo/Makefile
Normal file
46
common/package/utils/sysupgrade-helper/src/lib/lzo/Makefile
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# (C) Copyright 2008
|
||||
# Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)liblzo.o
|
||||
|
||||
SOBJS =
|
||||
|
||||
COBJS-$(CONFIG_LZO) += lzo1x_decompress.o
|
||||
|
||||
COBJS = $(COBJS-y)
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* LZO1X Decompressor from MiniLZO
|
||||
*
|
||||
* Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
*
|
||||
* The full LZO package can be found at:
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*
|
||||
* Changed for kernel use by:
|
||||
* Nitin Gupta <nitingupta910@gmail.com>
|
||||
* Richard Purdie <rpurdie@openedhand.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/lzo.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include "lzodefs.h"
|
||||
|
||||
#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
|
||||
#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x))
|
||||
#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op)
|
||||
|
||||
#define COPY4(dst, src) \
|
||||
put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
|
||||
|
||||
static const unsigned char lzop_magic[] = {
|
||||
0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a
|
||||
};
|
||||
|
||||
#define HEADER_HAS_FILTER 0x00000800L
|
||||
|
||||
static inline const unsigned char *parse_header(const unsigned char *src)
|
||||
{
|
||||
u16 version;
|
||||
int i;
|
||||
|
||||
/* read magic: 9 first bytes */
|
||||
for (i = 0; i < ARRAY_SIZE(lzop_magic); i++) {
|
||||
if (*src++ != lzop_magic[i])
|
||||
return NULL;
|
||||
}
|
||||
/* get version (2bytes), skip library version (2),
|
||||
* 'need to be extracted' version (2) and
|
||||
* method (1) */
|
||||
version = get_unaligned_be16(src);
|
||||
src += 7;
|
||||
if (version >= 0x0940)
|
||||
src++;
|
||||
if (get_unaligned_be32(src) & HEADER_HAS_FILTER)
|
||||
src += 4; /* filter info */
|
||||
|
||||
/* skip flags, mode and mtime_low */
|
||||
src += 12;
|
||||
if (version >= 0x0940)
|
||||
src += 4; /* skip mtime_high */
|
||||
|
||||
i = *src++;
|
||||
/* don't care about the file name, and skip checksum */
|
||||
src += i + 4;
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
int lzop_decompress(const unsigned char *src, size_t src_len,
|
||||
unsigned char *dst, size_t *dst_len)
|
||||
{
|
||||
unsigned char *start = dst;
|
||||
const unsigned char *send = src + src_len;
|
||||
u32 slen, dlen;
|
||||
size_t tmp;
|
||||
int r;
|
||||
|
||||
src = parse_header(src);
|
||||
if (!src)
|
||||
return LZO_E_ERROR;
|
||||
|
||||
while (src < send) {
|
||||
/* read uncompressed block size */
|
||||
dlen = get_unaligned_be32(src);
|
||||
src += 4;
|
||||
|
||||
/* exit if last block */
|
||||
if (dlen == 0) {
|
||||
*dst_len = dst - start;
|
||||
return LZO_E_OK;
|
||||
}
|
||||
|
||||
/* read compressed block size, and skip block checksum info */
|
||||
slen = get_unaligned_be32(src);
|
||||
src += 8;
|
||||
|
||||
if (slen <= 0 || slen > dlen)
|
||||
return LZO_E_ERROR;
|
||||
|
||||
/* decompress */
|
||||
tmp = dlen;
|
||||
r = lzo1x_decompress_safe((u8 *) src, slen, dst, &tmp);
|
||||
|
||||
if (r != LZO_E_OK)
|
||||
return r;
|
||||
|
||||
if (dlen != tmp)
|
||||
return LZO_E_ERROR;
|
||||
|
||||
src += slen;
|
||||
dst += dlen;
|
||||
}
|
||||
|
||||
return LZO_E_INPUT_OVERRUN;
|
||||
}
|
||||
|
||||
int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, size_t *out_len)
|
||||
{
|
||||
const unsigned char * const ip_end = in + in_len;
|
||||
unsigned char * const op_end = out + *out_len;
|
||||
const unsigned char *ip = in, *m_pos;
|
||||
unsigned char *op = out;
|
||||
size_t t;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
if (*ip > 17) {
|
||||
t = *ip++ - 17;
|
||||
if (t < 4)
|
||||
goto match_next;
|
||||
if (HAVE_OP(t, op_end, op))
|
||||
goto output_overrun;
|
||||
if (HAVE_IP(t + 1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
goto first_literal_run;
|
||||
}
|
||||
|
||||
while ((ip < ip_end)) {
|
||||
t = *ip++;
|
||||
if (t >= 16)
|
||||
goto match;
|
||||
if (t == 0) {
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
while (*ip == 0) {
|
||||
t += 255;
|
||||
ip++;
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
}
|
||||
t += 15 + *ip++;
|
||||
}
|
||||
if (HAVE_OP(t + 3, op_end, op))
|
||||
goto output_overrun;
|
||||
if (HAVE_IP(t + 4, ip_end, ip))
|
||||
goto input_overrun;
|
||||
|
||||
COPY4(op, ip);
|
||||
op += 4;
|
||||
ip += 4;
|
||||
if (--t > 0) {
|
||||
if (t >= 4) {
|
||||
do {
|
||||
COPY4(op, ip);
|
||||
op += 4;
|
||||
ip += 4;
|
||||
t -= 4;
|
||||
} while (t >= 4);
|
||||
if (t > 0) {
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
}
|
||||
|
||||
first_literal_run:
|
||||
t = *ip++;
|
||||
if (t >= 16)
|
||||
goto match;
|
||||
m_pos = op - (1 + M2_MAX_OFFSET);
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
|
||||
if (HAVE_OP(3, op_end, op))
|
||||
goto output_overrun;
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos;
|
||||
|
||||
goto match_done;
|
||||
|
||||
do {
|
||||
match:
|
||||
if (t >= 64) {
|
||||
m_pos = op - 1;
|
||||
m_pos -= (t >> 2) & 7;
|
||||
m_pos -= *ip++ << 3;
|
||||
t = (t >> 5) - 1;
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
if (HAVE_OP(t + 3 - 1, op_end, op))
|
||||
goto output_overrun;
|
||||
goto copy_match;
|
||||
} else if (t >= 32) {
|
||||
t &= 31;
|
||||
if (t == 0) {
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
while (*ip == 0) {
|
||||
t += 255;
|
||||
ip++;
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
}
|
||||
t += 31 + *ip++;
|
||||
}
|
||||
m_pos = op - 1;
|
||||
m_pos -= get_unaligned_le16(ip) >> 2;
|
||||
ip += 2;
|
||||
} else if (t >= 16) {
|
||||
m_pos = op;
|
||||
m_pos -= (t & 8) << 11;
|
||||
|
||||
t &= 7;
|
||||
if (t == 0) {
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
while (*ip == 0) {
|
||||
t += 255;
|
||||
ip++;
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
}
|
||||
t += 7 + *ip++;
|
||||
}
|
||||
m_pos -= get_unaligned_le16(ip) >> 2;
|
||||
ip += 2;
|
||||
if (m_pos == op)
|
||||
goto eof_found;
|
||||
m_pos -= 0x4000;
|
||||
} else {
|
||||
m_pos = op - 1;
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
if (HAVE_OP(2, op_end, op))
|
||||
goto output_overrun;
|
||||
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos;
|
||||
goto match_done;
|
||||
}
|
||||
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
if (HAVE_OP(t + 3 - 1, op_end, op))
|
||||
goto output_overrun;
|
||||
|
||||
if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
|
||||
COPY4(op, m_pos);
|
||||
op += 4;
|
||||
m_pos += 4;
|
||||
t -= 4 - (3 - 1);
|
||||
do {
|
||||
COPY4(op, m_pos);
|
||||
op += 4;
|
||||
m_pos += 4;
|
||||
t -= 4;
|
||||
} while (t >= 4);
|
||||
if (t > 0)
|
||||
do {
|
||||
*op++ = *m_pos++;
|
||||
} while (--t > 0);
|
||||
} else {
|
||||
copy_match:
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos++;
|
||||
do {
|
||||
*op++ = *m_pos++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
match_done:
|
||||
t = ip[-2] & 3;
|
||||
if (t == 0)
|
||||
break;
|
||||
match_next:
|
||||
if (HAVE_OP(t, op_end, op))
|
||||
goto output_overrun;
|
||||
if (HAVE_IP(t + 1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
|
||||
*op++ = *ip++;
|
||||
if (t > 1) {
|
||||
*op++ = *ip++;
|
||||
if (t > 2)
|
||||
*op++ = *ip++;
|
||||
}
|
||||
|
||||
t = *ip++;
|
||||
} while (ip < ip_end);
|
||||
}
|
||||
|
||||
*out_len = op - out;
|
||||
return LZO_E_EOF_NOT_FOUND;
|
||||
|
||||
eof_found:
|
||||
*out_len = op - out;
|
||||
return (ip == ip_end ? LZO_E_OK :
|
||||
(ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
|
||||
input_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_INPUT_OVERRUN;
|
||||
|
||||
output_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_OUTPUT_OVERRUN;
|
||||
|
||||
lookbehind_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_LOOKBEHIND_OVERRUN;
|
||||
}
|
||||
43
common/package/utils/sysupgrade-helper/src/lib/lzo/lzodefs.h
Normal file
43
common/package/utils/sysupgrade-helper/src/lib/lzo/lzodefs.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* lzodefs.h -- architecture, OS and compiler specific defines
|
||||
*
|
||||
* Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
*
|
||||
* The full LZO package can be found at:
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*
|
||||
* Changed for kernel use by:
|
||||
* Nitin Gupta <nitingupta910@gmail.com>
|
||||
* Richard Purdie <rpurdie@openedhand.com>
|
||||
*/
|
||||
|
||||
#define LZO_VERSION 0x2020
|
||||
#define LZO_VERSION_STRING "2.02"
|
||||
#define LZO_VERSION_DATE "Oct 17 2005"
|
||||
|
||||
#define M1_MAX_OFFSET 0x0400
|
||||
#define M2_MAX_OFFSET 0x0800
|
||||
#define M3_MAX_OFFSET 0x4000
|
||||
#define M4_MAX_OFFSET 0xbfff
|
||||
|
||||
#define M1_MIN_LEN 2
|
||||
#define M1_MAX_LEN 2
|
||||
#define M2_MIN_LEN 3
|
||||
#define M2_MAX_LEN 8
|
||||
#define M3_MIN_LEN 3
|
||||
#define M3_MAX_LEN 33
|
||||
#define M4_MIN_LEN 3
|
||||
#define M4_MAX_LEN 9
|
||||
|
||||
#define M1_MARKER 0
|
||||
#define M2_MARKER 64
|
||||
#define M3_MARKER 32
|
||||
#define M4_MARKER 16
|
||||
|
||||
#define D_BITS 14
|
||||
#define D_MASK ((1u << D_BITS) - 1)
|
||||
#define D_HIGH ((D_MASK >> 1) + 1)
|
||||
|
||||
#define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \
|
||||
<< (s1)) ^ (p)[0])
|
||||
#define DX3(p, s1, s2, s3) ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0])
|
||||
314
common/package/utils/sysupgrade-helper/src/lib/md5.c
Normal file
314
common/package/utils/sysupgrade-helper/src/lib/md5.c
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* This file was transplanted with slight modifications from Linux sources
|
||||
* (fs/cifs/md5.c) into U-Boot by Bartlomiej Sieka <tur@semihalf.com>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*/
|
||||
|
||||
/* This code slightly modified to fit into Samba by
|
||||
abartlet@samba.org Jun 2001
|
||||
and to fit the cifs vfs by
|
||||
Steve French sfrench@us.ibm.com */
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
#endif /* USE_HOSTCC */
|
||||
#include <u-boot/md5.h>
|
||||
|
||||
static void
|
||||
MD5Transform(__u32 buf[4], __u32 const in[16]);
|
||||
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
static void
|
||||
byteReverse(unsigned char *buf, unsigned longs)
|
||||
{
|
||||
__u32 t;
|
||||
do {
|
||||
t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(__u32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
static void
|
||||
MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
static void
|
||||
MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
register __u32 t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((__u32) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memmove(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memmove(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memmove(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memmove(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
static void
|
||||
MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
unsigned int count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
ctx->in32[14] = ctx->bits[0];
|
||||
ctx->in32[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (__u32 *) ctx->in);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memmove(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
static void
|
||||
MD5Transform(__u32 buf[4], __u32 const in[16])
|
||||
{
|
||||
register __u32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate and store in 'output' the MD5 digest of 'len' bytes at
|
||||
* 'input'. 'output' must have enough space to hold 16 bytes.
|
||||
*/
|
||||
void
|
||||
md5 (unsigned char *input, int len, unsigned char output[16])
|
||||
{
|
||||
struct MD5Context context;
|
||||
|
||||
MD5Init(&context);
|
||||
MD5Update(&context, input, len);
|
||||
MD5Final(output, &context);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'.
|
||||
* 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the
|
||||
* watchdog every 'chunk_sz' bytes of input processed.
|
||||
*/
|
||||
void
|
||||
md5_wd (unsigned char *input, int len, unsigned char output[16],
|
||||
unsigned int chunk_sz)
|
||||
{
|
||||
struct MD5Context context;
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
unsigned char *end, *curr;
|
||||
int chunk;
|
||||
#endif
|
||||
|
||||
MD5Init(&context);
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
curr = input;
|
||||
end = input + len;
|
||||
while (curr < end) {
|
||||
chunk = end - curr;
|
||||
if (chunk > chunk_sz)
|
||||
chunk = chunk_sz;
|
||||
MD5Update(&context, curr, chunk);
|
||||
curr += chunk;
|
||||
WATCHDOG_RESET ();
|
||||
}
|
||||
#else
|
||||
MD5Update(&context, input, len);
|
||||
#endif
|
||||
|
||||
MD5Final(output, &context);
|
||||
}
|
||||
50
common/package/utils/sysupgrade-helper/src/lib/net_utils.c
Normal file
50
common/package/utils/sysupgrade-helper/src/lib/net_utils.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Generic network code. Moved from net.c
|
||||
*
|
||||
* Copyright 1994 - 2000 Neil Russell.
|
||||
* Copyright 2000 Roland Borde
|
||||
* Copyright 2000 Paolo Scaffardi
|
||||
* Copyright 2000-2002 Wolfgang Denk, wd@denx.de
|
||||
* Copyright 2009 Dirk Behme, dirk.behme@googlemail.com
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
IPaddr_t string_to_ip(const char *s)
|
||||
{
|
||||
IPaddr_t addr;
|
||||
char *e;
|
||||
int i;
|
||||
|
||||
if (s == NULL)
|
||||
return(0);
|
||||
|
||||
for (addr=0, i=0; i<4; ++i) {
|
||||
ulong val = s ? simple_strtoul(s, &e, 10) : 0;
|
||||
addr <<= 8;
|
||||
addr |= (val & 0xFF);
|
||||
if (s) {
|
||||
s = (*e) ? e+1 : e;
|
||||
}
|
||||
}
|
||||
|
||||
return (htonl(addr));
|
||||
}
|
||||
71
common/package/utils/sysupgrade-helper/src/lib/qsort.c
Normal file
71
common/package/utils/sysupgrade-helper/src/lib/qsort.c
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Code adapted from uClibc-0.9.30.3
|
||||
*
|
||||
* It is therefore covered by the GNU LESSER GENERAL PUBLIC LICENSE
|
||||
* Version 2.1, February 1999
|
||||
*
|
||||
* Wolfgang Denk <wd@denx.de>
|
||||
*/
|
||||
|
||||
/* This code is derived from a public domain shell sort routine by
|
||||
* Ray Gardner and found in Bob Stout's snippets collection. The
|
||||
* original code is included below in an #if 0/#endif block.
|
||||
*
|
||||
* I modified it to avoid the possibility of overflow in the wgap
|
||||
* calculation, as well as to reduce the generated code size with
|
||||
* bcc and gcc. */
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <common.h>
|
||||
#include <exports.h>
|
||||
|
||||
void qsort(void *base,
|
||||
size_t nel,
|
||||
size_t width,
|
||||
int (*comp)(const void *, const void *))
|
||||
{
|
||||
size_t wgap, i, j, k;
|
||||
char tmp;
|
||||
|
||||
if ((nel > 1) && (width > 0)) {
|
||||
assert(nel <= ((size_t)(-1)) / width); /* check for overflow */
|
||||
wgap = 0;
|
||||
do {
|
||||
wgap = 3 * wgap + 1;
|
||||
} while (wgap < (nel-1)/3);
|
||||
/* From the above, we know that either wgap == 1 < nel or */
|
||||
/* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
|
||||
wgap *= width; /* So this can not overflow if wnel doesn't. */
|
||||
nel *= width; /* Convert nel to 'wnel' */
|
||||
do {
|
||||
i = wgap;
|
||||
do {
|
||||
j = i;
|
||||
do {
|
||||
register char *a;
|
||||
register char *b;
|
||||
|
||||
j -= wgap;
|
||||
a = j + ((char *)base);
|
||||
b = a + wgap;
|
||||
if ((*comp)(a, b) <= 0) {
|
||||
break;
|
||||
}
|
||||
k = width;
|
||||
do {
|
||||
tmp = *a;
|
||||
*a++ = *b;
|
||||
*b++ = tmp;
|
||||
} while (--k);
|
||||
} while (j >= wgap);
|
||||
i += width;
|
||||
} while (i < nel);
|
||||
wgap = (wgap - width)/3;
|
||||
} while (wgap);
|
||||
}
|
||||
}
|
||||
|
||||
int strcmp_compar(const void *p1, const void *p2)
|
||||
{
|
||||
return strcmp(*(const char **)p1, *(const char **)p2);
|
||||
}
|
||||
48
common/package/utils/sysupgrade-helper/src/lib/rand.c
Normal file
48
common/package/utils/sysupgrade-helper/src/lib/rand.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Simple xorshift PRNG
|
||||
* see http://www.jstatsoft.org/v08/i14/paper
|
||||
*
|
||||
* Copyright (c) 2012 Michael Walle
|
||||
* Michael Walle <michael@walle.cc>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
static unsigned int y = 1U;
|
||||
|
||||
unsigned int rand_r(unsigned int *seedp)
|
||||
{
|
||||
*seedp ^= (*seedp << 13);
|
||||
*seedp ^= (*seedp >> 17);
|
||||
*seedp ^= (*seedp << 5);
|
||||
|
||||
return *seedp;
|
||||
}
|
||||
|
||||
unsigned int rand(void)
|
||||
{
|
||||
return rand_r(&y);
|
||||
}
|
||||
|
||||
void srand(unsigned int seed)
|
||||
{
|
||||
y = seed;
|
||||
}
|
||||
390
common/package/utils/sysupgrade-helper/src/lib/rbtree.c
Normal file
390
common/package/utils/sysupgrade-helper/src/lib/rbtree.c
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
Red Black Trees
|
||||
(C) 1999 Andrea Arcangeli <andrea@suse.de>
|
||||
(C) 2002 David Woodhouse <dwmw2@infradead.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
linux/lib/rbtree.c
|
||||
*/
|
||||
|
||||
#include <ubi_uboot.h>
|
||||
#include <linux/rbtree.h>
|
||||
|
||||
static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
|
||||
{
|
||||
struct rb_node *right = node->rb_right;
|
||||
struct rb_node *parent = rb_parent(node);
|
||||
|
||||
if ((node->rb_right = right->rb_left))
|
||||
rb_set_parent(right->rb_left, node);
|
||||
right->rb_left = node;
|
||||
|
||||
rb_set_parent(right, parent);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
if (node == parent->rb_left)
|
||||
parent->rb_left = right;
|
||||
else
|
||||
parent->rb_right = right;
|
||||
}
|
||||
else
|
||||
root->rb_node = right;
|
||||
rb_set_parent(node, right);
|
||||
}
|
||||
|
||||
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
|
||||
{
|
||||
struct rb_node *left = node->rb_left;
|
||||
struct rb_node *parent = rb_parent(node);
|
||||
|
||||
if ((node->rb_left = left->rb_right))
|
||||
rb_set_parent(left->rb_right, node);
|
||||
left->rb_right = node;
|
||||
|
||||
rb_set_parent(left, parent);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
if (node == parent->rb_right)
|
||||
parent->rb_right = left;
|
||||
else
|
||||
parent->rb_left = left;
|
||||
}
|
||||
else
|
||||
root->rb_node = left;
|
||||
rb_set_parent(node, left);
|
||||
}
|
||||
|
||||
void rb_insert_color(struct rb_node *node, struct rb_root *root)
|
||||
{
|
||||
struct rb_node *parent, *gparent;
|
||||
|
||||
while ((parent = rb_parent(node)) && rb_is_red(parent))
|
||||
{
|
||||
gparent = rb_parent(parent);
|
||||
|
||||
if (parent == gparent->rb_left)
|
||||
{
|
||||
{
|
||||
register struct rb_node *uncle = gparent->rb_right;
|
||||
if (uncle && rb_is_red(uncle))
|
||||
{
|
||||
rb_set_black(uncle);
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent->rb_right == node)
|
||||
{
|
||||
register struct rb_node *tmp;
|
||||
__rb_rotate_left(parent, root);
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
__rb_rotate_right(gparent, root);
|
||||
} else {
|
||||
{
|
||||
register struct rb_node *uncle = gparent->rb_left;
|
||||
if (uncle && rb_is_red(uncle))
|
||||
{
|
||||
rb_set_black(uncle);
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent->rb_left == node)
|
||||
{
|
||||
register struct rb_node *tmp;
|
||||
__rb_rotate_right(parent, root);
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
__rb_rotate_left(gparent, root);
|
||||
}
|
||||
}
|
||||
|
||||
rb_set_black(root->rb_node);
|
||||
}
|
||||
|
||||
static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
|
||||
struct rb_root *root)
|
||||
{
|
||||
struct rb_node *other;
|
||||
|
||||
while ((!node || rb_is_black(node)) && node != root->rb_node)
|
||||
{
|
||||
if (parent->rb_left == node)
|
||||
{
|
||||
other = parent->rb_right;
|
||||
if (rb_is_red(other))
|
||||
{
|
||||
rb_set_black(other);
|
||||
rb_set_red(parent);
|
||||
__rb_rotate_left(parent, root);
|
||||
other = parent->rb_right;
|
||||
}
|
||||
if ((!other->rb_left || rb_is_black(other->rb_left)) &&
|
||||
(!other->rb_right || rb_is_black(other->rb_right)))
|
||||
{
|
||||
rb_set_red(other);
|
||||
node = parent;
|
||||
parent = rb_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!other->rb_right || rb_is_black(other->rb_right))
|
||||
{
|
||||
struct rb_node *o_left;
|
||||
if ((o_left = other->rb_left))
|
||||
rb_set_black(o_left);
|
||||
rb_set_red(other);
|
||||
__rb_rotate_right(other, root);
|
||||
other = parent->rb_right;
|
||||
}
|
||||
rb_set_color(other, rb_color(parent));
|
||||
rb_set_black(parent);
|
||||
if (other->rb_right)
|
||||
rb_set_black(other->rb_right);
|
||||
__rb_rotate_left(parent, root);
|
||||
node = root->rb_node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
other = parent->rb_left;
|
||||
if (rb_is_red(other))
|
||||
{
|
||||
rb_set_black(other);
|
||||
rb_set_red(parent);
|
||||
__rb_rotate_right(parent, root);
|
||||
other = parent->rb_left;
|
||||
}
|
||||
if ((!other->rb_left || rb_is_black(other->rb_left)) &&
|
||||
(!other->rb_right || rb_is_black(other->rb_right)))
|
||||
{
|
||||
rb_set_red(other);
|
||||
node = parent;
|
||||
parent = rb_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!other->rb_left || rb_is_black(other->rb_left))
|
||||
{
|
||||
register struct rb_node *o_right;
|
||||
if ((o_right = other->rb_right))
|
||||
rb_set_black(o_right);
|
||||
rb_set_red(other);
|
||||
__rb_rotate_left(other, root);
|
||||
other = parent->rb_left;
|
||||
}
|
||||
rb_set_color(other, rb_color(parent));
|
||||
rb_set_black(parent);
|
||||
if (other->rb_left)
|
||||
rb_set_black(other->rb_left);
|
||||
__rb_rotate_right(parent, root);
|
||||
node = root->rb_node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node)
|
||||
rb_set_black(node);
|
||||
}
|
||||
|
||||
void rb_erase(struct rb_node *node, struct rb_root *root)
|
||||
{
|
||||
struct rb_node *child, *parent;
|
||||
int color;
|
||||
|
||||
if (!node->rb_left)
|
||||
child = node->rb_right;
|
||||
else if (!node->rb_right)
|
||||
child = node->rb_left;
|
||||
else
|
||||
{
|
||||
struct rb_node *old = node, *left;
|
||||
|
||||
node = node->rb_right;
|
||||
while ((left = node->rb_left) != NULL)
|
||||
node = left;
|
||||
child = node->rb_right;
|
||||
parent = rb_parent(node);
|
||||
color = rb_color(node);
|
||||
|
||||
if (child)
|
||||
rb_set_parent(child, parent);
|
||||
if (parent == old) {
|
||||
parent->rb_right = child;
|
||||
parent = node;
|
||||
} else
|
||||
parent->rb_left = child;
|
||||
|
||||
node->rb_parent_color = old->rb_parent_color;
|
||||
node->rb_right = old->rb_right;
|
||||
node->rb_left = old->rb_left;
|
||||
|
||||
if (rb_parent(old))
|
||||
{
|
||||
if (rb_parent(old)->rb_left == old)
|
||||
rb_parent(old)->rb_left = node;
|
||||
else
|
||||
rb_parent(old)->rb_right = node;
|
||||
} else
|
||||
root->rb_node = node;
|
||||
|
||||
rb_set_parent(old->rb_left, node);
|
||||
if (old->rb_right)
|
||||
rb_set_parent(old->rb_right, node);
|
||||
goto color;
|
||||
}
|
||||
|
||||
parent = rb_parent(node);
|
||||
color = rb_color(node);
|
||||
|
||||
if (child)
|
||||
rb_set_parent(child, parent);
|
||||
if (parent)
|
||||
{
|
||||
if (parent->rb_left == node)
|
||||
parent->rb_left = child;
|
||||
else
|
||||
parent->rb_right = child;
|
||||
}
|
||||
else
|
||||
root->rb_node = child;
|
||||
|
||||
color:
|
||||
if (color == RB_BLACK)
|
||||
__rb_erase_color(child, parent, root);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns the first node (in sort order) of the tree.
|
||||
*/
|
||||
struct rb_node *rb_first(struct rb_root *root)
|
||||
{
|
||||
struct rb_node *n;
|
||||
|
||||
n = root->rb_node;
|
||||
if (!n)
|
||||
return NULL;
|
||||
while (n->rb_left)
|
||||
n = n->rb_left;
|
||||
return n;
|
||||
}
|
||||
|
||||
struct rb_node *rb_last(struct rb_root *root)
|
||||
{
|
||||
struct rb_node *n;
|
||||
|
||||
n = root->rb_node;
|
||||
if (!n)
|
||||
return NULL;
|
||||
while (n->rb_right)
|
||||
n = n->rb_right;
|
||||
return n;
|
||||
}
|
||||
|
||||
struct rb_node *rb_next(struct rb_node *node)
|
||||
{
|
||||
struct rb_node *parent;
|
||||
|
||||
if (rb_parent(node) == node)
|
||||
return NULL;
|
||||
|
||||
/* If we have a right-hand child, go down and then left as far
|
||||
as we can. */
|
||||
if (node->rb_right) {
|
||||
node = node->rb_right;
|
||||
while (node->rb_left)
|
||||
node=node->rb_left;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* No right-hand children. Everything down and left is
|
||||
smaller than us, so any 'next' node must be in the general
|
||||
direction of our parent. Go up the tree; any time the
|
||||
ancestor is a right-hand child of its parent, keep going
|
||||
up. First time it's a left-hand child of its parent, said
|
||||
parent is our 'next' node. */
|
||||
while ((parent = rb_parent(node)) && node == parent->rb_right)
|
||||
node = parent;
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
struct rb_node *rb_prev(struct rb_node *node)
|
||||
{
|
||||
struct rb_node *parent;
|
||||
|
||||
if (rb_parent(node) == node)
|
||||
return NULL;
|
||||
|
||||
/* If we have a left-hand child, go down and then right as far
|
||||
as we can. */
|
||||
if (node->rb_left) {
|
||||
node = node->rb_left;
|
||||
while (node->rb_right)
|
||||
node=node->rb_right;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* No left-hand children. Go up till we find an ancestor which
|
||||
is a right-hand child of its parent */
|
||||
while ((parent = rb_parent(node)) && node == parent->rb_left)
|
||||
node = parent;
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
void rb_replace_node(struct rb_node *victim, struct rb_node *new,
|
||||
struct rb_root *root)
|
||||
{
|
||||
struct rb_node *parent = rb_parent(victim);
|
||||
|
||||
/* Set the surrounding nodes to point to the replacement */
|
||||
if (parent) {
|
||||
if (victim == parent->rb_left)
|
||||
parent->rb_left = new;
|
||||
else
|
||||
parent->rb_right = new;
|
||||
} else {
|
||||
root->rb_node = new;
|
||||
}
|
||||
if (victim->rb_left)
|
||||
rb_set_parent(victim->rb_left, new);
|
||||
if (victim->rb_right)
|
||||
rb_set_parent(victim->rb_right, new);
|
||||
|
||||
/* Copy the pointers/colour from the victim to the replacement */
|
||||
*new = *victim;
|
||||
}
|
||||
452
common/package/utils/sysupgrade-helper/src/lib/sha1.c
Normal file
452
common/package/utils/sysupgrade-helper/src/lib/sha1.c
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
/*
|
||||
* Heiko Schocher, DENX Software Engineering, hs@denx.de.
|
||||
* based on:
|
||||
* FIPS-180-1 compliant SHA-1 implementation
|
||||
*
|
||||
* Copyright (C) 2003-2006 Christophe Devine
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License, version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
/*
|
||||
* The SHA-1 standard was published by NIST in 1993.
|
||||
*
|
||||
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||
*/
|
||||
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <common.h>
|
||||
#include <linux/string.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif /* USE_HOSTCC */
|
||||
#include <watchdog.h>
|
||||
#include "u-boot-sha1.h"
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) { \
|
||||
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
|
||||
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
|
||||
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
|
||||
| ( (unsigned long) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
void sha1_starts (sha1_context * ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
static void sha1_process (sha1_context * ctx, unsigned char data[64])
|
||||
{
|
||||
unsigned long temp, W[16], A, B, C, D, E;
|
||||
|
||||
GET_UINT32_BE (W[0], data, 0);
|
||||
GET_UINT32_BE (W[1], data, 4);
|
||||
GET_UINT32_BE (W[2], data, 8);
|
||||
GET_UINT32_BE (W[3], data, 12);
|
||||
GET_UINT32_BE (W[4], data, 16);
|
||||
GET_UINT32_BE (W[5], data, 20);
|
||||
GET_UINT32_BE (W[6], data, 24);
|
||||
GET_UINT32_BE (W[7], data, 28);
|
||||
GET_UINT32_BE (W[8], data, 32);
|
||||
GET_UINT32_BE (W[9], data, 36);
|
||||
GET_UINT32_BE (W[10], data, 40);
|
||||
GET_UINT32_BE (W[11], data, 44);
|
||||
GET_UINT32_BE (W[12], data, 48);
|
||||
GET_UINT32_BE (W[13], data, 52);
|
||||
GET_UINT32_BE (W[14], data, 56);
|
||||
GET_UINT32_BE (W[15], data, 60);
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define R(t) ( \
|
||||
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
|
||||
W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
|
||||
( W[t & 0x0F] = S(temp,1) ) \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,x) { \
|
||||
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define K 0x5A827999
|
||||
|
||||
P (A, B, C, D, E, W[0]);
|
||||
P (E, A, B, C, D, W[1]);
|
||||
P (D, E, A, B, C, W[2]);
|
||||
P (C, D, E, A, B, W[3]);
|
||||
P (B, C, D, E, A, W[4]);
|
||||
P (A, B, C, D, E, W[5]);
|
||||
P (E, A, B, C, D, W[6]);
|
||||
P (D, E, A, B, C, W[7]);
|
||||
P (C, D, E, A, B, W[8]);
|
||||
P (B, C, D, E, A, W[9]);
|
||||
P (A, B, C, D, E, W[10]);
|
||||
P (E, A, B, C, D, W[11]);
|
||||
P (D, E, A, B, C, W[12]);
|
||||
P (C, D, E, A, B, W[13]);
|
||||
P (B, C, D, E, A, W[14]);
|
||||
P (A, B, C, D, E, W[15]);
|
||||
P (E, A, B, C, D, R (16));
|
||||
P (D, E, A, B, C, R (17));
|
||||
P (C, D, E, A, B, R (18));
|
||||
P (B, C, D, E, A, R (19));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0x6ED9EBA1
|
||||
|
||||
P (A, B, C, D, E, R (20));
|
||||
P (E, A, B, C, D, R (21));
|
||||
P (D, E, A, B, C, R (22));
|
||||
P (C, D, E, A, B, R (23));
|
||||
P (B, C, D, E, A, R (24));
|
||||
P (A, B, C, D, E, R (25));
|
||||
P (E, A, B, C, D, R (26));
|
||||
P (D, E, A, B, C, R (27));
|
||||
P (C, D, E, A, B, R (28));
|
||||
P (B, C, D, E, A, R (29));
|
||||
P (A, B, C, D, E, R (30));
|
||||
P (E, A, B, C, D, R (31));
|
||||
P (D, E, A, B, C, R (32));
|
||||
P (C, D, E, A, B, R (33));
|
||||
P (B, C, D, E, A, R (34));
|
||||
P (A, B, C, D, E, R (35));
|
||||
P (E, A, B, C, D, R (36));
|
||||
P (D, E, A, B, C, R (37));
|
||||
P (C, D, E, A, B, R (38));
|
||||
P (B, C, D, E, A, R (39));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define K 0x8F1BBCDC
|
||||
|
||||
P (A, B, C, D, E, R (40));
|
||||
P (E, A, B, C, D, R (41));
|
||||
P (D, E, A, B, C, R (42));
|
||||
P (C, D, E, A, B, R (43));
|
||||
P (B, C, D, E, A, R (44));
|
||||
P (A, B, C, D, E, R (45));
|
||||
P (E, A, B, C, D, R (46));
|
||||
P (D, E, A, B, C, R (47));
|
||||
P (C, D, E, A, B, R (48));
|
||||
P (B, C, D, E, A, R (49));
|
||||
P (A, B, C, D, E, R (50));
|
||||
P (E, A, B, C, D, R (51));
|
||||
P (D, E, A, B, C, R (52));
|
||||
P (C, D, E, A, B, R (53));
|
||||
P (B, C, D, E, A, R (54));
|
||||
P (A, B, C, D, E, R (55));
|
||||
P (E, A, B, C, D, R (56));
|
||||
P (D, E, A, B, C, R (57));
|
||||
P (C, D, E, A, B, R (58));
|
||||
P (B, C, D, E, A, R (59));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0xCA62C1D6
|
||||
|
||||
P (A, B, C, D, E, R (60));
|
||||
P (E, A, B, C, D, R (61));
|
||||
P (D, E, A, B, C, R (62));
|
||||
P (C, D, E, A, B, R (63));
|
||||
P (B, C, D, E, A, R (64));
|
||||
P (A, B, C, D, E, R (65));
|
||||
P (E, A, B, C, D, R (66));
|
||||
P (D, E, A, B, C, R (67));
|
||||
P (C, D, E, A, B, R (68));
|
||||
P (B, C, D, E, A, R (69));
|
||||
P (A, B, C, D, E, R (70));
|
||||
P (E, A, B, C, D, R (71));
|
||||
P (D, E, A, B, C, R (72));
|
||||
P (C, D, E, A, B, R (73));
|
||||
P (B, C, D, E, A, R (74));
|
||||
P (A, B, C, D, E, R (75));
|
||||
P (E, A, B, C, D, R (76));
|
||||
P (D, E, A, B, C, R (77));
|
||||
P (C, D, E, A, B, R (78));
|
||||
P (B, C, D, E, A, R (79));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
void sha1_update (sha1_context * ctx, unsigned char *input, int ilen)
|
||||
{
|
||||
int fill;
|
||||
unsigned long left;
|
||||
|
||||
if (ilen <= 0)
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < (unsigned long) ilen)
|
||||
ctx->total[1]++;
|
||||
|
||||
if (left && ilen >= fill) {
|
||||
memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
|
||||
sha1_process (ctx, ctx->buffer);
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (ilen >= 64) {
|
||||
sha1_process (ctx, input);
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if (ilen > 0) {
|
||||
memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char sha1_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
void sha1_finish (sha1_context * ctx, unsigned char output[20])
|
||||
{
|
||||
unsigned long last, padn;
|
||||
unsigned long high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = (ctx->total[0] >> 29)
|
||||
| (ctx->total[1] << 3);
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
PUT_UINT32_BE (high, msglen, 0);
|
||||
PUT_UINT32_BE (low, msglen, 4);
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
sha1_update (ctx, (unsigned char *) sha1_padding, padn);
|
||||
sha1_update (ctx, msglen, 8);
|
||||
|
||||
PUT_UINT32_BE (ctx->state[0], output, 0);
|
||||
PUT_UINT32_BE (ctx->state[1], output, 4);
|
||||
PUT_UINT32_BE (ctx->state[2], output, 8);
|
||||
PUT_UINT32_BE (ctx->state[3], output, 12);
|
||||
PUT_UINT32_BE (ctx->state[4], output, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output = SHA-1( input buffer )
|
||||
*/
|
||||
void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
|
||||
{
|
||||
sha1_context ctx;
|
||||
|
||||
sha1_starts (&ctx);
|
||||
sha1_update (&ctx, input, ilen);
|
||||
sha1_finish (&ctx, output);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
|
||||
* bytes of input processed.
|
||||
*/
|
||||
void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
|
||||
unsigned int chunk_sz)
|
||||
{
|
||||
sha1_context ctx;
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
unsigned char *end, *curr;
|
||||
int chunk;
|
||||
#endif
|
||||
|
||||
sha1_starts (&ctx);
|
||||
|
||||
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
|
||||
curr = input;
|
||||
end = input + ilen;
|
||||
while (curr < end) {
|
||||
chunk = end - curr;
|
||||
if (chunk > chunk_sz)
|
||||
chunk = chunk_sz;
|
||||
sha1_update (&ctx, curr, chunk);
|
||||
curr += chunk;
|
||||
WATCHDOG_RESET ();
|
||||
}
|
||||
#else
|
||||
sha1_update (&ctx, input, ilen);
|
||||
#endif
|
||||
|
||||
sha1_finish (&ctx, output);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output = HMAC-SHA-1( input buffer, hmac key )
|
||||
*/
|
||||
void sha1_hmac (unsigned char *key, int keylen,
|
||||
unsigned char *input, int ilen, unsigned char output[20])
|
||||
{
|
||||
int i;
|
||||
sha1_context ctx;
|
||||
unsigned char k_ipad[64];
|
||||
unsigned char k_opad[64];
|
||||
unsigned char tmpbuf[20];
|
||||
|
||||
memset (k_ipad, 0x36, 64);
|
||||
memset (k_opad, 0x5C, 64);
|
||||
|
||||
for (i = 0; i < keylen; i++) {
|
||||
if (i >= 64)
|
||||
break;
|
||||
|
||||
k_ipad[i] ^= key[i];
|
||||
k_opad[i] ^= key[i];
|
||||
}
|
||||
|
||||
sha1_starts (&ctx);
|
||||
sha1_update (&ctx, k_ipad, 64);
|
||||
sha1_update (&ctx, input, ilen);
|
||||
sha1_finish (&ctx, tmpbuf);
|
||||
|
||||
sha1_starts (&ctx);
|
||||
sha1_update (&ctx, k_opad, 64);
|
||||
sha1_update (&ctx, tmpbuf, 20);
|
||||
sha1_finish (&ctx, output);
|
||||
|
||||
memset (k_ipad, 0, 64);
|
||||
memset (k_opad, 0, 64);
|
||||
memset (tmpbuf, 0, 20);
|
||||
memset (&ctx, 0, sizeof (sha1_context));
|
||||
}
|
||||
|
||||
static const char _sha1_src[] = "_sha1_src";
|
||||
|
||||
#ifdef SELF_TEST
|
||||
/*
|
||||
* FIPS-180-1 test vectors
|
||||
*/
|
||||
static const char sha1_test_str[3][57] = {
|
||||
{"abc"},
|
||||
{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
|
||||
{""}
|
||||
};
|
||||
|
||||
static const unsigned char sha1_test_sum[3][20] = {
|
||||
{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
|
||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
|
||||
{0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
|
||||
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
|
||||
{0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
|
||||
0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int sha1_self_test (void)
|
||||
{
|
||||
int i, j;
|
||||
unsigned char buf[1000];
|
||||
unsigned char sha1sum[20];
|
||||
sha1_context ctx;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
printf (" SHA-1 test #%d: ", i + 1);
|
||||
|
||||
sha1_starts (&ctx);
|
||||
|
||||
if (i < 2)
|
||||
sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
|
||||
strlen (sha1_test_str[i]));
|
||||
else {
|
||||
memset (buf, 'a', 1000);
|
||||
for (j = 0; j < 1000; j++)
|
||||
sha1_update (&ctx, buf, 1000);
|
||||
}
|
||||
|
||||
sha1_finish (&ctx, sha1sum);
|
||||
|
||||
if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
|
||||
printf ("failed\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
printf ("passed\n");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
int sha1_self_test (void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
262
common/package/utils/sysupgrade-helper/src/lib/sha256.c
Normal file
262
common/package/utils/sysupgrade-helper/src/lib/sha256.c
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* FIPS-180-2 compliant SHA-256 implementation
|
||||
*
|
||||
* Copyright (C) 2001-2003 Christophe Devine
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
#include <common.h>
|
||||
#endif /* USE_HOSTCC */
|
||||
#include <watchdog.h>
|
||||
#include <linux/string.h>
|
||||
#include <sha256.h>
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) { \
|
||||
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
|
||||
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
|
||||
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
|
||||
| ( (unsigned long) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void sha256_starts(sha256_context * ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x6A09E667;
|
||||
ctx->state[1] = 0xBB67AE85;
|
||||
ctx->state[2] = 0x3C6EF372;
|
||||
ctx->state[3] = 0xA54FF53A;
|
||||
ctx->state[4] = 0x510E527F;
|
||||
ctx->state[5] = 0x9B05688C;
|
||||
ctx->state[6] = 0x1F83D9AB;
|
||||
ctx->state[7] = 0x5BE0CD19;
|
||||
}
|
||||
|
||||
void sha256_process(sha256_context * ctx, uint8_t data[64])
|
||||
{
|
||||
uint32_t temp1, temp2;
|
||||
uint32_t W[64];
|
||||
uint32_t A, B, C, D, E, F, G, H;
|
||||
|
||||
GET_UINT32_BE(W[0], data, 0);
|
||||
GET_UINT32_BE(W[1], data, 4);
|
||||
GET_UINT32_BE(W[2], data, 8);
|
||||
GET_UINT32_BE(W[3], data, 12);
|
||||
GET_UINT32_BE(W[4], data, 16);
|
||||
GET_UINT32_BE(W[5], data, 20);
|
||||
GET_UINT32_BE(W[6], data, 24);
|
||||
GET_UINT32_BE(W[7], data, 28);
|
||||
GET_UINT32_BE(W[8], data, 32);
|
||||
GET_UINT32_BE(W[9], data, 36);
|
||||
GET_UINT32_BE(W[10], data, 40);
|
||||
GET_UINT32_BE(W[11], data, 44);
|
||||
GET_UINT32_BE(W[12], data, 48);
|
||||
GET_UINT32_BE(W[13], data, 52);
|
||||
GET_UINT32_BE(W[14], data, 56);
|
||||
GET_UINT32_BE(W[15], data, 60);
|
||||
|
||||
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
|
||||
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
|
||||
|
||||
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
|
||||
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||||
S0(W[t - 15]) + W[t - 16] \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) { \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
|
||||
P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
|
||||
P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
|
||||
P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
|
||||
P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
|
||||
P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
|
||||
P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
|
||||
P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
|
||||
P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
|
||||
P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
|
||||
P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
|
||||
P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
|
||||
P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
|
||||
P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
|
||||
P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
|
||||
P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
|
||||
P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
|
||||
P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
|
||||
P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
|
||||
P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
|
||||
P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
|
||||
P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
|
||||
P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
|
||||
P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
|
||||
P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
|
||||
P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
|
||||
P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
|
||||
P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
|
||||
P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
|
||||
P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
|
||||
P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
|
||||
P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
|
||||
P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
|
||||
P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
|
||||
P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
|
||||
P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
|
||||
P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
|
||||
P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
|
||||
P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
|
||||
P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
|
||||
P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
|
||||
P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
|
||||
P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
|
||||
P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
|
||||
P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
|
||||
P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
|
||||
P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
|
||||
P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
|
||||
P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
|
||||
P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
|
||||
P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
|
||||
P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
|
||||
P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
|
||||
P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
|
||||
P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
|
||||
P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
|
||||
P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
|
||||
P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
|
||||
P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
|
||||
P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
|
||||
P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
|
||||
P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
|
||||
P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
|
||||
P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
|
||||
P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
}
|
||||
|
||||
void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length)
|
||||
{
|
||||
uint32_t left, fill;
|
||||
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += length;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < length)
|
||||
ctx->total[1]++;
|
||||
|
||||
if (left && length >= fill) {
|
||||
memcpy((void *) (ctx->buffer + left), (void *) input, fill);
|
||||
sha256_process(ctx, ctx->buffer);
|
||||
length -= fill;
|
||||
input += fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (length >= 64) {
|
||||
sha256_process(ctx, input);
|
||||
length -= 64;
|
||||
input += 64;
|
||||
}
|
||||
|
||||
if (length)
|
||||
memcpy((void *) (ctx->buffer + left), (void *) input, length);
|
||||
}
|
||||
|
||||
static uint8_t sha256_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void sha256_finish(sha256_context * ctx, uint8_t digest[32])
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
uint8_t msglen[8];
|
||||
|
||||
high = ((ctx->total[0] >> 29)
|
||||
| (ctx->total[1] << 3));
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
PUT_UINT32_BE(high, msglen, 0);
|
||||
PUT_UINT32_BE(low, msglen, 4);
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
sha256_update(ctx, sha256_padding, padn);
|
||||
sha256_update(ctx, msglen, 8);
|
||||
|
||||
PUT_UINT32_BE(ctx->state[0], digest, 0);
|
||||
PUT_UINT32_BE(ctx->state[1], digest, 4);
|
||||
PUT_UINT32_BE(ctx->state[2], digest, 8);
|
||||
PUT_UINT32_BE(ctx->state[3], digest, 12);
|
||||
PUT_UINT32_BE(ctx->state[4], digest, 16);
|
||||
PUT_UINT32_BE(ctx->state[5], digest, 20);
|
||||
PUT_UINT32_BE(ctx->state[6], digest, 24);
|
||||
PUT_UINT32_BE(ctx->state[7], digest, 28);
|
||||
}
|
||||
673
common/package/utils/sysupgrade-helper/src/lib/string.c
Normal file
673
common/package/utils/sysupgrade-helper/src/lib/string.c
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
/*
|
||||
* linux/lib/string.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/*
|
||||
* stupid library routines.. The optimized versions should generally be found
|
||||
* as inline code in <asm-xx/string.h>
|
||||
*
|
||||
* These are buggy as well..
|
||||
*
|
||||
* * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
|
||||
* - Added strsep() which will replace strtok() soon (because strsep() is
|
||||
* reentrant and should be faster). Use only strsep() in new code, please.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <malloc.h>
|
||||
|
||||
|
||||
#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */
|
||||
/**
|
||||
* strnicmp - Case insensitive, length-limited string comparison
|
||||
* @s1: One string
|
||||
* @s2: The other string
|
||||
* @len: the maximum number of characters to compare
|
||||
*/
|
||||
int strnicmp(const char *s1, const char *s2, size_t len)
|
||||
{
|
||||
/* Yes, Virginia, it had better be unsigned */
|
||||
unsigned char c1, c2;
|
||||
|
||||
c1 = 0; c2 = 0;
|
||||
if (len) {
|
||||
do {
|
||||
c1 = *s1; c2 = *s2;
|
||||
s1++; s2++;
|
||||
if (!c1)
|
||||
break;
|
||||
if (!c2)
|
||||
break;
|
||||
if (c1 == c2)
|
||||
continue;
|
||||
c1 = tolower(c1);
|
||||
c2 = tolower(c2);
|
||||
if (c1 != c2)
|
||||
break;
|
||||
} while (--len);
|
||||
}
|
||||
return (int)c1 - (int)c2;
|
||||
}
|
||||
#endif
|
||||
|
||||
char * ___strtok;
|
||||
|
||||
/**
|
||||
* strlcpy - Copy a %NUL terminated string into a sized buffer
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
* @size: size of destination buffer
|
||||
*
|
||||
* Compatible with *BSD: the result is always a valid
|
||||
* NUL-terminated string that fits in the buffer (unless,
|
||||
* of course, the buffer size is zero). It does not pad
|
||||
* out the result like strncpy() does.
|
||||
*/
|
||||
size_t strlcpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t ret = strlen(src);
|
||||
|
||||
if (size) {
|
||||
size_t len = (ret >= size) ? size - 1 : ret;
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCPY
|
||||
/**
|
||||
* strcpy - Copy a %NUL terminated string
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
*/
|
||||
char * strcpy(char * dest,const char *src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
/* nothing */;
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNCPY
|
||||
/**
|
||||
* strncpy - Copy a length-limited, %NUL-terminated string
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
* @count: The maximum number of bytes to copy
|
||||
*
|
||||
* Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
|
||||
* However, the result is not %NUL-terminated if the source exceeds
|
||||
* @count bytes.
|
||||
*/
|
||||
char * strncpy(char * dest,const char *src,size_t count)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (count-- && (*dest++ = *src++) != '\0')
|
||||
/* nothing */;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCAT
|
||||
/**
|
||||
* strcat - Append one %NUL-terminated string to another
|
||||
* @dest: The string to be appended to
|
||||
* @src: The string to append to it
|
||||
*/
|
||||
char * strcat(char * dest, const char * src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNCAT
|
||||
/**
|
||||
* strncat - Append a length-limited, %NUL-terminated string to another
|
||||
* @dest: The string to be appended to
|
||||
* @src: The string to append to it
|
||||
* @count: The maximum numbers of bytes to copy
|
||||
*
|
||||
* Note that in contrast to strncpy, strncat ensures the result is
|
||||
* terminated.
|
||||
*/
|
||||
char * strncat(char *dest, const char *src, size_t count)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
if (count) {
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++)) {
|
||||
if (--count == 0) {
|
||||
*dest = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCMP
|
||||
/**
|
||||
* strcmp - Compare two strings
|
||||
* @cs: One string
|
||||
* @ct: Another string
|
||||
*/
|
||||
int strcmp(const char * cs,const char * ct)
|
||||
{
|
||||
register signed char __res;
|
||||
|
||||
while (1) {
|
||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
||||
break;
|
||||
}
|
||||
|
||||
return __res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNCMP
|
||||
/**
|
||||
* strncmp - Compare two length-limited strings
|
||||
* @cs: One string
|
||||
* @ct: Another string
|
||||
* @count: The maximum number of bytes to compare
|
||||
*/
|
||||
int strncmp(const char * cs,const char * ct,size_t count)
|
||||
{
|
||||
register signed char __res = 0;
|
||||
|
||||
while (count) {
|
||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
||||
break;
|
||||
count--;
|
||||
}
|
||||
|
||||
return __res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCHR
|
||||
/**
|
||||
* strchr - Find the first occurrence of a character in a string
|
||||
* @s: The string to be searched
|
||||
* @c: The character to search for
|
||||
*/
|
||||
char * strchr(const char * s, int c)
|
||||
{
|
||||
for(; *s != (char) c; ++s)
|
||||
if (*s == '\0')
|
||||
return NULL;
|
||||
return (char *) s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRRCHR
|
||||
/**
|
||||
* strrchr - Find the last occurrence of a character in a string
|
||||
* @s: The string to be searched
|
||||
* @c: The character to search for
|
||||
*/
|
||||
char * strrchr(const char * s, int c)
|
||||
{
|
||||
const char *p = s + strlen(s);
|
||||
do {
|
||||
if (*p == (char)c)
|
||||
return (char *)p;
|
||||
} while (--p >= s);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* skip_spaces - Removes leading whitespace from @str.
|
||||
* @str: The string to be stripped.
|
||||
*
|
||||
* Returns a pointer to the first non-whitespace character in @str.
|
||||
*/
|
||||
char *skip_spaces(const char *str)
|
||||
{
|
||||
while (isspace(*str))
|
||||
++str;
|
||||
return (char *)str;
|
||||
}
|
||||
|
||||
/**
|
||||
* strim - Removes leading and trailing whitespace from @s.
|
||||
* @s: The string to be stripped.
|
||||
*
|
||||
* Note that the first trailing whitespace is replaced with a %NUL-terminator
|
||||
* in the given string @s. Returns a pointer to the first non-whitespace
|
||||
* character in @s.
|
||||
*/
|
||||
char *strim(char *s)
|
||||
{
|
||||
size_t size;
|
||||
char *end;
|
||||
|
||||
s = skip_spaces(s);
|
||||
size = strlen(s);
|
||||
if (!size)
|
||||
return s;
|
||||
|
||||
end = s + size - 1;
|
||||
while (end >= s && isspace(*end))
|
||||
end--;
|
||||
*(end + 1) = '\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
#ifndef __HAVE_ARCH_STRLEN
|
||||
/**
|
||||
* strlen - Find the length of a string
|
||||
* @s: The string to be sized
|
||||
*/
|
||||
size_t strlen(const char * s)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNLEN
|
||||
/**
|
||||
* strnlen - Find the length of a length-limited string
|
||||
* @s: The string to be sized
|
||||
* @count: The maximum number of bytes to search
|
||||
*/
|
||||
size_t strnlen(const char * s, size_t count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRDUP
|
||||
char * strdup(const char *s)
|
||||
{
|
||||
char *new;
|
||||
|
||||
if ((s == NULL) ||
|
||||
((new = malloc (strlen(s) + 1)) == NULL) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (new, s);
|
||||
return new;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSPN
|
||||
/**
|
||||
* strspn - Calculate the length of the initial substring of @s which only
|
||||
* contain letters in @accept
|
||||
* @s: The string to be searched
|
||||
* @accept: The string to search for
|
||||
*/
|
||||
size_t strspn(const char *s, const char *accept)
|
||||
{
|
||||
const char *p;
|
||||
const char *a;
|
||||
size_t count = 0;
|
||||
|
||||
for (p = s; *p != '\0'; ++p) {
|
||||
for (a = accept; *a != '\0'; ++a) {
|
||||
if (*p == *a)
|
||||
break;
|
||||
}
|
||||
if (*a == '\0')
|
||||
return count;
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRPBRK
|
||||
/**
|
||||
* strpbrk - Find the first occurrence of a set of characters
|
||||
* @cs: The string to be searched
|
||||
* @ct: The characters to search for
|
||||
*/
|
||||
char * strpbrk(const char * cs,const char * ct)
|
||||
{
|
||||
const char *sc1,*sc2;
|
||||
|
||||
for( sc1 = cs; *sc1 != '\0'; ++sc1) {
|
||||
for( sc2 = ct; *sc2 != '\0'; ++sc2) {
|
||||
if (*sc1 == *sc2)
|
||||
return (char *) sc1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRTOK
|
||||
/**
|
||||
* strtok - Split a string into tokens
|
||||
* @s: The string to be searched
|
||||
* @ct: The characters to search for
|
||||
*
|
||||
* WARNING: strtok is deprecated, use strsep instead.
|
||||
*/
|
||||
char * strtok(char * s,const char * ct)
|
||||
{
|
||||
char *sbegin, *send;
|
||||
|
||||
sbegin = s ? s : ___strtok;
|
||||
if (!sbegin) {
|
||||
return NULL;
|
||||
}
|
||||
sbegin += strspn(sbegin,ct);
|
||||
if (*sbegin == '\0') {
|
||||
___strtok = NULL;
|
||||
return( NULL );
|
||||
}
|
||||
send = strpbrk( sbegin, ct);
|
||||
if (send && *send != '\0')
|
||||
*send++ = '\0';
|
||||
___strtok = send;
|
||||
return (sbegin);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSEP
|
||||
/**
|
||||
* strsep - Split a string into tokens
|
||||
* @s: The string to be searched
|
||||
* @ct: The characters to search for
|
||||
*
|
||||
* strsep() updates @s to point after the token, ready for the next call.
|
||||
*
|
||||
* It returns empty tokens, too, behaving exactly like the libc function
|
||||
* of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
|
||||
* Same semantics, slimmer shape. ;)
|
||||
*/
|
||||
char * strsep(char **s, const char *ct)
|
||||
{
|
||||
char *sbegin = *s, *end;
|
||||
|
||||
if (sbegin == NULL)
|
||||
return NULL;
|
||||
|
||||
end = strpbrk(sbegin, ct);
|
||||
if (end)
|
||||
*end++ = '\0';
|
||||
*s = end;
|
||||
|
||||
return sbegin;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSWAB
|
||||
/**
|
||||
* strswab - swap adjacent even and odd bytes in %NUL-terminated string
|
||||
* s: address of the string
|
||||
*
|
||||
* returns the address of the swapped string or NULL on error. If
|
||||
* string length is odd, last byte is untouched.
|
||||
*/
|
||||
char *strswab(const char *s)
|
||||
{
|
||||
char *p, *q;
|
||||
|
||||
if ((NULL == s) || ('\0' == *s)) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) {
|
||||
char tmp;
|
||||
|
||||
tmp = *p;
|
||||
*p = *q;
|
||||
*q = tmp;
|
||||
}
|
||||
|
||||
return (char *) s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMSET
|
||||
/**
|
||||
* memset - Fill a region of memory with the given value
|
||||
* @s: Pointer to the start of the area.
|
||||
* @c: The byte to fill the area with
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* Do not use memset() to access IO space, use memset_io() instead.
|
||||
*/
|
||||
void * memset(void * s,int c,size_t count)
|
||||
{
|
||||
unsigned long *sl = (unsigned long *) s;
|
||||
unsigned long cl = 0;
|
||||
char *s8;
|
||||
int i;
|
||||
|
||||
/* do it one word at a time (32 bits or 64 bits) while possible */
|
||||
if ( ((ulong)s & (sizeof(*sl) - 1)) == 0) {
|
||||
for (i = 0; i < sizeof(*sl); i++) {
|
||||
cl <<= 8;
|
||||
cl |= c & 0xff;
|
||||
}
|
||||
while (count >= sizeof(*sl)) {
|
||||
*sl++ = cl;
|
||||
count -= sizeof(*sl);
|
||||
}
|
||||
}
|
||||
/* fill 8 bits at a time */
|
||||
s8 = (char *)sl;
|
||||
while (count--)
|
||||
*s8++ = c;
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_BCOPY
|
||||
/**
|
||||
* bcopy - Copy one area of memory to another
|
||||
* @src: Where to copy from
|
||||
* @dest: Where to copy to
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* Note that this is the same as memcpy(), with the arguments reversed.
|
||||
* memcpy() is the standard, bcopy() is a legacy BSD function.
|
||||
*
|
||||
* You should not use this function to access IO space, use memcpy_toio()
|
||||
* or memcpy_fromio() instead.
|
||||
*/
|
||||
char * bcopy(const char * src, char * dest, int count)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (count--)
|
||||
*tmp++ = *src++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCPY
|
||||
/**
|
||||
* memcpy - Copy one area of memory to another
|
||||
* @dest: Where to copy to
|
||||
* @src: Where to copy from
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* You should not use this function to access IO space, use memcpy_toio()
|
||||
* or memcpy_fromio() instead.
|
||||
*/
|
||||
void * memcpy(void *dest, const void *src, size_t count)
|
||||
{
|
||||
unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src;
|
||||
char *d8, *s8;
|
||||
|
||||
if (src == dest)
|
||||
return dest;
|
||||
|
||||
/* while all data is aligned (common case), copy a word at a time */
|
||||
if ( (((ulong)dest | (ulong)src) & (sizeof(*dl) - 1)) == 0) {
|
||||
while (count >= sizeof(*dl)) {
|
||||
*dl++ = *sl++;
|
||||
count -= sizeof(*dl);
|
||||
}
|
||||
}
|
||||
/* copy the reset one byte at a time */
|
||||
d8 = (char *)dl;
|
||||
s8 = (char *)sl;
|
||||
while (count--)
|
||||
*d8++ = *s8++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMMOVE
|
||||
/**
|
||||
* memmove - Copy one area of memory to another
|
||||
* @dest: Where to copy to
|
||||
* @src: Where to copy from
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* Unlike memcpy(), memmove() copes with overlapping areas.
|
||||
*/
|
||||
void * memmove(void * dest,const void *src,size_t count)
|
||||
{
|
||||
char *tmp, *s;
|
||||
|
||||
if (src == dest)
|
||||
return dest;
|
||||
|
||||
if (dest <= src) {
|
||||
tmp = (char *) dest;
|
||||
s = (char *) src;
|
||||
while (count--)
|
||||
*tmp++ = *s++;
|
||||
}
|
||||
else {
|
||||
tmp = (char *) dest + count;
|
||||
s = (char *) src + count;
|
||||
while (count--)
|
||||
*--tmp = *--s;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCMP
|
||||
/**
|
||||
* memcmp - Compare two areas of memory
|
||||
* @cs: One area of memory
|
||||
* @ct: Another area of memory
|
||||
* @count: The size of the area.
|
||||
*/
|
||||
int memcmp(const void * cs,const void * ct,size_t count)
|
||||
{
|
||||
const unsigned char *su1, *su2;
|
||||
int res = 0;
|
||||
|
||||
for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
|
||||
if ((res = *su1 - *su2) != 0)
|
||||
break;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMSCAN
|
||||
/**
|
||||
* memscan - Find a character in an area of memory.
|
||||
* @addr: The memory area
|
||||
* @c: The byte to search for
|
||||
* @size: The size of the area.
|
||||
*
|
||||
* returns the address of the first occurrence of @c, or 1 byte past
|
||||
* the area if @c is not found
|
||||
*/
|
||||
void * memscan(void * addr, int c, size_t size)
|
||||
{
|
||||
unsigned char * p = (unsigned char *) addr;
|
||||
|
||||
while (size) {
|
||||
if (*p == c)
|
||||
return (void *) p;
|
||||
p++;
|
||||
size--;
|
||||
}
|
||||
return (void *) p;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSTR
|
||||
/**
|
||||
* strstr - Find the first substring in a %NUL terminated string
|
||||
* @s1: The string to be searched
|
||||
* @s2: The string to search for
|
||||
*/
|
||||
char * strstr(const char * s1,const char * s2)
|
||||
{
|
||||
int l1, l2;
|
||||
|
||||
l2 = strlen(s2);
|
||||
if (!l2)
|
||||
return (char *) s1;
|
||||
l1 = strlen(s1);
|
||||
while (l1 >= l2) {
|
||||
l1--;
|
||||
if (!memcmp(s1,s2,l2))
|
||||
return (char *) s1;
|
||||
s1++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCHR
|
||||
/**
|
||||
* memchr - Find a character in an area of memory.
|
||||
* @s: The memory area
|
||||
* @c: The byte to search for
|
||||
* @n: The size of the area.
|
||||
*
|
||||
* returns the address of the first occurrence of @c, or %NULL
|
||||
* if @c is not found
|
||||
*/
|
||||
void *memchr(const void *s, int c, size_t n)
|
||||
{
|
||||
const unsigned char *p = s;
|
||||
while (n-- != 0) {
|
||||
if ((unsigned char)c == *p++) {
|
||||
return (void *)(p-1);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
38
common/package/utils/sysupgrade-helper/src/lib/strmhz.c
Normal file
38
common/package/utils/sysupgrade-helper/src/lib/strmhz.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* (C) Copyright 2002-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
|
||||
char *strmhz (char *buf, unsigned long hz)
|
||||
{
|
||||
long l, n;
|
||||
long m;
|
||||
|
||||
n = DIV_ROUND(hz, 1000) / 1000L;
|
||||
l = sprintf (buf, "%ld", n);
|
||||
|
||||
hz -= n * 1000000L;
|
||||
m = DIV_ROUND(hz, 1000L);
|
||||
if (m != 0)
|
||||
sprintf (buf + l, ".%03ld", m);
|
||||
return (buf);
|
||||
}
|
||||
49
common/package/utils/sysupgrade-helper/src/lib/time.c
Normal file
49
common/package/utils/sysupgrade-helper/src/lib/time.c
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* (C) Copyright 2000-2009
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#ifndef CONFIG_WD_PERIOD
|
||||
# define CONFIG_WD_PERIOD (10 * 1000 * 1000) /* 10 seconds default*/
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void udelay(unsigned long usec)
|
||||
{
|
||||
ulong kv;
|
||||
|
||||
do {
|
||||
WATCHDOG_RESET();
|
||||
kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec;
|
||||
__udelay (kv);
|
||||
usec -= kv;
|
||||
} while(usec);
|
||||
}
|
||||
|
||||
void mdelay(unsigned long msec)
|
||||
{
|
||||
while (msec--)
|
||||
udelay(1000);
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# (C) Copyright 2012 Samsung Electronics
|
||||
# Donghwa Lee <dh09.lee@samsung.com>
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)libtizen.o
|
||||
|
||||
SOBJS =
|
||||
|
||||
COBJS-$(CONFIG_TIZEN) += tizen.o
|
||||
|
||||
COBJS := $(sort $(COBJS-y))
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
40
common/package/utils/sysupgrade-helper/src/lib/tizen/tizen.c
Normal file
40
common/package/utils/sysupgrade-helper/src/lib/tizen/tizen.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* (C) Copyright 2012 Samsung Electronics
|
||||
* Donghwa Lee <dh09.lee@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* aint with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <lcd.h>
|
||||
#include <libtizen.h>
|
||||
|
||||
#include "tizen_hd_logo.h"
|
||||
#include "tizen_hd_logo_data.h"
|
||||
|
||||
void get_tizen_logo_info(vidinfo_t *vid)
|
||||
{
|
||||
switch (vid->resolution) {
|
||||
case HD_RESOLUTION:
|
||||
vid->logo_width = TIZEN_HD_LOGO_WIDTH;
|
||||
vid->logo_height = TIZEN_HD_LOGO_HEIGHT;
|
||||
vid->logo_addr = (ulong)tizen_hd_logo;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
5071
common/package/utils/sysupgrade-helper/src/lib/tizen/tizen_hd_logo.h
Normal file
5071
common/package/utils/sysupgrade-helper/src/lib/tizen/tizen_hd_logo.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* (C) Copyright 2012 Samsung Electronics
|
||||
* Donghwa Lee <dh09.lee@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* aint with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TIZEN_HD_LOGO_DATA_H_
|
||||
#define _TIZEN_HD_LOGO_DATA_H_
|
||||
|
||||
#define TIZEN_HD_LOGO_WIDTH 520
|
||||
#define TIZEN_HD_LOGO_HEIGHT 120
|
||||
#define TIZEN_HD_LOGO_BPP 32
|
||||
|
||||
#endif /* _TIZEN_HD_LOGO_DATA_H_ */
|
||||
85
common/package/utils/sysupgrade-helper/src/lib/uuid.c
Normal file
85
common/package/utils/sysupgrade-helper/src/lib/uuid.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2011 Calxeda, Inc.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/ctype.h>
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* This is what a UUID string looks like.
|
||||
*
|
||||
* x is a hexadecimal character. fields are separated by '-'s. When converting
|
||||
* to a binary UUID, le means the field should be converted to little endian,
|
||||
* and be means it should be converted to big endian.
|
||||
*
|
||||
* 0 9 14 19 24
|
||||
* xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
* le le le be be
|
||||
*/
|
||||
|
||||
int uuid_str_valid(const char *uuid)
|
||||
{
|
||||
int i, valid;
|
||||
|
||||
if (uuid == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0, valid = 1; uuid[i] && valid; i++) {
|
||||
switch (i) {
|
||||
case 8: case 13: case 18: case 23:
|
||||
valid = (uuid[i] == '-');
|
||||
break;
|
||||
default:
|
||||
valid = isxdigit(uuid[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != 36 || !valid)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uuid_str_to_bin(const char *uuid, unsigned char *out)
|
||||
{
|
||||
uint16_t tmp16;
|
||||
uint32_t tmp32;
|
||||
uint64_t tmp64;
|
||||
|
||||
if (!uuid || !out)
|
||||
return;
|
||||
|
||||
tmp32 = cpu_to_le32(simple_strtoul(uuid, NULL, 16));
|
||||
memcpy(out, &tmp32, 4);
|
||||
|
||||
tmp16 = cpu_to_le16(simple_strtoul(uuid + 9, NULL, 16));
|
||||
memcpy(out + 4, &tmp16, 2);
|
||||
|
||||
tmp16 = cpu_to_le16(simple_strtoul(uuid + 14, NULL, 16));
|
||||
memcpy(out + 6, &tmp16, 2);
|
||||
|
||||
tmp16 = cpu_to_be16(simple_strtoul(uuid + 19, NULL, 16));
|
||||
memcpy(out + 8, &tmp16, 2);
|
||||
|
||||
tmp64 = cpu_to_be64(simple_strtoull(uuid + 24, NULL, 16));
|
||||
memcpy(out + 10, (char *)&tmp64 + 2, 6);
|
||||
}
|
||||
818
common/package/utils/sysupgrade-helper/src/lib/vsprintf.c
Normal file
818
common/package/utils/sysupgrade-helper/src/lib/vsprintf.c
Normal file
|
|
@ -0,0 +1,818 @@
|
|||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*
|
||||
* from hush: simple_itoa() was lifted from boa-0.93.15
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <common.h>
|
||||
#if !defined (CONFIG_PANIC_HANG)
|
||||
#include <command.h>
|
||||
#endif
|
||||
|
||||
#include <div64.h>
|
||||
# define NUM_TYPE long long
|
||||
#define noinline __attribute__((noinline))
|
||||
|
||||
/* some reluctance to put this into a new limits.h, so it is here */
|
||||
#define INT_MAX ((int)(~0U>>1))
|
||||
|
||||
const char hex_asc[] = "0123456789abcdef";
|
||||
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
|
||||
#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
|
||||
|
||||
static inline char *pack_hex_byte(char *buf, u8 byte)
|
||||
{
|
||||
*buf++ = hex_asc_hi(byte);
|
||||
*buf++ = hex_asc_lo(byte);
|
||||
return buf;
|
||||
}
|
||||
|
||||
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
unsigned long result = 0,value;
|
||||
|
||||
if (*cp == '0') {
|
||||
cp++;
|
||||
if ((*cp == 'x') && isxdigit(cp[1])) {
|
||||
base = 16;
|
||||
cp++;
|
||||
}
|
||||
if (!base) {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
if (!base) {
|
||||
base = 10;
|
||||
}
|
||||
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
|
||||
? toupper(*cp) : *cp)-'A'+10) < base) {
|
||||
result = result*base + value;
|
||||
cp++;
|
||||
}
|
||||
if (endp)
|
||||
*endp = (char *)cp;
|
||||
return result;
|
||||
}
|
||||
|
||||
int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
|
||||
{
|
||||
char *tail;
|
||||
unsigned long val;
|
||||
size_t len;
|
||||
|
||||
*res = 0;
|
||||
len = strlen(cp);
|
||||
if (len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
val = simple_strtoul(cp, &tail, base);
|
||||
if (tail == cp)
|
||||
return -EINVAL;
|
||||
|
||||
if ((*tail == '\0') ||
|
||||
((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
|
||||
*res = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
long simple_strtol(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
if(*cp=='-')
|
||||
return -simple_strtoul(cp+1,endp,base);
|
||||
return simple_strtoul(cp,endp,base);
|
||||
}
|
||||
|
||||
int ustrtoul(const char *cp, char **endp, unsigned int base)
|
||||
{
|
||||
unsigned long result = simple_strtoul(cp, endp, base);
|
||||
switch (**endp) {
|
||||
case 'G' :
|
||||
result *= 1024;
|
||||
/* fall through */
|
||||
case 'M':
|
||||
result *= 1024;
|
||||
/* fall through */
|
||||
case 'K':
|
||||
case 'k':
|
||||
result *= 1024;
|
||||
if ((*endp)[1] == 'i') {
|
||||
if ((*endp)[2] == 'B')
|
||||
(*endp) += 3;
|
||||
else
|
||||
(*endp) += 2;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long long simple_strtoull (const char *cp, char **endp, unsigned int base)
|
||||
{
|
||||
unsigned long long result = 0, value;
|
||||
|
||||
if (*cp == '0') {
|
||||
cp++;
|
||||
if ((*cp == 'x') && isxdigit (cp[1])) {
|
||||
base = 16;
|
||||
cp++;
|
||||
}
|
||||
if (!base) {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
if (!base) {
|
||||
base = 10;
|
||||
}
|
||||
while (isxdigit (*cp) && (value = isdigit (*cp)
|
||||
? *cp - '0'
|
||||
: (islower (*cp) ? toupper (*cp) : *cp) - 'A' + 10) < base) {
|
||||
result = result * base + value;
|
||||
cp++;
|
||||
}
|
||||
if (endp)
|
||||
*endp = (char *) cp;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* we use this so that we can do without the ctype library */
|
||||
#define is_digit(c) ((c) >= '0' && (c) <= '9')
|
||||
|
||||
static int skip_atoi(const char **s)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
while (is_digit(**s))
|
||||
i = i*10 + *((*s)++) - '0';
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Decimal conversion is by far the most typical, and is used
|
||||
* for /proc and /sys data. This directly impacts e.g. top performance
|
||||
* with many processes running. We optimize it for speed
|
||||
* using code from
|
||||
* http://www.cs.uiowa.edu/~jones/bcd/decimal.html
|
||||
* (with permission from the author, Douglas W. Jones). */
|
||||
|
||||
/* Formats correctly any integer in [0,99999].
|
||||
* Outputs from one to five digits depending on input.
|
||||
* On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
|
||||
static char* put_dec_trunc(char *buf, unsigned q)
|
||||
{
|
||||
unsigned d3, d2, d1, d0;
|
||||
d1 = (q>>4) & 0xf;
|
||||
d2 = (q>>8) & 0xf;
|
||||
d3 = (q>>12);
|
||||
|
||||
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
|
||||
q = (d0 * 0xcd) >> 11;
|
||||
d0 = d0 - 10*q;
|
||||
*buf++ = d0 + '0'; /* least significant digit */
|
||||
d1 = q + 9*d3 + 5*d2 + d1;
|
||||
if (d1 != 0) {
|
||||
q = (d1 * 0xcd) >> 11;
|
||||
d1 = d1 - 10*q;
|
||||
*buf++ = d1 + '0'; /* next digit */
|
||||
|
||||
d2 = q + 2*d2;
|
||||
if ((d2 != 0) || (d3 != 0)) {
|
||||
q = (d2 * 0xd) >> 7;
|
||||
d2 = d2 - 10*q;
|
||||
*buf++ = d2 + '0'; /* next digit */
|
||||
|
||||
d3 = q + 4*d3;
|
||||
if (d3 != 0) {
|
||||
q = (d3 * 0xcd) >> 11;
|
||||
d3 = d3 - 10*q;
|
||||
*buf++ = d3 + '0'; /* next digit */
|
||||
if (q != 0)
|
||||
*buf++ = q + '0'; /* most sign. digit */
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
/* Same with if's removed. Always emits five digits */
|
||||
static char* put_dec_full(char *buf, unsigned q)
|
||||
{
|
||||
/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
|
||||
/* but anyway, gcc produces better code with full-sized ints */
|
||||
unsigned d3, d2, d1, d0;
|
||||
d1 = (q>>4) & 0xf;
|
||||
d2 = (q>>8) & 0xf;
|
||||
d3 = (q>>12);
|
||||
|
||||
/*
|
||||
* Possible ways to approx. divide by 10
|
||||
* gcc -O2 replaces multiply with shifts and adds
|
||||
* (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
|
||||
* (x * 0x67) >> 10: 1100111
|
||||
* (x * 0x34) >> 9: 110100 - same
|
||||
* (x * 0x1a) >> 8: 11010 - same
|
||||
* (x * 0x0d) >> 7: 1101 - same, shortest code (on i386)
|
||||
*/
|
||||
|
||||
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
|
||||
q = (d0 * 0xcd) >> 11;
|
||||
d0 = d0 - 10*q;
|
||||
*buf++ = d0 + '0';
|
||||
d1 = q + 9*d3 + 5*d2 + d1;
|
||||
q = (d1 * 0xcd) >> 11;
|
||||
d1 = d1 - 10*q;
|
||||
*buf++ = d1 + '0';
|
||||
|
||||
d2 = q + 2*d2;
|
||||
q = (d2 * 0xd) >> 7;
|
||||
d2 = d2 - 10*q;
|
||||
*buf++ = d2 + '0';
|
||||
|
||||
d3 = q + 4*d3;
|
||||
q = (d3 * 0xcd) >> 11; /* - shorter code */
|
||||
/* q = (d3 * 0x67) >> 10; - would also work */
|
||||
d3 = d3 - 10*q;
|
||||
*buf++ = d3 + '0';
|
||||
*buf++ = q + '0';
|
||||
return buf;
|
||||
}
|
||||
/* No inlining helps gcc to use registers better */
|
||||
static noinline char* put_dec(char *buf, unsigned NUM_TYPE num)
|
||||
{
|
||||
while (1) {
|
||||
unsigned rem;
|
||||
if (num < 100000)
|
||||
return put_dec_trunc(buf, num);
|
||||
rem = do_div(num, 100000);
|
||||
buf = put_dec_full(buf, rem);
|
||||
}
|
||||
}
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
#define SPACE 8 /* space if plus */
|
||||
#define LEFT 16 /* left justified */
|
||||
#define SMALL 32 /* Must be 32 == 0x20 */
|
||||
#define SPECIAL 64 /* 0x */
|
||||
|
||||
#ifdef CONFIG_SYS_VSNPRINTF
|
||||
/*
|
||||
* Macro to add a new character to our output string, but only if it will
|
||||
* fit. The macro moves to the next character position in the output string.
|
||||
*/
|
||||
#define ADDCH(str, ch) do { \
|
||||
if ((str) < end) \
|
||||
*(str) = (ch); \
|
||||
++str; \
|
||||
} while (0)
|
||||
#else
|
||||
#define ADDCH(str, ch) (*(str)++ = (ch))
|
||||
#endif
|
||||
|
||||
static char *number(char *buf, char *end, unsigned NUM_TYPE num,
|
||||
int base, int size, int precision, int type)
|
||||
{
|
||||
/* we are called with base 8, 10 or 16, only, thus don't need "G..." */
|
||||
static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
|
||||
|
||||
char tmp[66];
|
||||
char sign;
|
||||
char locase;
|
||||
int need_pfx = ((type & SPECIAL) && base != 10);
|
||||
int i;
|
||||
|
||||
/* locase = 0 or 0x20. ORing digits or letters with 'locase'
|
||||
* produces same digits or (maybe lowercased) letters */
|
||||
locase = (type & SMALL);
|
||||
if (type & LEFT)
|
||||
type &= ~ZEROPAD;
|
||||
sign = 0;
|
||||
if (type & SIGN) {
|
||||
if ((signed NUM_TYPE) num < 0) {
|
||||
sign = '-';
|
||||
num = - (signed NUM_TYPE) num;
|
||||
size--;
|
||||
} else if (type & PLUS) {
|
||||
sign = '+';
|
||||
size--;
|
||||
} else if (type & SPACE) {
|
||||
sign = ' ';
|
||||
size--;
|
||||
}
|
||||
}
|
||||
if (need_pfx) {
|
||||
size--;
|
||||
if (base == 16)
|
||||
size--;
|
||||
}
|
||||
|
||||
/* generate full string in tmp[], in reverse order */
|
||||
i = 0;
|
||||
if (num == 0)
|
||||
tmp[i++] = '0';
|
||||
/* Generic code, for any base:
|
||||
else do {
|
||||
tmp[i++] = (digits[do_div(num,base)] | locase);
|
||||
} while (num != 0);
|
||||
*/
|
||||
else if (base != 10) { /* 8 or 16 */
|
||||
int mask = base - 1;
|
||||
int shift = 3;
|
||||
if (base == 16) shift = 4;
|
||||
do {
|
||||
tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
|
||||
num >>= shift;
|
||||
} while (num);
|
||||
} else { /* base 10 */
|
||||
i = put_dec(tmp, num) - tmp;
|
||||
}
|
||||
|
||||
/* printing 100 using %2d gives "100", not "00" */
|
||||
if (i > precision)
|
||||
precision = i;
|
||||
/* leading space padding */
|
||||
size -= precision;
|
||||
if (!(type & (ZEROPAD + LEFT))) {
|
||||
while (--size >= 0)
|
||||
ADDCH(buf, ' ');
|
||||
}
|
||||
/* sign */
|
||||
if (sign)
|
||||
ADDCH(buf, sign);
|
||||
/* "0x" / "0" prefix */
|
||||
if (need_pfx) {
|
||||
ADDCH(buf, '0');
|
||||
if (base == 16)
|
||||
ADDCH(buf, 'X' | locase);
|
||||
}
|
||||
/* zero or space padding */
|
||||
if (!(type & LEFT)) {
|
||||
char c = (type & ZEROPAD) ? '0' : ' ';
|
||||
|
||||
while (--size >= 0)
|
||||
ADDCH(buf, c);
|
||||
}
|
||||
/* hmm even more zero padding? */
|
||||
while (i <= --precision)
|
||||
ADDCH(buf, '0');
|
||||
/* actual digits of result */
|
||||
while (--i >= 0)
|
||||
ADDCH(buf, tmp[i]);
|
||||
/* trailing space padding */
|
||||
while (--size >= 0)
|
||||
ADDCH(buf, ' ');
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char *string(char *buf, char *end, char *s, int field_width,
|
||||
int precision, int flags)
|
||||
{
|
||||
int len, i;
|
||||
|
||||
if (s == 0)
|
||||
s = "<NULL>";
|
||||
|
||||
len = strnlen(s, precision);
|
||||
|
||||
if (!(flags & LEFT))
|
||||
while (len < field_width--)
|
||||
ADDCH(buf, ' ');
|
||||
for (i = 0; i < len; ++i)
|
||||
ADDCH(buf, *s++);
|
||||
while (len < field_width--)
|
||||
ADDCH(buf, ' ');
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMD_NET
|
||||
static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
|
||||
int precision, int flags)
|
||||
{
|
||||
char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
|
||||
char *p = mac_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
p = pack_hex_byte(p, addr[i]);
|
||||
if (!(flags & SPECIAL) && i != 5)
|
||||
*p++ = ':';
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return string(buf, end, mac_addr, field_width, precision,
|
||||
flags & ~SPECIAL);
|
||||
}
|
||||
|
||||
static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,
|
||||
int precision, int flags)
|
||||
{
|
||||
char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
|
||||
char *p = ip6_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
p = pack_hex_byte(p, addr[2 * i]);
|
||||
p = pack_hex_byte(p, addr[2 * i + 1]);
|
||||
if (!(flags & SPECIAL) && i != 7)
|
||||
*p++ = ':';
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return string(buf, end, ip6_addr, field_width, precision,
|
||||
flags & ~SPECIAL);
|
||||
}
|
||||
|
||||
static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
|
||||
int precision, int flags)
|
||||
{
|
||||
char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
|
||||
char temp[3]; /* hold each IP quad in reverse order */
|
||||
char *p = ip4_addr;
|
||||
int i, digits;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
digits = put_dec_trunc(temp, addr[i]) - temp;
|
||||
/* reverse the digits in the quad */
|
||||
while (digits--)
|
||||
*p++ = temp[digits];
|
||||
if (i != 3)
|
||||
*p++ = '.';
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return string(buf, end, ip4_addr, field_width, precision,
|
||||
flags & ~SPECIAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Show a '%p' thing. A kernel extension is that the '%p' is followed
|
||||
* by an extra set of alphanumeric characters that are extended format
|
||||
* specifiers.
|
||||
*
|
||||
* Right now we handle:
|
||||
*
|
||||
* - 'M' For a 6-byte MAC address, it prints the address in the
|
||||
* usual colon-separated hex notation
|
||||
* - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated
|
||||
* decimal for v4 and colon separated network-order 16 bit hex for v6)
|
||||
* - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is
|
||||
* currently the same
|
||||
*
|
||||
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64
|
||||
* function pointers are really function descriptors, which contain a
|
||||
* pointer to the real address.
|
||||
*/
|
||||
static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
||||
int field_width, int precision, int flags)
|
||||
{
|
||||
if (!ptr)
|
||||
return string(buf, end, "(null)", field_width, precision,
|
||||
flags);
|
||||
|
||||
#ifdef CONFIG_CMD_NET
|
||||
switch (*fmt) {
|
||||
case 'm':
|
||||
flags |= SPECIAL;
|
||||
/* Fallthrough */
|
||||
case 'M':
|
||||
return mac_address_string(buf, end, ptr, field_width,
|
||||
precision, flags);
|
||||
case 'i':
|
||||
flags |= SPECIAL;
|
||||
/* Fallthrough */
|
||||
case 'I':
|
||||
if (fmt[1] == '6')
|
||||
return ip6_addr_string(buf, end, ptr, field_width,
|
||||
precision, flags);
|
||||
if (fmt[1] == '4')
|
||||
return ip4_addr_string(buf, end, ptr, field_width,
|
||||
precision, flags);
|
||||
flags &= ~SPECIAL;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
flags |= SMALL;
|
||||
if (field_width == -1) {
|
||||
field_width = 2*sizeof(void *);
|
||||
flags |= ZEROPAD;
|
||||
}
|
||||
return number(buf, end, (unsigned long)ptr, 16, field_width,
|
||||
precision, flags);
|
||||
}
|
||||
|
||||
static int vsnprintf_internal(char *buf, size_t size, const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
unsigned NUM_TYPE num;
|
||||
int base;
|
||||
char *str;
|
||||
|
||||
int flags; /* flags to number() */
|
||||
|
||||
int field_width; /* width of output field */
|
||||
int precision; /* min. # of digits for integers; max
|
||||
number of chars for from string */
|
||||
int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
||||
/* 'z' support added 23/7/1999 S.H. */
|
||||
/* 'z' changed to 'Z' --davidm 1/25/99 */
|
||||
/* 't' added for ptrdiff_t */
|
||||
char *end = buf + size;
|
||||
|
||||
#ifdef CONFIG_SYS_VSNPRINTF
|
||||
/* Make sure end is always >= buf - do we want this in U-Boot? */
|
||||
if (end < buf) {
|
||||
end = ((void *)-1);
|
||||
size = end - buf;
|
||||
}
|
||||
#endif
|
||||
str = buf;
|
||||
|
||||
for (; *fmt ; ++fmt) {
|
||||
if (*fmt != '%') {
|
||||
ADDCH(str, *fmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process flags */
|
||||
flags = 0;
|
||||
repeat:
|
||||
++fmt; /* this also skips first '%' */
|
||||
switch (*fmt) {
|
||||
case '-': flags |= LEFT; goto repeat;
|
||||
case '+': flags |= PLUS; goto repeat;
|
||||
case ' ': flags |= SPACE; goto repeat;
|
||||
case '#': flags |= SPECIAL; goto repeat;
|
||||
case '0': flags |= ZEROPAD; goto repeat;
|
||||
}
|
||||
|
||||
/* get field width */
|
||||
field_width = -1;
|
||||
if (is_digit(*fmt))
|
||||
field_width = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
field_width = va_arg(args, int);
|
||||
if (field_width < 0) {
|
||||
field_width = -field_width;
|
||||
flags |= LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the precision */
|
||||
precision = -1;
|
||||
if (*fmt == '.') {
|
||||
++fmt;
|
||||
if (is_digit(*fmt))
|
||||
precision = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
precision = va_arg(args, int);
|
||||
}
|
||||
if (precision < 0)
|
||||
precision = 0;
|
||||
}
|
||||
|
||||
/* get the conversion qualifier */
|
||||
qualifier = -1;
|
||||
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
|
||||
*fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
|
||||
qualifier = *fmt;
|
||||
++fmt;
|
||||
if (qualifier == 'l' && *fmt == 'l') {
|
||||
qualifier = 'L';
|
||||
++fmt;
|
||||
}
|
||||
}
|
||||
|
||||
/* default base */
|
||||
base = 10;
|
||||
|
||||
switch (*fmt) {
|
||||
case 'c':
|
||||
if (!(flags & LEFT)) {
|
||||
while (--field_width > 0)
|
||||
ADDCH(str, ' ');
|
||||
}
|
||||
ADDCH(str, (unsigned char) va_arg(args, int));
|
||||
while (--field_width > 0)
|
||||
ADDCH(str, ' ');
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
str = string(str, end, va_arg(args, char *),
|
||||
field_width, precision, flags);
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
str = pointer(fmt+1, str, end,
|
||||
va_arg(args, void *),
|
||||
field_width, precision, flags);
|
||||
/* Skip all alphanumeric pointer suffixes */
|
||||
while (isalnum(fmt[1]))
|
||||
fmt++;
|
||||
continue;
|
||||
|
||||
case 'n':
|
||||
if (qualifier == 'l') {
|
||||
long * ip = va_arg(args, long *);
|
||||
*ip = (str - buf);
|
||||
} else {
|
||||
int * ip = va_arg(args, int *);
|
||||
*ip = (str - buf);
|
||||
}
|
||||
continue;
|
||||
|
||||
case '%':
|
||||
ADDCH(str, '%');
|
||||
continue;
|
||||
|
||||
/* integer number formats - set up the flags and "break" */
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
flags |= SMALL;
|
||||
case 'X':
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
flags |= SIGN;
|
||||
case 'u':
|
||||
break;
|
||||
|
||||
default:
|
||||
ADDCH(str, '%');
|
||||
if (*fmt)
|
||||
ADDCH(str, *fmt);
|
||||
else
|
||||
--fmt;
|
||||
continue;
|
||||
}
|
||||
if (qualifier == 'L') /* "quad" for 64 bit variables */
|
||||
num = va_arg(args, unsigned long long);
|
||||
else if (qualifier == 'l') {
|
||||
num = va_arg(args, unsigned long);
|
||||
if (flags & SIGN)
|
||||
num = (signed long) num;
|
||||
} else if (qualifier == 'Z' || qualifier == 'z') {
|
||||
num = va_arg(args, size_t);
|
||||
} else if (qualifier == 't') {
|
||||
num = va_arg(args, ptrdiff_t);
|
||||
} else if (qualifier == 'h') {
|
||||
num = (unsigned short) va_arg(args, int);
|
||||
if (flags & SIGN)
|
||||
num = (signed short) num;
|
||||
} else {
|
||||
num = va_arg(args, unsigned int);
|
||||
if (flags & SIGN)
|
||||
num = (signed int) num;
|
||||
}
|
||||
str = number(str, end, num, base, field_width, precision,
|
||||
flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_VSNPRINTF
|
||||
if (size > 0) {
|
||||
ADDCH(str, '\0');
|
||||
if (str > end)
|
||||
end[-1] = '\0';
|
||||
--str;
|
||||
}
|
||||
#else
|
||||
*str = '\0';
|
||||
#endif
|
||||
/* the trailing null byte doesn't count towards the total */
|
||||
return str-buf;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_VSNPRINTF
|
||||
int vsnprintf(char *buf, size_t size, const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
return vsnprintf_internal(buf, size, fmt, args);
|
||||
}
|
||||
|
||||
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = vsnprintf(buf, size, fmt, args);
|
||||
|
||||
if (likely(i < size))
|
||||
return i;
|
||||
if (size != 0)
|
||||
return size - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snprintf(char *buf, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i = vsnprintf(buf, size, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int scnprintf(char *buf, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i = vscnprintf(buf, size, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return i;
|
||||
}
|
||||
#endif /* CONFIG_SYS_VSNPRINT */
|
||||
|
||||
/**
|
||||
* Format a string and place it in a buffer (va_list version)
|
||||
*
|
||||
* @param buf The buffer to place the result into
|
||||
* @param fmt The format string to use
|
||||
* @param args Arguments for the format string
|
||||
*
|
||||
* The function returns the number of characters written
|
||||
* into @buf. Use vsnprintf() or vscnprintf() in order to avoid
|
||||
* buffer overflows.
|
||||
*
|
||||
* If you're not already dealing with a va_list consider using sprintf().
|
||||
*/
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
return vsnprintf_internal(buf, INT_MAX, fmt, args);
|
||||
}
|
||||
|
||||
int sprintf(char * buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vsprintf(buf,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
||||
|
||||
void panic(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
putc('\n');
|
||||
va_end(args);
|
||||
#if defined (CONFIG_PANIC_HANG)
|
||||
hang();
|
||||
#else
|
||||
udelay (100000); /* allow messages to go out */
|
||||
do_reset (NULL, 0, 0, NULL);
|
||||
#endif
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void __assert_fail(const char *assertion, const char *file, unsigned line,
|
||||
const char *function)
|
||||
{
|
||||
/* This will not return */
|
||||
panic("%s:%u: %s: Assertion `%s' failed.", file, line, function,
|
||||
assertion);
|
||||
}
|
||||
|
||||
char *simple_itoa(ulong i)
|
||||
{
|
||||
/* 21 digits plus null terminator, good for 64-bit or smaller ints */
|
||||
static char local[22];
|
||||
char *p = &local[21];
|
||||
|
||||
*p-- = '\0';
|
||||
do {
|
||||
*p-- = '0' + i % 10;
|
||||
i /= 10;
|
||||
} while (i > 0);
|
||||
return p + 1;
|
||||
}
|
||||
44
common/package/utils/sysupgrade-helper/src/lib/zlib/Makefile
Normal file
44
common/package/utils/sysupgrade-helper/src/lib/zlib/Makefile
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)libz.o
|
||||
|
||||
COBJS-$(CONFIG_ZLIB) += zlib.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
125
common/package/utils/sysupgrade-helper/src/lib/zlib/adler32.c
Normal file
125
common/package/utils/sysupgrade-helper/src/lib/zlib/adler32.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
||||
#ifdef NO_DIVIDE
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD4(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD4(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32(adler, buf, len)
|
||||
uLong adler;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
|
||||
/* split Adler-32 into component sums */
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if (len == 1) {
|
||||
adler += buf[0];
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE)
|
||||
sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||
if (buf == Z_NULL)
|
||||
return 1L;
|
||||
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if (len < 16) {
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD4(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while (len >= NMAX) {
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
DO16(buf); /* 16 sums unrolled */
|
||||
buf += 16;
|
||||
} while (--n);
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if (len) { /* avoid modulos if none remaining */
|
||||
while (len >= 16) {
|
||||
len -= 16;
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* return recombined sums */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
357
common/package/utils/sysupgrade-helper/src/lib/zlib/inffast.c
Normal file
357
common/package/utils/sysupgrade-helper/src/lib/zlib/inffast.c
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* U-boot: we already included these
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
*/
|
||||
|
||||
#ifndef ASMINF
|
||||
|
||||
/* Allow machine dependent optimization for post-increment or pre-increment.
|
||||
Based on testing to date,
|
||||
Pre-increment preferred for:
|
||||
- PowerPC G3 (Adler)
|
||||
- MIPS R5000 (Randers-Pehrson)
|
||||
Post-increment preferred for:
|
||||
- none
|
||||
No measurable difference:
|
||||
- Pentium III (Anderson)
|
||||
- M68060 (Nikl)
|
||||
*/
|
||||
#ifdef POSTINC
|
||||
# define OFF 0
|
||||
# define PUP(a) *(a)++
|
||||
#else
|
||||
# define OFF 1
|
||||
# define PUP(a) *++(a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Decode literal, length, and distance codes and write out the resulting
|
||||
literal and match bytes until either not enough input or output is
|
||||
available, an end-of-block is encountered, or a data error is encountered.
|
||||
When large enough input and output buffers are supplied to inflate(), for
|
||||
example, a 16K input buffer and a 64K output buffer, more than 95% of the
|
||||
inflate execution time is spent in this routine.
|
||||
|
||||
Entry assumptions:
|
||||
|
||||
state->mode == LEN
|
||||
strm->avail_in >= 6
|
||||
strm->avail_out >= 258
|
||||
start >= strm->avail_out
|
||||
state->bits < 8
|
||||
|
||||
On return, state->mode is one of:
|
||||
|
||||
LEN -- ran out of enough output space or enough available input
|
||||
TYPE -- reached end of block code, inflate() to interpret next block
|
||||
BAD -- error in block data
|
||||
|
||||
Notes:
|
||||
|
||||
- The maximum input bits used by a length/distance pair is 15 bits for the
|
||||
length code, 5 bits for the length extra, 15 bits for the distance code,
|
||||
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
|
||||
Therefore if strm->avail_in >= 6, then there is enough input to avoid
|
||||
checking for available input while decoding.
|
||||
|
||||
- The maximum bytes that a single length/distance pair can output is 258
|
||||
bytes, which is the maximum length that can be coded. inflate_fast()
|
||||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
void inflate_fast(strm, start)
|
||||
z_streamp strm;
|
||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *in; /* local strm->next_in */
|
||||
unsigned char FAR *last; /* while in < last, enough input available */
|
||||
unsigned char FAR *out; /* local strm->next_out */
|
||||
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char FAR *end; /* while out < end, enough space available */
|
||||
#ifdef INFLATE_STRICT
|
||||
unsigned dmax; /* maximum distance from zlib header */
|
||||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
|
||||
unsigned long hold; /* local strm->hold */
|
||||
unsigned bits; /* local strm->bits */
|
||||
code const FAR *lcode; /* local strm->lencode */
|
||||
code const FAR *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
code this; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
unsigned dist; /* match distance */
|
||||
unsigned char FAR *from; /* where to copy match from */
|
||||
|
||||
/* copy state to local variables */
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
in = strm->next_in - OFF;
|
||||
last = in + (strm->avail_in - 5);
|
||||
if (in > last && strm->avail_in > 5) {
|
||||
/*
|
||||
* overflow detected, limit strm->avail_in to the
|
||||
* max. possible size and recalculate last
|
||||
*/
|
||||
strm->avail_in = 0xffffffff - (uintptr_t)in;
|
||||
last = in + (strm->avail_in - 5);
|
||||
}
|
||||
out = strm->next_out - OFF;
|
||||
beg = out - (start - strm->avail_out);
|
||||
end = out + (strm->avail_out - 257);
|
||||
#ifdef INFLATE_STRICT
|
||||
dmax = state->dmax;
|
||||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
write = state->write;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
lcode = state->lencode;
|
||||
dcode = state->distcode;
|
||||
lmask = (1U << state->lenbits) - 1;
|
||||
dmask = (1U << state->distbits) - 1;
|
||||
|
||||
/* decode literals and length/distances until end-of-block or not enough
|
||||
input data or output space */
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(this.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
PUP(out) = (unsigned char)(this.val);
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = (unsigned)(this.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
len += (unsigned)hold & ((1U << op) - 1);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(this.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(this.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
dist += (unsigned)hold & ((1U << op) - 1);
|
||||
#ifdef INFLATE_STRICT
|
||||
if (dist > dmax) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||
op = (unsigned)(out - beg); /* max distance in output */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
from = window - OFF;
|
||||
if (write == 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
else if (write < op) { /* wrap around window */
|
||||
from += wsize + write - op;
|
||||
op -= write;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = window - OFF;
|
||||
if (write < len) { /* some from start of window */
|
||||
op = write;
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* contiguous in window */
|
||||
from += write - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
while (len > 2) {
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
len -= 3;
|
||||
}
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned short *sout;
|
||||
unsigned long loops;
|
||||
|
||||
from = out - dist; /* copy direct from output */
|
||||
/* minimum length is three */
|
||||
/* Align out addr */
|
||||
if (!((long)(out - 1 + OFF) & 1)) {
|
||||
PUP(out) = PUP(from);
|
||||
len--;
|
||||
}
|
||||
sout = (unsigned short *)(out - OFF);
|
||||
if (dist > 2 ) {
|
||||
unsigned short *sfrom;
|
||||
|
||||
sfrom = (unsigned short *)(from - OFF);
|
||||
loops = len >> 1;
|
||||
do
|
||||
PUP(sout) = get_unaligned(++sfrom);
|
||||
while (--loops);
|
||||
out = (unsigned char *)sout + OFF;
|
||||
from = (unsigned char *)sfrom + OFF;
|
||||
} else { /* dist == 1 or dist == 2 */
|
||||
unsigned short pat16;
|
||||
|
||||
pat16 = *(sout-2+2*OFF);
|
||||
if (dist == 1)
|
||||
#if defined(__BIG_ENDIAN)
|
||||
pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
|
||||
#elif defined(__LITTLE_ENDIAN)
|
||||
pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00 ) >> 8);
|
||||
#else
|
||||
#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
|
||||
#endif
|
||||
loops = len >> 1;
|
||||
do
|
||||
PUP(sout) = pat16;
|
||||
while (--loops);
|
||||
out = (unsigned char *)sout + OFF;
|
||||
}
|
||||
if (len & 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
this = dcode[this.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
this = lcode[this.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} while (in < last && out < end);
|
||||
|
||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||
len = bits >> 3;
|
||||
in -= len;
|
||||
bits -= len << 3;
|
||||
hold &= (1U << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm->next_in = in + OFF;
|
||||
strm->next_out = out + OFF;
|
||||
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
|
||||
strm->avail_out = (unsigned)(out < end ?
|
||||
257 + (end - out) : 257 - (out - end));
|
||||
state->hold = hold;
|
||||
state->bits = bits;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
|
||||
- Using bit fields for code structure
|
||||
- Different op definition to avoid & for extra bits (do & for table bits)
|
||||
- Three separate decoding do-loops for direct, window, and write == 0
|
||||
- Special case for distance > 1 copies to do overlapped load and store copy
|
||||
- Explicit branch predictions (based on measured branch probabilities)
|
||||
- Deferring match copy and interspersed it with decoding subsequent codes
|
||||
- Swapping literal/length else
|
||||
- Swapping window/direct else
|
||||
- Larger unrolled copy loops (three is about right)
|
||||
- Moving len -= 3 statement into middle of loop
|
||||
*/
|
||||
|
||||
#endif /* !ASMINF */
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995-2003 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
void inflate_fast OF((z_streamp strm, unsigned start));
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/* inffixed.h -- table for decoding fixed codes
|
||||
* Generated automatically by makefixed().
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It
|
||||
is part of the implementation of the compression library and
|
||||
is subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
static const code lenfix[512] = {
|
||||
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
|
||||
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
|
||||
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
|
||||
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
|
||||
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
|
||||
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
|
||||
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
|
||||
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
|
||||
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
|
||||
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
|
||||
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
|
||||
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
|
||||
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
|
||||
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
|
||||
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
|
||||
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
|
||||
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
|
||||
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
|
||||
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
|
||||
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
|
||||
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
|
||||
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
|
||||
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
|
||||
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
|
||||
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
|
||||
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
|
||||
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
|
||||
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
|
||||
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
|
||||
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
|
||||
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
|
||||
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
|
||||
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
|
||||
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
|
||||
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
|
||||
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
|
||||
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
|
||||
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
|
||||
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
|
||||
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
|
||||
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
|
||||
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
|
||||
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
|
||||
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
|
||||
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
|
||||
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
|
||||
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
|
||||
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
|
||||
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
|
||||
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
|
||||
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
|
||||
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
|
||||
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
|
||||
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
|
||||
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
|
||||
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
|
||||
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
|
||||
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
|
||||
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
|
||||
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
|
||||
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
|
||||
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
|
||||
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
|
||||
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
|
||||
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
|
||||
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
|
||||
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
|
||||
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
|
||||
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
|
||||
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
|
||||
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
|
||||
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
|
||||
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
|
||||
{0,9,255}
|
||||
};
|
||||
|
||||
static const code distfix[32] = {
|
||||
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
|
||||
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
|
||||
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
|
||||
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
|
||||
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
|
||||
{22,5,193},{64,5,0}
|
||||
};
|
||||
956
common/package/utils/sysupgrade-helper/src/lib/zlib/inflate.c
Normal file
956
common/package/utils/sysupgrade-helper/src/lib/zlib/inflate.c
Normal file
|
|
@ -0,0 +1,956 @@
|
|||
/* inflate.c -- zlib decompression
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
local void fixedtables OF((struct inflate_state FAR *state));
|
||||
local int updatewindow OF((z_streamp strm, unsigned out));
|
||||
|
||||
int ZEXPORT inflateReset(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
strm->total_in = strm->total_out = state->total = 0;
|
||||
strm->msg = Z_NULL;
|
||||
strm->adler = 1; /* to support ill-conceived Java test suite */
|
||||
state->mode = HEAD;
|
||||
state->last = 0;
|
||||
state->havedict = 0;
|
||||
state->dmax = 32768U;
|
||||
state->head = Z_NULL;
|
||||
state->wsize = 0;
|
||||
state->whave = 0;
|
||||
state->write = 0;
|
||||
state->hold = 0;
|
||||
state->bits = 0;
|
||||
state->lencode = state->distcode = state->next = state->codes;
|
||||
WATCHDOG_RESET();
|
||||
Tracev((stderr, "inflate: reset\n"));
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
|
||||
z_streamp strm;
|
||||
int windowBits;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
||||
stream_size != (int)(sizeof(z_stream)))
|
||||
return Z_VERSION_ERROR;
|
||||
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
}
|
||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
||||
state = (struct inflate_state FAR *)
|
||||
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||
Tracev((stderr, "inflate: allocated\n"));
|
||||
strm->state = (struct internal_state FAR *)state;
|
||||
if (windowBits < 0) {
|
||||
state->wrap = 0;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
else {
|
||||
state->wrap = (windowBits >> 4) + 1;
|
||||
#ifdef GUNZIP
|
||||
if (windowBits < 48) windowBits &= 15;
|
||||
#endif
|
||||
}
|
||||
if (windowBits < 8 || windowBits > 15) {
|
||||
ZFREE(strm, state);
|
||||
strm->state = Z_NULL;
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
state->wbits = (unsigned)windowBits;
|
||||
state->window = Z_NULL;
|
||||
return inflateReset(strm);
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit_(strm, version, stream_size)
|
||||
z_streamp strm;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
|
||||
}
|
||||
|
||||
local void fixedtables(state)
|
||||
struct inflate_state FAR *state;
|
||||
{
|
||||
state->lencode = lenfix;
|
||||
state->lenbits = 9;
|
||||
state->distcode = distfix;
|
||||
state->distbits = 5;
|
||||
}
|
||||
|
||||
/*
|
||||
Update the window with the last wsize (normally 32K) bytes written before
|
||||
returning. If window does not exist yet, create it. This is only called
|
||||
when a window is already in use, or when output has been written during this
|
||||
inflate call, but the end of the deflate stream has not been reached yet.
|
||||
It is also called to create a window for dictionary data when a dictionary
|
||||
is loaded.
|
||||
|
||||
Providing output buffers larger than 32K to inflate() should provide a speed
|
||||
advantage, since only the last 32K of output is copied to the sliding window
|
||||
upon return from inflate(), and since all distances after the first 32K of
|
||||
output will fall in the output data, making match copies simpler and faster.
|
||||
The advantage may be dependent on the size of the processor's data caches.
|
||||
*/
|
||||
local int updatewindow(strm, out)
|
||||
z_streamp strm;
|
||||
unsigned out;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned copy, dist;
|
||||
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
/* if it hasn't been done already, allocate space for the window */
|
||||
if (state->window == Z_NULL) {
|
||||
state->window = (unsigned char FAR *)
|
||||
ZALLOC(strm, 1U << state->wbits,
|
||||
sizeof(unsigned char));
|
||||
if (state->window == Z_NULL) return 1;
|
||||
}
|
||||
|
||||
/* if window not in use yet, initialize */
|
||||
if (state->wsize == 0) {
|
||||
state->wsize = 1U << state->wbits;
|
||||
state->write = 0;
|
||||
state->whave = 0;
|
||||
}
|
||||
|
||||
/* copy state->wsize or less output bytes into the circular window */
|
||||
copy = out - strm->avail_out;
|
||||
if (copy >= state->wsize) {
|
||||
zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
|
||||
state->write = 0;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
dist = state->wsize - state->write;
|
||||
if (dist > copy) dist = copy;
|
||||
zmemcpy(state->window + state->write, strm->next_out - copy, dist);
|
||||
copy -= dist;
|
||||
if (copy) {
|
||||
zmemcpy(state->window, strm->next_out - copy, copy);
|
||||
state->write = copy;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
state->write += dist;
|
||||
if (state->write == state->wsize) state->write = 0;
|
||||
if (state->whave < state->wsize) state->whave += dist;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Macros for inflate(): */
|
||||
|
||||
/* check function to use adler32() for zlib or crc32() for gzip */
|
||||
#ifdef GUNZIP
|
||||
# define UPDATE(check, buf, len) \
|
||||
(state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
|
||||
#else
|
||||
# define UPDATE(check, buf, len) adler32(check, buf, len)
|
||||
#endif
|
||||
|
||||
/* check macros for header crc */
|
||||
#ifdef GUNZIP
|
||||
# define CRC2(check, word) \
|
||||
do { \
|
||||
hbuf[0] = (unsigned char)(word); \
|
||||
hbuf[1] = (unsigned char)((word) >> 8); \
|
||||
check = crc32(check, hbuf, 2); \
|
||||
} while (0)
|
||||
|
||||
# define CRC4(check, word) \
|
||||
do { \
|
||||
hbuf[0] = (unsigned char)(word); \
|
||||
hbuf[1] = (unsigned char)((word) >> 8); \
|
||||
hbuf[2] = (unsigned char)((word) >> 16); \
|
||||
hbuf[3] = (unsigned char)((word) >> 24); \
|
||||
check = crc32(check, hbuf, 4); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* Load registers with state in inflate() for speed */
|
||||
#define LOAD() \
|
||||
do { \
|
||||
put = strm->next_out; \
|
||||
left = strm->avail_out; \
|
||||
next = strm->next_in; \
|
||||
have = strm->avail_in; \
|
||||
hold = state->hold; \
|
||||
bits = state->bits; \
|
||||
} while (0)
|
||||
|
||||
/* Restore state from registers in inflate() */
|
||||
#define RESTORE() \
|
||||
do { \
|
||||
strm->next_out = put; \
|
||||
strm->avail_out = left; \
|
||||
strm->next_in = next; \
|
||||
strm->avail_in = have; \
|
||||
state->hold = hold; \
|
||||
state->bits = bits; \
|
||||
} while (0)
|
||||
|
||||
/* Clear the input bit accumulator */
|
||||
#define INITBITS() \
|
||||
do { \
|
||||
hold = 0; \
|
||||
bits = 0; \
|
||||
} while (0)
|
||||
|
||||
/* Get a byte of input into the bit accumulator, or return from inflate()
|
||||
if there is no input available. */
|
||||
#define PULLBYTE() \
|
||||
do { \
|
||||
if (have == 0) goto inf_leave; \
|
||||
have--; \
|
||||
hold += (unsigned long)(*next++) << bits; \
|
||||
bits += 8; \
|
||||
} while (0)
|
||||
|
||||
/* Assure that there are at least n bits in the bit accumulator. If there is
|
||||
not enough available input to do that, then return from inflate(). */
|
||||
#define NEEDBITS(n) \
|
||||
do { \
|
||||
while (bits < (unsigned)(n)) \
|
||||
PULLBYTE(); \
|
||||
} while (0)
|
||||
|
||||
/* Return the low n bits of the bit accumulator (n < 16) */
|
||||
#define BITS(n) \
|
||||
((unsigned)hold & ((1U << (n)) - 1))
|
||||
|
||||
/* Remove n bits from the bit accumulator */
|
||||
#define DROPBITS(n) \
|
||||
do { \
|
||||
hold >>= (n); \
|
||||
bits -= (unsigned)(n); \
|
||||
} while (0)
|
||||
|
||||
/* Remove zero to seven bits as needed to go to a byte boundary */
|
||||
#define BYTEBITS() \
|
||||
do { \
|
||||
hold >>= bits & 7; \
|
||||
bits -= bits & 7; \
|
||||
} while (0)
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define REVERSE(q) \
|
||||
((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
/*
|
||||
inflate() uses a state machine to process as much input data and generate as
|
||||
much output data as possible before returning. The state machine is
|
||||
structured roughly as follows:
|
||||
|
||||
for (;;) switch (state) {
|
||||
...
|
||||
case STATEn:
|
||||
if (not enough input data or output space to make progress)
|
||||
return;
|
||||
... make progress ...
|
||||
state = STATEm;
|
||||
break;
|
||||
...
|
||||
}
|
||||
|
||||
so when inflate() is called again, the same case is attempted again, and
|
||||
if the appropriate resources are provided, the machine proceeds to the
|
||||
next state. The NEEDBITS() macro is usually the way the state evaluates
|
||||
whether it can proceed or should return. NEEDBITS() does the return if
|
||||
the requested bits are not available. The typical use of the BITS macros
|
||||
is:
|
||||
|
||||
NEEDBITS(n);
|
||||
... do something with BITS(n) ...
|
||||
DROPBITS(n);
|
||||
|
||||
where NEEDBITS(n) either returns from inflate() if there isn't enough
|
||||
input left to load n bits into the accumulator, or it continues. BITS(n)
|
||||
gives the low n bits in the accumulator. When done, DROPBITS(n) drops
|
||||
the low n bits off the accumulator. INITBITS() clears the accumulator
|
||||
and sets the number of available bits to zero. BYTEBITS() discards just
|
||||
enough bits to put the accumulator on a byte boundary. After BYTEBITS()
|
||||
and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
|
||||
|
||||
NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
|
||||
if there is no input available. The decoding of variable length codes uses
|
||||
PULLBYTE() directly in order to pull just enough bytes to decode the next
|
||||
code, and no more.
|
||||
|
||||
Some states loop until they get enough input, making sure that enough
|
||||
state information is maintained to continue the loop where it left off
|
||||
if NEEDBITS() returns in the loop. For example, want, need, and keep
|
||||
would all have to actually be part of the saved state in case NEEDBITS()
|
||||
returns:
|
||||
|
||||
case STATEw:
|
||||
while (want < need) {
|
||||
NEEDBITS(n);
|
||||
keep[want++] = BITS(n);
|
||||
DROPBITS(n);
|
||||
}
|
||||
state = STATEx;
|
||||
case STATEx:
|
||||
|
||||
As shown above, if the next state is also the next case, then the break
|
||||
is omitted.
|
||||
|
||||
A state may also return if there is not enough output space available to
|
||||
complete that state. Those states are copying stored data, writing a
|
||||
literal byte, and copying a matching string.
|
||||
|
||||
When returning, a "goto inf_leave" is used to update the total counters,
|
||||
update the check value, and determine whether any progress has been made
|
||||
during that inflate() call in order to return the proper return code.
|
||||
Progress is defined as a change in either strm->avail_in or strm->avail_out.
|
||||
When there is a window, goto inf_leave will update the window with the last
|
||||
output written. If a goto inf_leave occurs in the middle of decompression
|
||||
and there is no window currently, goto inf_leave will create one and copy
|
||||
output to the window for the next call of inflate().
|
||||
|
||||
In this implementation, the flush parameter of inflate() only affects the
|
||||
return code (per zlib.h). inflate() always writes as much as possible to
|
||||
strm->next_out, given the space available and the provided input--the effect
|
||||
documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
|
||||
the allocation of and copying into a sliding window until necessary, which
|
||||
provides the effect documented in zlib.h for Z_FINISH when the entire input
|
||||
stream available. So the only thing the flush parameter actually does is:
|
||||
when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
|
||||
will return Z_BUF_ERROR if it has not reached the end of the stream.
|
||||
*/
|
||||
int ZEXPORT inflate(strm, flush)
|
||||
z_streamp strm;
|
||||
int flush;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *next; /* next input */
|
||||
unsigned char FAR *put; /* next output */
|
||||
unsigned have, left; /* available input and output */
|
||||
unsigned long hold; /* bit buffer */
|
||||
unsigned bits; /* bits in bit buffer */
|
||||
unsigned in, out; /* save starting available input and output */
|
||||
unsigned copy; /* number of stored or match bytes to copy */
|
||||
unsigned char FAR *from; /* where to copy match bytes from */
|
||||
code this; /* current decoding table entry */
|
||||
code last; /* parent table entry */
|
||||
unsigned len; /* length to copy for repeats, bits to drop */
|
||||
int ret; /* return code */
|
||||
#ifdef GUNZIP
|
||||
unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
|
||||
#endif
|
||||
static const unsigned short order[19] = /* permutation of code lengths */
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL ||
|
||||
(strm->next_in == Z_NULL && strm->avail_in != 0))
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
|
||||
LOAD();
|
||||
in = have;
|
||||
out = left;
|
||||
ret = Z_OK;
|
||||
for (;;)
|
||||
switch (state->mode) {
|
||||
case HEAD:
|
||||
if (state->wrap == 0) {
|
||||
state->mode = TYPEDO;
|
||||
break;
|
||||
}
|
||||
NEEDBITS(16);
|
||||
#ifdef GUNZIP
|
||||
if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
|
||||
state->check = crc32(0L, Z_NULL, 0);
|
||||
CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = FLAGS;
|
||||
break;
|
||||
}
|
||||
state->flags = 0; /* expect zlib header */
|
||||
if (state->head != Z_NULL)
|
||||
state->head->done = -1;
|
||||
if (!(state->wrap & 1) || /* check if zlib header allowed */
|
||||
#else
|
||||
if (
|
||||
#endif
|
||||
((BITS(8) << 8) + (hold >> 8)) % 31) {
|
||||
strm->msg = (char *)"incorrect header check";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
if (BITS(4) != Z_DEFLATED) {
|
||||
strm->msg = (char *)"unknown compression method";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
DROPBITS(4);
|
||||
len = BITS(4) + 8;
|
||||
if (len > state->wbits) {
|
||||
strm->msg = (char *)"invalid window size";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->dmax = 1U << len;
|
||||
Tracev((stderr, "inflate: zlib header ok\n"));
|
||||
strm->adler = state->check = adler32(0L, Z_NULL, 0);
|
||||
state->mode = hold & 0x200 ? DICTID : TYPE;
|
||||
INITBITS();
|
||||
break;
|
||||
#ifdef GUNZIP
|
||||
case FLAGS:
|
||||
NEEDBITS(16);
|
||||
state->flags = (int)(hold);
|
||||
if ((state->flags & 0xff) != Z_DEFLATED) {
|
||||
strm->msg = (char *)"unknown compression method";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
if (state->flags & 0xe000) {
|
||||
strm->msg = (char *)"unknown header flags set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
if (state->head != Z_NULL)
|
||||
state->head->text = (int)((hold >> 8) & 1);
|
||||
if (state->flags & 0x0200) CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = TIME;
|
||||
case TIME:
|
||||
NEEDBITS(32);
|
||||
if (state->head != Z_NULL)
|
||||
state->head->time = hold;
|
||||
if (state->flags & 0x0200) CRC4(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = OS;
|
||||
case OS:
|
||||
NEEDBITS(16);
|
||||
if (state->head != Z_NULL) {
|
||||
state->head->xflags = (int)(hold & 0xff);
|
||||
state->head->os = (int)(hold >> 8);
|
||||
}
|
||||
if (state->flags & 0x0200) CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = EXLEN;
|
||||
case EXLEN:
|
||||
if (state->flags & 0x0400) {
|
||||
NEEDBITS(16);
|
||||
state->length = (unsigned)(hold);
|
||||
if (state->head != Z_NULL)
|
||||
state->head->extra_len = (unsigned)hold;
|
||||
if (state->flags & 0x0200) CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
}
|
||||
else if (state->head != Z_NULL)
|
||||
state->head->extra = Z_NULL;
|
||||
state->mode = EXTRA;
|
||||
case EXTRA:
|
||||
if (state->flags & 0x0400) {
|
||||
copy = state->length;
|
||||
if (copy > have) copy = have;
|
||||
if (copy) {
|
||||
if (state->head != Z_NULL &&
|
||||
state->head->extra != Z_NULL) {
|
||||
len = state->head->extra_len - state->length;
|
||||
zmemcpy(state->head->extra + len, next,
|
||||
len + copy > state->head->extra_max ?
|
||||
state->head->extra_max - len : copy);
|
||||
}
|
||||
if (state->flags & 0x0200)
|
||||
state->check = crc32(state->check, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
state->length -= copy;
|
||||
}
|
||||
if (state->length) goto inf_leave;
|
||||
}
|
||||
state->length = 0;
|
||||
state->mode = NAME;
|
||||
case NAME:
|
||||
if (state->flags & 0x0800) {
|
||||
if (have == 0) goto inf_leave;
|
||||
copy = 0;
|
||||
do {
|
||||
len = (unsigned)(next[copy++]);
|
||||
if (state->head != Z_NULL &&
|
||||
state->head->name != Z_NULL &&
|
||||
state->length < state->head->name_max)
|
||||
state->head->name[state->length++] = len;
|
||||
} while (len && copy < have);
|
||||
if (state->flags & 0x0200)
|
||||
state->check = crc32(state->check, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
if (len) goto inf_leave;
|
||||
}
|
||||
else if (state->head != Z_NULL)
|
||||
state->head->name = Z_NULL;
|
||||
state->length = 0;
|
||||
state->mode = COMMENT;
|
||||
case COMMENT:
|
||||
if (state->flags & 0x1000) {
|
||||
if (have == 0) goto inf_leave;
|
||||
copy = 0;
|
||||
do {
|
||||
len = (unsigned)(next[copy++]);
|
||||
if (state->head != Z_NULL &&
|
||||
state->head->comment != Z_NULL &&
|
||||
state->length < state->head->comm_max)
|
||||
state->head->comment[state->length++] = len;
|
||||
} while (len && copy < have);
|
||||
if (state->flags & 0x0200)
|
||||
state->check = crc32(state->check, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
if (len) goto inf_leave;
|
||||
}
|
||||
else if (state->head != Z_NULL)
|
||||
state->head->comment = Z_NULL;
|
||||
state->mode = HCRC;
|
||||
case HCRC:
|
||||
if (state->flags & 0x0200) {
|
||||
NEEDBITS(16);
|
||||
if (hold != (state->check & 0xffff)) {
|
||||
strm->msg = (char *)"header crc mismatch";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
INITBITS();
|
||||
}
|
||||
if (state->head != Z_NULL) {
|
||||
state->head->hcrc = (int)((state->flags >> 9) & 1);
|
||||
state->head->done = 1;
|
||||
}
|
||||
strm->adler = state->check = crc32(0L, Z_NULL, 0);
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
#endif
|
||||
case DICTID:
|
||||
NEEDBITS(32);
|
||||
strm->adler = state->check = REVERSE(hold);
|
||||
INITBITS();
|
||||
state->mode = DICT;
|
||||
case DICT:
|
||||
if (state->havedict == 0) {
|
||||
RESTORE();
|
||||
return Z_NEED_DICT;
|
||||
}
|
||||
strm->adler = state->check = adler32(0L, Z_NULL, 0);
|
||||
state->mode = TYPE;
|
||||
case TYPE:
|
||||
WATCHDOG_RESET();
|
||||
if (flush == Z_BLOCK) goto inf_leave;
|
||||
case TYPEDO:
|
||||
if (state->last) {
|
||||
BYTEBITS();
|
||||
state->mode = CHECK;
|
||||
break;
|
||||
}
|
||||
NEEDBITS(3);
|
||||
state->last = BITS(1);
|
||||
DROPBITS(1);
|
||||
switch (BITS(2)) {
|
||||
case 0: /* stored block */
|
||||
Tracev((stderr, "inflate: stored block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = STORED;
|
||||
break;
|
||||
case 1: /* fixed block */
|
||||
fixedtables(state);
|
||||
Tracev((stderr, "inflate: fixed codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = LEN; /* decode codes */
|
||||
break;
|
||||
case 2: /* dynamic block */
|
||||
Tracev((stderr, "inflate: dynamic codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = TABLE;
|
||||
break;
|
||||
case 3:
|
||||
strm->msg = (char *)"invalid block type";
|
||||
state->mode = BAD;
|
||||
}
|
||||
DROPBITS(2);
|
||||
break;
|
||||
case STORED:
|
||||
BYTEBITS(); /* go to byte boundary */
|
||||
NEEDBITS(32);
|
||||
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
|
||||
strm->msg = (char *)"invalid stored block lengths";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->length = (unsigned)hold & 0xffff;
|
||||
Tracev((stderr, "inflate: stored length %u\n",
|
||||
state->length));
|
||||
INITBITS();
|
||||
state->mode = COPY;
|
||||
case COPY:
|
||||
copy = state->length;
|
||||
if (copy) {
|
||||
if (copy > have) copy = have;
|
||||
if (copy > left) copy = left;
|
||||
if (copy == 0) goto inf_leave;
|
||||
zmemcpy(put, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
left -= copy;
|
||||
put += copy;
|
||||
state->length -= copy;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: stored end\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
case TABLE:
|
||||
NEEDBITS(14);
|
||||
state->nlen = BITS(5) + 257;
|
||||
DROPBITS(5);
|
||||
state->ndist = BITS(5) + 1;
|
||||
DROPBITS(5);
|
||||
state->ncode = BITS(4) + 4;
|
||||
DROPBITS(4);
|
||||
#ifndef PKZIP_BUG_WORKAROUND
|
||||
if (state->nlen > 286 || state->ndist > 30) {
|
||||
strm->msg = (char *)"too many length or distance symbols";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
Tracev((stderr, "inflate: table sizes ok\n"));
|
||||
state->have = 0;
|
||||
state->mode = LENLENS;
|
||||
case LENLENS:
|
||||
while (state->have < state->ncode) {
|
||||
NEEDBITS(3);
|
||||
state->lens[order[state->have++]] = (unsigned short)BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
while (state->have < 19)
|
||||
state->lens[order[state->have++]] = 0;
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lenbits = 7;
|
||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid code lengths set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: code lengths ok\n"));
|
||||
state->have = 0;
|
||||
state->mode = CODELENS;
|
||||
case CODELENS:
|
||||
while (state->have < state->nlen + state->ndist) {
|
||||
for (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.val < 16) {
|
||||
NEEDBITS(this.bits);
|
||||
DROPBITS(this.bits);
|
||||
state->lens[state->have++] = this.val;
|
||||
}
|
||||
else {
|
||||
if (this.val == 16) {
|
||||
NEEDBITS(this.bits + 2);
|
||||
DROPBITS(this.bits);
|
||||
if (state->have == 0) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
len = state->lens[state->have - 1];
|
||||
copy = 3 + BITS(2);
|
||||
DROPBITS(2);
|
||||
}
|
||||
else if (this.val == 17) {
|
||||
NEEDBITS(this.bits + 3);
|
||||
DROPBITS(this.bits);
|
||||
len = 0;
|
||||
copy = 3 + BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
else {
|
||||
NEEDBITS(this.bits + 7);
|
||||
DROPBITS(this.bits);
|
||||
len = 0;
|
||||
copy = 11 + BITS(7);
|
||||
DROPBITS(7);
|
||||
}
|
||||
if (state->have + copy > state->nlen + state->ndist) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
while (copy--)
|
||||
state->lens[state->have++] = (unsigned short)len;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle error breaks in while */
|
||||
if (state->mode == BAD) break;
|
||||
|
||||
/* build code tables */
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lenbits = 9;
|
||||
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid literal/lengths set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->distcode = (code const FAR *)(state->next);
|
||||
state->distbits = 6;
|
||||
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
||||
&(state->next), &(state->distbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid distances set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: codes ok\n"));
|
||||
state->mode = LEN;
|
||||
case LEN:
|
||||
WATCHDOG_RESET();
|
||||
if (have >= 6 && left >= 258) {
|
||||
RESTORE();
|
||||
inflate_fast(strm, out);
|
||||
LOAD();
|
||||
break;
|
||||
}
|
||||
for (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.op && (this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
for (;;) {
|
||||
this = state->lencode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
state->length = (unsigned)this.val;
|
||||
if ((int)(this.op) == 0) {
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
state->mode = LIT;
|
||||
break;
|
||||
}
|
||||
if (this.op & 32) {
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
if (this.op & 64) {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
state->mode = LENEXT;
|
||||
case LENEXT:
|
||||
if (state->extra) {
|
||||
NEEDBITS(state->extra);
|
||||
state->length += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", state->length));
|
||||
state->mode = DIST;
|
||||
case DIST:
|
||||
for (;;) {
|
||||
this = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if ((this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
for (;;) {
|
||||
this = state->distcode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
if (this.op & 64) {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->offset = (unsigned)this.val;
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
state->mode = DISTEXT;
|
||||
case DISTEXT:
|
||||
if (state->extra) {
|
||||
NEEDBITS(state->extra);
|
||||
state->offset += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
}
|
||||
#ifdef INFLATE_STRICT
|
||||
if (state->offset > state->dmax) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (state->offset > state->whave + out - left) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracevv((stderr, "inflate: distance %u\n", state->offset));
|
||||
state->mode = MATCH;
|
||||
case MATCH:
|
||||
if (left == 0) goto inf_leave;
|
||||
copy = out - left;
|
||||
if (state->offset > copy) { /* copy from window */
|
||||
copy = state->offset - copy;
|
||||
if (copy > state->write) {
|
||||
copy -= state->write;
|
||||
from = state->window + (state->wsize - copy);
|
||||
}
|
||||
else
|
||||
from = state->window + (state->write - copy);
|
||||
if (copy > state->length) copy = state->length;
|
||||
}
|
||||
else { /* copy from output */
|
||||
from = put - state->offset;
|
||||
copy = state->length;
|
||||
}
|
||||
if (copy > left) copy = left;
|
||||
left -= copy;
|
||||
state->length -= copy;
|
||||
do {
|
||||
*put++ = *from++;
|
||||
} while (--copy);
|
||||
if (state->length == 0) state->mode = LEN;
|
||||
break;
|
||||
case LIT:
|
||||
if (left == 0) goto inf_leave;
|
||||
*put++ = (unsigned char)(state->length);
|
||||
left--;
|
||||
state->mode = LEN;
|
||||
break;
|
||||
case CHECK:
|
||||
if (state->wrap) {
|
||||
NEEDBITS(32);
|
||||
out -= left;
|
||||
strm->total_out += out;
|
||||
state->total += out;
|
||||
if (out)
|
||||
strm->adler = state->check =
|
||||
UPDATE(state->check, put - out, out);
|
||||
out = left;
|
||||
if ((
|
||||
#ifdef GUNZIP
|
||||
state->flags ? hold :
|
||||
#endif
|
||||
REVERSE(hold)) != state->check) {
|
||||
strm->msg = (char *)"incorrect data check";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
INITBITS();
|
||||
Tracev((stderr, "inflate: check matches trailer\n"));
|
||||
}
|
||||
#ifdef GUNZIP
|
||||
state->mode = LENGTH;
|
||||
case LENGTH:
|
||||
if (state->wrap && state->flags) {
|
||||
NEEDBITS(32);
|
||||
if (hold != (state->total & 0xffffffffUL)) {
|
||||
strm->msg = (char *)"incorrect length check";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
INITBITS();
|
||||
Tracev((stderr, "inflate: length matches trailer\n"));
|
||||
}
|
||||
#endif
|
||||
state->mode = DONE;
|
||||
case DONE:
|
||||
ret = Z_STREAM_END;
|
||||
goto inf_leave;
|
||||
case BAD:
|
||||
ret = Z_DATA_ERROR;
|
||||
goto inf_leave;
|
||||
case MEM:
|
||||
return Z_MEM_ERROR;
|
||||
case SYNC:
|
||||
default:
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
Return from inflate(), updating the total counts and the check value.
|
||||
If there was no progress during the inflate() call, return a buffer
|
||||
error. Call updatewindow() to create and/or update the window state.
|
||||
Note: a memory error from inflate() is non-recoverable.
|
||||
*/
|
||||
inf_leave:
|
||||
RESTORE();
|
||||
if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
|
||||
if (updatewindow(strm, out)) {
|
||||
state->mode = MEM;
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
in -= strm->avail_in;
|
||||
out -= strm->avail_out;
|
||||
strm->total_in += in;
|
||||
strm->total_out += out;
|
||||
state->total += out;
|
||||
if (state->wrap && out)
|
||||
strm->adler = state->check =
|
||||
UPDATE(state->check, strm->next_out - out, out);
|
||||
strm->data_type = state->bits + (state->last ? 64 : 0) +
|
||||
(state->mode == TYPE ? 128 : 0);
|
||||
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
|
||||
ret = Z_BUF_ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateEnd(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (state->window != Z_NULL) {
|
||||
WATCHDOG_RESET();
|
||||
ZFREE(strm, state->window);
|
||||
}
|
||||
ZFREE(strm, strm->state);
|
||||
strm->state = Z_NULL;
|
||||
Tracev((stderr, "inflate: end\n"));
|
||||
return Z_OK;
|
||||
}
|
||||
115
common/package/utils/sysupgrade-helper/src/lib/zlib/inflate.h
Normal file
115
common/package/utils/sysupgrade-helper/src/lib/zlib/inflate.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* define NO_GZIP when compiling if you want to disable gzip header and
|
||||
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
|
||||
the crc code when it is not needed. For shared libraries, gzip decoding
|
||||
should be left enabled. */
|
||||
#ifndef NO_GZIP
|
||||
# define GUNZIP
|
||||
#endif
|
||||
|
||||
/* Possible inflate modes between inflate() calls */
|
||||
typedef enum {
|
||||
HEAD, /* i: waiting for magic header */
|
||||
FLAGS, /* i: waiting for method and flags (gzip) */
|
||||
TIME, /* i: waiting for modification time (gzip) */
|
||||
OS, /* i: waiting for extra flags and operating system (gzip) */
|
||||
EXLEN, /* i: waiting for extra length (gzip) */
|
||||
EXTRA, /* i: waiting for extra bytes (gzip) */
|
||||
NAME, /* i: waiting for end of file name (gzip) */
|
||||
COMMENT, /* i: waiting for end of comment (gzip) */
|
||||
HCRC, /* i: waiting for header crc (gzip) */
|
||||
DICTID, /* i: waiting for dictionary check value */
|
||||
DICT, /* waiting for inflateSetDictionary() call */
|
||||
TYPE, /* i: waiting for type bits, including last-flag bit */
|
||||
TYPEDO, /* i: same, but skip check to exit inflate on new block */
|
||||
STORED, /* i: waiting for stored size (length and complement) */
|
||||
COPY, /* i/o: waiting for input or output to copy stored block */
|
||||
TABLE, /* i: waiting for dynamic block table lengths */
|
||||
LENLENS, /* i: waiting for code length code lengths */
|
||||
CODELENS, /* i: waiting for length/lit and distance code lengths */
|
||||
LEN, /* i: waiting for length/lit code */
|
||||
LENEXT, /* i: waiting for length extra bits */
|
||||
DIST, /* i: waiting for distance code */
|
||||
DISTEXT, /* i: waiting for distance extra bits */
|
||||
MATCH, /* o: waiting for output space to copy string */
|
||||
LIT, /* o: waiting for output space to write literal */
|
||||
CHECK, /* i: waiting for 32-bit check value */
|
||||
LENGTH, /* i: waiting for 32-bit length (gzip) */
|
||||
DONE, /* finished check, done -- remain here until reset */
|
||||
BAD, /* got a data error -- remain here until reset */
|
||||
MEM, /* got an inflate() memory error -- remain here until reset */
|
||||
SYNC /* looking for synchronization bytes to restart inflate() */
|
||||
} inflate_mode;
|
||||
|
||||
/*
|
||||
State transitions between above modes -
|
||||
|
||||
(most modes can go to the BAD or MEM mode -- not shown for clarity)
|
||||
|
||||
Process header:
|
||||
HEAD -> (gzip) or (zlib)
|
||||
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
|
||||
NAME -> COMMENT -> HCRC -> TYPE
|
||||
(zlib) -> DICTID or TYPE
|
||||
DICTID -> DICT -> TYPE
|
||||
Read deflate blocks:
|
||||
TYPE -> STORED or TABLE or LEN or CHECK
|
||||
STORED -> COPY -> TYPE
|
||||
TABLE -> LENLENS -> CODELENS -> LEN
|
||||
Read deflate codes:
|
||||
LEN -> LENEXT or LIT or TYPE
|
||||
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
|
||||
LIT -> LEN
|
||||
Process trailer:
|
||||
CHECK -> LENGTH -> DONE
|
||||
*/
|
||||
|
||||
/* state maintained between inflate() calls. Approximately 7K bytes. */
|
||||
struct inflate_state {
|
||||
inflate_mode mode; /* current inflate mode */
|
||||
int last; /* true if processing last block */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
int havedict; /* true if dictionary provided */
|
||||
int flags; /* gzip header method and flags (0 if zlib) */
|
||||
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
|
||||
unsigned long check; /* protected copy of check value */
|
||||
unsigned long total; /* protected copy of output count */
|
||||
gz_headerp head; /* where to save gzip header information */
|
||||
/* sliding window */
|
||||
unsigned wbits; /* log base 2 of requested window size */
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if needed */
|
||||
/* bit accumulator */
|
||||
unsigned long hold; /* input bit accumulator */
|
||||
unsigned bits; /* number of bits in "in" */
|
||||
/* for string and stored block copying */
|
||||
unsigned length; /* literal or length of data to copy */
|
||||
unsigned offset; /* distance back to copy string from */
|
||||
/* for table and code decoding */
|
||||
unsigned extra; /* extra bits needed */
|
||||
/* fixed and dynamic code tables */
|
||||
code const FAR *lencode; /* starting table for length/literal codes */
|
||||
code const FAR *distcode; /* starting table for distance codes */
|
||||
unsigned lenbits; /* index bits for lencode */
|
||||
unsigned distbits; /* index bits for distcode */
|
||||
/* dynamic table building */
|
||||
unsigned ncode; /* number of code length code lengths */
|
||||
unsigned nlen; /* number of length code lengths */
|
||||
unsigned ndist; /* number of distance code lengths */
|
||||
unsigned have; /* number of code lengths in lens[] */
|
||||
code FAR *next; /* next available space in codes[] */
|
||||
unsigned short lens[320]; /* temporary storage for code lengths */
|
||||
unsigned short work[288]; /* work area for code table building */
|
||||
code codes[ENOUGH]; /* space for code tables */
|
||||
};
|
||||
329
common/package/utils/sysupgrade-helper/src/lib/zlib/inftrees.c
Normal file
329
common/package/utils/sysupgrade-helper/src/lib/zlib/inftrees.c
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* U-boot: we already included these
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
*/
|
||||
|
||||
#define MAXBITS 15
|
||||
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
include such an acknowledgment, I would appreciate that you keep this
|
||||
copyright string in the executable of your product.
|
||||
*/
|
||||
|
||||
/*
|
||||
Build a set of tables to decode the provided canonical Huffman code.
|
||||
The code lengths are lens[0..codes-1]. The result starts at *table,
|
||||
whose indices are 0..2^bits-1. work is a writable array of at least
|
||||
lens shorts, which is used as a work area. type is the type of code
|
||||
to be generated, CODES, LENS, or DISTS. On return, zero is success,
|
||||
-1 is an invalid code, and +1 means that ENOUGH isn't enough. table
|
||||
on return points to the next available entry's address. bits is the
|
||||
requested root table index bits, and on return it is the actual root
|
||||
table index bits. It will differ if the request is greater than the
|
||||
longest code or if it is less than the shortest code.
|
||||
*/
|
||||
int inflate_table(type, lens, codes, table, bits, work)
|
||||
codetype type;
|
||||
unsigned short FAR *lens;
|
||||
unsigned codes;
|
||||
code FAR * FAR *table;
|
||||
unsigned FAR *bits;
|
||||
unsigned short FAR *work;
|
||||
{
|
||||
unsigned len; /* a code's length in bits */
|
||||
unsigned sym; /* index of code symbols */
|
||||
unsigned min, max; /* minimum and maximum code lengths */
|
||||
unsigned root; /* number of index bits for root table */
|
||||
unsigned curr; /* number of index bits for current table */
|
||||
unsigned drop; /* code bits to drop for sub-table */
|
||||
int left; /* number of prefix codes available */
|
||||
unsigned used; /* code entries in table used */
|
||||
unsigned huff; /* Huffman code */
|
||||
unsigned incr; /* for incrementing code, index */
|
||||
unsigned fill; /* index for replicating entries */
|
||||
unsigned low; /* low bits for current root entry */
|
||||
unsigned mask; /* mask for low root bits */
|
||||
code this; /* table entry for duplication */
|
||||
code FAR *next; /* next available space in table */
|
||||
const unsigned short FAR *base; /* base value table to use */
|
||||
const unsigned short FAR *extra; /* extra bits table to use */
|
||||
int end; /* use base and extra for symbol > end */
|
||||
unsigned short count[MAXBITS+1]; /* number of codes of each length */
|
||||
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
|
||||
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577, 0, 0};
|
||||
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
|
||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
||||
28, 28, 29, 29, 64, 64};
|
||||
|
||||
/*
|
||||
Process a set of code lengths to create a canonical Huffman code. The
|
||||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||||
symbols by length from short to long, and retaining the symbol order
|
||||
for codes with equal lengths. Then the code starts with all zero bits
|
||||
for the first code of the shortest length, and the codes are integer
|
||||
increments for the same length, and zeros are appended as the length
|
||||
increases. For the deflate format, these bits are stored backwards
|
||||
from their more natural integer increment ordering, and so when the
|
||||
decoding tables are built in the large loop below, the integer codes
|
||||
are incremented backwards.
|
||||
|
||||
This routine assumes, but does not check, that all of the entries in
|
||||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||||
1..MAXBITS is interpreted as that code length. zero means that that
|
||||
symbol does not occur in this code.
|
||||
|
||||
The codes are sorted by computing a count of codes for each length,
|
||||
creating from that a table of starting indices for each length in the
|
||||
sorted table, and then entering the symbols in order in the sorted
|
||||
table. The sorted table is work[], with that space being provided by
|
||||
the caller.
|
||||
|
||||
The length counts are used for other purposes as well, i.e. finding
|
||||
the minimum and maximum length codes, determining if there are any
|
||||
codes at all, checking for a valid set of lengths, and looking ahead
|
||||
at length counts to determine sub-table sizes when building the
|
||||
decoding tables.
|
||||
*/
|
||||
|
||||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||||
for (len = 0; len <= MAXBITS; len++)
|
||||
count[len] = 0;
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
count[lens[sym]]++;
|
||||
|
||||
/* bound code lengths, force root to be within code lengths */
|
||||
root = *bits;
|
||||
for (max = MAXBITS; max >= 1; max--)
|
||||
if (count[max] != 0) break;
|
||||
if (root > max) root = max;
|
||||
if (max == 0) { /* no symbols to code at all */
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)1;
|
||||
this.val = (unsigned short)0;
|
||||
*(*table)++ = this; /* make a table to force an error */
|
||||
*(*table)++ = this;
|
||||
*bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min <= MAXBITS; min++)
|
||||
if (count[min] != 0) break;
|
||||
if (root < min) root = min;
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1;
|
||||
left -= count[len];
|
||||
if (left < 0) return -1; /* over-subscribed */
|
||||
}
|
||||
if (left > 0 && (type == CODES || max != 1))
|
||||
return -1; /* incomplete set */
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++)
|
||||
offs[len + 1] = offs[len] + count[len];
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
|
||||
|
||||
/*
|
||||
Create and fill in decoding tables. In this loop, the table being
|
||||
filled is at next and has curr index bits. The code being used is huff
|
||||
with length len. That code is converted to an index by dropping drop
|
||||
bits off of the bottom. For codes where len is less than drop + curr,
|
||||
those top drop + curr - len bits are incremented through all values to
|
||||
fill the table with replicated entries.
|
||||
|
||||
root is the number of index bits for the root table. When len exceeds
|
||||
root, sub-tables are created pointed to by the root entry with an index
|
||||
of the low root bits of huff. This is saved in low to check for when a
|
||||
new sub-table should be started. drop is zero when the root table is
|
||||
being filled, and drop is root when sub-tables are being filled.
|
||||
|
||||
When a new sub-table is needed, it is necessary to look ahead in the
|
||||
code lengths to determine what size sub-table is needed. The length
|
||||
counts are used for this, and so count[] is decremented as codes are
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked when a LENS table is being made
|
||||
against the space in *table, ENOUGH, minus the maximum space needed by
|
||||
the worst case distance code, MAXD. This should never happen, but the
|
||||
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
|
||||
This assumes that when type == LENS, bits == 9.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when
|
||||
all codes of length max, i.e. all codes, have been processed. This
|
||||
routine permits incomplete codes, so another loop after this one fills
|
||||
in the rest of the decoding tables with invalid code markers.
|
||||
*/
|
||||
|
||||
/* set up for code type */
|
||||
switch (type) {
|
||||
case CODES:
|
||||
base = extra = work; /* dummy value--not used */
|
||||
end = 19;
|
||||
break;
|
||||
case LENS:
|
||||
base = lbase;
|
||||
base -= 257;
|
||||
extra = lext;
|
||||
extra -= 257;
|
||||
end = 256;
|
||||
break;
|
||||
default: /* DISTS */
|
||||
base = dbase;
|
||||
extra = dext;
|
||||
end = -1;
|
||||
}
|
||||
|
||||
/* initialize state for loop */
|
||||
huff = 0; /* starting code */
|
||||
sym = 0; /* starting code symbol */
|
||||
len = min; /* starting code length */
|
||||
next = *table; /* current table to fill in */
|
||||
curr = root; /* current table index bits */
|
||||
drop = 0; /* current bits to drop from code for index */
|
||||
low = (unsigned)(-1); /* trigger new sub-table when len > root */
|
||||
used = 1U << root; /* use root table entries */
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
return 1;
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
if ((int)(work[sym]) < end) {
|
||||
this.op = (unsigned char)0;
|
||||
this.val = work[sym];
|
||||
}
|
||||
else if ((int)(work[sym]) > end) {
|
||||
this.op = (unsigned char)(extra[work[sym]]);
|
||||
this.val = base[work[sym]];
|
||||
}
|
||||
else {
|
||||
this.op = (unsigned char)(32 + 64); /* end of block */
|
||||
this.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
incr = 1U << (len - drop);
|
||||
fill = 1U << curr;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
next[(huff >> drop) + fill] = this;
|
||||
} while (fill != 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
|
||||
/* go to next symbol, update count, len */
|
||||
sym++;
|
||||
if (--(count[len]) == 0) {
|
||||
if (len == max) break;
|
||||
len = lens[work[sym]];
|
||||
}
|
||||
|
||||
/* create new sub-table if needed */
|
||||
if (len > root && (huff & mask) != low) {
|
||||
/* if first time, transition to sub-tables */
|
||||
if (drop == 0)
|
||||
drop = root;
|
||||
|
||||
/* increment past last table */
|
||||
next += min; /* here min is 1 << curr */
|
||||
|
||||
/* determine length of next table */
|
||||
curr = len - drop;
|
||||
left = (int)(1 << curr);
|
||||
while (curr + drop < max) {
|
||||
left -= count[curr + drop];
|
||||
if (left <= 0) break;
|
||||
curr++;
|
||||
left <<= 1;
|
||||
}
|
||||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
return 1;
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
low = huff & mask;
|
||||
(*table)[low].op = (unsigned char)curr;
|
||||
(*table)[low].bits = (unsigned char)root;
|
||||
(*table)[low].val = (unsigned short)(next - *table);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
||||
loop above in incrementing huff for table indices. It is assumed that
|
||||
len is equal to curr + drop, so there is no loop needed to increment
|
||||
through high index bits. When the current sub-table is filled, the loop
|
||||
drops back to the root table to fill in any remaining entries there.
|
||||
*/
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
this.val = (unsigned short)0;
|
||||
while (huff != 0) {
|
||||
/* when done with sub-table, drop back to root table */
|
||||
if (drop != 0 && (huff & mask) != low) {
|
||||
drop = 0;
|
||||
len = root;
|
||||
next = *table;
|
||||
this.bits = (unsigned char)len;
|
||||
}
|
||||
|
||||
/* put invalid code marker in table */
|
||||
next[huff >> drop] = this;
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
*table += used;
|
||||
*bits = root;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* Structure for decoding tables. Each entry provides either the
|
||||
information needed to do the operation requested by the code that
|
||||
indexed that table entry, or it provides a pointer to another
|
||||
table that indexes more bits of the code. op indicates whether
|
||||
the entry is a pointer to another table, a literal, a length or
|
||||
distance, an end-of-block, or an invalid code. For a table
|
||||
pointer, the low four bits of op is the number of index bits of
|
||||
that table. For a length or distance, the low four bits of op
|
||||
is the number of extra bits to get after the code. bits is
|
||||
the number of bits in this code or part of the code to drop off
|
||||
of the bit buffer. val is the actual byte to output in the case
|
||||
of a literal, the base length or distance, or the offset from
|
||||
the current table to the next table. Each entry is four bytes. */
|
||||
typedef struct {
|
||||
unsigned char op; /* operation, extra bits, table bits */
|
||||
unsigned char bits; /* bits in this part of the code */
|
||||
unsigned short val; /* offset in table or code value */
|
||||
} code;
|
||||
|
||||
/* op values as set by inflate_table():
|
||||
00000000 - literal
|
||||
0000tttt - table link, tttt != 0 is the number of table index bits
|
||||
0001eeee - length or distance, eeee is the number of extra bits
|
||||
01100000 - end of block
|
||||
01000000 - invalid code
|
||||
*/
|
||||
|
||||
/* Maximum size of dynamic tree. The maximum found in a long but non-
|
||||
exhaustive search was 1444 code structures (852 for length/literals
|
||||
and 592 for distances, the latter actually the result of an
|
||||
exhaustive search). The true maximum is not known, but the value
|
||||
below is more than safe. */
|
||||
#define ENOUGH 2048
|
||||
#define MAXD 592
|
||||
|
||||
/* Type of code to build for inftable() */
|
||||
typedef enum {
|
||||
CODES,
|
||||
LENS,
|
||||
DISTS
|
||||
} codetype;
|
||||
|
||||
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||
unsigned codes, code FAR * FAR *table,
|
||||
unsigned FAR *bits, unsigned short FAR *work));
|
||||
24
common/package/utils/sysupgrade-helper/src/lib/zlib/zlib.c
Normal file
24
common/package/utils/sysupgrade-helper/src/lib/zlib/zlib.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* This file is derived from various .h and .c files from the zlib-1.2.3
|
||||
* distribution by Jean-loup Gailly and Mark Adler, with some additions
|
||||
* by Paul Mackerras to aid in implementing Deflate compression and
|
||||
* decompression for PPP packets. See zlib.h for conditions of
|
||||
* distribution and use.
|
||||
*
|
||||
* Changes that have been made include:
|
||||
* - changed functions not used outside this file to "local"
|
||||
* - added minCompression parameter to deflateInit2
|
||||
* - added Z_PACKET_FLUSH (see zlib.h for details)
|
||||
* - added inflateIncomp
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
#include "inffixed.h"
|
||||
#include "inffast.c"
|
||||
#include "inftrees.c"
|
||||
#include "inflate.c"
|
||||
#include "zutil.c"
|
||||
#include "adler32.c"
|
||||
20
common/package/utils/sysupgrade-helper/src/lib/zlib/zlib.h
Normal file
20
common/package/utils/sysupgrade-helper/src/lib/zlib/zlib.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* Glue between u-boot and upstream zlib */
|
||||
#ifndef __GLUE_ZLIB_H__
|
||||
#define __GLUE_ZLIB_H__
|
||||
|
||||
#include <common.h>
|
||||
#include <compiler.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <watchdog.h>
|
||||
#include "u-boot/zlib.h"
|
||||
|
||||
/* avoid conflicts */
|
||||
#undef OFF
|
||||
#undef ASMINF
|
||||
#undef POSTINC
|
||||
#undef NO_GZIP
|
||||
#define GUNZIP
|
||||
#undef STDC
|
||||
#undef NO_ERRNO_H
|
||||
|
||||
#endif
|
||||
73
common/package/utils/sysupgrade-helper/src/lib/zlib/zutil.c
Normal file
73
common/package/utils/sysupgrade-helper/src/lib/zlib/zutil.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/* zutil.c -- target dependent utility functions for the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
#ifndef NO_DUMMY_DECL
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#endif
|
||||
|
||||
const char * const z_errmsg[10] = {
|
||||
"need dictionary", /* Z_NEED_DICT 2 */
|
||||
"stream end", /* Z_STREAM_END 1 */
|
||||
"", /* Z_OK 0 */
|
||||
"file error", /* Z_ERRNO (-1) */
|
||||
"stream error", /* Z_STREAM_ERROR (-2) */
|
||||
"data error", /* Z_DATA_ERROR (-3) */
|
||||
"insufficient memory", /* Z_MEM_ERROR (-4) */
|
||||
"buffer error", /* Z_BUF_ERROR (-5) */
|
||||
"incompatible version",/* Z_VERSION_ERROR (-6) */
|
||||
""};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#ifndef verbose
|
||||
#define verbose 0
|
||||
#endif
|
||||
int z_verbose = verbose;
|
||||
|
||||
void z_error (m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "%s\n", m);
|
||||
hang ();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* exported to allow conversion of error code to string for compress() and
|
||||
* uncompress()
|
||||
*/
|
||||
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
|
||||
|
||||
#ifndef STDC
|
||||
extern voidp malloc OF((uInt size));
|
||||
extern voidp calloc OF((uInt items, uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
{
|
||||
if (opaque)
|
||||
items += size - size; /* make compiler happy */
|
||||
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
|
||||
(voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
void zcfree (opaque, ptr, nb)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
unsigned nb;
|
||||
{
|
||||
free(ptr);
|
||||
if (opaque)
|
||||
return; /* make compiler happy */
|
||||
}
|
||||
|
||||
#endif /* MY_ZCALLOC */
|
||||
122
common/package/utils/sysupgrade-helper/src/lib/zlib/zutil.h
Normal file
122
common/package/utils/sysupgrade-helper/src/lib/zlib/zutil.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef STDC
|
||||
# ifndef _WIN32_WCE
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_ERRNO_H
|
||||
# ifdef _WIN32_WCE
|
||||
/* The Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
* errno. We define it as a global variable to simplify porting.
|
||||
* Its value is always 0 and should not be used. We rename it to
|
||||
* avoid conflict with other libraries that use the same workaround.
|
||||
*/
|
||||
# define errno z_errno
|
||||
# endif
|
||||
extern int errno;
|
||||
#else
|
||||
# ifndef _WIN32_WCE
|
||||
# include <errno.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
/* compile with -Dlocal if your debugger can't find static symbols */
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef uch FAR uchf;
|
||||
typedef unsigned short ush;
|
||||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
/* (size given to avoid silly warnings with Visual C++) */
|
||||
|
||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
||||
|
||||
#define ERR_RETURN(strm,err) \
|
||||
return (strm->msg = (char*)ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
|
||||
#ifndef DEF_WBITS
|
||||
# define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
/* default windowBits for decompression. MAX_WBITS is for compression only */
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
/* default memLevel */
|
||||
|
||||
#define STORED_BLOCK 0
|
||||
#define STATIC_TREES 1
|
||||
#define DYN_TREES 2
|
||||
/* The three kinds of block type */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
/* functions */
|
||||
|
||||
#include <linux/string.h>
|
||||
#define zmemcpy memcpy
|
||||
#define zmemcmp memcmp
|
||||
#define zmemzero(dest, len) memset(dest, 0, len)
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
/* Not valid for U-boot
|
||||
# include <stdio.h> */
|
||||
extern int z_verbose;
|
||||
extern void z_error OF((char *m));
|
||||
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
||||
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
||||
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
||||
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
|
||||
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
|
||||
void zcfree OF((voidpf opaque, voidpf ptr, unsigned size));
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), 0)
|
||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||
|
||||
#endif /* ZUTIL_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue