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

4.104.115
Last change on this file since be8e188 was c6b714f, checked in by Chris Johns <chrisj@…>, on 11/25/12 at 23:57:29

Load the sections by default. It is not much extra overhead.

Clean up the error messages.
Remove the copy constructor call on creating sections.
Change the symbols trace to the new symbols trace level.

  • 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",
422                          "elf:file:begin: " + name__);
423      else
424      {
425        if (ek == ELF_K_AR)
426          archive = true;
427        else if (ek == ELF_K_ELF)
428          archive = false;
429        else
430          throw rld::error ("File format not ELF or archive",
431                            "elf:file:begin: " + name__);
432      }
433
434      if (!writable_)
435      {
436        /*
437         * If an ELF file make sure they all match. On the first file that
438         * begins an ELF session record its settings.
439         */
440        if (ek == ELF_K_ELF)
441        {
442          oclass = ::gelf_getclass (elf__);
443          ident_str = elf_getident (elf__, &ident_size);
444        }
445      }
446
447      fd_ = fd__;
448      name_ = name__;
449      writable = writable_;
450      elf_ = elf__;
451
452      if (!archive && !writable)
453      {
454        load_header ();
455        load_sections ();
456      }
457    }
458
459    void
460    file::end ()
461    {
462      if (elf_)
463      {
464        if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
465          std::cout << "libelf::end: " << elf_
466                    << ' ' << name_ << std::endl;
467        ::elf_end (elf_);
468        elf_ = 0;
469      }
470
471      if (fd_ >= 0)
472      {
473        if (!writable)
474        {
475          if (ehdr)
476          {
477            delete ehdr;
478            ehdr = 0;
479          }
480          if (phdr)
481          {
482            delete phdr;
483            phdr = 0;
484          }
485        }
486
487        fd_ = -1;
488        name_.clear ();
489        archive = false;
490        elf_ = 0;
491        oclass = 0;
492        ident_str = 0;
493        ident_size = 0;
494        writable = false;
495        secs.clear ();
496      }
497    }
498
499    void
500    file::write ()
501    {
502      check_writable ("write");
503
504      std::string shstrtab;
505
506      for (section_table::iterator sti = secs.begin ();
507           sti != secs.end ();
508           ++sti)
509      {
510        section& sec = (*sti).second;
511        int added_at = shstrtab.size ();
512        shstrtab += '\0' + sec.name ();
513        sec.set_name (added_at + 1);
514      }
515
516      unsigned int shstrtab_name = shstrtab.size () + 1;
517
518      /*
519       * Done this way to clang happy on darwin.
520       */
521      shstrtab += '\0';
522      shstrtab += ".shstrtab";
523
524      /*
525       * Create the string table section.
526       */
527      section shstrsec (*this,
528                        secs.size () + 1,          /* index */
529                        ".shstrtab",               /* name */
530                        SHT_STRTAB,                /* type */
531                        1,                         /* alignment */
532                        SHF_STRINGS | SHF_ALLOC,   /* flags */
533                        0,                         /* address */
534                        0,                         /* offset */
535                        shstrtab.size ());         /* size */
536
537      shstrsec.add_data (ELF_T_BYTE,
538                         1,
539                         shstrtab.size (),
540                         (void*) shstrtab.c_str ());
541
542      shstrsec.set_name (shstrtab_name);
543
544      ::elf_setshstrndx (elf_, shstrsec.index ());
545      ::elf_flagehdr (elf_, ELF_C_SET, ELF_F_DIRTY);
546
547      if (elf_update (elf_, ELF_C_NULL) < 0)
548        libelf_error ("elf_update:layout: " + name_);
549
550      ::elf_flagphdr (elf_, ELF_C_SET, ELF_F_DIRTY);
551
552      if (::elf_update (elf_, ELF_C_WRITE) < 0)
553        libelf_error ("elf_update:write: " + name_);
554    }
555
556    void
557    file::load_header ()
558    {
559      check ("load_header");
560
561      if (!ehdr)
562      {
563        if (!writable)
564          ehdr = new elf_ehdr;
565        else
566        {
567          throw rld::error ("No ELF header; set the header first",
568                            "elf:file:load_header: " + name_);
569        }
570      }
571
572      if (::gelf_getehdr (elf_, ehdr) == 0)
573        error ("gelf_getehdr");
574    }
575
576    unsigned int
577    file::machinetype () const
578    {
579      check_ehdr ("machinetype");
580      return ehdr->e_machine;
581    }
582
583    unsigned int
584    file::type () const
585    {
586      check_ehdr ("type");
587      return ehdr->e_type;
588    }
589
590    unsigned int
591    file::object_class () const
592    {
593      check ("object_class");
594      return oclass;
595    }
596
597    unsigned int
598    file::data_type () const
599    {
600      check ("data_type");
601      if (!ident_str)
602        throw rld::error ("No ELF ident str", "elf:file:data_type: " + name_);
603      return ident_str[EI_DATA];
604    }
605
606    bool
607    file::is_archive () const
608    {
609      check ("is_archive");
610      return archive;
611    }
612
613    bool
614    file::is_executable () const
615    {
616      check_ehdr ("is_executable");
617      return ehdr->e_type != ET_REL;
618    }
619
620    bool
621    file::is_relocatable() const
622    {
623      check_ehdr ("is_relocatable");
624      return ehdr->e_type == ET_REL;
625    }
626
627    int
628    file::section_count () const
629    {
630      check_ehdr ("section_count");
631      return ehdr->e_shnum;
632    }
633
634    void
635    file::load_sections ()
636    {
637      if (secs.empty ())
638      {
639        check ("load_sections_headers");
640        for (int sn = 0; sn < section_count (); ++sn)
641        {
642          section sec (*this, sn);
643          secs[sec.name ()] = sec;
644        }
645      }
646    }
647
648    void
649    file::get_sections (sections& filtered_secs, unsigned int type)
650    {
651      load_sections ();
652      filtered_secs.clear ();
653      for (section_table::iterator si = secs.begin ();
654           si != secs.end ();
655           ++si)
656      {
657        section& sec = (*si).second;
658        if ((type == 0) || (sec.type () == type))
659          filtered_secs.push_back (&sec);
660      }
661    }
662
663    void
664    file::load_symbols ()
665    {
666      if (symbols.empty ())
667      {
668        sections symbol_secs;
669
670        get_sections (symbol_secs, SHT_SYMTAB);
671
672        for (sections::iterator si = symbol_secs.begin ();
673             si != symbol_secs.end ();
674             ++si)
675        {
676          section& sec = *(*si);
677          int      syms = sec.entries ();
678
679          for (int s = 0; s < syms; ++s)
680          {
681            elf_sym esym;
682
683            if (!::gelf_getsym (sec.data (), s, &esym))
684             error ("gelf_getsym");
685
686            std::string name = get_string (sec.link (), esym.st_name);
687
688            if (!name.empty ())
689            {
690              symbols::symbol sym (name, esym);
691
692              if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
693              {
694                std::cout << "elf:symbol: ";
695                sym.output (std::cout);
696                std::cout << std::endl;
697              }
698
699              symbols.push_back (sym);
700            }
701          }
702        }
703      }
704    }
705
706    void
707    file::get_symbols (symbols::pointers& filtered_syms,
708                       bool               unresolved,
709                       bool               local,
710                       bool               weak,
711                       bool               global)
712    {
713      if (rld::verbose () >= RLD_VERBOSE_DETAILS)
714        std::cout << "elf:get-syms: unresolved:" << unresolved
715                  << " local:" << local
716                  << " weak:" << weak
717                  << " global:" << global
718                  << " " << name_
719                  << std::endl;
720
721      load_symbols ();
722
723      filtered_syms.clear ();
724
725      for (symbols::bucket::iterator si = symbols.begin ();
726           si != symbols.end ();
727           ++si)
728      {
729        symbols::symbol& sym = *si;
730
731        int stype = sym.type ();
732        int sbind = sym.binding ();
733
734        /*
735         * If wanting unresolved symbols and the type is no-type and the
736         * section is undefined, or, the type is no-type or object or function
737         * and the bind is local and we want local symbols, or the bind is weak
738         * and we want weak symbols, or the bind is global and we want global
739         * symbols then add the filtered symbols container.
740         */
741        bool add = false;
742
743        if ((stype == STT_NOTYPE) && (sym.index () == SHN_UNDEF))
744        {
745          if (unresolved)
746            add = true;
747        }
748        else if (!unresolved)
749        {
750          if (((stype == STT_NOTYPE) ||
751               (stype == STT_OBJECT) ||
752               (stype == STT_FUNC)) &&
753              ((local && (sbind == STB_LOCAL)) ||
754                  (weak && (sbind == STB_WEAK)) ||
755               (global && (sbind == STB_GLOBAL))))
756            add = true;
757        }
758
759        if (add)
760          filtered_syms.push_back (&sym);
761      }
762    }
763
764    int
765    file::strings_section () const
766    {
767      check_ehdr ("strings_sections");
768      return ehdr->e_shstrndx;
769    }
770
771    std::string
772    file::get_string (int section, size_t offset)
773    {
774      check ("get_string");
775      char* s = ::elf_strptr (elf_, section, offset);
776      if (!s)
777        error ("elf_strptr");
778      return s;
779    }
780
781    std::string
782    file::get_string (size_t offset)
783    {
784      check ("get_string");
785      char* s = ::elf_strptr (elf_, strings_section (), offset);
786      if (!s)
787        error ("elf_strptr");
788      return s;
789    }
790
791    void
792    file::set_header (elf_half      type,
793                      int           class_,
794                      elf_half      machinetype,
795                      unsigned char datatype)
796    {
797      check_writable ("set_header");
798
799      if (ehdr)
800          throw rld::error ("ELF header already set",
801                            "elf:file:set_header: " + name_);
802
803      ehdr = (elf_ehdr*) ::gelf_newehdr (elf_, class_);
804      if (ehdr == 0)
805        error ("gelf_newehdr");
806
807      if (::gelf_getehdr (elf_, ehdr) == 0)
808        error ("gelf_getehdr");
809
810      ehdr->e_type = type;
811      ehdr->e_machine = machinetype;
812      ehdr->e_flags = 0;
813      ehdr->e_ident[EI_DATA] = datatype;
814      ehdr->e_version = EV_CURRENT;
815
816      ::elf_flagphdr (elf_, ELF_C_SET , ELF_F_DIRTY);
817    }
818
819    void
820    file::add (section& sec)
821    {
822      check_writable ("add");
823      secs[sec.name ()] = sec;
824    }
825
826    void
827    file::add (program_header& phdr)
828    {
829      check_writable ("add");
830      phdrs.push_back (phdr);
831    }
832
833    elf*
834    file::get_elf ()
835    {
836      return elf_;
837    }
838
839    const std::string&
840    file::name () const
841    {
842      return name_;
843    }
844
845    bool
846    file::is_writable () const
847    {
848      return writable;
849    }
850
851    void
852    file::check (const char* where) const
853    {
854      if (!elf_ || (fd_ < 0))
855      {
856        std::string w = where;
857        throw rld::error ("No ELF file or file descriptor", "elf:file:" + w);
858      }
859    }
860
861    void
862    file::check_ehdr (const char* where) const
863    {
864      check (where);
865      if (!ehdr)
866      {
867        std::string w = where;
868        throw rld::error ("no elf header", "elf:file:" + w);
869      }
870    }
871
872    void
873    file::check_phdr (const char* where) const
874    {
875      check (where);
876      if (!phdr)
877      {
878        std::string w = where;
879        throw rld::error ("no elf program header", "elf:file:" + w);
880      }
881    }
882
883    void
884    file::check_writable (const char* where) const
885    {
886      check (where);
887      if (!writable)
888      {
889        std::string w = where;
890        throw rld::error ("not writable", "elf:file:" + w);
891      }
892    }
893
894    void
895    file::error (const char* where) const
896    {
897      std::string w = where;
898      libelf_error (w + ": " + name_);
899    }
900
901    const std::string
902    machine_type (unsigned int machinetype)
903    {
904      struct types_and_labels
905      {
906        const char*  name;        //< The RTEMS label.
907        unsigned int machinetype; //< The machine type.
908      };
909      types_and_labels types_to_labels[] =
910      {
911        { "arm",     EM_ARM },
912        { "avr",     EM_AVR },
913        { "bfin",    EM_BLACKFIN },
914        { "h8300",   EM_H8_300 },
915        { "i386",    EM_386 },
916     /* { "m32c",    EM_M32C }, Not in libelf I imported */
917        { "m32r",    EM_M32R },
918        { "m68k",    EM_68K },
919        { "m68k",    EM_COLDFIRE },
920        { "mips",    EM_MIPS },
921        { "powerpc", EM_PPC },
922        { "sh",      EM_SH },
923        { "sparc",   EM_SPARC },
924        { "sparc64", EM_SPARC },
925        { 0,         EM_NONE }
926      };
927
928      int m = 0;
929      while (types_to_labels[m].machinetype != EM_NONE)
930      {
931        if (machinetype == types_to_labels[m].machinetype)
932          return types_to_labels[m].name;
933        ++m;
934      }
935
936      std::ostringstream what;
937      what << "unknown machine type: " << elf_object_machinetype;
938      throw rld::error (what, "machine-type");
939    }
940
941    const std::string
942    machine_type ()
943    {
944      return machine_type (elf_object_machinetype);
945    }
946
947    unsigned int
948    object_class ()
949    {
950      return elf_object_class;
951    }
952
953    unsigned int
954    object_machine_type ()
955    {
956      return elf_object_machinetype;
957    }
958
959    unsigned int
960    object_datatype ()
961    {
962      return elf_object_datatype;
963    }
964
965    void
966    check_file(const file& file)
967    {
968      if (elf_object_machinetype == EM_NONE)
969        elf_object_machinetype = file.machinetype ();
970      else if (file.machinetype () != elf_object_machinetype)
971      {
972        std::ostringstream oss;
973        oss << "elf:check_file:" << file.name ()
974            << ": " << elf_object_machinetype << '/' << file.machinetype ();
975        throw rld::error ("Mixed machine types not supported.", oss.str ());
976      }
977
978      if (elf_object_class == ELFCLASSNONE)
979        elf_object_class = file.object_class ();
980      else if (file.object_class () != elf_object_class)
981        throw rld::error ("Mixed classes not allowed (32bit/64bit).",
982                          "elf:check_file: " + file.name ());
983
984      if (elf_object_datatype == ELFDATANONE)
985        elf_object_datatype = file.data_type ();
986      else if (elf_object_datatype != file.data_type ())
987        throw rld::error ("Mixed data types not allowed (LSB/MSB).",
988                          "elf:check_file: " + file.name ());
989    }
990
991  }
992}
Note: See TracBrowser for help on using the repository browser.