PATCH(1/2) libdl and rtems-tools. Add zlib compression for rap files
Сергей Круглов
sergkruglov at bk.ru
Tue Feb 26 07:05:15 UTC 2019
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 != ',')
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20190226/0ee3356f/attachment-0001.html>
More information about the users
mailing list