cpukit/include/rtems/rtl/rtl-obj-comp.h cpukit/libdl/rtl-obj-comp.c cpukit/libdl/rtl-rap.c
diff -Naur cpukit/include/rtl/rtl-obj-comp.h cpukit_patched/include/rtl/rtl-obj-comp.h --- cpukit/include/rtl/rtl-obj-comp.h 2018-10-22 15:05:16 +0400 +++ cpukit_patched/include/rtl/rtl-obj-comp.h 2019-02-15 16:46:26 +0400 @@ -39,6 +39,7 @@ */ #define RTEMS_RTL_COMP_NONE (0) #define RTEMS_RTL_COMP_LZ77 (1) +#define RTEMS_RTL_COMP_ZLIB (2) /** * The compressed file. diff -Naur cpukit/libdl/rtl-obj-comp.c cpukit_patched/libdl/rtl-obj-comp.c --- libdl/rtl-obj-comp.c 2018-10-22 15:05:18 +0400 +++ libdl_patched/rtl-obj-comp.c 2019-02-21 14:08:27 +0400 @@ -28,8 +28,19 @@ #include "fastlz.h" +#include <zlib.h> + #include <stdio.h> +static unsigned write_z; +static unsigned have_z; +static unsigned char *in_z; +static unsigned char *out_z; +static unsigned char *ptr_in; +static unsigned char *ptr_out; +static z_stream strm; +static bool start; + bool rtems_rtl_obj_comp_open (rtems_rtl_obj_comp* comp, size_t size) @@ -46,7 +57,23 @@ rtems_rtl_set_error (ENOMEM, "no memory for compressor buffer"); return false; } + in_z = rtems_rtl_alloc_new(RTEMS_RTL_ALLOC_OBJECT, size, false); + if (!in_z) + { + rtems_rtl_set_error(ENOMEM, "no memory for compressor buffer"); + rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, comp->buffer); + return false; + } + out_z = rtems_rtl_alloc_new(RTEMS_RTL_ALLOC_OBJECT, comp->size * 3, false); + if (!out_z) + { + rtems_rtl_set_error(ENOMEM, "no memory for compressor buffer"); + rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, comp->buffer); + rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, in_z); + return false; + } comp->read = 0; + start = true; return true; } @@ -54,6 +81,10 @@ rtems_rtl_obj_comp_close (rtems_rtl_obj_comp* comp) { rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, comp->buffer); + rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, out_z); + rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, in_z); + if (comp->compression == RTEMS_RTL_COMP_ZLIB) + (void) inflateEnd(&strm); comp->cache = NULL; comp->fd = -1; comp->compression = RTEMS_RTL_COMP_LZ77; @@ -61,6 +92,7 @@ comp->size = 0; comp->offset = 0; comp->read = 0; + start = true; } void @@ -70,6 +102,12 @@ int compression, off_t offset) { + if (!start) + { + start = true; + if (compression == RTEMS_RTL_COMP_ZLIB) + (void) inflateEnd(&strm); + } comp->cache = cache; comp->fd = fd; comp->compression = compression; @@ -77,13 +115,13 @@ comp->level = 0; comp->read = 0; } - bool rtems_rtl_obj_comp_read (rtems_rtl_obj_comp* comp, void* buffer, size_t length) { uint8_t* bin = buffer; + int ret_z; if (!comp->cache) { @@ -126,25 +164,32 @@ size_t in_length = sizeof (block_size); int decompressed; - if (!rtems_rtl_obj_cache_read (comp->cache, comp->fd, comp->offset, - (void**) &input, &in_length)) - return false; - - block_size = (input[0] << 8) | input[1]; - - comp->offset += sizeof (block_size); + block_size = length > 2048 ? 2048 : length; + + if (comp->compression == RTEMS_RTL_COMP_LZ77) + { + if (!rtems_rtl_obj_cache_read(comp->cache, comp->fd, + comp->offset, (void**) &input, &in_length)) + return false; + block_size = (input[0] << 8) | input[1]; + comp->offset += sizeof(block_size); + } in_length = block_size; - if (!rtems_rtl_obj_cache_read (comp->cache, comp->fd, comp->offset, - (void**) &input, &in_length)) - return false; - - if (in_length != block_size) + if ((comp->compression == RTEMS_RTL_COMP_NONE) || + (comp->compression == RTEMS_RTL_COMP_LZ77)) { - rtems_rtl_set_error (EIO, "compressed read failed: bs=%u in=%zu", - block_size, in_length); - return false; + if (!rtems_rtl_obj_cache_read(comp->cache, comp->fd, + comp->offset, (void**) &input, &in_length)) + return false; + + if (in_length != block_size) + { + rtems_rtl_set_error(EIO,"compressed read failed: bs=%u in=%u", + block_size, in_length); + return false; + } } switch (comp->compression) @@ -152,6 +197,7 @@ case RTEMS_RTL_COMP_NONE: memcpy (comp->buffer, input, in_length); decompressed = in_length; + comp->offset += block_size; break; case RTEMS_RTL_COMP_LZ77: @@ -162,15 +208,79 @@ rtems_rtl_set_error (EBADF, "decompression failed"); return false; } + comp->offset += block_size; break; + case RTEMS_RTL_COMP_ZLIB: + if (start) + { + start = false; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret_z = inflateInit(&strm); + if (ret_z != Z_OK) + { + rtems_rtl_set_error(EBADF, "Invalid init inflate"); + return false; + } + ptr_in = out_z; + have_z = 0; + } + ptr_out = comp->buffer; + write_z = 0; + while (1) + { + while (have_z > 0) + { + write_z = have_z > (block_size - (ptr_out - comp->buffer)) ? + block_size - (ptr_out - comp->buffer) : have_z; + memcpy(ptr_out, ptr_in, write_z); + ptr_out += write_z; + ptr_in += write_z; + have_z -= write_z; + if ((ptr_out - comp->buffer) == block_size) + break; + } + if ((ptr_out - comp->buffer) == block_size) + break; + if (strm.avail_in == 0) + { + strm.avail_in = comp->size; + if (!rtems_rtl_obj_cache_read(comp->cache, comp->fd, + comp->offset, (void**) &in_z, &strm.avail_in)) + return false; + comp->offset += strm.avail_in; + if (strm.avail_in == 0) + break; + strm.next_in = in_z; + } + strm.avail_out = comp->size * 3; + strm.next_out = out_z; + ptr_in = out_z; + ret_z = inflate(&strm, Z_NO_FLUSH); + if ((ret_z == Z_STREAM_ERROR) || (ret_z == Z_NEED_DICT) || + (ret_z == Z_DATA_ERROR) || (ret_z == Z_MEM_ERROR)) + { + rtems_rtl_set_error(EBADF, "Invalid inflate"); + return false; + } + have_z = comp->size * 3 - strm.avail_out; + } + decompressed = ptr_out - comp->buffer; + if (decompressed == 0) + { + rtems_rtl_set_error(EBADF, "decompression failed"); + return false; + } + break; default: rtems_rtl_set_error (EINVAL, "bad compression type"); return false; } - comp->offset += block_size; - comp->level = decompressed; } } diff -Naur cpukit/libdl/rtl-rap.c cpukit_patched/libdl/rtl-rap.c --- libdl/rtl-rap.c 2019-02-18 16:36:20 +0400 +++ libdl_patched/rtl-rap.c 2019-02-21 11:23:33 +0400 @@ -626,6 +626,10 @@ if (rtems_rtl_symbol_global_find (rap->strtab + name) && (ELF_ST_BIND (data & 0xffff) != STB_WEAK)) { + printf("Warning:duplicate global symbol: %s, use kernel symbol\n", rap->strtab + name); + obj->global_syms--; // for use --gc-sections (ld) and -ffunction-sections -fdata-sections (gcc) + continue; +/* rtems_rtl_set_error (EINVAL, "duplicate global symbol: %s", rap->strtab + name); rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->global_table); @@ -633,6 +637,7 @@ obj->global_syms = 0; obj->global_size = 0; return false; +*/ } symsect = rtems_rtl_obj_find_section_by_index (obj, data >> 16); @@ -731,7 +736,15 @@ *compression = RTEMS_RTL_COMP_LZ77; eptr = sptr + 4; } - else + else if ((sptr[0] == 'Z') && + (sptr[1] == 'L') && + (sptr[2] == 'I') && + (sptr[3] == 'B')) + { + *compression = RTEMS_RTL_COMP_ZLIB; + eptr = sptr + 4; + } + else return false; if (*eptr != ',')
_______________________________________________ users mailing list users@rtems.org http://lists.rtems.org/mailman/listinfo/users