PATCH(2/2) libdl and rtems-tools. Add zlib compression for rap files

Сергей Круглов sergkruglov at bk.ru
Tue Feb 26 07:11:14 UTC 2019


rtems-tools/linkers/rtems-ld.cpp
rtems-tools/linkers/rtems-ra.cpp
rtems-tools/linkers/rtems-rapper.cpp
rtems-tools/linkers/wscript
rtems-tools/rtemstoolkit/rld-compression.cpp
rtems-tools/rtemstoolkit/rld-compression.h
rtems-tools/rtemstoolkit/rld-outputter.cpp
rtems-tools/rtemstoolkit/rld-outputter.h
rtems-tools/rtemstoolkit/rld-rap.cpp
rtems-tools/rtemstoolkit/rld-rap.h


diff -Naur rtems-tools/linkers/rtems-ld.cpp rtems-tools_patched/linkers/rtems-ld.cpp
--- rtems-tools/linkers/rtems-ld.cpp    2018-12-03 11:40:06 +0400
+++ rtems-tools_patched/linkers/rtems-ld.cpp    2019-02-21 16:07:57 +0400
@@ -76,6 +76,7 @@
   { "one-file",    no_argument,            NULL,           's' },
   { "rtems",       required_argument,      NULL,           'r' },
   { "rtems-bsp",   required_argument,      NULL,           'B' },
+  { "compress",    required_argument,      NULL,           'z' },
   { NULL,          0,                      NULL,            0 }
};

@@ -119,6 +120,7 @@
             << " -R        : include file paths (also --rpath)" << std::endl
             << " -P        : place objects from archives (also --runtime-lib)" << std::endl
             << " -s        : Include archive elf object files (also --one-file)" << std::endl
+            << " -z        : Compression algorithm 0,1,2 (default 1) NONE, LZ77, ZLIB" << std::endl
             << " -Wl,opts  : link compatible flags, ignored" << std::endl
             << " -r path   : RTEMS path (also --rtems)" << std::endl
             << " -B bsp    : RTEMS arch/bsp (also --rtems-bsp)" << std::endl
@@ -192,6 +194,7 @@
     std::string          output = "a.out";
     std::string          outra;
     std::string          base_name;
+    std::string          algorithm = "1";
     std::string          output_type = "rap";
     bool                 standard_libs = true;
     bool                 map = false;
@@ -204,7 +207,7 @@

     while (true)
     {
-      int opt = ::getopt_long (argc, argv, "hvwVMnsSb:E:o:O:L:l:c:e:d:u:C:W:R:P:r:B:", rld_opts, NULL);
+      int opt = ::getopt_long (argc, argv, "hvwVMnsSb:E:o:O:L:l:c:e:d:u:z:C:W:R:P:r:B:", rld_opts, NULL);
       if (opt < 0)
         break;

@@ -301,6 +304,10 @@
           base_name = optarg;
           break;

+        case 'z':
+          algorithm = optarg;
+          break;
+
         case 'S':
           rld::rap::add_obj_details = false;
           break;
@@ -504,9 +511,13 @@
                                            dependents, cache);
         else if (output_type == "rap")
         {
-          rld::outputter::rap_application (output, entry, exit,
-                                           dependents, cache, symbols,
-                                           one_file);
+          int i = atoi(algorithm.c_str());
+
+          if ((i < 0) || (i > 2))
+            rld::error("Unknown compression", "output");
+
+          rld::outputter::rap_application(output, entry, exit, dependents,
+                            cache, symbols, one_file, i);
           if (!outra.empty ())
           {
             rld::path::paths ra_libs;
diff -Naur rtems-tools/linkers/rtems-ra.cpp rtems-tools_patched/linkers/rtems-ra.cpp
--- rtems-tools/linkers/rtems-ra.cpp    2018-12-03 11:40:06 +0400
+++ rtems-tools_patched/linkers/rtems-ra.cpp    2019-02-21 16:08:04 +0400
@@ -376,8 +376,8 @@
             /* Todo: include absolute name for rap_name */

             rld::outputter::rap_application (rap_name, entry, exit,
-                                             dependents, *cache, symbols,
-                                             true);
+                                         dependents, *cache, symbols,
+                                         true, 1);
           }

           dependents.clear ();
diff -Naur rtems-tools/linkers/rtems-rapper.cpp rtems-tools_patched/linkers/rtems-rapper.cpp
--- rtems-tools/linkers/rtems-rapper.cpp    2018-12-03 11:40:05 +0400
+++ rtems-tools_patched/linkers/rtems-rapper.cpp    2019-02-21 14:36:07 +0400
@@ -468,6 +468,14 @@
       rhdr_compression = "LZ77";
       eptr = sptr + 4;
     }
+    else if ((sptr[0] == 'Z') &&
+             (sptr[1] == 'L') &&
+             (sptr[2] == 'I') &&
+             (sptr[3] == 'B'))
+    {
+      rhdr_compression = "ZLIB";
+      eptr = sptr + 4;
+    }
     else
       throw rld::error ("Cannot parse RAP header", "open: " + name);

@@ -543,8 +551,15 @@
   file::load ()
   {
     image.seek (rhdr_len);
+    int i;
+    if (rhdr_compression == "NONE")
+      i = 0;
+    if (rhdr_compression == "LZ77")
+      i = 1;
+    if (rhdr_compression == "ZLIB")
+      i = 2;

-    rld::compress::compressor comp (image, rap_comp_buffer, false);
+    rld::compress::compressor comp (image, rap_comp_buffer, false, i);

     /*
      * uint32_t: machinetype
@@ -645,7 +660,15 @@

     image.seek (rhdr_len);

-    rld::compress::compressor comp (image, rap_comp_buffer, false);
+        int i;
+    if (rhdr_compression == "NONE")
+      i = 0;
+    if (rhdr_compression == "LZ77")
+      i = 1;
+    if (rhdr_compression == "ZLIB")
+      i = 2;
+    rld::compress::compressor comp (image, rap_comp_buffer, false, i);
+
     rld::files::image         out (name);

     out.open (true);
diff -Naur rtems-tools/linkers/wscript rtems-tools_patched/linkers/wscript
--- rtems-tools/linkers/wscript    2018-06-19 10:43:47 +0400
+++ rtems-tools_patched/linkers/wscript    2019-02-21 14:28:43 +0400
@@ -90,6 +90,7 @@
                 cflags = conf['cflags'] + conf['warningflags'],
                 cxxflags = conf['cxxflags'] + conf['warningflags'],
                 linkflags = conf['linkflags'],
+                lib = ['z'],
                 use = modules)

     #
@@ -102,6 +103,7 @@
                 cflags = conf['cflags'] + conf['warningflags'],
                 cxxflags = conf['cxxflags'] + conf['warningflags'],
                 linkflags = conf['linkflags'],
+                lib = ['z'],
                 use = modules)

     #
@@ -140,6 +142,7 @@
                 cflags = conf['cflags'] + conf['warningflags'],
                 cxxflags = conf['cxxflags'] + conf['warningflags'],
                 linkflags = conf['linkflags'],
+                lib = ['z'],
                 use = modules)

     #
@@ -152,6 +155,7 @@
                 cflags = conf['cflags'] + conf['warningflags'],
                 cxxflags = conf['cxxflags'] + conf['warningflags'],
                 linkflags = conf['linkflags'],
+                lib = ['z'],
                 use = modules)

     #
diff -Naur rtems-tools/rtemstoolkit/rld-compression.cpp rtems-tools_patched/rtemstoolkit/rld-compression.cpp
--- rtems-tools/rtemstoolkit/rld-compression.cpp    2017-09-18 15:01:39 +0400
+++ rtems-tools_patched/rtemstoolkit/rld-compression.cpp    2019-02-21 16:08:37 +0400
@@ -35,8 +35,18 @@
#include <rld.h>
#include <rld-compression.h>

+#include <zlib.h>
#include "fastlz.h"

+static int ret_z;
+static unsigned have_z, wr, count_z;
+static z_stream strm;
+static unsigned char *in_z;
+static unsigned char *out_z;
+static unsigned char *ptr_in;
+static unsigned char *ptr_out;
+#define CHUNK 16384
+
namespace rld
{
   namespace compress
@@ -44,7 +54,7 @@
     compressor::compressor (files::image& image,
                             size_t        size,
                             bool          out,
-                            bool          compress)
+                            int           compress)
       : image (image),
         size (size),
         out (out),
@@ -234,32 +244,64 @@
     void
     compressor::output (bool forced)
     {
-      if (out && ((forced && level) || (level >= size)))
-      {
-        if (compress)
+        if (out && ((forced && level) || (level >= size)))
         {
-          int     writing = ::fastlz_compress (buffer, level, io);
-          uint8_t header[2];
-
-          if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
-            std::cout << "rtl: comp: offset=" << total_compressed
-                      << " block-size=" << writing << std::endl;
-
-          header[0] = writing >> 8;
-          header[1] = writing;
-
-          image.write (header, 2);
-          image.write (io, writing);
-
-          total_compressed += 2 + writing;
+            switch (compress) {
+              case 0: {
+                image.write(buffer, level);
+                total_compressed += level;
+                break;
+              }
+              case 1: {
+                int writing = ::fastlz_compress(buffer, level, io);
+                uint8_t header[2];
+                if (rld::verbose() >= RLD_VERBOSE_FULL_DEBUG)
+                     std::cout << "rtl: comp: offset=" << total_compressed 
+                               << " block-size=" << writing << std::endl;
+                header[0] = writing >> 8;
+                header[1] = writing;
+                image.write(header, 2);
+                image.write(io, writing);
+                total_compressed += 2 + writing;
+                break;
+              }
+              case 2: {
+                if (start)
+                {
+                  start = false;
+                  strm.zalloc = Z_NULL;
+                  strm.zfree = Z_NULL;
+                  strm.opaque = Z_NULL;
+                  out_z = new uint8_t[CHUNK];
+                  ret_z = ::deflateInit(&strm, Z_BEST_COMPRESSION);
+                  if (ret_z != Z_OK)
+                          throw rld::error("Invalid init deflate", "compression");
+                }
+                int flush = (forced != 0) ? Z_FINISH : Z_NO_FLUSH;
+                strm.next_in = buffer;
+                strm.avail_in = level;
+                do
+                {
+                  strm.avail_out = CHUNK;
+                  strm.next_out = out_z;
+                  ret_z = ::deflate(&strm, flush);
+                  if (ret_z == Z_STREAM_ERROR)
+                          throw rld::error("Invalid deflate", "compression");
+                  have_z = CHUNK - strm.avail_out;
+                  image.write(out_z, have_z);
+                  total_compressed += have_z;
+                } while (strm.avail_out == 0);
+                if (forced != 0)
+                {
+                  start = true;
+                  delete[] out_z;
+                  (void) ::deflateEnd(&strm);
+                }
+                break;
+              }
+            }
+            level = 0;
         }
-        else
-        {
-          image.write (buffer, level);
-        }
-
-        level = 0;
-      }
     }

     void
@@ -267,37 +309,100 @@
     {
       if (!out && (level == 0))
       {
-        if (compress)
-        {
-          uint8_t header[2];
-
-          if (image.read (header, 2) == 2)
-          {
-            ssize_t block_size =
-              (((ssize_t) header[0]) << 8) | (ssize_t) header[1];
-
-            if (block_size == 0)
-              throw rld::error ("Block size is invalid (0)", "compression");
-
-            total_compressed += 2 + block_size;
-
-            if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
-              std::cout << "rtl: decomp: block-size=" << block_size
-                        << std::endl;
-
-            if (image.read (io, block_size) != block_size)
-              throw rld::error ("Read past end", "compression");
-
-            level = ::fastlz_decompress (io, block_size, buffer, size);
+        switch (compress) {
+          case 0: {
+            level = image.read(buffer, size);
+            total_compressed += level;
+            break;
+          }
+          case 1: {
+            uint8_t header[2];
+            if (image.read(header, 2) == 2)
+            {
+              uint32_t block_size = (((uint32_t) header[0]) << 8) | (uint32_t) header[1];
+              if (block_size == 0)
+                  throw rld::error("Block size is invalid (0)", "uncompression");
+              total_compressed += 2 + block_size;
+              if (rld::verbose() >= RLD_VERBOSE_FULL_DEBUG)
+                  std::cout << "rtl: decomp: block-size=" << block_size << std::endl;
+              if ((uint32_t) image.read(io, block_size) != block_size)
+                  throw rld::error("Read past end", "uncompression");
+              level = ::fastlz_decompress(io, block_size, buffer, size);
+            }
+            break;
+          }
+          case 2: {
+            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)
+                      throw rld::error("Invalid init inflate", "uncompression");
+              out_z = new uint8_t[CHUNK];
+              in_z = new uint8_t[CHUNK];
+              have_z = 0;
+              count_z = 0;
+            }
+            ptr_out = buffer;
+            wr = 0;
+            while (1) {
+              if (have_z > 0) 
+              {
+                wr = have_z > (size - (ptr_out - buffer)) ? size - (ptr_out - buffer) : have_z;
+                memcpy(ptr_out, ptr_in, wr);
+                ptr_out += wr;
+                ptr_in += wr;
+                have_z -= wr;
+                if ((size_t)(ptr_out - buffer) == size)
+                   break;
+              } else 
+              {
+                if (strm.avail_in == 0)
+                {
+                  strm.avail_in = image.read(in_z, CHUNK);
+                  count_z += strm.avail_in;
+                  strm.next_in = in_z;
+                }
+                if (strm.avail_in == 0)
+                  break;
+              }
+              strm.avail_out = CHUNK;
+              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)) 
+              {
+                delete[] out_z;
+                delete[] in_z;
+                (void) inflateEnd(&strm);
+                throw rld::error("Invalid inflate", "uncompression");
+              }
+              have_z = CHUNK - strm.avail_out;
+              if (have_z > 0)
+              {
+                wr = have_z > (size - (ptr_out - buffer)) ? size - (ptr_out - buffer) : have_z;
+                memcpy(ptr_out, ptr_in, wr);
+                ptr_out += wr;
+                ptr_in += wr;
+                have_z -= wr;
+                if ((size_t)(ptr_out - buffer) == size)
+                  break;
+              }
+            }
+            level = ptr_out - buffer;
+            total_compressed += count_z;
+            count_z = 0;
+            break;
           }
         }
-        else
-        {
-          image.read (buffer, size);
-          level = size;
-        }
-      }
     }

   }
}
+}
diff -Naur rtems-tools/rtemstoolkit/rld-compression.h rtems-tools_patched/rtemstoolkit/rld-compression.h
--- rtems-tools/rtemstoolkit/rld-compression.h    2016-01-13 15:35:31 +0400
+++ rtems-tools_patched/rtemstoolkit/rld-compression.h    2019-02-21 14:40:07 +0400
@@ -48,7 +48,7 @@
       compressor (files::image& image,
                   size_t        size,
                   bool          out = true,
-                  bool          compress = true);
+                  int           compress = 1);

       /**
        * Destruct the compressor.
@@ -147,7 +147,7 @@
       files::image& image;            //< The image to read or write to or from.
       size_t        size;             //< The size of the buffer.
       bool          out;              //< If true the it is compression.
-      bool          compress;         //< If true compress the data.
+      int           compress;         //< The type of compressor the data.
       uint8_t*      buffer;           //< The decompressed buffer
       uint8_t*      io;               //< The I/O buffer.
       size_t        level;            //< The amount of data in the buffer.
@@ -155,6 +155,7 @@
                                       //  transferred.
       size_t        total_compressed; //< The amount of compressed data
                                       //  transferred.
+      bool        start;
     };

     /**
diff -Naur rtems-tools/rtemstoolkit/rld-outputter.cpp rtems-tools_patched/rtemstoolkit/rld-outputter.cpp
--- rtems-tools/rtemstoolkit/rld-outputter.cpp    2018-04-18 10:52:00 +0400
+++ rtems-tools_patched/rtemstoolkit/rld-outputter.cpp    2019-02-21 14:41:49 +0400
@@ -435,7 +435,8 @@
                      const files::object_list& dependents,
                      const files::cache&       cache,
                      const symbols::table&     symbols,
-                     bool                      one_file)
+                     bool                      one_file,
+                     int                       algorithm)
     {
       if (rld::verbose () >= RLD_VERBOSE_INFO)
         std::cout << "outputter:application: " << name << std::endl;
@@ -456,7 +457,7 @@

       try
       {
-        rap::write (app, entry, exit, objects, symbols);
+        rap::write (app, entry, exit, objects, symbols, algorithm);
       }
       catch (...)
       {
diff -Naur rtems-tools/rtemstoolkit/rld-outputter.h rtems-tools_patched/rtemstoolkit/rld-outputter.h
--- rtems-tools/rtemstoolkit/rld-outputter.h    2018-04-18 10:52:00 +0400
+++ rtems-tools_patched/rtemstoolkit/rld-outputter.h    2019-02-21 14:42:55 +0400
@@ -117,7 +117,8 @@
                           const files::object_list& dependents,
                           const files::cache&       cache,
                           const symbols::table&     symbols,
-                          bool                      one_file);
+                          bool                      one_file,
+                          int                       algorithm);

   }
}
diff -Naur rtems-tools/rtemstoolkit/rld-rap.cpp rtems-tools_patched/rtemstoolkit/rld-rap.cpp
--- rtems-tools/rtemstoolkit/rld-rap.cpp    2018-04-18 10:52:00 +0400
+++ rtems-tools_patched/rtemstoolkit/rld-rap.cpp    2019-02-21 14:46:37 +0400
@@ -1684,15 +1684,22 @@
            const std::string&        init,
            const std::string&        fini,
            const files::object_list& app_objects,
-           const symbols::table&     /* symbols */) /* Add back for incremental
-                                                     * linking */
+           const symbols::table&,    /* symbols */ /* Add back for incremental
+                                                    * linking */
+           int type_compress)
     {
       std::string header;
+      
+      if (type_compress == 0)
+        header = "RAP,00000000,0002,NONE,00000000\n";
+      if (type_compress == 1)
+        header = "RAP,00000000,0002,LZ77,00000000\n";
+      if (type_compress == 2)
+        header = "RAP,00000000,0002,ZLIB,00000000\n";

-      header = "RAP,00000000,0002,LZ77,00000000\n";
       app.write (header.c_str (), header.size ());

-      compress::compressor compressor (app, 2 * 1024);
+      compress::compressor compressor (app, 2 * 1024, true, type_compress);
       image                rap;

       rap.layout (app_objects, init, fini);
diff -Naur rtems-tools/rtemstoolkit/rld-rap.h rtems-tools_patched/rtemstoolkit/rld-rap.h
--- rtems-tools/rtemstoolkit/rld-rap.h    2016-01-13 15:35:31 +0400
+++ rtems-tools_patched/rtemstoolkit/rld-rap.h    2019-02-21 14:46:12 +0400
@@ -90,7 +90,8 @@
                 const std::string&        init,
                 const std::string&        fini,
                 const files::object_list& objects,
-                const symbols::table&     symbols);
+                const symbols::table&     symbols,
+                int                       compress);
   }
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20190226/e4ec1b86/attachment-0001.html>


More information about the users mailing list