Changeset 977c3de in rtems-tools for linkers/rld-files.cpp


Ignore:
Timestamp:
Nov 17, 2012, 6:34:33 AM (7 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.10, 4.11, master
Children:
065ac15
Parents:
0b65a28
Message:

Refactor the ELF support to allow ELF write suppport.

The refactoring allows better reuse of the ELF support and cleans up
some hacks from the generic file and archive handling improving the
separation of the file handling from the file format, ie ELF. The
handling of ELF object files and ELF object files inside archives
is cleaner.

The refactor cleaned up the symbol handling where the symbols now
reside in the ELF file object and references are take in symbol
pointer containers and symbol table containers.

The main purpose of the refactor is to allow support for creating
and writing ELF files.

Also added an rtems-syms command where special symbol support
can be added.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • linkers/rld-files.cpp

    r0b65a28 r977c3de  
    11/*
    2  * Copyright (c) 2011, Chris Johns <chrisj@rtems.org> 
     2 * Copyright (c) 2011, Chris Johns <chrisj@rtems.org>
    33 *
    44 * Permission to use, copy, modify, and/or distribute this software for any
    55 * purpose with or without fee is hereby granted, provided that the above
    66 * copyright notice and this permission notice appear in all copies.
    7  * 
     7 *
    88 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    99 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     
    4646    {
    4747      uint64_t value = 0;
    48      
     48
    4949      while (len && (*string != ' '))
    5050      {
     
    105105      else if ((path_[path_.size () - 1] == RLD_PATH_SEPARATOR) &&
    106106               (file_[0] == RLD_PATH_SEPARATOR))
    107         joined = path_ + &file_[1];       
     107        joined = path_ + &file_[1];
    108108      else
    109109        joined = path_ + file_;
     
    148148                off_t              offset,
    149149                size_t             size)
    150       : aname_ (aname), 
     150      : aname_ (aname),
    151151        oname_ (oname),
    152152        offset_ (offset),
     
    247247      return oname_;
    248248    }
    249    
    250     const std::string 
     249
     250    const std::string
    251251    file::full () const
    252252    {
     
    298298      : name_ (name),
    299299        references_ (0),
    300         fd_ (-1),
    301         elf_ (0)
     300        fd_ (-1)
    302301    {
    303302    }
     
    307306        references_ (0),
    308307        fd_ (-1),
    309         elf_ (0),
    310         symbol_refs (0)
     308        symbol_refs (0),
     309        writeable (false)
    311310    {
    312311    }
     
    315314      : references_ (0),
    316315        fd_ (-1),
    317         elf_ (0),
    318316        symbol_refs (0)
    319317    {
     
    336334
    337335    void
    338     image::open (bool writable)
     336    image::open (bool writeable_)
    339337    {
    340338      const std::string path = name_.path ();
    341339
    342340      if (path.empty ())
    343         throw rld::error ("No file name", "open" + path);
     341        throw rld::error ("No file name", "open:" + path);
    344342
    345343      if (rld::verbose () >= RLD_VERBOSE_DETAILS)
    346344        std::cout << "image::open: " << name (). full ()
     345                  << " writable:" << (char*) (writeable_ ? "yes" : "no")
    347346                  << " refs:" << references_ + 1 << std::endl;
    348347
    349348      if (fd_ < 0)
    350349      {
    351         if (writable)
     350        writeable = writeable_;
     351
     352        if (writeable)
    352353          fd_ = ::open (path.c_str (), OPEN_FLAGS | O_RDWR | O_CREAT | O_TRUNC, CREATE_MODE);
    353354        else
     
    356357          throw rld::error (::strerror (errno), "open:" + path);
    357358      }
     359      else
     360      {
     361        if (writeable_ != writeable)
     362          throw rld::error ("Cannot change write status", "open:" + path);
     363      }
    358364
    359365      ++references_;
     
    386392      return rsize;
    387393    }
    388  
     394
    389395    ssize_t
    390396    image::write (const void* buffer, size_t size)
     
    395401      return wsize;
    396402    }
    397  
     403
    398404    void
    399405    image::seek (off_t offset)
     
    402408        throw rld::error (strerror (errno), "lseek:" + name ().path ());
    403409    }
    404  
     410
    405411    bool
    406412    image::seek_read (off_t offset, uint8_t* buffer, size_t size)
     
    409415      return size == (size_t) read (buffer, size);
    410416    }
    411  
     417
    412418    bool
    413419    image::seek_write (off_t offset, const void* buffer, size_t size)
     
    416422      return size == (size_t) write (buffer, size);
    417423    }
    418  
     424
    419425    const file&
    420426    image::name () const
     
    424430
    425431    int
    426     image::references () const 
     432    image::references () const
    427433    {
    428434      return references_;
     
    430436
    431437    size_t
    432     image::size () const 
     438    image::size () const
    433439    {
    434440      return name ().size ();
     
    436442
    437443    int
    438     image::fd () const 
     444    image::fd () const
    439445    {
    440446      return fd_;
    441447    }
    442448
    443     rld::elf::elf*
    444     image::elf (bool )
     449    rld::elf::file&
     450    image::elf ()
    445451    {
    446452      return elf_;
     
    448454
    449455    void
    450     image::set_elf (rld::elf::elf* elf)
    451     {
    452       elf_ = elf;
    453     }
    454 
    455     void
    456456    image::symbol_referenced ()
    457457    {
    458458      ++symbol_refs;
    459459    }
    460    
     460
    461461    int
    462462    image::symbol_references () const
     
    475475        while (size)
    476476        {
     477          /*
     478           * @fixme the reading and writing are not POSIX; sigints could split them.
     479           */
     480
    477481          size_t l = size < COPY_FILE_BUFFER_SIZE ? size : COPY_FILE_BUFFER_SIZE;
    478482          ssize_t r = ::read (in.fd (), buffer, l);
     
    546550    }
    547551
     552    void
     553    archive::begin ()
     554    {
     555      elf ().begin (name ().full (), fd ());
     556
     557      /*
     558       * Make sure it is an archive.
     559       */
     560      if (!elf ().is_archive ())
     561        throw rld::error ("Not an archive.",
     562                          "archive-begin:" + name ().full ());
     563    }
     564
     565    void
     566    archive::end ()
     567    {
     568      elf ().end ();
     569    }
     570
    548571    bool
    549572    archive::is (const std::string& path) const
     
    581604         * The archive file headers are always aligned to an even address.
    582605         */
    583         size = 
    584           (scan_decimal (&header[rld_archive_size], 
     606        size =
     607          (scan_decimal (&header[rld_archive_size],
    585608                         rld_archive_size_size) + 1) & ~1;
    586609
     
    626649                while (extended_file_names == 0)
    627650                {
    628                   size_t esize = 
     651                  size_t esize =
    629652                    (scan_decimal (&header[rld_archive_size],
    630653                                   rld_archive_size_size) + 1) & ~1;
    631654                  off += esize + rld_archive_fhdr_size;
    632                    
     655
    633656                  if (!read_header (off, &header[0]))
    634657                    throw rld::error ("No GNU extended file name section found",
    635658                                      "get-names:" + name ().path ());
    636              
     659
    637660                  if ((header[0] == '/') && (header[1] == '/'))
    638661                  {
     
    694717        throw rld::error ("Invalid header magic numbers at " +
    695718                          rld::to_string (offset), "read-header:" + name ().path ());
    696      
     719
    697720      return true;
    698721    }
     
    726749
    727750        memset (header, ' ', sizeof (header));
    728        
     751
    729752        size_t len = name.length ();
    730753        if (len > rld_archive_fname_size)
     
    757780         */
    758781        std::string extended_file_names;
    759        
     782
    760783        for (object_list::iterator oi = objects.begin ();
    761784             oi != objects.end ();
     
    819842        throw;
    820843      }
    821      
     844
    822845      close ();
    823846    }
     
    878901    {
    879902      /*
    880        * Begin an ELF session and get the ELF header.
     903       * Begin a session.
    881904       */
    882       rld::elf::begin (*this);
    883       rld::elf::get_header (*this, ehdr);
     905      if (archive_)
     906        elf ().begin (name ().full (), archive_->elf(), name ().offset ());
     907      else
     908        elf ().begin (name ().full (), fd ());
     909
     910      /*
     911       * Cannot be an archive.
     912       */
     913      if (elf ().is_archive ())
     914        throw rld::error ("Is an archive not an object file.",
     915                          "object-begin:" + name ().full ());
     916
     917      /*
     918       * We only support executable or relocatable ELF files.
     919       */
     920      if (!elf ().is_executable () && !elf ().is_relocatable ())
     921        throw rld::error ("Invalid ELF type (only ET_EXEC/ET_REL supported).",
     922                          "object-begin:" + name ().full ());
     923
     924      elf::check_file (elf ());
    884925    }
    885926
     
    887928    object::end ()
    888929    {
    889       rld::elf::end (*this);
     930      elf ().end ();
    890931    }
    891932
     
    895936      if (rld::verbose () >= RLD_VERBOSE_DETAILS)
    896937        std::cout << "object:load-sym: " << name ().full () << std::endl;
    897       rld::elf::load_symbols (symbols, *this, local);
    898     }
    899 
    900     std::string
    901     object::get_string (int section, size_t offset)
    902     {
    903       return rld::elf::get_string (*this, section, offset);
    904     }
    905    
     938
     939      rld::symbols::pointers syms;
     940
     941      elf ().get_symbols (syms, false, local);
     942
     943      if (rld::verbose () >= RLD_VERBOSE_DETAILS)
     944        std::cout << "object:load-sym: exported: total "
     945                  << syms.size () << std::endl;
     946
     947      for (symbols::pointers::iterator si = syms.begin ();
     948           si != syms.end ();
     949           ++si)
     950      {
     951        symbols::symbol& sym = *(*si);
     952
     953        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
     954        {
     955          std::cout << "object:load-sym: exported: ";
     956          sym.output (std::cout);
     957          std::cout << std::endl;
     958        }
     959
     960        sym.set_object (*this);
     961        symbols[sym.name ()] = &sym;
     962        externals.push_back (&sym);
     963      }
     964
     965      elf ().get_symbols (syms, true);
     966
     967      if (rld::verbose () >= RLD_VERBOSE_DETAILS)
     968        std::cout << "object:load-sym: unresolved: total "
     969                  << syms.size () << std::endl;
     970
     971      for (symbols::pointers::iterator si = syms.begin ();
     972           si != syms.end ();
     973           ++si)
     974      {
     975        symbols::symbol& sym = *(*si);
     976
     977        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
     978        {
     979          std::cout << "object:load-sym: unresolved: ";
     980          sym.output (std::cout);
     981          std::cout << std::endl;
     982        }
     983
     984        unresolved[sym.name ()] = &sym;
     985      }
     986    }
     987
    906988    int
    907     object::references () const 
     989    object::references () const
    908990    {
    909991      if (archive_)
     
    913995
    914996    size_t
    915     object::size () const 
     997    object::size () const
    916998    {
    917999      if (archive_)
     
    9211003
    9221004    int
    923     object::fd () const 
     1005    object::fd () const
    9241006    {
    9251007      if (archive_)
     
    9281010    }
    9291011
    930     rld::elf::elf*
    931     object::elf (bool archive__)
    932     {
    933       if (archive__ && archive_)
    934         return archive_->elf ();
    935       return image::elf ();
    936     }
    937 
    9381012    void
    9391013    object::symbol_referenced ()
     
    9431017        archive_->symbol_referenced ();
    9441018    }
    945    
     1019
    9461020    archive*
    9471021    object::get_archive ()
     
    9501024    }
    9511025
     1026#if 0
    9521027    int
    9531028    object::sections () const
     
    9611036      return ehdr.e_shstrndx;
    9621037    }
     1038#endif
    9631039
    9641040    rld::symbols::table&
     
    9681044    }
    9691045
    970     rld::symbols::list&
     1046    rld::symbols::pointers&
    9711047    object::external_symbols ()
    9721048    {
     
    10481124            std::cout << "cache:archive-begin: " << path << std::endl;
    10491125          ar->open ();
    1050           rld::elf::begin (*ar);
     1126          ar->begin ();
    10511127        }
    10521128      }
     
    10641140          if (rld::verbose () >= RLD_VERBOSE_TRACE)
    10651141            std::cout << "cache:archive-end: " << path << std::endl;
    1066           rld::elf::end (*ar);
     1142          ar->end ();
    10671143          ar->close ();
    10681144        }
     
    10831159        archive_end (((*ai).second)->path ());
    10841160    }
    1085    
     1161
    10861162    void
    10871163    cache::collect_object_files ()
     
    11741250      return archives_;
    11751251    }
    1176  
     1252
    11771253    objects&
    11781254    cache::get_objects ()
Note: See TracChangeset for help on using the changeset viewer.