Changeset a1d4930 in rtems-tools


Ignore:
Timestamp:
Nov 21, 2012, 12:05:04 AM (7 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.10, 4.11, master
Children:
eb34811
Parents:
fe19d06
Message:

Set the correct header size field.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • linkers/rld-outputter.cpp

    rfe19d06 ra1d4930  
    3333
    3434#include <rld.h>
    35 #include <rld.h>
     35
     36#include "fastlz.h"
    3637
    3738namespace rld
     
    4041  {
    4142    const std::string
    42     script_text (rld::files::object_list& dependents,
    43                  rld::files::cache&       cache)
    44     {
    45       std::ostringstream      out;
    46       rld::files::object_list objects;
     43    script_text (files::object_list& dependents,
     44                 files::cache&       cache)
     45    {
     46      std::ostringstream out;
     47      files::object_list objects;
     48
     49      /*
     50       * The merge removes them from the dependent list.
     51       */
     52      files::object_list dep_copy (dependents);
    4753
    4854      cache.get_objects (objects);
    49 
    50       objects.merge (dependents);
     55      objects.merge (dep_copy);
    5156      objects.unique ();
    5257
    53       for (rld::files::object_list::iterator oi = objects.begin ();
     58      for (files::object_list::iterator oi = objects.begin ();
    5459           oi != objects.end ();
    5560           ++oi)
    5661      {
    57         rld::files::object& obj = *(*oi);
     62        files::object& obj = *(*oi);
    5863
    5964        if (rld::verbose () >= RLD_VERBOSE_INFO)
     
    6267        out << "o:" << obj.name ().basename () << std::endl;
    6368
    64         rld::symbols::table& unresolved = obj.unresolved_symbols ();
     69        symbols::table& unresolved = obj.unresolved_symbols ();
    6570
    6671        int count = 0;
    67         for (rld::symbols::table::iterator ursi = unresolved.begin ();
     72        for (symbols::table::iterator ursi = unresolved.begin ();
    6873             ursi != unresolved.begin ();
    6974             ++ursi)
    7075        {
    71           rld::symbols::symbol& urs = *((*ursi).second);
     76          symbols::symbol& urs = *((*ursi).second);
    7277
    7378          ++count;
     
    8388    }
    8489
    85     const std::string
    86     metadata_object (const std::string&       name,
    87                      rld::files::object_list& dependents,
    88                      rld::files::cache&       cache)
    89     {
     90    void
     91    metadata_object (files::object&      metadata,
     92                     files::object_list& dependents,
     93                     files::cache&       cache)
     94    {
     95      if (rld::verbose () >= RLD_VERBOSE_INFO)
     96        std::cout << "metadata: " << metadata.name ().full () << std::endl;
     97
    9098      const std::string script = script_text (dependents, cache);
    91 
    92       std::string ext = files::extension (name);
    93       std::string mdname =
    94         name.substr (0, name.length () - ext.length ()) + "-metadata.o";
    95 
    96       if (rld::verbose () >= RLD_VERBOSE_INFO)
    97         std::cout << "metadata: " << mdname << std::endl;
    98 
    99       files::object metadata (mdname);
    10099
    101100      metadata.open (true);
     
    103102
    104103      elf::file& elf = metadata.elf ();
    105 
    106       std::cout << "class: " << elf::object_class () << std::endl;
    107104
    108105      elf.set_header (ET_EXEC,
     
    131128      metadata.end ();
    132129      metadata.close ();
    133 
    134       return mdname;
    135130    }
    136131
    137132    void
    138     archive (const std::string&       name,
    139              rld::files::object_list& dependents,
    140              rld::files::cache&       cache)
    141     {
    142       if (rld::verbose () >= RLD_VERBOSE_INFO)
    143         std::cout << "outputter:archive: " << name << std::endl;
    144 
    145       std::string metadata = metadata_object (name,
    146                                               dependents,
    147                                               cache);
    148 
     133    archive (const std::string&  name,
     134             files::object_list& dependents,
     135             files::cache&       cache)
     136    {
     137      if (rld::verbose () >= RLD_VERBOSE_INFO)
     138        std::cout << "outputter:archive: " << name
     139                  << ", dependents: " << dependents.size () << std::endl;
     140
     141      std::string ext = files::extension (name);
     142      std::string mdname =
     143        name.substr (0, name.length () - ext.length ()) + "-metadata.o";
     144
     145      files::object metadata (mdname);
     146
     147      metadata_object (metadata, dependents, cache);
     148
     149      /*
     150       * The merge removes them from the dependent list.
     151       */
     152      files::object_list dep_copy (dependents);
    149153      files::object_list objects;
     154
    150155      cache.get_objects (objects);
    151 
    152       for (rld::files::object_list::iterator oi = dependents.begin ();
    153            oi != dependents.end ();
    154            ++oi)
    155         objects.push_back (*oi);
    156 
     156      objects.merge (dep_copy);
     157      objects.push_front (&metadata);
    157158      objects.unique ();
    158159
    159       rld::files::archive arch (name);
     160      files::archive arch (name);
    160161      arch.create (objects);
    161162    }
    162163
    163164    void
    164     script (const std::string&       name,
    165             rld::files::object_list& dependents,
    166             rld::files::cache&       cache)
     165    script (const std::string&  name,
     166            files::object_list& dependents,
     167            files::cache&       cache)
    167168    {
    168169      if (rld::verbose () >= RLD_VERBOSE_INFO)
     
    184185      {
    185186        out.close ();
     187        throw;
    186188      }
    187189
    188190      out.close ();
    189191    }
     192
     193    /**
     194     * Append the output data to the output buffer and if full compress and
     195     * write to the output file. If the output buffer is 0 flush the output
     196     * buffer.
     197     */
     198    static void
     199    app_write_output (files::image&  out,
     200                      const uint8_t* out_buffer,
     201                      const size_t   out_buffer_size,
     202                      size_t&        out_buffer_level,
     203                      const void*    output_,
     204                      size_t         outputting,
     205                      uint8_t*       compress_buffer,
     206                      size_t&        out_total)
     207    {
     208      const uint8_t* output = static_cast <const uint8_t*> (output_);
     209
     210      while (outputting)
     211      {
     212        if (output)
     213        {
     214          size_t appending;
     215
     216          if (outputting > (out_buffer_size - out_buffer_level))
     217            appending = out_buffer_size - out_buffer_level;
     218          else
     219            appending = outputting;
     220
     221          ::memcpy ((void*) (out_buffer + out_buffer_level),
     222                    output,
     223                    appending);
     224
     225          out_buffer_level += appending;
     226          outputting -= appending;
     227        }
     228        else
     229        {
     230          outputting = 0;
     231        }
     232
     233        if (!output || (out_buffer_level >= out_buffer_size))
     234        {
     235          int writing =
     236            ::fastlz_compress (out_buffer, out_buffer_level, compress_buffer);
     237
     238          out.write (compress_buffer, writing);
     239
     240          out_total += writing;
     241
     242          out_buffer_level = 0;
     243        }
     244      }
     245    }
     246
     247    void
     248    application (const std::string&  name,
     249                 files::object_list& dependents,
     250                 files::cache&       cache)
     251    {
     252      if (rld::verbose () >= RLD_VERBOSE_INFO)
     253        std::cout << "outputter:application: " << name << std::endl;
     254
     255      files::object_list dep_copy (dependents);
     256      files::object_list objects;
     257      std::string        header;
     258      std::string        script;
     259      files::image       app (name);
     260
     261      header = "RTEMS-APP,00000000,01.00.00,LZ77,00000000\n";
     262      header += '\0';
     263
     264      script = script_text (dependents, cache);
     265
     266      cache.get_objects (objects);
     267      objects.merge (dep_copy);
     268      objects.unique ();
     269
     270      app.open (true);
     271      app.write (header.c_str (), header.size ());
     272
     273      #define INPUT_BUFFER_SIZE  (64 * 1024)
     274      #define OUTPUT_BUFFER_SIZE (128 * 1024)
     275      #define FASTLZ_BUFFER_SIZE (OUTPUT_BUFFER_SIZE + ((int) (OUTPUT_BUFFER_SIZE * 0.10)))
     276
     277      uint8_t* in_buffer = 0;
     278      uint8_t* out_buffer = 0;
     279      uint8_t* compress_buffer = 0;
     280      size_t   out_level = 0;
     281      size_t   in_total = 0;
     282      size_t   out_total = 0;
     283
     284      try
     285      {
     286        in_buffer = new uint8_t[INPUT_BUFFER_SIZE];
     287        out_buffer = new uint8_t[OUTPUT_BUFFER_SIZE];
     288        compress_buffer = new uint8_t[FASTLZ_BUFFER_SIZE];
     289
     290        app_write_output (app,
     291                          out_buffer, OUTPUT_BUFFER_SIZE, out_level,
     292                          script.c_str (), script.size (),
     293                          compress_buffer,
     294                          out_total);
     295
     296        in_total += script.size ();
     297
     298        for (files::object_list::iterator oi = objects.begin ();
     299             oi != objects.end ();
     300             ++oi)
     301        {
     302          files::object& obj = *(*oi);
     303
     304          obj.open ();
     305
     306          try
     307          {
     308            obj.seek (0);
     309
     310            size_t in_size = obj.name ().size ();
     311
     312            while (in_size)
     313            {
     314              size_t reading =
     315                in_size < INPUT_BUFFER_SIZE ? in_size : INPUT_BUFFER_SIZE;
     316
     317              obj.read (in_buffer, reading);
     318
     319              app_write_output (app,
     320                                out_buffer, OUTPUT_BUFFER_SIZE, out_level,
     321                                in_buffer, reading,
     322                                compress_buffer,
     323                                out_total);
     324
     325              in_size -= reading;
     326              in_total += reading;
     327            }
     328          }
     329          catch (...)
     330          {
     331            obj.close ();
     332            throw;
     333          }
     334
     335          obj.close ();
     336        }
     337      }
     338      catch (...)
     339      {
     340        delete [] in_buffer;
     341        delete [] out_buffer;
     342        delete [] compress_buffer;
     343        throw;
     344      }
     345
     346      app_write_output (app,
     347                        out_buffer, OUTPUT_BUFFER_SIZE, out_level,
     348                        0, out_level,
     349                        compress_buffer,
     350                        out_total);
     351
     352      app.close ();
     353
     354      delete [] in_buffer;
     355      delete [] out_buffer;
     356      delete [] compress_buffer;
     357
     358      if (rld::verbose () >= RLD_VERBOSE_INFO)
     359      {
     360        int pcent = (out_total * 100) / in_total;
     361        int premand = (((out_total * 1000) + 500) / in_total) % 10;
     362        std::cout << "outputter:application: objects: " << objects.size ()
     363                  << ", size: " << out_total
     364                  << ", compression: " << pcent << '.' << premand << '%'
     365                  << std::endl;
     366      }
     367    }
     368
    190369  }
    191370}
Note: See TracChangeset for help on using the changeset viewer.