mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-14 02:26:59 -07:00
add: hw ver: show FPGA versions for both HF and LF FPGA configs
add: hw ver: show used and free flash memory chg: prepare fpgaloader for compressed FPGA configs
This commit is contained in:
parent
96c4f5517e
commit
e61530408c
19 changed files with 5137 additions and 134 deletions
|
@ -30,7 +30,8 @@ THUMBSRC = start.c \
|
|||
util.c \
|
||||
string.c \
|
||||
usb_cdc.c \
|
||||
cmd.c
|
||||
cmd.c \
|
||||
inflate.c
|
||||
|
||||
# These are to be compiled in ARM mode
|
||||
ARMSRC = fpgaloader.c \
|
||||
|
|
|
@ -310,7 +310,7 @@ void ReadMem(int addr)
|
|||
/* osimage version information is linked in */
|
||||
extern struct version_information version_information;
|
||||
/* bootrom version information is pointed to from _bootphase1_version_pointer */
|
||||
extern char *_bootphase1_version_pointer, _flash_start, _flash_end;
|
||||
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __os_size__;
|
||||
void SendVersion(void)
|
||||
{
|
||||
char temp[512]; /* Limited data payload in USB packets */
|
||||
|
@ -331,10 +331,13 @@ void SendVersion(void)
|
|||
FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
|
||||
DbpString(temp);
|
||||
|
||||
FpgaGatherVersion(temp, sizeof(temp));
|
||||
FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
|
||||
DbpString(temp);
|
||||
// Send Chip ID
|
||||
cmd_send(CMD_ACK,*(AT91C_DBGU_CIDR),0,0,NULL,0);
|
||||
FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
|
||||
DbpString(temp);
|
||||
|
||||
// Send Chip ID and used flash memory
|
||||
cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), (uint32_t)&_bootrom_end - (uint32_t)&_bootrom_start + (uint32_t)&__os_size__, 0, NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef WITH_LF
|
||||
|
|
|
@ -55,7 +55,7 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
|||
void FpgaWriteConfWord(uint8_t v);
|
||||
void FpgaDownloadAndGo(int bitstream_version);
|
||||
int FpgaGatherBitstreamVersion();
|
||||
void FpgaGatherVersion(char *dst, int len);
|
||||
void FpgaGatherVersion(int bitstream_version, char *dst, int len);
|
||||
void FpgaSetupSsc(void);
|
||||
void SetupSpi(int mode);
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||
|
|
BIN
armsrc/fpga_hf.bit.gz
Normal file
BIN
armsrc/fpga_hf.bit.gz
Normal file
Binary file not shown.
BIN
armsrc/fpga_lf.bit.gz
Normal file
BIN
armsrc/fpga_lf.bit.gz
Normal file
Binary file not shown.
|
@ -14,6 +14,19 @@
|
|||
#include "util.h"
|
||||
#include "string.h"
|
||||
|
||||
// remember which version of the bitstream we have already downloaded to the FPGA
|
||||
static int downloaded_bitstream = FPGA_BITSTREAM_ERR;
|
||||
|
||||
// this is where the bitstreams are located in memory:
|
||||
extern uint8_t _binary_fpga_lf_bit_start, _binary_fpga_lf_bit_end;
|
||||
extern uint8_t _binary_fpga_hf_bit_start, _binary_fpga_hf_bit_end;
|
||||
static uint8_t *fpga_image_ptr = NULL;
|
||||
|
||||
static const uint8_t _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
|
||||
static const uint8_t _gzip_header[] = {0x1f, 0x8b, 0x08}; // including compression method 0x08 (deflate)
|
||||
#define GZIP_HEADER_SIZE sizeof(_gzip_header)
|
||||
#define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(_bitparse_fixed_header)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up the Serial Peripheral Interface as master
|
||||
// Used to write the FPGA config word
|
||||
|
@ -150,6 +163,19 @@ bool FpgaSetupSscDma(uint8_t *buf, int len)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void reset_fpga_stream(uint8_t *image_start)
|
||||
{
|
||||
fpga_image_ptr = image_start;
|
||||
}
|
||||
|
||||
|
||||
uint8_t get_from_fpga_stream(void)
|
||||
{
|
||||
return *fpga_image_ptr++;
|
||||
}
|
||||
|
||||
|
||||
static void DownloadFPGA_byte(unsigned char w)
|
||||
{
|
||||
#define SEND_BIT(x) { if(w & (1<<x) ) HIGH(GPIO_FPGA_DIN); else LOW(GPIO_FPGA_DIN); HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); }
|
||||
|
@ -163,9 +189,8 @@ static void DownloadFPGA_byte(unsigned char w)
|
|||
SEND_BIT(0);
|
||||
}
|
||||
|
||||
// Download the fpga image starting at FpgaImage and with length FpgaImageLen bytes
|
||||
// If bytereversal is set: reverse the byte order in each 4-byte word
|
||||
static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int bytereversal)
|
||||
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
||||
static void DownloadFPGA(int FpgaImageLen)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
|
@ -218,21 +243,8 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
|
|||
return;
|
||||
}
|
||||
|
||||
if(bytereversal) {
|
||||
/* This is only supported for uint32_t aligned images */
|
||||
if( ((int)FpgaImage % sizeof(uint32_t)) == 0 ) {
|
||||
i=0;
|
||||
while(FpgaImageLen-->0)
|
||||
DownloadFPGA_byte(FpgaImage[(i++)^0x3]);
|
||||
/* Explanation of the magic in the above line:
|
||||
* i^0x3 inverts the lower two bits of the integer i, counting backwards
|
||||
* for each 4 byte increment. The generated sequence of (i++)^3 is
|
||||
* 3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 etc. pp.
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
while(FpgaImageLen-->0)
|
||||
DownloadFPGA_byte(*FpgaImage++);
|
||||
while(FpgaImageLen-->0) {
|
||||
DownloadFPGA_byte(get_from_fpga_stream());
|
||||
}
|
||||
|
||||
// continue to clock FPGA until ready signal goes high
|
||||
|
@ -250,39 +262,21 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
|
|||
LED_D_OFF();
|
||||
}
|
||||
|
||||
static char *bitparse_headers_start;
|
||||
static char *bitparse_bitstream_end;
|
||||
static int bitparse_initialized = 0;
|
||||
|
||||
/* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
|
||||
* 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01
|
||||
* After that the format is 1 byte section type (ASCII character), 2 byte length
|
||||
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
|
||||
* length.
|
||||
*/
|
||||
static const char _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
|
||||
static int bitparse_init(void * start_address, void *end_address)
|
||||
int bitparse_find_section(char section_name, unsigned int *section_length)
|
||||
{
|
||||
bitparse_initialized = 0;
|
||||
|
||||
if(memcmp(_bitparse_fixed_header, start_address, sizeof(_bitparse_fixed_header)) != 0) {
|
||||
return 0; /* Not matched */
|
||||
} else {
|
||||
bitparse_headers_start= ((char*)start_address) + sizeof(_bitparse_fixed_header);
|
||||
bitparse_bitstream_end= (char*)end_address;
|
||||
bitparse_initialized = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int bitparse_find_section(char section_name, char **section_start, unsigned int *section_length)
|
||||
{
|
||||
char *pos = bitparse_headers_start;
|
||||
int result = 0;
|
||||
|
||||
if(!bitparse_initialized) return 0;
|
||||
|
||||
while(pos < bitparse_bitstream_end) {
|
||||
char current_name = *pos++;
|
||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||
uint16_t numbytes = 0;
|
||||
while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
|
||||
char current_name = get_from_fpga_stream();
|
||||
numbytes++;
|
||||
unsigned int current_length = 0;
|
||||
if(current_name < 'a' || current_name > 'e') {
|
||||
/* Strange section name, abort */
|
||||
|
@ -292,11 +286,13 @@ int bitparse_find_section(char section_name, char **section_start, unsigned int
|
|||
switch(current_name) {
|
||||
case 'e':
|
||||
/* Four byte length field */
|
||||
current_length += (*pos++) << 24;
|
||||
current_length += (*pos++) << 16;
|
||||
current_length += get_from_fpga_stream() << 24;
|
||||
current_length += get_from_fpga_stream() << 16;
|
||||
numbytes += 2;
|
||||
default: /* Fall through, two byte length field */
|
||||
current_length += (*pos++) << 8;
|
||||
current_length += (*pos++) << 0;
|
||||
current_length += get_from_fpga_stream() << 8;
|
||||
current_length += get_from_fpga_stream() << 0;
|
||||
numbytes += 2;
|
||||
}
|
||||
|
||||
if(current_name != 'e' && current_length > 255) {
|
||||
|
@ -306,108 +302,136 @@ int bitparse_find_section(char section_name, char **section_start, unsigned int
|
|||
|
||||
if(current_name == section_name) {
|
||||
/* Found it */
|
||||
*section_start = pos;
|
||||
*section_length = current_length;
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
pos += current_length; /* Skip section */
|
||||
for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) {
|
||||
get_from_fpga_stream();
|
||||
numbytes++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void init_fpga_inflate(void)
|
||||
{
|
||||
// initialize zlib for inflate
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find out which FPGA image format is stored in flash, then call DownloadFPGA
|
||||
// with the right parameters to download the image
|
||||
//-----------------------------------------------------------------------------
|
||||
extern char _binary_fpga_lf_bit_start, _binary_fpga_lf_bit_end;
|
||||
extern char _binary_fpga_hf_bit_start, _binary_fpga_hf_bit_end;
|
||||
void FpgaDownloadAndGo(int bitstream_version)
|
||||
{
|
||||
void *bit_start;
|
||||
void *bit_end;
|
||||
|
||||
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
||||
|
||||
// check whether or not the bitstream is already loaded
|
||||
if (FpgaGatherBitstreamVersion() == bitstream_version)
|
||||
if (downloaded_bitstream == bitstream_version)
|
||||
return;
|
||||
|
||||
if (bitstream_version == FPGA_BITSTREAM_LF) {
|
||||
bit_start = &_binary_fpga_lf_bit_start;
|
||||
bit_end = &_binary_fpga_lf_bit_end;
|
||||
reset_fpga_stream(&_binary_fpga_lf_bit_start);
|
||||
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
|
||||
bit_start = &_binary_fpga_hf_bit_start;
|
||||
bit_end = &_binary_fpga_hf_bit_end;
|
||||
reset_fpga_stream(&_binary_fpga_hf_bit_start);
|
||||
} else
|
||||
return;
|
||||
/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
|
||||
*/
|
||||
if(bitparse_init(bit_start, bit_end)) {
|
||||
/* Successfully initialized the .bit parser. Find the 'e' section and
|
||||
* send its contents to the FPGA.
|
||||
*/
|
||||
char *bitstream_start;
|
||||
unsigned int bitstream_length;
|
||||
if(bitparse_find_section('e', &bitstream_start, &bitstream_length)) {
|
||||
DownloadFPGA(bitstream_start, bitstream_length, 0);
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < GZIP_HEADER_SIZE; i++) {
|
||||
header[i] = get_from_fpga_stream();
|
||||
}
|
||||
|
||||
// Check for compressed new flash image format (starts with gzip header)
|
||||
if(memcmp(_gzip_header, header, GZIP_HEADER_SIZE) == 0) {
|
||||
init_fpga_inflate();
|
||||
}
|
||||
|
||||
for (; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
|
||||
header[i] = get_from_fpga_stream();
|
||||
}
|
||||
|
||||
// Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
|
||||
if(memcmp(_bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) {
|
||||
unsigned int bitstream_length;
|
||||
if(bitparse_find_section('e', &bitstream_length)) {
|
||||
DownloadFPGA(bitstream_length);
|
||||
downloaded_bitstream = bitstream_version;
|
||||
return; /* All done */
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback for the old flash image format: Check for the magic marker 0xFFFFFFFF
|
||||
* 0xAA995566 at address 0x102000. This is raw bitstream with a size of 336,768 bits
|
||||
* = 10,524 uint32_t, stored as uint32_t e.g. little-endian in memory, but each DWORD
|
||||
* is still to be transmitted in MSBit first order. Set the invert flag to indicate
|
||||
* that the DownloadFPGA function should invert every 4 byte sequence when doing
|
||||
* the bytewise download.
|
||||
*/
|
||||
if( *(uint32_t*)0x102000 == 0xFFFFFFFF && *(uint32_t*)0x102004 == 0xAA995566 )
|
||||
DownloadFPGA((char*)0x102000, 10524*4, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int FpgaGatherBitstreamVersion()
|
||||
{
|
||||
char temp[256];
|
||||
FpgaGatherVersion(temp, sizeof (temp));
|
||||
if (!memcmp("LF", temp, 2))
|
||||
return FPGA_BITSTREAM_LF;
|
||||
else if (!memcmp("HF", temp, 2))
|
||||
return FPGA_BITSTREAM_HF;
|
||||
return FPGA_BITSTREAM_ERR;
|
||||
return downloaded_bitstream;
|
||||
}
|
||||
|
||||
void FpgaGatherVersion(char *dst, int len)
|
||||
void FpgaGatherVersion(int bitstream_version, char *dst, int len)
|
||||
{
|
||||
char *fpga_info;
|
||||
unsigned int fpga_info_len;
|
||||
dst[0] = 0;
|
||||
if(!bitparse_find_section('e', &fpga_info, &fpga_info_len)) {
|
||||
strncat(dst, "FPGA image: legacy image without version information", len-1);
|
||||
} else {
|
||||
/* USB packets only have 48 bytes data payload, so be terse */
|
||||
if(bitparse_find_section('a', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
|
||||
if (!memcmp("fpga_lf", fpga_info, 7))
|
||||
strncat(dst, "LF ", len-1);
|
||||
else if (!memcmp("fpga_hf", fpga_info, 7))
|
||||
strncat(dst, "HF ", len-1);
|
||||
char tempstr[40];
|
||||
|
||||
dst[0] = '\0';
|
||||
|
||||
if (bitstream_version == FPGA_BITSTREAM_LF) {
|
||||
reset_fpga_stream(&_binary_fpga_lf_bit_start);
|
||||
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
|
||||
reset_fpga_stream(&_binary_fpga_hf_bit_start);
|
||||
} else
|
||||
return;
|
||||
|
||||
|
||||
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
|
||||
get_from_fpga_stream();
|
||||
}
|
||||
|
||||
if(bitparse_find_section('a', &fpga_info_len)) {
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
}
|
||||
strncat(dst, "FPGA image built", len-1);
|
||||
#if 0
|
||||
if(bitparse_find_section('b', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
|
||||
strncat(dst, " for ", len-1);
|
||||
strncat(dst, fpga_info, len-1);
|
||||
if (!memcmp("fpga_lf", tempstr, 7))
|
||||
strncat(dst, "LF ", len-1);
|
||||
else if (!memcmp("fpga_hf", tempstr, 7))
|
||||
strncat(dst, "HF ", len-1);
|
||||
}
|
||||
strncat(dst, "FPGA image built", len-1);
|
||||
if(bitparse_find_section('b', &fpga_info_len)) {
|
||||
strncat(dst, " for ", len-1);
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(bitparse_find_section('c', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
|
||||
strncat(dst, " on ", len-1);
|
||||
strncat(dst, fpga_info, len-1);
|
||||
strncat(dst, tempstr, len-1);
|
||||
}
|
||||
if(bitparse_find_section('c', &fpga_info_len)) {
|
||||
strncat(dst, " on ", len-1);
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
}
|
||||
if(bitparse_find_section('d', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
|
||||
strncat(dst, " at ", len-1);
|
||||
strncat(dst, fpga_info, len-1);
|
||||
strncat(dst, tempstr, len-1);
|
||||
}
|
||||
if(bitparse_find_section('d', &fpga_info_len)) {
|
||||
strncat(dst, " at ", len-1);
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
}
|
||||
strncat(dst, tempstr, len-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
armsrc/inffast.h
Normal file
11
armsrc/inffast.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995-2003, 2010 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 ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
|
94
armsrc/inffixed.h
Normal file
94
armsrc/inffixed.h
Normal file
|
@ -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 this 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}
|
||||
};
|
1512
armsrc/inflate.c
Normal file
1512
armsrc/inflate.c
Normal file
File diff suppressed because it is too large
Load diff
122
armsrc/inflate.h
Normal file
122
armsrc/inflate.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2009 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: same as COPY below, but only first time in */
|
||||
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: same as LEN below, but only first time in */
|
||||
LEN, /* i: waiting for length/lit/eob 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 BAD or MEM on error -- not shown for clarity)
|
||||
|
||||
Process header:
|
||||
HEAD -> (gzip) or (zlib) or (raw)
|
||||
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
|
||||
HCRC -> TYPE
|
||||
(zlib) -> DICTID or TYPE
|
||||
DICTID -> DICT -> TYPE
|
||||
(raw) -> TYPEDO
|
||||
Read deflate blocks:
|
||||
TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
|
||||
STORED -> COPY_ -> COPY -> TYPE
|
||||
TABLE -> LENLENS -> CODELENS -> LEN_
|
||||
LEN_ -> LEN
|
||||
Read deflate codes in fixed or dynamic block:
|
||||
LEN -> LENEXT or LIT or TYPE
|
||||
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
|
||||
LIT -> LEN
|
||||
Process trailer:
|
||||
CHECK -> LENGTH -> DONE
|
||||
*/
|
||||
|
||||
/* state maintained between inflate() calls. Approximately 10K 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 wnext; /* 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 */
|
||||
int sane; /* if false, allow invalid distance too far */
|
||||
int back; /* bits back of last unprocessed length/lit */
|
||||
unsigned was; /* initial length of match */
|
||||
};
|
62
armsrc/inftrees.h
Normal file
62
armsrc/inftrees.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995-2005, 2010 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 the dynamic table. The maximum number of code structures is
|
||||
1444, which is the sum of 852 for literal/length codes and 592 for distance
|
||||
codes. These values were found by exhaustive searches using the program
|
||||
examples/enough.c found in the zlib distribtution. The arguments to that
|
||||
program are the number of symbols, the initial root table size, and the
|
||||
maximum bit length of a code. "enough 286 9 15" for literal/length codes
|
||||
returns returns 852, and "enough 30 6 15" for distance codes returns 592.
|
||||
The initial root table size (9 or 6) is found in the fifth argument of the
|
||||
inflate_table() calls in inflate.c and infback.c. If the root table size is
|
||||
changed, then these maximum sizes would be need to be recalculated and
|
||||
updated. */
|
||||
#define ENOUGH_LENS 852
|
||||
#define ENOUGH_DISTS 592
|
||||
#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
|
||||
|
||||
/* Type of code to build for inflate_table() */
|
||||
typedef enum {
|
||||
CODES,
|
||||
LENS,
|
||||
DISTS
|
||||
} codetype;
|
||||
|
||||
int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||
unsigned codes, code FAR * FAR *table,
|
||||
unsigned FAR *bits, unsigned short FAR *work));
|
|
@ -51,6 +51,7 @@ SECTIONS
|
|||
__data_src_start__ = LOADADDR(.data);
|
||||
__data_start__ = ADDR(.data);
|
||||
__data_end__ = __data_start__ + SIZEOF(.data);
|
||||
__os_size__ = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata);
|
||||
|
||||
.bss : {
|
||||
__bss_start__ = .;
|
||||
|
|
511
armsrc/zconf.h
Normal file
511
armsrc/zconf.h
Normal file
|
@ -0,0 +1,511 @@
|
|||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
* Even better than compiling with -DZ_PREFIX would be to use configure to set
|
||||
* this permanently in zconf.h using "./configure --zprefix".
|
||||
*/
|
||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||
# define Z_PREFIX_SET
|
||||
|
||||
/* all linked symbols */
|
||||
# define _dist_code z__dist_code
|
||||
# define _length_code z__length_code
|
||||
# define _tr_align z__tr_align
|
||||
# define _tr_flush_bits z__tr_flush_bits
|
||||
# define _tr_flush_block z__tr_flush_block
|
||||
# define _tr_init z__tr_init
|
||||
# define _tr_stored_block z__tr_stored_block
|
||||
# define _tr_tally z__tr_tally
|
||||
# define adler32 z_adler32
|
||||
# define adler32_combine z_adler32_combine
|
||||
# define adler32_combine64 z_adler32_combine64
|
||||
# ifndef Z_SOLO
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# endif
|
||||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflatePending z_deflatePending
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateResetKeep z_deflateResetKeep
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateSetHeader z_deflateSetHeader
|
||||
# define deflateTune z_deflateTune
|
||||
# define deflate_copyright z_deflate_copyright
|
||||
# define get_crc_table z_get_crc_table
|
||||
# ifndef Z_SOLO
|
||||
# define gz_error z_gz_error
|
||||
# define gz_intmax z_gz_intmax
|
||||
# define gz_strwinerror z_gz_strwinerror
|
||||
# define gzbuffer z_gzbuffer
|
||||
# define gzclearerr z_gzclearerr
|
||||
# define gzclose z_gzclose
|
||||
# define gzclose_r z_gzclose_r
|
||||
# define gzclose_w z_gzclose_w
|
||||
# define gzdirect z_gzdirect
|
||||
# define gzdopen z_gzdopen
|
||||
# define gzeof z_gzeof
|
||||
# define gzerror z_gzerror
|
||||
# define gzflush z_gzflush
|
||||
# define gzgetc z_gzgetc
|
||||
# define gzgetc_ z_gzgetc_
|
||||
# define gzgets z_gzgets
|
||||
# define gzoffset z_gzoffset
|
||||
# define gzoffset64 z_gzoffset64
|
||||
# define gzopen z_gzopen
|
||||
# define gzopen64 z_gzopen64
|
||||
# ifdef _WIN32
|
||||
# define gzopen_w z_gzopen_w
|
||||
# endif
|
||||
# define gzprintf z_gzprintf
|
||||
# define gzvprintf z_gzvprintf
|
||||
# define gzputc z_gzputc
|
||||
# define gzputs z_gzputs
|
||||
# define gzread z_gzread
|
||||
# define gzrewind z_gzrewind
|
||||
# define gzseek z_gzseek
|
||||
# define gzseek64 z_gzseek64
|
||||
# define gzsetparams z_gzsetparams
|
||||
# define gztell z_gztell
|
||||
# define gztell64 z_gztell64
|
||||
# define gzungetc z_gzungetc
|
||||
# define gzwrite z_gzwrite
|
||||
# endif
|
||||
# define inflate z_inflate
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define inflateBackInit_ z_inflateBackInit_
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define inflateGetHeader z_inflateGetHeader
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflateMark z_inflateMark
|
||||
# define inflatePrime z_inflatePrime
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateReset2 z_inflateReset2
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateGetDictionary z_inflateGetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateUndermine z_inflateUndermine
|
||||
# define inflateResetKeep z_inflateResetKeep
|
||||
# define inflate_copyright z_inflate_copyright
|
||||
# define inflate_fast z_inflate_fast
|
||||
# define inflate_table z_inflate_table
|
||||
# ifndef Z_SOLO
|
||||
# define uncompress z_uncompress
|
||||
# endif
|
||||
# define zError z_zError
|
||||
# ifndef Z_SOLO
|
||||
# define zcalloc z_zcalloc
|
||||
# define zcfree z_zcfree
|
||||
# endif
|
||||
# define zlibCompileFlags z_zlibCompileFlags
|
||||
# define zlibVersion z_zlibVersion
|
||||
|
||||
/* all zlib typedefs in zlib.h and zconf.h */
|
||||
# define Byte z_Byte
|
||||
# define Bytef z_Bytef
|
||||
# define alloc_func z_alloc_func
|
||||
# define charf z_charf
|
||||
# define free_func z_free_func
|
||||
# ifndef Z_SOLO
|
||||
# define gzFile z_gzFile
|
||||
# endif
|
||||
# define gz_header z_gz_header
|
||||
# define gz_headerp z_gz_headerp
|
||||
# define in_func z_in_func
|
||||
# define intf z_intf
|
||||
# define out_func z_out_func
|
||||
# define uInt z_uInt
|
||||
# define uIntf z_uIntf
|
||||
# define uLong z_uLong
|
||||
# define uLongf z_uLongf
|
||||
# define voidp z_voidp
|
||||
# define voidpc z_voidpc
|
||||
# define voidpf z_voidpf
|
||||
|
||||
/* all zlib structs in zlib.h and zconf.h */
|
||||
# define gz_header_s z_gz_header_s
|
||||
# define internal_state z_internal_state
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(ZLIB_CONST) && !defined(z_const)
|
||||
# define z_const const
|
||||
#else
|
||||
# define z_const
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef Z_ARG /* function prototypes for stdarg */
|
||||
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# define Z_ARG(args) args
|
||||
# else
|
||||
# define Z_ARG(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
|
||||
# include <limits.h>
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned
|
||||
# elif (ULONG_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned long
|
||||
# elif (USHRT_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned short
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef Z_U4
|
||||
typedef Z_U4 z_crc_t;
|
||||
#else
|
||||
typedef unsigned long z_crc_t;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_STDARG_H
|
||||
#endif
|
||||
|
||||
#ifdef STDC
|
||||
# ifndef Z_SOLO
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifndef Z_SOLO
|
||||
# include <stdarg.h> /* for va_list */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef Z_SOLO
|
||||
# include <stddef.h> /* for wchar_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||
* though the former does not conform to the LFS document), but considering
|
||||
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||
* equivalently requesting no 64-bit operations
|
||||
*/
|
||||
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
|
||||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
#ifndef Z_SOLO
|
||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# ifndef z_off_t
|
||||
# define z_off_t off_t
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
|
||||
# define Z_LFS64
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
|
||||
# define Z_LARGE64
|
||||
#endif
|
||||
|
||||
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
|
||||
# define Z_WANT64
|
||||
#endif
|
||||
|
||||
#if !defined(SEEK_SET) && !defined(Z_SOLO)
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && defined(Z_LARGE64)
|
||||
# define z_off64_t off64_t
|
||||
#else
|
||||
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
|
||||
# define z_off64_t __int64
|
||||
# else
|
||||
# define z_off64_t z_off_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
#pragma map(deflateInit_,"DEIN")
|
||||
#pragma map(deflateInit2_,"DEIN2")
|
||||
#pragma map(deflateEnd,"DEEND")
|
||||
#pragma map(deflateBound,"DEBND")
|
||||
#pragma map(inflateInit_,"ININ")
|
||||
#pragma map(inflateInit2_,"ININ2")
|
||||
#pragma map(inflateEnd,"INEND")
|
||||
#pragma map(inflateSync,"INSY")
|
||||
#pragma map(inflateSetDictionary,"INSEDI")
|
||||
#pragma map(compressBound,"CMBND")
|
||||
#pragma map(inflate_table,"INTABL")
|
||||
#pragma map(inflate_fast,"INFA")
|
||||
#pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
1768
armsrc/zlib.h
Normal file
1768
armsrc/zlib.h
Normal file
File diff suppressed because it is too large
Load diff
253
armsrc/zutil.h
Normal file
253
armsrc/zutil.h
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2013 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
|
||||
|
||||
#ifdef HAVE_HIDDEN
|
||||
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||
#else
|
||||
# define ZLIB_INTERNAL
|
||||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
#if defined(STDC) && !defined(Z_SOLO)
|
||||
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef Z_SOLO
|
||||
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||
#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 z_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 = 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 */
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
/* target dependencies */
|
||||
|
||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||
# define OS_CODE 0x00
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||
/* Allow compilation with ANSI keywords only enabled */
|
||||
void _Cdecl farfree( void *block );
|
||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||
# else
|
||||
# include <alloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef AMIGA
|
||||
# define OS_CODE 0x01
|
||||
#endif
|
||||
|
||||
#if defined(VAXC) || defined(VMS)
|
||||
# define OS_CODE 0x02
|
||||
# define F_OPEN(name, mode) \
|
||||
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
|
||||
#endif
|
||||
|
||||
#if defined(ATARI) || defined(atarist)
|
||||
# define OS_CODE 0x05
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
# define OS_CODE 0x06
|
||||
# if defined(M_I86) && !defined(Z_SOLO)
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||
# define OS_CODE 0x07
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TOPS20
|
||||
# define OS_CODE 0x0a
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
|
||||
# define OS_CODE 0x0b
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __50SERIES /* Prime/PRIMOS */
|
||||
# define OS_CODE 0x0f
|
||||
#endif
|
||||
|
||||
#if defined(_BEOS_) || defined(RISCOS)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
|
||||
# if defined(_WIN32_WCE)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef _PTRDIFF_T_DEFINED
|
||||
typedef int ptrdiff_t;
|
||||
# define _PTRDIFF_T_DEFINED
|
||||
# endif
|
||||
# else
|
||||
# define fdopen(fd,type) _fdopen(fd,type)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(MSDOS)
|
||||
#pragma warn -8004
|
||||
#pragma warn -8008
|
||||
#pragma warn -8066
|
||||
#endif
|
||||
|
||||
/* provide prototypes for these when building zlib without LFS */
|
||||
#if !defined(_WIN32) && \
|
||||
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||
#endif
|
||||
|
||||
/* common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
#ifndef F_OPEN
|
||||
# define F_OPEN(name, mode) fopen((name), (mode))
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
|
||||
#if defined(pyr) || defined(Z_SOLO)
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||
/* Use our own functions for small and medium model with MSC <= 5.0.
|
||||
* You may have to use the same strategy for Borland C (untested).
|
||||
* The __SC__ check is for Symantec.
|
||||
*/
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
|
||||
# define HAVE_MEMCPY
|
||||
#endif
|
||||
#ifdef HAVE_MEMCPY
|
||||
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
|
||||
# define zmemcpy _fmemcpy
|
||||
# define zmemcmp _fmemcmp
|
||||
# define zmemzero(dest, len) _fmemset(dest, 0, len)
|
||||
# else
|
||||
# define zmemcpy memcpy
|
||||
# define zmemcmp memcmp
|
||||
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||
# endif
|
||||
#else
|
||||
void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
||||
int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
||||
void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
|
||||
#endif
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
extern int ZLIB_INTERNAL z_verbose;
|
||||
extern void ZLIB_INTERNAL 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
|
||||
|
||||
#ifndef Z_SOLO
|
||||
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
||||
unsigned size));
|
||||
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
||||
#endif
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
#endif /* ZUTIL_H */
|
|
@ -12,7 +12,8 @@ CXX=g++
|
|||
VPATH = ../common
|
||||
OBJDIR = obj
|
||||
|
||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
|
||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
|
||||
LUALIB = ../liblua/liblua.a
|
||||
LDFLAGS = $(COMMON_FLAGS)
|
||||
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||
LUAPLATFORM = generic
|
||||
|
@ -108,15 +109,15 @@ COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
|||
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
||||
|
||||
RM = rm -f
|
||||
BINS = proxmark3 flasher #snooper cli
|
||||
BINS = proxmark3 flasher fpga_compress #snooper cli
|
||||
CLEAN = cli cli.exe flasher flasher.exe proxmark3 proxmark3.exe snooper snooper.exe $(CMDOBJS) $(OBJDIR)/*.o *.o *.moc.cpp
|
||||
|
||||
all: lua_build $(BINS)
|
||||
|
||||
all-static: LDLIBS:=-static $(LDLIBS)
|
||||
all-static: snooper cli flasher
|
||||
all-static: snooper cli flasher fpga_compress
|
||||
|
||||
proxmark3: LDLIBS+=$(QTLDLIBS)
|
||||
proxmark3: LDLIBS+=$(QTLDLIBS) $(LUALIB)
|
||||
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUI)
|
||||
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
|
@ -129,6 +130,9 @@ cli: $(OBJDIR)/cli.o $(COREOBJS) $(CMDOBJS) $(OBJDIR)/guidummy.o
|
|||
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS)
|
||||
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
fpga_compress: $(OBJDIR)/fpga_compress.o
|
||||
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
|
|
408
client/cmdhftopaz.c
Normal file
408
client/cmdhftopaz.c
Normal file
|
@ -0,0 +1,408 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2015 Piwi
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// High frequency Topaz (NFC Type 1) commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhftopaz.h"
|
||||
#include "cmdhf14a.h"
|
||||
#include "ui.h"
|
||||
#include "mifare.h"
|
||||
#include "proxmark3.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "protocols.h"
|
||||
|
||||
#define TOPAZ_MAX_MEMORY 2048
|
||||
|
||||
static struct {
|
||||
uint8_t HR01[2];
|
||||
uint8_t uid[7];
|
||||
uint8_t size;
|
||||
uint8_t data_blocks[TOPAZ_MAX_MEMORY/8][8];
|
||||
uint8_t *dynamic_lock_areas;
|
||||
uint8_t *dynamic_reserved_areas;
|
||||
} topaz_tag;
|
||||
|
||||
|
||||
static void topaz_switch_on_field(void)
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE, 0, 0}};
|
||||
SendCommand(&c);
|
||||
}
|
||||
|
||||
|
||||
static void topaz_switch_off_field(void)
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
|
||||
SendCommand(&c);
|
||||
}
|
||||
|
||||
|
||||
static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response)
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE, len, 0}};
|
||||
memcpy(c.d.asBytes, cmd, len);
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
WaitForResponse(CMD_ACK, &resp);
|
||||
|
||||
if (resp.arg[0] > 0) {
|
||||
memcpy(response, resp.d.asBytes, resp.arg[0]);
|
||||
}
|
||||
|
||||
return resp.arg[0];
|
||||
}
|
||||
|
||||
|
||||
static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response)
|
||||
{
|
||||
if (len > 1) {
|
||||
uint8_t first, second;
|
||||
ComputeCrc14443(CRC_14443_B, cmd, len-2, &first, &second);
|
||||
cmd[len-2] = first;
|
||||
cmd[len-1] = second;
|
||||
}
|
||||
|
||||
return topaz_send_cmd_raw(cmd, len, response);
|
||||
}
|
||||
|
||||
|
||||
static int topaz_select(uint8_t *atqa, uint8_t *rid_response)
|
||||
{
|
||||
// ToDo: implement anticollision
|
||||
|
||||
uint8_t wupa_cmd[] = {TOPAZ_WUPA};
|
||||
uint8_t rid_cmd[] = {TOPAZ_RID, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
topaz_switch_on_field();
|
||||
|
||||
if (!topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa)) {
|
||||
topaz_switch_off_field();
|
||||
return -1; // WUPA failed
|
||||
}
|
||||
|
||||
if (!topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response)) {
|
||||
topaz_switch_off_field();
|
||||
return -2; // RID failed
|
||||
}
|
||||
|
||||
return 0; // OK
|
||||
}
|
||||
|
||||
|
||||
static int topaz_rall(uint8_t *uid, uint8_t *response)
|
||||
{
|
||||
uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
memcpy(&rall_cmd[3], uid, 4);
|
||||
if (!topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response)) {
|
||||
topaz_switch_off_field();
|
||||
return -1; // RALL failed
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bool topaz_block_is_locked(uint8_t blockno, uint8_t *lockbits)
|
||||
{
|
||||
if(lockbits[blockno/8] >> (blockno % 8) & 0x01) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int topaz_print_CC(uint8_t *data)
|
||||
{
|
||||
if(data[0] != 0xe1) {
|
||||
return -1; // no NDEF message
|
||||
}
|
||||
|
||||
PrintAndLog("Capability Container: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]);
|
||||
PrintAndLog(" %02x: NDEF Magic Number", data[0]);
|
||||
PrintAndLog(" %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
|
||||
PrintAndLog(" %02x: Physical Memory Size of this tag: %d bytes", data[2], (data[2] + 1) * 8);
|
||||
PrintAndLog(" %02x: %s / %s", data[3],
|
||||
(data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security",
|
||||
(data[3] & 0x0F)==0 ? "Write access granted without any security" : (data[3] & 0x0F)==0x0F ? "No write access granted at all" : "(RFU)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void get_TLV(uint8_t **TLV_ptr, uint8_t *tag, uint16_t *length, uint8_t **value)
|
||||
{
|
||||
*length = 0;
|
||||
*value = NULL;
|
||||
|
||||
*tag = **TLV_ptr;
|
||||
*TLV_ptr += 1;
|
||||
switch (*tag) {
|
||||
case 0x00: // NULL TLV.
|
||||
case 0xFE: // Terminator TLV.
|
||||
break;
|
||||
case 0x01: // Lock Control TLV
|
||||
case 0x02: // Reserved Memory TLV
|
||||
case 0x03: // NDEF message TLV
|
||||
case 0xFD: // proprietary TLV
|
||||
*length = **TLV_ptr;
|
||||
*TLV_ptr += 1;
|
||||
if (*length == 0xff) {
|
||||
*length = **TLV_ptr << 8;
|
||||
*TLV_ptr += 1;
|
||||
*length |= **TLV_ptr;
|
||||
*TLV_ptr += 1;
|
||||
}
|
||||
*value = *TLV_ptr;
|
||||
*TLV_ptr += *length;
|
||||
break;
|
||||
default: // RFU
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool topaz_print_lock_control_TLVs(uint8_t *memory)
|
||||
{
|
||||
uint8_t *TLV_ptr = memory;
|
||||
uint8_t tag = 0;
|
||||
uint16_t length;
|
||||
uint8_t *value;
|
||||
bool lock_TLV_present = false;
|
||||
|
||||
while(*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) {
|
||||
// all Lock Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV)
|
||||
get_TLV(&TLV_ptr, &tag, &length, &value);
|
||||
if (tag == 0x01) { // the Lock Control TLV
|
||||
uint8_t pages_addr = value[0] >> 4;
|
||||
uint8_t byte_offset = value[0] & 0x0f;
|
||||
uint8_t size_in_bits = value[1] ? value[1] : 256;
|
||||
uint8_t bytes_per_page = 1 << (value[2] & 0x0f);
|
||||
uint8_t bytes_locked_per_bit = 1 << (value[2] >> 4);
|
||||
PrintAndLog("Lock Area of %d bits at byte offset 0x%02x. Each Lock Bit locks %d bytes.",
|
||||
size_in_bits,
|
||||
pages_addr * bytes_per_page + byte_offset,
|
||||
bytes_locked_per_bit);
|
||||
lock_TLV_present = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lock_TLV_present) {
|
||||
PrintAndLog("(No Lock Control TLV present)");
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int topaz_print_reserved_memory_control_TLVs(uint8_t *memory)
|
||||
{
|
||||
uint8_t *TLV_ptr = memory;
|
||||
uint8_t tag = 0;
|
||||
uint16_t length;
|
||||
uint8_t *value;
|
||||
bool reserved_memory_control_TLV_present = false;
|
||||
|
||||
while(*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) {
|
||||
// all Reserved Memory Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV)
|
||||
get_TLV(&TLV_ptr, &tag, &length, &value);
|
||||
if (tag == 0x02) { // the Reserved Memory Control TLV
|
||||
uint8_t pages_addr = value[0] >> 4;
|
||||
uint8_t byte_offset = value[0] & 0x0f;
|
||||
uint8_t size_in_bytes = value[1] ? value[1] : 256;
|
||||
uint8_t bytes_per_page = 1 << (value[2] & 0x0f);
|
||||
PrintAndLog("Reserved Memory of %d bytes at byte offset 0x%02x.",
|
||||
size_in_bytes,
|
||||
pages_addr * bytes_per_page + byte_offset);
|
||||
reserved_memory_control_TLV_present = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reserved_memory_control_TLV_present) {
|
||||
PrintAndLog("(No Reserved Memory Control TLV present)");
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void topaz_print_lifecycle_state(uint8_t *data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void topaz_print_NDEF(uint8_t *data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int CmdHFTopazReader(const char *Cmd)
|
||||
{
|
||||
int status;
|
||||
uint8_t atqa[2];
|
||||
uint8_t rid_response[8];
|
||||
uint8_t *uid_echo = &rid_response[2];
|
||||
uint8_t rall_response[124];
|
||||
|
||||
status = topaz_select(atqa, rid_response);
|
||||
|
||||
if (status == -1) {
|
||||
PrintAndLog("Error: couldn't receive ATQA");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PrintAndLog("ATQA : %02x %02x", atqa[1], atqa[0]);
|
||||
if (atqa[1] != 0x0c && atqa[0] != 0x00) {
|
||||
PrintAndLog("Tag doesn't support the Topaz protocol.");
|
||||
topaz_switch_off_field();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status == -2) {
|
||||
PrintAndLog("Error: tag didn't answer to RID");
|
||||
topaz_switch_off_field();
|
||||
return -1;
|
||||
}
|
||||
|
||||
topaz_tag.HR01[0] = rid_response[0];
|
||||
topaz_tag.HR01[1] = rid_response[1];
|
||||
|
||||
// ToDo: CRC check
|
||||
PrintAndLog("HR0 : %02x (%sa Topaz tag (%scapable of carrying a NDEF message), %s memory map)", rid_response[0],
|
||||
(rid_response[0] & 0xF0) == 0x10 ? "" : "not ",
|
||||
(rid_response[0] & 0xF0) == 0x10 ? "" : "not ",
|
||||
(rid_response[0] & 0x0F) == 0x10 ? "static" : "dynamic");
|
||||
PrintAndLog("HR1 : %02x", rid_response[1]);
|
||||
|
||||
status = topaz_rall(uid_echo, rall_response);
|
||||
|
||||
if(status == -1) {
|
||||
PrintAndLog("Error: tag didn't answer to RALL");
|
||||
topaz_switch_off_field();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(topaz_tag.uid, rall_response+2, 7);
|
||||
PrintAndLog("UID : %02x %02x %02x %02x %02x %02x %02x",
|
||||
topaz_tag.uid[6],
|
||||
topaz_tag.uid[5],
|
||||
topaz_tag.uid[4],
|
||||
topaz_tag.uid[3],
|
||||
topaz_tag.uid[2],
|
||||
topaz_tag.uid[1],
|
||||
topaz_tag.uid[0]);
|
||||
PrintAndLog(" UID[6] (Manufacturer Byte) = %02x, Manufacturer: %s",
|
||||
topaz_tag.uid[6],
|
||||
getTagInfo(topaz_tag.uid[6]));
|
||||
|
||||
memcpy(topaz_tag.data_blocks, rall_response+2, 0x10*8);
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Static Data blocks 00 to 0c:");
|
||||
PrintAndLog("block# | offset | Data | Locked?");
|
||||
char line[80];
|
||||
for (uint16_t i = 0; i <= 0x0c; i++) {
|
||||
for (uint16_t j = 0; j < 8; j++) {
|
||||
sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[i][j] /*rall_response[2 + 8*i + j]*/);
|
||||
}
|
||||
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", i, i*8, line, topaz_block_is_locked(i, &topaz_tag.data_blocks[0x0d][0]) ? "yes" : "no");
|
||||
}
|
||||
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Static Reserved block 0d:");
|
||||
for (uint16_t j = 0; j < 8; j++) {
|
||||
sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[0x0d][j]);
|
||||
}
|
||||
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", 0x0d, 0x0d*8, line, "n/a");
|
||||
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Static Lockbits and OTP Bytes:");
|
||||
for (uint16_t j = 0; j < 8; j++) {
|
||||
sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[0x0e][j]);
|
||||
}
|
||||
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e*8, line, "n/a");
|
||||
|
||||
PrintAndLog("");
|
||||
|
||||
status = topaz_print_CC(&topaz_tag.data_blocks[1][0]);
|
||||
|
||||
if (status == -1) {
|
||||
PrintAndLog("No NDEF message present");
|
||||
topaz_switch_off_field();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PrintAndLog("");
|
||||
bool lock_TLV_present = topaz_print_lock_control_TLVs(&topaz_tag.data_blocks[1][4]);
|
||||
|
||||
PrintAndLog("");
|
||||
bool reserved_mem_present = topaz_print_reserved_memory_control_TLVs(&topaz_tag.data_blocks[1][4]);
|
||||
|
||||
topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]);
|
||||
|
||||
topaz_print_NDEF(&topaz_tag.data_blocks[1][0]);
|
||||
|
||||
topaz_switch_off_field();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHFTopazSim(const char *Cmd)
|
||||
{
|
||||
PrintAndLog("not yet implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHFTopazCmdRaw(const char *Cmd)
|
||||
{
|
||||
PrintAndLog("not yet implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"reader", CmdHFTopazReader, 0, "Act like a Topaz reader"},
|
||||
{"sim", CmdHFTopazSim, 0, "<UID> -- Simulate Topaz tag"},
|
||||
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop a Topaz reader-tag communication"},
|
||||
{"raw", CmdHFTopazCmdRaw, 0, "Send raw hex data to tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
int CmdHFTopaz(const char *Cmd) {
|
||||
// flush
|
||||
WaitForResponseTimeout(CMD_ACK,NULL,100);
|
||||
|
||||
// parse
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -23,9 +23,11 @@
|
|||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static void lookupChipID(uint32_t iChipID)
|
||||
static void lookupChipID(uint32_t iChipID, uint32_t mem_used)
|
||||
{
|
||||
char asBuff[100];
|
||||
uint32_t mem_avail = 0;
|
||||
|
||||
switch(iChipID)
|
||||
{
|
||||
case 0x270B0A40:
|
||||
|
@ -103,37 +105,43 @@ static void lookupChipID(uint32_t iChipID)
|
|||
switch((iChipID&0xF00)>>8)
|
||||
{
|
||||
case 0:
|
||||
sprintf(asBuff,"None");
|
||||
mem_avail = 0;
|
||||
break;
|
||||
case 1:
|
||||
sprintf(asBuff,"8K bytes");
|
||||
mem_avail = 8;
|
||||
break;
|
||||
case 2:
|
||||
sprintf(asBuff,"16K bytes");
|
||||
mem_avail = 16;
|
||||
break;
|
||||
case 3:
|
||||
sprintf(asBuff,"32K bytes");
|
||||
mem_avail = 32;
|
||||
break;
|
||||
case 5:
|
||||
sprintf(asBuff,"64K bytes");
|
||||
mem_avail = 64;
|
||||
break;
|
||||
case 7:
|
||||
sprintf(asBuff,"128K bytes");
|
||||
mem_avail = 128;
|
||||
break;
|
||||
case 9:
|
||||
sprintf(asBuff,"256K bytes");
|
||||
mem_avail = 256;
|
||||
break;
|
||||
case 10:
|
||||
sprintf(asBuff,"512K bytes");
|
||||
mem_avail = 512;
|
||||
break;
|
||||
case 12:
|
||||
sprintf(asBuff,"1024K bytes");
|
||||
mem_avail = 1024;
|
||||
break;
|
||||
case 14:
|
||||
sprintf(asBuff,"2048K bytes");
|
||||
mem_avail = 2048;
|
||||
break;
|
||||
}
|
||||
PrintAndLog("Nonvolatile Program Memory Size: %s",asBuff);
|
||||
PrintAndLog("Nonvolatile Program Memory Size: %dK bytes. Used: %d bytes (%2.0f\%). Free: %d bytes (%2.0f\%).",
|
||||
mem_avail,
|
||||
mem_used,
|
||||
mem_avail == 0 ? 0 : (float)mem_used/(mem_avail*1024)*100,
|
||||
mem_avail*1024 - mem_used,
|
||||
mem_avail == 0 ? 0 : (float)(mem_avail*1024-mem_used)/(mem_avail*1024)*100
|
||||
);
|
||||
switch((iChipID&0xF000)>>12)
|
||||
{
|
||||
case 0:
|
||||
|
@ -400,7 +408,7 @@ int CmdVersion(const char *Cmd)
|
|||
UsbCommand resp;
|
||||
SendCommand(&c);
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
|
||||
lookupChipID(resp.arg[0]);
|
||||
lookupChipID(resp.arg[0], resp.arg[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
221
client/fpga_compress.c
Normal file
221
client/fpga_compress.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Flasher frontend tool
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sleep.h"
|
||||
#include "proxmark3.h"
|
||||
#include "flash.h"
|
||||
#include "uart.h"
|
||||
#include "usb_cmd.h"
|
||||
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
struct huffman_record {
|
||||
int16_t symbol;
|
||||
uint16_t count;
|
||||
uint8_t code_size;
|
||||
uint8_t code;
|
||||
struct huffman_record *left;
|
||||
struct huffman_record *right;
|
||||
struct huffman_record *next;
|
||||
};
|
||||
|
||||
typedef struct huffman_record huffman_record_t;
|
||||
|
||||
#define FPGA_CONFIG_SIZE 42175
|
||||
static uint8_t fpga_config[FPGA_CONFIG_SIZE];
|
||||
static huffman_record_t leaf_nodes[256];
|
||||
static uint8_t start_code[256];
|
||||
|
||||
static void usage(char *argv0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d] <infile> <outfile>\n\n", argv0);
|
||||
fprintf(stderr, "\t-d\tdecompress\n\n");
|
||||
}
|
||||
|
||||
|
||||
void add_to_heap(huffman_record_t **heap, huffman_record_t *new_record)
|
||||
{
|
||||
huffman_record_t *succ = *heap;
|
||||
huffman_record_t *pred = NULL;
|
||||
|
||||
// fprintf(stderr, "Adding symbol %d, count %d\n", new_record->symbol, new_record->count);
|
||||
|
||||
while (succ != NULL && new_record->count > succ->count) {
|
||||
pred = succ;
|
||||
succ = succ->next;
|
||||
}
|
||||
|
||||
// insert new record
|
||||
new_record->next = succ;
|
||||
if (pred == NULL) { // first record in heap
|
||||
*heap = new_record;
|
||||
} else {
|
||||
pred->next = new_record;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t set_codesize(huffman_record_t *tree_ptr, uint8_t depth)
|
||||
{
|
||||
uint16_t max_size = depth;
|
||||
tree_ptr->code_size = depth;
|
||||
if (tree_ptr->left != NULL) {
|
||||
max_size = MAX(set_codesize(tree_ptr->left, depth+1), max_size);
|
||||
}
|
||||
if (tree_ptr->right != NULL) {
|
||||
max_size = MAX(set_codesize(tree_ptr->right, depth+1), max_size);
|
||||
}
|
||||
return max_size;
|
||||
}
|
||||
|
||||
int huffman_encode(FILE *infile, FILE *outfile)
|
||||
{
|
||||
int i;
|
||||
|
||||
// init leaf_nodes:
|
||||
for (i = 0; i < 256; i++) {
|
||||
leaf_nodes[i].count = 0;
|
||||
leaf_nodes[i].symbol = i;
|
||||
leaf_nodes[i].left = NULL;
|
||||
leaf_nodes[i].right = NULL;
|
||||
leaf_nodes[i].next = NULL;
|
||||
}
|
||||
|
||||
// read the input file into fpga_config[] and count occurrences of each symbol:
|
||||
i = 0;
|
||||
while(!feof(infile)) {
|
||||
uint8_t c;
|
||||
c = fgetc(infile);
|
||||
fpga_config[i++] = c;
|
||||
leaf_nodes[c].count++;
|
||||
if (i > FPGA_CONFIG_SIZE+1) {
|
||||
fprintf(stderr, "Input file too big (> %d bytes). This is probably not a PM3 FPGA config file.", FPGA_CONFIG_SIZE);
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "\nStatistics: (symbol: count)\n");
|
||||
for (i = 0; i < 256; i++) {
|
||||
fprintf(stderr, "%3d: %5d\n", i, leaf_nodes[i].count);
|
||||
}
|
||||
|
||||
// build the Huffman tree:
|
||||
huffman_record_t *heap_ptr = NULL;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
add_to_heap(&heap_ptr, &leaf_nodes[i]);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\nSorted statistics: (symbol: count)\n");
|
||||
for (huffman_record_t *p = heap_ptr; p != NULL; p = p->next) {
|
||||
fprintf(stderr, "%3d: %5d\n", p->symbol, p->count);
|
||||
}
|
||||
|
||||
for (i = 0; i < 255; i++) {
|
||||
// remove and combine the first two nodes
|
||||
huffman_record_t *p1, *p2;
|
||||
p1 = heap_ptr;
|
||||
p2 = heap_ptr->next;
|
||||
heap_ptr = p2->next;
|
||||
huffman_record_t *new_node = malloc(sizeof(huffman_record_t));
|
||||
new_node->left = p1;
|
||||
new_node->right = p2;
|
||||
new_node->count = p1->count + p2->count;
|
||||
add_to_heap(&heap_ptr, new_node);
|
||||
}
|
||||
|
||||
uint16_t max_codesize = set_codesize(heap_ptr, 0);
|
||||
|
||||
fprintf(stderr, "\nStatistics: (symbol: count, codesize)\n");
|
||||
uint32_t compressed_size = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
fprintf(stderr, "%3d: %5d, %d\n", leaf_nodes[i].symbol, leaf_nodes[i].count, leaf_nodes[i].code_size);
|
||||
compressed_size += leaf_nodes[i].count * leaf_nodes[i].code_size;
|
||||
}
|
||||
fprintf(stderr, "Compressed size = %ld (%f% of original size)", (compressed_size+7)/8, (float)(compressed_size)/(FPGA_CONFIG_SIZE * 8) * 100);
|
||||
fprintf(stderr, "Max Codesize = %d bits", max_codesize);
|
||||
|
||||
uint8_t code = 0;
|
||||
for (i = max_codesize; i > 0; i--) {
|
||||
code = (code + 1) >> 1;
|
||||
start_code[i] = code;
|
||||
for (uint16_t j = 0; j < 256; j++) {
|
||||
if (leaf_nodes[j].code_size == i) {
|
||||
leaf_nodes[j].code = code;
|
||||
code++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fprintf(stderr, "\nStatistics: (symbol: count, codesize, code)\n");
|
||||
for (i = 0; i < 256; i++) {
|
||||
fprintf(stderr, "%3d: %5d, %d, %02x\n", leaf_nodes[i].symbol, leaf_nodes[i].count, leaf_nodes[i].code_size, leaf_nodes[i].code);
|
||||
}
|
||||
|
||||
fclose(infile);
|
||||
fclose(outfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int huffman_decode(FILE *infile, FILE *outfile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool decode = false;
|
||||
char *infilename;
|
||||
char *outfilename;
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
if (!strcmp(argv[1], "-d")) {
|
||||
decode = true;
|
||||
infilename = argv[2];
|
||||
outfilename = argv[3];
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
infilename = argv[1];
|
||||
outfilename = argv[2];
|
||||
}
|
||||
|
||||
FILE *infile = fopen(infilename, "rb");
|
||||
if (infile == NULL) {
|
||||
fprintf(stderr, "Error. Cannot open input file %s", infilename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *outfile = fopen(outfilename, "wb");
|
||||
if (outfile == NULL) {
|
||||
fprintf(stderr, "Error. Cannot open output file %s", outfilename);
|
||||
fclose(infile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (decode) {
|
||||
return huffman_decode(infile, outfile);
|
||||
} else {
|
||||
return huffman_encode(infile, outfile);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue