source: rtems-tools/linkers/rld-elf.cpp @ fe19d06

4.104.11
Last change on this file since fe19d06 was fd8a2c5, checked in by Chris Johns <chrisj@…>, on Nov 20, 2012 at 8:53:24 AM

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.

  • Property mode set to 100644
File size: 23.6 KB
Line 
1/*
2 * Copyright (c) 2011-2012, Chris Johns <chrisj@rtems.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/**
17 * @file
18 *
19 * @ingroup rtems-ld
20 *
21 * @brief RTEMS Linker ELF module manages the ELF format images.
22 *
23 */
24
25#include <string.h>
26
27#include <rld.h>
28
29namespace rld
30{
31  namespace elf
32  {
33    /**
34     * Throw an ELF error.
35     *
36     * @param where Where the error is raised.
37     */
38    void libelf_error (const std::string& where)
39    {
40      throw rld::error (::elf_errmsg (-1), "libelf:" + where);
41    }
42
43    /**
44     * We record the first class, machine and .. type of object file we get the
45     * header of and all header must match. We cannot mix object module types.
46     */
47    static unsigned int elf_object_class = ELFCLASSNONE;
48    static unsigned int elf_object_machinetype = EM_NONE;
49    static unsigned int elf_object_datatype = ELFDATANONE;
50
51    /**
52     * A single place to initialise the libelf library. This must be called
53     * before any libelf API calls are made.
54     */
55    static void
56    libelf_initialise ()
57    {
58      static bool libelf_initialised = false;
59      if (!libelf_initialised)
60      {
61        if (::elf_version (EV_CURRENT) == EV_NONE)
62          libelf_error ("initialisation");
63        libelf_initialised = true;
64      }
65    }
66
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
114    section::section (file& file_, int index_)
115      : file_ (&file_),
116        index_ (index_),
117        scn (0),
118        data_ (0)
119    {
120      memset (&shdr, 0, sizeof (shdr));
121
122      scn = ::elf_getscn (file_.get_elf (), index_);
123      if (!scn)
124        libelf_error ("elf_getscn: " + file_.name ());
125
126      if (!::gelf_getshdr (scn, &shdr))
127        libelf_error ("gelf_getshdr: " + file_.name ());
128
129      if (shdr.sh_type != SHT_NULL)
130      {
131        name_ = file_.get_string (shdr.sh_name);
132        data_ = ::elf_getdata (scn, 0);
133        if (!data_)
134          libelf_error ("elf_getdata: " + name_ + '(' + file_.name () + ')');
135      }
136    }
137
138    section::section (const section& orig)
139      : file_ (orig.file_),
140        index_ (orig.index_),
141        name_ (orig.name_),
142        scn (orig.scn),
143        shdr (orig.shdr),
144        data_ (orig.data_)
145    {
146    }
147
148    section::section ()
149      : file_ (0),
150        index_ (-1),
151        scn (0),
152        data_ (0)
153    {
154      memset (&shdr, 0, sizeof (shdr));
155    }
156
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
181    int
182    section::index () const
183    {
184      check ("index");
185      return index_;
186    }
187
188    const std::string&
189    section::name () const
190    {
191      check ("name");
192      return name_;
193    }
194
195    elf_data*
196    section::data ()
197    {
198      check ("data");
199      return data_;
200    }
201
202    elf_word
203    section::type () const
204    {
205      check ("type");
206      return shdr.sh_type;
207    }
208
209    elf_xword
210    section::flags () const
211    {
212      check ("flags");
213      return shdr.sh_flags;
214    }
215
216    elf_addr
217    section::address () const
218    {
219      check ("address");
220      return shdr.sh_addr;
221    }
222
223    elf_xword
224    section::alignment () const
225    {
226      check ("alignment");
227      return shdr.sh_addralign;
228    }
229
230    elf_off
231    section::offset () const
232    {
233      check ("offset");
234      return shdr.sh_offset;
235    }
236
237    elf_word
238    section::link () const
239    {
240      check ("link");
241      return shdr.sh_link;
242    }
243
244    elf_word
245    section::info () const
246    {
247      check ("info");
248      return shdr.sh_info;
249    }
250
251    elf_xword
252    section::size () const
253    {
254      check ("size");
255      return shdr.sh_size;
256    }
257
258    elf_xword
259    section::entry_size () const
260    {
261      check ("entry_size");
262      return shdr.sh_entsize;
263    }
264
265    int
266    section::entries () const
267    {
268      return size () / entry_size ();
269    }
270
271    void
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;
328    }
329
330    file::file ()
331      : fd_ (-1),
332        archive (false),
333        writable (false),
334        elf_ (0),
335        oclass (0),
336        ident_str (0),
337        ident_size (0),
338        ehdr (0),
339        phdr (0)
340    {
341    }
342
343    file::~file ()
344    {
345      end ();
346    }
347
348    void
349    file::begin (const std::string& name__, int fd__, const bool writable_)
350    {
351      begin (name__, fd__, writable_, 0, 0);
352    }
353
354    void
355    file::begin (const std::string& name__, file& archive_, off_t offset)
356    {
357      archive_.check ("begin:archive");
358
359      if (archive_.writable)
360        throw rld::error ("archive is writable", "elf:file:begin");
361
362      begin (name__, archive_.fd_, false, &archive_, offset);
363    }
364
365    #define rld_archive_fhdr_size (60)
366
367    void
368    file::begin (const std::string& name__,
369                 int                fd__,
370                 const bool         writable_,
371                 file*              archive_,
372                 off_t              offset_)
373    {
374      if (fd__ < 0)
375        throw rld::error ("no file descriptor", "elf:file:begin");
376
377      /*
378       * Begin's are not nesting.
379       */
380      if (elf_ || (fd_ >= 0))
381        throw rld::error ("already called", "elf:file:begin");
382
383      /*
384       * Cannot write directly into archive. Create a file then archive it.
385       */
386      if (archive_ && writable_)
387        throw rld::error ("cannot write into archives directly",
388                          "elf:file:begin");
389
390      libelf_initialise ();
391
392      /*
393       * Is this image part of an archive ?
394       */
395      if (archive_)
396      {
397        ssize_t offset = offset_ - rld_archive_fhdr_size;
398        if (::elf_rand (archive_->elf_, offset) != offset)
399          libelf_error ("rand: " + archive_->name_);
400      }
401
402      /*
403       * Note, the elf passed is either the archive or NULL.
404       */
405      elf* elf__ = ::elf_begin (fd__,
406                                writable_ ? ELF_C_WRITE : ELF_C_READ,
407                                archive_ ? archive_->elf_ : 0);
408      if (!elf__)
409        libelf_error ("begin: " + name__);
410
411      if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
412        std::cout << "elf::begin: " << elf__ << ' ' << name__ << std::endl;
413
414      elf_kind ek = ::elf_kind (elf__);
415
416      /*
417       * If this is inside an archive it must be an ELF file.
418       */
419
420      if (archive_ && (ek != ELF_K_ELF))
421        throw rld::error ("File format in archive not ELF", "elf:file:begin: " + name__);
422      else
423      {
424        if (ek == ELF_K_AR)
425          archive = true;
426        else if (ek == ELF_K_ELF)
427          archive = false;
428        else
429          throw rld::error ("File format not ELF or archive",
430                            "elf:file:begin: " + name__);
431      }
432
433      if (!writable_)
434      {
435        /*
436         * If an ELF file make sure they all match. On the first file that
437         * begins an ELF session record its settings.
438         */
439        if (ek == ELF_K_ELF)
440        {
441          oclass = ::gelf_getclass (elf__);
442          ident_str = elf_getident (elf__, &ident_size);
443        }
444      }
445
446      fd_ = fd__;
447      name_ = name__;
448      writable = writable_;
449      elf_ = elf__;
450
451      if (!archive && !writable)
452        load_header ();
453    }
454
455    void
456    file::end ()
457    {
458      if (elf_)
459      {
460        if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
461          std::cout << "libelf::end: " << elf_
462                    << ' ' << name_ << std::endl;
463        ::elf_end (elf_);
464        elf_ = 0;
465      }
466
467      if (fd_ >= 0)
468      {
469        if (!writable)
470        {
471          if (ehdr)
472          {
473            delete ehdr;
474            ehdr = 0;
475          }
476          if (phdr)
477          {
478            delete phdr;
479            phdr = 0;
480          }
481        }
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
562        {
563          throw rld::error ("No ELF header; set the header first",
564                            "elf:file:load_header: " + name_);
565        }
566      }
567
568      if (::gelf_getehdr (elf_, ehdr) == 0)
569        error ("gelf_getehdr");
570    }
571
572    unsigned int
573    file::machinetype () const
574    {
575      check_ehdr ("machinetype");
576      return ehdr->e_machine;
577    }
578
579    unsigned int
580    file::type () const
581    {
582      check_ehdr ("type");
583      return ehdr->e_type;
584    }
585
586    unsigned int
587    file::object_class () const
588    {
589      check ("object_class");
590      return oclass;
591    }
592
593    unsigned int
594    file::data_type () const
595    {
596      check ("data_type");
597      if (!ident_str)
598        throw rld::error ("No ELF ident str", "elf:file:data_type: " + name_);
599      return ident_str[EI_DATA];
600    }
601
602    bool
603    file::is_archive () const
604    {
605      check ("is_archive");
606      return archive;
607    }
608
609    bool
610    file::is_executable () const
611    {
612      check_ehdr ("is_executable");
613      return ehdr->e_type != ET_REL;
614    }
615
616    bool
617    file::is_relocatable() const
618    {
619      check_ehdr ("is_relocatable");
620      return ehdr->e_type == ET_REL;
621    }
622
623    int
624    file::section_count () const
625    {
626      check_ehdr ("section_count");
627      return ehdr->e_shnum;
628    }
629
630    void
631    file::load_sections ()
632    {
633      if (secs.empty ())
634      {
635        check ("load_sections_headers");
636        for (int sn = 0; sn < section_count (); ++sn)
637        {
638          section sec = section (*this, sn);
639          secs[sec.name ()] = sec;
640        }
641      }
642    }
643
644    void
645    file::get_sections (sections& filtered_secs, unsigned int type)
646    {
647      load_sections ();
648      filtered_secs.clear ();
649      for (section_table::iterator si = secs.begin ();
650           si != secs.end ();
651           ++si)
652      {
653        section& sec = (*si).second;
654        if ((type == 0) || (sec.type () == type))
655          filtered_secs.push_back (&sec);
656      }
657    }
658
659    void
660    file::load_symbols ()
661    {
662      if (symbols.empty ())
663      {
664        sections symbol_secs;
665
666        get_sections (symbol_secs, SHT_SYMTAB);
667
668        for (sections::iterator si = symbol_secs.begin ();
669             si != symbol_secs.end ();
670             ++si)
671        {
672          section& sec = *(*si);
673          int      syms = sec.entries ();
674
675          for (int s = 0; s < syms; ++s)
676          {
677            elf_sym esym;
678
679            if (!::gelf_getsym (sec.data (), s, &esym))
680             error ("gelf_getsym");
681
682            std::string name = get_string (sec.link (), esym.st_name);
683
684            if (!name.empty ())
685            {
686              symbols::symbol sym (name, esym);
687
688              if (rld::verbose () >= RLD_VERBOSE_TRACE)
689              {
690                std::cout << "elf::symbol: ";
691                sym.output (std::cout);
692                std::cout << std::endl;
693              }
694
695              symbols.push_back (sym);
696            }
697          }
698        }
699      }
700    }
701
702    void
703    file::get_symbols (symbols::pointers& filtered_syms,
704                       bool               unresolved,
705                       bool               local,
706                       bool               weak,
707                       bool               global)
708    {
709      if (rld::verbose () >= RLD_VERBOSE_DETAILS)
710        std::cout << "elf:get-syms: unresolved:" << unresolved
711                  << " local:" << local
712                  << " weak:" << weak
713                  << " global:" << global
714                  << " " << name_
715                  << std::endl;
716
717      load_symbols ();
718
719      filtered_syms.clear ();
720
721      for (symbols::bucket::iterator si = symbols.begin ();
722           si != symbols.end ();
723           ++si)
724      {
725        symbols::symbol& sym = *si;
726
727        int stype = sym.type ();
728        int sbind = sym.binding ();
729
730        /*
731         * If wanting unresolved symbols and the type is no-type and the
732         * section is undefined, or, the type is no-type or object or function
733         * and the bind is local and we want local symbols, or the bind is weak
734         * and we want weak symbols, or the bind is global and we want global
735         * symbols then add the filtered symbols container.
736         */
737        bool add = false;
738
739        if ((stype == STT_NOTYPE) && (sym.index () == SHN_UNDEF))
740        {
741          if (unresolved)
742            add = true;
743        }
744        else if (!unresolved)
745        {
746          if (((stype == STT_NOTYPE) ||
747               (stype == STT_OBJECT) ||
748               (stype == STT_FUNC)) &&
749              ((local && (sbind == STB_LOCAL)) ||
750                  (weak && (sbind == STB_WEAK)) ||
751               (global && (sbind == STB_GLOBAL))))
752            add = true;
753        }
754
755        if (add)
756          filtered_syms.push_back (&sym);
757      }
758    }
759
760    int
761    file::strings_section () const
762    {
763      check_ehdr ("strings_sections");
764      return ehdr->e_shstrndx;
765    }
766
767    std::string
768    file::get_string (int section, size_t offset)
769    {
770      check ("get_string");
771      char* s = ::elf_strptr (elf_, section, offset);
772      if (!s)
773        error ("elf_strptr");
774      return s;
775    }
776
777    std::string
778    file::get_string (size_t offset)
779    {
780      check ("get_string");
781      char* s = ::elf_strptr (elf_, strings_section (), offset);
782      if (!s)
783        error ("elf_strptr");
784      return s;
785    }
786
787    void
788    file::set_header (elf_half      type,
789                      int           class_,
790                      elf_half      machinetype,
791                      unsigned char datatype)
792    {
793      check_writable ("set_header");
794
795      if (ehdr)
796          throw rld::error ("ELF header already set",
797                            "elf:file:set_header: " + name_);
798
799      ehdr = (elf_ehdr*) ::gelf_newehdr (elf_, class_);
800      if (ehdr == 0)
801        error ("gelf_newehdr");
802
803      if (::gelf_getehdr (elf_, ehdr) == 0)
804        error ("gelf_getehdr");
805
806      ehdr->e_type = type;
807      ehdr->e_machine = machinetype;
808      ehdr->e_flags = 0;
809      ehdr->e_ident[EI_DATA] = datatype;
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);
827    }
828
829    elf*
830    file::get_elf ()
831    {
832      return elf_;
833    }
834
835    const std::string&
836    file::name () const
837    {
838      return name_;
839    }
840
841    bool
842    file::is_writable () const
843    {
844      return writable;
845    }
846
847    void
848    file::check (const char* where) const
849    {
850      if (!elf_ || (fd_ < 0))
851      {
852        std::string w = where;
853        throw rld::error ("no elf file or file descriptor", "elf:file:" + w);
854      }
855    }
856
857    void
858    file::check_ehdr (const char* where) const
859    {
860      check (where);
861      if (!ehdr)
862      {
863        std::string w = where;
864        throw rld::error ("no elf header", "elf:file:" + w);
865      }
866    }
867
868    void
869    file::check_phdr (const char* where) const
870    {
871      check (where);
872      if (!phdr)
873      {
874        std::string w = where;
875        throw rld::error ("no elf program header", "elf:file:" + w);
876      }
877    }
878
879    void
880    file::check_writable (const char* where) const
881    {
882      check (where);
883      if (!writable)
884      {
885        std::string w = where;
886        throw rld::error ("not writable", "elf:file:" + w);
887      }
888    }
889
890    void
891    file::error (const char* where) const
892    {
893      std::string w = where;
894      libelf_error (w + ": " + name_);
895    }
896
897    const std::string
898    machine_type (unsigned int machinetype)
899    {
900      struct types_and_labels
901      {
902        const char*  name;        //< The RTEMS label.
903        unsigned int machinetype; //< The machine type.
904      };
905      types_and_labels types_to_labels[] =
906      {
907        { "arm",     EM_ARM },
908        { "avr",     EM_AVR },
909        { "bfin",    EM_BLACKFIN },
910        { "h8300",   EM_H8_300 },
911        { "i386",    EM_386 },
912     /* { "m32c",    EM_M32C }, Not in libelf I imported */
913        { "m32r",    EM_M32R },
914        { "m68k",    EM_68K },
915        { "m68k",    EM_COLDFIRE },
916        { "mips",    EM_MIPS },
917        { "powerpc", EM_PPC },
918        { "sh",      EM_SH },
919        { "sparc",   EM_SPARC },
920        { "sparc64", EM_SPARC },
921        { 0,         EM_NONE }
922      };
923
924      int m = 0;
925      while (types_to_labels[m].machinetype != EM_NONE)
926      {
927        if (machinetype == types_to_labels[m].machinetype)
928          return types_to_labels[m].name;
929        ++m;
930      }
931
932      std::ostringstream what;
933      what << "unknown machine type: " << elf_object_machinetype;
934      throw rld::error (what, "machine-type");
935    }
936
937    const std::string
938    machine_type ()
939    {
940      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;
959    }
960
961    void
962    check_file(const file& file)
963    {
964      if (elf_object_machinetype == EM_NONE)
965        elf_object_machinetype = file.machinetype ();
966      else if (file.machinetype () != elf_object_machinetype)
967      {
968        std::ostringstream oss;
969        oss << "elf:check_file:" << file.name ()
970            << ": " << elf_object_machinetype << '/' << file.machinetype ();
971        throw rld::error ("Mixed machine types not supported.", oss.str ());
972      }
973
974      if (elf_object_class == ELFCLASSNONE)
975        elf_object_class = file.object_class ();
976      else if (file.object_class () != elf_object_class)
977        throw rld::error ("Mixed classes not allowed (32bit/64bit).",
978                          "elf:check_file: " + file.name ());
979
980      if (elf_object_datatype == ELFDATANONE)
981        elf_object_datatype = file.data_type ();
982      else if (elf_object_datatype != file.data_type ())
983        throw rld::error ("Mixed data types not allowed (LSB/MSB).",
984                          "elf:check_file: " + file.name ());
985    }
986
987  }
988}
Note: See TracBrowser for help on using the repository browser.