Changeset fd8a2c5 in rtems-tools


Ignore:
Timestamp:
Nov 20, 2012, 8:53:24 AM (7 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.10, 4.11, master
Children:
fe19d06
Parents:
9b66527
Message:

Add support to write a metadata ELF file.

This also adds support to the ELF classes that wrap libelf. While
this is now done and seems to work I will not be using an ELF
file to hold the metadata after all.

Location:
linkers
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • linkers/rld-elf-types.h

    r9b66527 rfd8a2c5  
    4040    typedef ::GElf_Word  elf_word;
    4141    typedef ::GElf_Xword elf_xword;
     42    typedef ::Elf_Type   elf_type;
    4243    typedef ::GElf_Addr  elf_addr;
    4344    typedef ::GElf_Off   elf_off;
  • linkers/rld-elf.cpp

    r9b66527 rfd8a2c5  
    4646     */
    4747    static unsigned int elf_object_class = ELFCLASSNONE;
    48     static unsigned int elf_object_data = ELFDATANONE;
    4948    static unsigned int elf_object_machinetype = EM_NONE;
     49    static unsigned int elf_object_datatype = ELFDATANONE;
    5050
    5151    /**
     
    6565    }
    6666
     67    section::section (file&              file_,
     68                      int                index_,
     69                      const std::string& name_,
     70                      elf_word           type,
     71                      elf_xword          alignment,
     72                      elf_xword          flags,
     73                      elf_addr           addr,
     74                      elf_off            offset,
     75                      elf_xword          size,
     76                      elf_word           link,
     77                      elf_word           info,
     78                      elf_xword          entry_size)
     79      : file_ (&file_),
     80        index_ (index_),
     81        name_ (name_),
     82        scn (0),
     83        data_ (0)
     84    {
     85      if (!file_.is_writable ())
     86        throw rld::error ("not writable",
     87                          "elf:section" + file_.name () + " (" + name_ + ')');
     88
     89      scn = ::elf_newscn (file_.get_elf ());
     90      if (!scn)
     91        libelf_error ("elf_newscn: " + name_ + " (" + file_.name () + ')');
     92
     93      if (::gelf_getshdr(scn, &shdr) == 0)
     94        libelf_error ("gelf_getshdr: " + name_ + " (" + file_.name () + ')');
     95
     96      shdr.sh_name = 0;
     97      shdr.sh_type = type;
     98      shdr.sh_flags = flags;
     99      shdr.sh_addr = addr;
     100      shdr.sh_offset = offset;
     101      shdr.sh_size = size;
     102      shdr.sh_link = link;
     103      shdr.sh_info = info;
     104      shdr.sh_addralign = alignment;
     105      shdr.sh_entsize = entry_size;
     106
     107      if (type == SHT_NOBITS)
     108        add_data (ELF_T_BYTE, alignment, size);
     109
     110      if (!gelf_update_shdr (scn, &shdr))
     111        libelf_error ("gelf_update_shdr: " + name_ + " (" + file_.name () + ')');
     112    }
     113
    67114    section::section (file& file_, int index_)
    68115      : file_ (&file_),
     
    83130      {
    84131        name_ = file_.get_string (shdr.sh_name);
    85         data_ = ::elf_getdata (scn, NULL);
     132        data_ = ::elf_getdata (scn, 0);
    86133        if (!data_)
    87134          libelf_error ("elf_getdata: " + name_ + '(' + file_.name () + ')');
     
    108155    }
    109156
     157    void
     158    section::add_data (elf_type  type,
     159                       elf_xword alignment,
     160                       elf_xword size,
     161                       void*     buffer,
     162                       elf_off   offset)
     163    {
     164      check_writable ("add_data");
     165
     166      data_ = ::elf_newdata(scn);
     167      if (!data_)
     168        libelf_error ("elf_newdata: " + name_ + " (" + file_->name () + ')');
     169
     170      data_->d_type = type;
     171      data_->d_off = offset;
     172      data_->d_size = size;
     173      data_->d_align = alignment;
     174      data_->d_version = EV_CURRENT;
     175      data_->d_buf = buffer;
     176
     177      if (!gelf_update_shdr (scn, &shdr))
     178        libelf_error ("gelf_update_shdr: " + name_ + " (" + file_->name () + ')');
     179    }
     180
    110181    int
    111182    section::index () const
    112183    {
    113       check ();
     184      check ("index");
    114185      return index_;
    115186    }
     
    118189    section::name () const
    119190    {
    120       check ();
     191      check ("name");
    121192      return name_;
    122193    }
     
    125196    section::data ()
    126197    {
    127       check ();
     198      check ("data");
    128199      return data_;
    129200    }
     
    132203    section::type () const
    133204    {
    134       check ();
     205      check ("type");
    135206      return shdr.sh_type;
    136207    }
     
    139210    section::flags () const
    140211    {
    141       check ();
     212      check ("flags");
    142213      return shdr.sh_flags;
    143214    }
     
    146217    section::address () const
    147218    {
    148       check ();
     219      check ("address");
    149220      return shdr.sh_addr;
    150221    }
     
    153224    section::alignment () const
    154225    {
    155       check ();
     226      check ("alignment");
    156227      return shdr.sh_addralign;
    157228    }
     
    160231    section::offset () const
    161232    {
    162       check ();
     233      check ("offset");
    163234      return shdr.sh_offset;
    164235    }
     
    167238    section::link () const
    168239    {
    169       check ();
     240      check ("link");
    170241      return shdr.sh_link;
    171242    }
     
    174245    section::info () const
    175246    {
    176       check ();
     247      check ("info");
    177248      return shdr.sh_info;
    178249    }
     
    181252    section::size () const
    182253    {
    183       check ();
     254      check ("size");
    184255      return shdr.sh_size;
    185256    }
     
    188259    section::entry_size () const
    189260    {
    190       check ();
     261      check ("entry_size");
    191262      return shdr.sh_entsize;
    192263    }
     
    199270
    200271    void
    201     section::check () const
    202     {
    203       if (!file_ || (index_ < 0))
    204         throw rld::error ("Invalid section.", "section:check:");
     272    section::set_name (unsigned int index)
     273    {
     274      check_writable ("set_name");
     275      shdr.sh_name = index;
     276      if (!gelf_update_shdr (scn, &shdr))
     277        libelf_error ("gelf_update_shdr: " + name_ + " (" + file_->name () + ')');
     278    }
     279
     280    void
     281    section::check (const char* where) const
     282    {
     283      if (!file_ || (index_ < 0) || !scn)
     284      {
     285        std::string w = where;
     286        throw rld::error ("Section not initialised.", "section:check:" + w);
     287      }
     288    }
     289
     290    void
     291    section::check_writable (const char* where) const
     292    {
     293      check (where);
     294      if (!file_->is_writable ())
     295      {
     296        std::string w = where;
     297        throw rld::error ("File is read-only.", "section:check:");
     298      }
     299    }
     300
     301    program_header::program_header ()
     302    {
     303      memset (&phdr, 0, sizeof (phdr));
     304    }
     305
     306    program_header::~program_header ()
     307    {
     308    }
     309
     310    void
     311    program_header::set (elf_word type,
     312                         elf_word flags,
     313                         elf_off offset,
     314                         elf_xword filesz,
     315                         elf_xword memsz,
     316                         elf_xword align,
     317                         elf_addr vaddr,
     318                         elf_addr paddr)
     319    {
     320      phdr.p_type = type;
     321      phdr.p_flags = flags;
     322      phdr.p_offset = offset;
     323      phdr.p_vaddr = vaddr;
     324      phdr.p_paddr = paddr;
     325      phdr.p_filesz = filesz;
     326      phdr.p_memsz = memsz;
     327      phdr.p_align = align;
    205328    }
    206329
     
    326449      elf_ = elf__;
    327450
    328       if (!archive)
     451      if (!archive && !writable)
    329452        load_header ();
    330453    }
     
    339462                    << ' ' << name_ << std::endl;
    340463        ::elf_end (elf_);
    341       }
    342 
    343       fd_ = -1;
    344       name_.clear ();
    345       archive = false;
    346       elf_ = 0;
    347       oclass = 0;
    348       ident_str = 0;
    349       ident_size = 0;
    350 
    351       if (!writable)
    352       {
    353         if (ehdr)
     464        elf_ = 0;
     465      }
     466
     467      if (fd_ >= 0)
     468      {
     469        if (!writable)
    354470        {
    355           delete ehdr;
    356           ehdr = 0;
     471          if (ehdr)
     472          {
     473            delete ehdr;
     474            ehdr = 0;
     475          }
     476          if (phdr)
     477          {
     478            delete phdr;
     479            phdr = 0;
     480          }
    357481        }
    358         if (phdr)
     482
     483        fd_ = -1;
     484        name_.clear ();
     485        archive = false;
     486        elf_ = 0;
     487        oclass = 0;
     488        ident_str = 0;
     489        ident_size = 0;
     490        writable = false;
     491        secs.clear ();
     492      }
     493    }
     494
     495    void
     496    file::write ()
     497    {
     498      check_writable ("write");
     499
     500      std::string shstrtab;
     501
     502      for (section_table::iterator sti = secs.begin ();
     503           sti != secs.end ();
     504           ++sti)
     505      {
     506        section& sec = (*sti).second;
     507        int added_at = shstrtab.size ();
     508        shstrtab += '\0' + sec.name ();
     509        sec.set_name (added_at + 1);
     510      }
     511
     512      unsigned int shstrtab_name = shstrtab.size () + 1;
     513
     514      /*
     515       * Done this way to clang happy on darwin.
     516       */
     517      shstrtab += '\0';
     518      shstrtab += ".shstrtab";
     519
     520      /*
     521       * Create the string table section.
     522       */
     523      section shstrsec (*this,
     524                        secs.size () + 1,          /* index */
     525                        ".shstrtab",               /* name */
     526                        SHT_STRTAB,                /* type */
     527                        1,                         /* alignment */
     528                        SHF_STRINGS | SHF_ALLOC,   /* flags */
     529                        0,                         /* address */
     530                        0,                         /* offset */
     531                        shstrtab.size ());         /* size */
     532
     533      shstrsec.add_data (ELF_T_BYTE,
     534                         1,
     535                         shstrtab.size (),
     536                         (void*) shstrtab.c_str ());
     537
     538      shstrsec.set_name (shstrtab_name);
     539
     540      ::elf_setshstrndx (elf_, shstrsec.index ());
     541      ::elf_flagehdr (elf_, ELF_C_SET, ELF_F_DIRTY);
     542
     543      if (elf_update (elf_, ELF_C_NULL) < 0)
     544        libelf_error ("elf_update:layout: " + name_);
     545
     546      ::elf_flagphdr (elf_, ELF_C_SET, ELF_F_DIRTY);
     547
     548      if (::elf_update (elf_, ELF_C_WRITE) < 0)
     549        libelf_error ("elf_update:write: " + name_);
     550    }
     551
     552    void
     553    file::load_header ()
     554    {
     555      check ("load_header");
     556
     557      if (!ehdr)
     558      {
     559        if (!writable)
     560          ehdr = new elf_ehdr;
     561        else
    359562        {
    360           delete phdr;
    361           phdr = 0;
     563          throw rld::error ("No ELF header; set the header first",
     564                            "elf:file:load_header: " + name_);
    362565        }
    363566      }
    364567
    365       writable = false;
    366 
    367       stab.clear ();
    368       secs.clear ();
    369     }
    370 
    371     void
    372     file::load_header ()
    373     {
    374       check ("get_header");
    375 
    376       if (!writable && !ehdr)
    377         ehdr = new elf_ehdr;
    378 
    379       if (::gelf_getehdr (elf_, ehdr) == NULL)
    380         error ("get-header");
     568      if (::gelf_getehdr (elf_, ehdr) == 0)
     569        error ("gelf_getehdr");
    381570    }
    382571
     
    446635        check ("load_sections_headers");
    447636        for (int sn = 0; sn < section_count (); ++sn)
    448           secs.push_back (section (*this, sn));
     637        {
     638          section sec = section (*this, sn);
     639          secs[sec.name ()] = sec;
     640        }
    449641      }
    450642    }
     
    455647      load_sections ();
    456648      filtered_secs.clear ();
    457       for (sections::iterator si = secs.begin ();
     649      for (section_table::iterator si = secs.begin ();
    458650           si != secs.end ();
    459651           ++si)
    460652      {
    461         if ((type == 0) || ((*si).type () == type))
    462           filtered_secs.push_back (*si);
     653        section& sec = (*si).second;
     654        if ((type == 0) || (sec.type () == type))
     655          filtered_secs.push_back (&sec);
    463656      }
    464657    }
     
    477670             ++si)
    478671        {
    479           section& sec = *si;
     672          section& sec = *(*si);
    480673          int      syms = sec.entries ();
    481674
     
    600793      check_writable ("set_header");
    601794
     795      if (ehdr)
     796          throw rld::error ("ELF header already set",
     797                            "elf:file:set_header: " + name_);
     798
    602799      ehdr = (elf_ehdr*) ::gelf_newehdr (elf_, class_);
    603 
    604800      if (ehdr == 0)
    605         error ("set-header");
     801        error ("gelf_newehdr");
     802
     803      if (::gelf_getehdr (elf_, ehdr) == 0)
     804        error ("gelf_getehdr");
    606805
    607806      ehdr->e_type = type;
    608807      ehdr->e_machine = machinetype;
     808      ehdr->e_flags = 0;
    609809      ehdr->e_ident[EI_DATA] = datatype;
    610 
    611       //::gelf_flagphdr (elf_, ELF_C_SET , ELF_F_DIRTY);
     810      ehdr->e_version = EV_CURRENT;
     811
     812      ::elf_flagphdr (elf_, ELF_C_SET , ELF_F_DIRTY);
     813    }
     814
     815    void
     816    file::add (section& sec)
     817    {
     818      check_writable ("add");
     819      secs[sec.name ()] = sec;
     820    }
     821
     822    void
     823    file::add (program_header& phdr)
     824    {
     825      check_writable ("add");
     826      phdrs.push_back (phdr);
    612827    }
    613828
     
    720935    }
    721936
    722     const std::string machine_type ()
     937    const std::string
     938    machine_type ()
    723939    {
    724940      return machine_type (elf_object_machinetype);
     941    }
     942
     943    unsigned int
     944    object_class ()
     945    {
     946      return elf_object_class;
     947    }
     948
     949    unsigned int
     950    object_machine_type ()
     951    {
     952      return elf_object_machinetype;
     953    }
     954
     955    unsigned int
     956    object_datatype ()
     957    {
     958      return elf_object_datatype;
    725959    }
    726960
     
    744978                          "elf:check_file: " + file.name ());
    745979
    746       if (elf_object_data == ELFDATANONE)
    747         elf_object_data = file.data_type ();
    748       else if (elf_object_data != file.data_type ())
     980      if (elf_object_datatype == ELFDATANONE)
     981        elf_object_datatype = file.data_type ();
     982      else if (elf_object_datatype != file.data_type ())
    749983        throw rld::error ("Mixed data types not allowed (LSB/MSB).",
    750984                          "elf:check_file: " + file.name ());
  • linkers/rld-elf.h

    r9b66527 rfd8a2c5  
    2727
    2828#include <list>
     29#include <map>
    2930
    3031#include <rld.h>
     
    4647    public:
    4748      /**
    48        * Construct the section getting the details.
    49        *
    50        * @param elf The ELF file this section is part of.
    51        * @param index The sections index in the ELF file.
     49       * Construct the section getting the details from the ELF file given the
     50       * section index.
     51       *
     52       * The section types are (from elf(3)):
     53       *
     54       *  Section Type         Library Type     Description
     55       *  ------------         ------------     -----------
     56       *   SHT_DYNAMIC          ELF_T_DYN        `.dynamic' section entries.
     57       *   SHT_DYNSYM           ELF_T_SYM        Symbols for dynamic linking.
     58       *   SHT_FINI_ARRAY       ELF_T_ADDR       Termination function pointers.
     59       *   SHT_GROUP            ELF_T_WORD       Section group marker.
     60       *   SHT_HASH             ELF_T_HASH       Symbol hashes.
     61       *   SHT_INIT_ARRAY       ELF_T_ADDR       Initialization function pointers.
     62       *   SHT_NOBITS           ELF_T_BYTE       Empty sections.  See elf(5).
     63       *   SHT_NOTE             ELF_T_NOTE       ELF note records.
     64       *   SHT_PREINIT_ARRAY    ELF_T_ADDR       Pre-initialization function
     65       *                                         pointers.
     66       *   SHT_PROGBITS         ELF_T_BYTE       Machine code.
     67       *   SHT_REL              ELF_T_REL        ELF relocation records.
     68       *   SHT_RELA             ELF_T_RELA       Relocation records with addends.
     69       *   SHT_STRTAB           ELF_T_BYTE       String tables.
     70       *   SHT_SYMTAB           ELF_T_SYM        Symbol tables.
     71       *   SHT_SYMTAB_SHNDX     ELF_T_WORD       Used with extended section
     72       *                                         numbering.
     73       *   SHT_GNU_verdef       ELF_T_VDEF       Symbol version definitions.
     74       *   SHT_GNU_verneed      ELF_T_VNEED      Symbol versioning requirements.
     75       *   SHT_GNU_versym       ELF_T_HALF       Version symbols.
     76       *   SHT_SUNW_move        ELF_T_MOVE       ELF move records.
     77       *   SHT_SUNW_syminfo     ELF_T_SYMINFO    Additional symbol flags.
     78       *
     79       * @param file_ The ELF file this section is part of.
     80       * @param index_ The section's index.
     81       * @param name The section's name.
     82       * @param type The section's type.
     83       * @param alignment The section's alignment.
     84       * @param flags The section's flags.
     85       * @param addr The section's in-memory address.
     86       * @param offset The section's offset in the file.
     87       * @param size The section's file in bytes.
     88       * @param link The section's header table link.
     89       * @param info The section's extra information.
     90       * @param entry_size The section's entry size.
     91       */
     92      section (file&              file_,
     93               int                index_,
     94               const std::string& name,
     95               elf_word           type,
     96               elf_xword          alignment,
     97               elf_xword          flags,
     98               elf_addr           addr,
     99               elf_off            offset,
     100               elf_xword          size,
     101               elf_word           link = 0,
     102               elf_word           info = 0,
     103               elf_xword          entry_size = 0);
     104
     105      /**
     106       * Construct the section given the details. The ELF file must be
     107       * writable.
     108       *
     109       * @param file_ The ELF file this section is part of.
     110       * @param index The section's index in the ELF file.
    52111       */
    53112      section (file& file_, int index);
     
    64123
    65124      /**
     125       * Add a data segment descriptor to the section if the file is writable.
     126       *
     127       * These are following data types (from elf(3)):
     128       *
     129       *   ELF_T_ADDR     Machine addresses.
     130       *   ELF_T_BYTE     Byte data.  The library will not attempt to translate
     131       *                  byte data.
     132       *   ELF_T_CAP      Software and hardware capability records.
     133       *   ELF_T_DYN      Records used in a section of type SHT_DYNAMIC.
     134       *   ELF_T_EHDR     ELF executable header.
     135       *   ELF_T_HALF     16-bit unsigned words.
     136       *   ELF_T_LWORD    64 bit unsigned words.
     137       *   ELF_T_MOVE     ELF Move records.
     138       *   ELF_T_NOTE     ELF Note structures.
     139       *   ELF_T_OFF      File offsets.
     140       *   ELF_T_PHDR     ELF program header table entries.
     141       *   ELF_T_REL      ELF relocation entries.
     142       *   ELF_T_RELA     ELF relocation entries with addends.
     143       *   ELF_T_SHDR     ELF section header entries.
     144       *   ELF_T_SWORD    Signed 32-bit words.
     145       *   ELF_T_SXWORD   Signed 64-bit words.
     146       *   ELF_T_SYMINFO  ELF symbol information.
     147       *   ELF_T_SYM      ELF symbol table entries.
     148       *   ELF_T_VDEF     Symbol version definition records.
     149       *   ELF_T_VNEED    Symbol version requirement records.
     150       *   ELF_T_WORD     Unsigned 32-bit words.
     151       *   ELF_T_XWORD    Unsigned 64-bit words.
     152       *
     153       * @param type The type of data in the segment.
     154       * @param alignment The in-file alignment of the data. Must be a power of 2.
     155       * @param size The number of bytes in this data descriptor.
     156       * @param buffer The data in memory.
     157       * @param offset The offset within the containing section. Can be computed.
     158       */
     159      void add_data (elf_type  type,
     160                     elf_xword alignment,
     161                     elf_xword size,
     162                     void*     buffer = 0,
     163                     elf_off   offset = 0);
     164
     165       /**
    66166       * The section's index in the ELF file.
    67167       *
     
    132232      int entries () const;
    133233
     234      /**
     235       * Set the name index if writable. This is normally done
     236       * automatically when adding the section to the file.
     237       */
     238      void set_name (unsigned int index);
     239
    134240    private:
    135241
    136242      /**
    137        * Check the section is acrtual valid.
    138        */
    139       void check () const;
     243       * Check the section is valid.
     244       *
     245       * @param where Where the check is being made.
     246       */
     247      void check (const char* where) const;
     248
     249      /**
     250       * Check the section is valid and writable.
     251       *
     252       * @param where Where the check is being made.
     253       */
     254      void check_writable (const char* where) const;
    140255
    141256      file*       file_;  //< The ELF file.
     
    148263
    149264    /**
    150      * Container of ELF sections.
    151      */
    152     typedef std::list < section > sections;
    153 
    154     /**
     265     * Container of ELF section pointers.
     266     */
     267    typedef std::list < section* > sections;
     268
     269    /**
     270     * Container of ELF section as a map, ie associative array.
     271     */
     272    typedef std::map < std::string, section > section_table;
     273
     274    /**
     275     * An ELF program header.
     276     */
     277    class program_header
     278    {
     279    public:
     280      /**
     281       * Construct a program header.
     282       */
     283      program_header ();
     284
     285      /**
     286       * Desctruct a program header.
     287       */
     288      ~program_header ();
     289
     290      /**
     291       * Set the program header.
     292       *
     293       * @param type The type of segment.
     294       * @param flags The segment's flags.
     295       * @param offset The offet to segment.
     296       * @param filesz The segment size in the file.
     297       * @param memsz The segment size in memory.
     298       * @param vaddr The virtual address in memory.
     299       * @param paddr The physical address if any.
     300       */
     301      void set (elf_word type,
     302                elf_word flags,
     303                elf_off offset,
     304                elf_xword filesz,
     305                elf_xword memsz,
     306                elf_xword align,
     307                elf_addr vaddr,
     308                elf_addr paddr = 0);
     309
     310    private:
     311
     312      elf_phdr phdr;  //< The ELF program header.
     313    };
     314
     315    /**
     316     * A container of program headers.
     317     */
     318    typedef std::list < program_header > program_headers;
     319
     320     /**
    155321     * An ELF file.
    156322     */
     
    158324    {
    159325    public:
    160       /**
     326     /**
    161327       * Construct an ELF file.
    162328       */
     
    190356       */
    191357      void end ();
     358
     359      /**
     360       * Write the ELF file creating it if it is writable. You should have
     361       * added the sections and the data segment descriptors to the sections
     362       * before calling write.
     363       */
     364      void write ();
    192365
    193366      /**
     
    301474       * Set the ELF header. Must be writable.
    302475       *
     476       * The classes are:
     477       *   ELFCLASSNONE  This class is invalid.
     478       *   ELFCLASS32    This defines the 32-bit architecture.  It sup- ports
     479       *                 machines with files and virtual address spa- ces up to
     480       *                 4 Gigabytes.
     481       *   ELFCLASS64    This defines the 64-bit architecture.
     482       *
     483       * The types are:
     484       *   ET_NONE  An unknown type.
     485       *   ET_REL   A relocatable file.
     486       *   ET_EXEC  An executable file.
     487       *   ET_DYN   A shared object.
     488       *   ET_CORE  A core file.
     489       *
     490       * The machine types are:
     491       *   TDB
     492       *
     493       * The datatypes are:
     494       *   ELFDATA2LSB  Two's complement, little-endian.
     495       *   ELFDATA2MSB  Two's complement, big-endian.
     496       *
    303497       * @param type The type of ELF file, ie executable, relocatable etc.
     498       * @param class_ The files ELF class.
    304499       * @param machinetype The type of machine code present in the ELF file.
    305500       * @param datatype The data type, ie LSB or MSB.
     
    309504                       elf_half      machinetype,
    310505                       unsigned char datatype);
     506
     507      /**
     508       * Add a section to the ELF file if writable.
     509       */
     510      void add (section& sec);
     511
     512      /**
     513       * Add a program header to the ELF file if writable.
     514       */
     515      void add (program_header& phdr);
    311516
    312517      /**
     
    388593      elf_ehdr*            ehdr;       //< The ELF header.
    389594      elf_phdr*            phdr;       //< The ELF program header.
    390       std::string          stab;       //< The string table.
    391       sections             secs;       //< The sections.
     595      section_table        secs;       //< The sections as a table.
     596      program_headers      phdrs;      //< The program headers when creating
     597                                       //  ELF files.
    392598      rld::symbols::bucket symbols;    //< The symbols. All tables point here.
    393599    };
     
    401607
    402608    /**
     609     * Return the global machine type set by the check_file call as a string.
     610     */
     611    const std::string machine_type ();
     612
     613    /**
     614     * Return the global class set by the check_file call.
     615     */
     616    unsigned int object_class ();
     617
     618    /**
    403619     * Return the global machine type set by the check_file call.
    404620     */
    405     const std::string machine_type ();
     621    unsigned int object_machine_type ();
     622
     623    /**
     624     * Return the global data type set by the check_file call.
     625     */
     626    unsigned int object_datatype ();
    406627
    407628    /**
  • linkers/rld-files.cpp

    r9b66527 rfd8a2c5  
    8080    }
    8181
     82    std::string
     83    dirname (const std::string& name)
     84    {
     85      size_t b = name.find_last_of (RLD_PATH_SEPARATOR);
     86      if (b != std::string::npos)
     87        return name.substr (0, b - 1);
     88      return name;
     89    }
     90
     91    std::string
     92    extension (const std::string& name)
     93    {
     94      size_t b = name.find_last_of ('.');
     95      if (b != std::string::npos)
     96        return name.substr (b);
     97      return name;
     98    }
     99
    82100    void
    83101    path_split (const std::string& path, rld::files::paths& paths)
     
    307325        fd_ (-1),
    308326        symbol_refs (0),
    309         writeable (false)
     327        writable (false)
    310328    {
    311329    }
     
    334352
    335353    void
    336     image::open (bool writeable_)
     354    image::open (bool writable_)
    337355    {
    338356      const std::string path = name_.path ();
     
    343361      if (rld::verbose () >= RLD_VERBOSE_DETAILS)
    344362        std::cout << "image::open: " << name (). full ()
    345                   << " writable:" << (char*) (writeable_ ? "yes" : "no")
     363                  << " writable:" << (char*) (writable_ ? "yes" : "no")
    346364                  << " refs:" << references_ + 1 << std::endl;
    347365
    348366      if (fd_ < 0)
    349367      {
    350         writeable = writeable_;
    351 
    352         if (writeable)
     368        writable = writable_;
     369
     370        if (writable)
    353371          fd_ = ::open (path.c_str (), OPEN_FLAGS | O_RDWR | O_CREAT | O_TRUNC, CREATE_MODE);
    354372        else
     
    359377      else
    360378      {
    361         if (writeable_ != writeable)
     379        if (writable_ != writable)
    362380          throw rld::error ("Cannot change write status", "open:" + path);
    363381      }
     
    915933        elf ().begin (name ().full (), archive_->elf(), name ().offset ());
    916934      else
    917         elf ().begin (name ().full (), fd ());
     935        elf ().begin (name ().full (), fd (), is_writable ());
    918936
    919937      /*
     
    927945       * We only support executable or relocatable ELF files.
    928946       */
    929       if (!elf ().is_executable () && !elf ().is_relocatable ())
    930         throw rld::error ("Invalid ELF type (only ET_EXEC/ET_REL supported).",
    931                           "object-begin:" + name ().full ());
    932 
    933       elf::check_file (elf ());
     947      if (!is_writable ())
     948      {
     949        if (!elf ().is_executable () && !elf ().is_relocatable ())
     950          throw rld::error ("Invalid ELF type (only ET_EXEC/ET_REL supported).",
     951                            "object-begin:" + name ().full ());
     952        elf::check_file (elf ());
     953      }
    934954    }
    935955
     
    13661386    {
    13671387      if (rld::verbose () >= RLD_VERBOSE_INFO)
    1368         std::cout << "Finding libraries:" << std::endl;
     1388        std::cout << "Finding libraries:." << std::endl;
    13691389      libraries.clear ();
    13701390      for (paths::size_type l = 0; l < libs.size (); ++l)
     
    13721392        std::string lib = "lib" + libs[l] + ".a";
    13731393        if (rld::verbose () >= RLD_VERBOSE_DETAILS)
    1374           std::cout << "searching: " << lib << std::endl;
     1394          std::cout << " searching: " << lib << std::endl;
    13751395        bool found = false;
    13761396        for (paths::size_type p = 0; p < libpaths.size (); ++p)
     
    13791399          path_join (libpaths[p], lib, plib);
    13801400          if (rld::verbose () >= RLD_VERBOSE_DETAILS)
    1381               std::cout << "checking: " << plib << std::endl;
     1401              std::cout << " checking: " << plib << std::endl;
    13821402          if (check_file (plib))
    13831403          {
    13841404            if (rld::verbose () >= RLD_VERBOSE_INFO)
    1385               std::cout << "found: " << plib << std::endl;
     1405              std::cout << " found: " << plib << std::endl;
    13861406            libraries.push_back (plib);
    13871407            found = true;
  • linkers/rld-files.h

    r9b66527 rfd8a2c5  
    7070
    7171    /**
     72     * Return the basename of the file name.
     73     *
     74     * @param name The full file name.
     75     * @return std::string The basename of the file.
     76     */
     77    std::string basename (const std::string& name);
     78
     79    /**
     80     * Return the dirname of the file name.
     81     *
     82     * @param name The full file name.
     83     * @return std::string The dirname of the file.
     84     */
     85    std::string dirname (const std::string& name);
     86
     87    /**
     88     * Return the extension of the file name.
     89     *
     90     * @param name The full file name.
     91     * @return std::string The extension of the file.
     92     */
     93    std::string extension (const std::string& name);
     94
     95    /**
    7296     * Split a path from a string with a delimiter to the path container. Add
    7397     * only the paths that exist and ignore those that do not.
     98     *
     99     * @param path The paths as a single string delimited by the path
     100     *             separator.
     101     * @param paths The split path paths.
    74102     */
    75103    void path_split (const std::string& path,
     
    360388       * Is the image writable ?
    361389       *
    362        * @retval true The image is writeable.
    363        * @retval false The image is not writeable.
    364        */
    365       bool is_writeable () const {
    366         return writeable;
     390       * @retval true The image is writable.
     391       * @retval false The image is not writable.
     392       */
     393      bool is_writable () const {
     394        return writable;
    367395      }
    368396
     
    374402      elf::file elf_;        //< The libelf reference.
    375403      int       symbol_refs; //< The number of symbols references made.
    376       bool      writeable;   //< The image is writable.
     404      bool      writable;    //< The image is writable.
    377405    };
    378406
     
    544572
    545573      /**
    546        * Get the string from the string table.
    547        */
    548 //      std::string get_string (int section, size_t offset);
    549 
    550       /**
    551574       * References to the image.
    552575       */
     
    573596       */
    574597      archive* get_archive ();
    575 
    576 #if 0
    577       /**
    578        * Number of sections in the object file.
    579        */
    580       int sections () const;
    581 
    582       /**
    583        * Section string index.
    584        */
    585       int section_strings () const;
    586 #endif
    587598
    588599      /**
  • linkers/rld-outputter.cpp

    r9b66527 rfd8a2c5  
    8383    }
    8484
     85    const std::string
     86    metadata_object (const std::string&       name,
     87                     rld::files::object_list& dependents,
     88                     rld::files::cache&       cache)
     89    {
     90      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);
     100
     101      metadata.open (true);
     102      metadata.begin ();
     103
     104      elf::file& elf = metadata.elf ();
     105
     106      std::cout << "class: " << elf::object_class () << std::endl;
     107
     108      elf.set_header (ET_EXEC,
     109                      elf::object_class (),
     110                      elf::object_datatype (),
     111                      elf::object_machine_type ());
     112
     113      elf::section md (elf,
     114                       elf.section_count () + 1,
     115                       ".rtemsmd",
     116                       SHT_STRTAB,
     117                       1,
     118                       0,
     119                       0,
     120                       0,
     121                       script.length ());
     122
     123      md.add_data (ELF_T_BYTE,
     124                   1,
     125                   script.length (),
     126                   (void*) script.c_str ());
     127
     128      elf.add (md);
     129      elf.write ();
     130
     131      metadata.end ();
     132      metadata.close ();
     133
     134      return mdname;
     135    }
     136
    85137    void
    86138    archive (const std::string&       name,
     
    91143        std::cout << "outputter:archive: " << name << std::endl;
    92144
    93       rld::files::object_list objects;
     145      std::string metadata = metadata_object (name,
     146                                              dependents,
     147                                              cache);
     148
     149      files::object_list objects;
    94150      cache.get_objects (objects);
    95151
Note: See TracChangeset for help on using the changeset viewer.