source: rtems-tools/rtemstoolkit/rld-elf.h @ 74768d2

4.11
Last change on this file since 74768d2 was 74768d2, checked in by Chris Johns <chrisj@…>, on 10/02/20 at 23:34:37

rtemstoolkit: Fix gcc warning in rtems-elf

  • Property mode set to 100644
File size: 22.2 KB
Line 
1/*
2 * Copyright (c) 2011, 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 libelf interface.
22 *
23 */
24
25#if !defined (_RLD_ELF_H_)
26#define _RLD_ELF_H_
27
28#include <list>
29#include <map>
30#include <vector>
31
32#include <rld.h>
33
34namespace rld
35{
36  namespace elf
37  {
38    /**
39     * Forward decl.
40     */
41    class file;
42
43    /**
44     * A relocation record.
45     */
46    class relocation
47    {
48    public:
49      /**
50       * Construct a relocation record.
51       *
52       * @param sym The symbol the relocation references.
53       * @param offset The offset in the section the relocation applies to.
54       * @param info The relocation info.
55       * @param addend The constant addend value.
56       */
57      relocation (const symbols::symbol& sym,
58                  elf_addr               offset,
59                  elf_xword              info,
60                  elf_sxword             addend = 0);
61
62      /**
63       * Default constructor.
64       */
65      relocation ();
66
67      /**
68       * The offset.
69       */
70      elf_addr offset () const;
71
72      /**
73       * The type of the relocation record.
74       */
75      uint32_t type () const;
76
77      /**
78       * The info.
79       */
80      elf_xword info () const;
81
82      /**
83       * The constant addend.
84       */
85      elf_sxword addend () const;
86
87      /**
88       * Return the symbol.
89       */
90      const symbols::symbol& symbol () const;
91
92    private:
93      const symbols::symbol* sym;     //< The symbol reference.
94      elf_addr               offset_;  //< The offset in the section.
95      elf_xword              info_;    //< The record's information.
96      elf_sxword             addend_;  //< The constant addend value.
97    };
98
99    /**
100     * A container of relocation records.
101     */
102    typedef std::vector < relocation > relocations;
103
104    /**
105     * An ELF Section. The current implementation only supports a single data
106     * descriptor with a section.
107     */
108    class section
109    {
110    public:
111      /**
112       * Construct the section getting the details from the ELF file given the
113       * section index.
114       *
115       * The section types are (from elf(3)):
116       *
117       *  Section Type         Library Type     Description
118       *  ------------         ------------     -----------
119       *   SHT_DYNAMIC          ELF_T_DYN        `.dynamic' section entries.
120       *   SHT_DYNSYM           ELF_T_SYM        Symbols for dynamic linking.
121       *   SHT_FINI_ARRAY       ELF_T_ADDR       Termination function pointers.
122       *   SHT_GROUP            ELF_T_WORD       Section group marker.
123       *   SHT_HASH             ELF_T_HASH       Symbol hashes.
124       *   SHT_INIT_ARRAY       ELF_T_ADDR       Initialization function pointers.
125       *   SHT_NOBITS           ELF_T_BYTE       Empty sections.  See elf(5).
126       *   SHT_NOTE             ELF_T_NOTE       ELF note records.
127       *   SHT_PREINIT_ARRAY    ELF_T_ADDR       Pre-initialization function
128       *                                         pointers.
129       *   SHT_PROGBITS         ELF_T_BYTE       Machine code.
130       *   SHT_REL              ELF_T_REL        ELF relocation records.
131       *   SHT_RELA             ELF_T_RELA       Relocation records with addends.
132       *   SHT_STRTAB           ELF_T_BYTE       String tables.
133       *   SHT_SYMTAB           ELF_T_SYM        Symbol tables.
134       *   SHT_SYMTAB_SHNDX     ELF_T_WORD       Used with extended section
135       *                                         numbering.
136       *   SHT_GNU_verdef       ELF_T_VDEF       Symbol version definitions.
137       *   SHT_GNU_verneed      ELF_T_VNEED      Symbol versioning requirements.
138       *   SHT_GNU_versym       ELF_T_HALF       Version symbols.
139       *   SHT_SUNW_move        ELF_T_MOVE       ELF move records.
140       *   SHT_SUNW_syminfo     ELF_T_SYMINFO    Additional symbol flags.
141       *
142       * @param file_ The ELF file this section is part of.
143       * @param index_ The section's index.
144       * @param name The section's name.
145       * @param type The section's type.
146       * @param alignment The section's alignment.
147       * @param flags The section's flags.
148       * @param addr The section's in-memory address.
149       * @param offset The section's offset in the file.
150       * @param size The section's file in bytes.
151       * @param link The section's header table link.
152       * @param info The section's extra information.
153       * @param entry_size The section's entry size.
154       */
155      section (file&              file_,
156               int                index_,
157               const std::string& name,
158               elf_word           type,
159               elf_xword          alignment,
160               elf_xword          flags,
161               elf_addr           addr,
162               elf_off            offset,
163               elf_xword          size,
164               elf_word           link = 0,
165               elf_word           info = 0,
166               elf_xword          entry_size = 0);
167
168      /**
169       * Construct the section given the details. The ELF file must be
170       * writable.
171       *
172       * @param file_ The ELF file this section is part of.
173       * @param index The section's index in the ELF file.
174       */
175      section (file& file_, int index);
176
177      /**
178       * Copy constructor.
179       */
180      section (const section& orig);
181
182      /**
183       * Default constructor.
184       */
185      section ();
186
187      /**
188       * Default assignment operator.
189       */
190      section& operator=(const rld::elf::section&) = default;
191
192      /**
193       * Add a data segment descriptor to the section if the file is writable.
194       *
195       * These are following data types (from elf(3)):
196       *
197       *   ELF_T_ADDR     Machine addresses.
198       *   ELF_T_BYTE     Byte data.  The library will not attempt to translate
199       *                  byte data.
200       *   ELF_T_CAP      Software and hardware capability records.
201       *   ELF_T_DYN      Records used in a section of type SHT_DYNAMIC.
202       *   ELF_T_EHDR     ELF executable header.
203       *   ELF_T_HALF     16-bit unsigned words.
204       *   ELF_T_LWORD    64 bit unsigned words.
205       *   ELF_T_MOVE     ELF Move records.
206       *   ELF_T_NOTE     ELF Note structures.
207       *   ELF_T_OFF      File offsets.
208       *   ELF_T_PHDR     ELF program header table entries.
209       *   ELF_T_REL      ELF relocation entries.
210       *   ELF_T_RELA     ELF relocation entries with addends.
211       *   ELF_T_SHDR     ELF section header entries.
212       *   ELF_T_SWORD    Signed 32-bit words.
213       *   ELF_T_SXWORD   Signed 64-bit words.
214       *   ELF_T_SYMINFO  ELF symbol information.
215       *   ELF_T_SYM      ELF symbol table entries.
216       *   ELF_T_VDEF     Symbol version definition records.
217       *   ELF_T_VNEED    Symbol version requirement records.
218       *   ELF_T_WORD     Unsigned 32-bit words.
219       *   ELF_T_XWORD    Unsigned 64-bit words.
220       *
221       * @param type The type of data in the segment.
222       * @param alignment The in-file alignment of the data. Must be a power of 2.
223       * @param size The number of bytes in this data descriptor.
224       * @param buffer The data in memory.
225       * @param offset The offset within the containing section. Can be computed.
226       */
227      void add_data (elf_type  type,
228                     elf_xword alignment,
229                     elf_xword size,
230                     void*     buffer = 0,
231                     elf_off   offset = 0);
232
233       /**
234       * The section's index in the ELF file.
235       *
236       * @return int The section number.
237       */
238      int index () const;
239
240      /**
241       * The name of the section.
242       *
243       * @return const std::string& The section's name.
244       */
245      const std::string& name () const;
246
247      /**
248       * The section's data.
249       */
250      elf_data* data ();
251
252      /**
253       * Get the type of the section.
254       */
255      elf_word type () const;
256
257      /**
258       * The section flags.
259       */
260      elf_xword flags () const;
261
262      /**
263       * In-memory address of the section.
264       */
265      elf_addr address () const;
266
267      /**
268       * Alignment constraint.
269       */
270      elf_xword alignment () const;
271
272      /**
273       * The file offset of the section.
274       */
275      elf_off offset () const;
276
277      /**
278       * The header table link.
279       */
280      elf_word link () const;
281
282      /**
283       * Extra information.
284       */
285      elf_word info () const;
286
287      /**
288       * Size of the section.
289       */
290      elf_xword size () const;
291
292      /**
293       * Size of the entries in the section.
294       */
295      elf_xword entry_size () const;
296
297      /**
298       * Number of entries.
299       */
300      int entries () const;
301
302      /**
303       * Return true if the relocation record have an addend field.
304       *
305       * @retval true The relocation record have the addend field.
306       */
307      bool get_reloc_type () const;
308
309      /**
310       * Set the name index if writable. This is normally done
311       * automatically when adding the section to the file.
312       */
313      void set_name (unsigned int index);
314
315      /**
316       * Set the type of relocation records.
317       *
318       * @param rela If true the records are rela type.
319       */
320      void set_reloc_type (bool rela);
321
322      /**
323       * Add a relocation.
324       *
325       * @param reloc The relocation record to add.
326       */
327      void add (const relocation& reloc);
328
329      /**
330       * Get the relocations.
331       */
332      const relocations& get_relocations () const;
333
334    private:
335
336      /**
337       * Check the section is valid.
338       *
339       * @param where Where the check is being made.
340       */
341      void check (const char* where) const;
342
343      /**
344       * Check the section is valid and writable.
345       *
346       * @param where Where the check is being made.
347       */
348      void check_writable (const char* where) const;
349
350      file*       file_;  //< The ELF file.
351      int         index_; //< The section header index.
352      std::string name_;  //< The section's name.
353      elf_scn*    scn;    //< ELF private section data.
354      elf_shdr    shdr;   //< The section header.
355      elf_data*   data_;  //< The section's data.
356      bool        rela;   //< The type of relocation records.
357      relocations relocs; //< The relocation records.
358    };
359
360    /**
361     * Container of ELF section pointers.
362     */
363    typedef std::list < section* > sections;
364
365    /**
366     * Container of ELF section as a map, ie associative array.
367     */
368    typedef std::map < std::string, section > section_table;
369
370    /**
371     * An ELF program header.
372     */
373    class program_header
374    {
375    public:
376      /**
377       * Construct a program header.
378       */
379      program_header ();
380
381      /**
382       * Desctruct a program header.
383       */
384      ~program_header ();
385
386      /**
387       * Set the program header.
388       *
389       * @param type The type of segment.
390       * @param flags The segment's flags.
391       * @param offset The offet to segment.
392       * @param filesz The segment size in the file.
393       * @param memsz The segment size in memory.
394       * @param align The segment alignment.
395       * @param vaddr The virtual address in memory.
396       * @param paddr The physical address if any.
397       */
398      void set (elf_word type,
399                elf_word flags,
400                elf_off offset,
401                elf_xword filesz,
402                elf_xword memsz,
403                elf_xword align,
404                elf_addr vaddr,
405                elf_addr paddr = 0);
406
407    private:
408
409      elf_phdr phdr;  //< The ELF program header.
410    };
411
412    /**
413     * A container of program headers.
414     */
415    typedef std::list < program_header > program_headers;
416
417    /**
418     * An ELF file.
419     */
420    class file
421    {
422    public:
423     /**
424       * Construct an ELF file.
425       */
426      file ();
427
428      /**
429       * Destruct the ELF file object.
430       */
431      ~file ();
432
433      /**
434       * Begin using the ELF file.
435       *
436       * @param name The full name of the file.
437       * @param fd The file descriptor to read or write the file.
438       * @param writable The file is writeable. The default is false.
439       */
440      void begin (const std::string& name, int fd, const bool writable = false);
441
442      /**
443       * Begin using the ELF file in an archive.
444       *
445       * @param name The full name of the file.
446       * @param archive The file that is the archive.
447       * @param offset The offset of the ELF file in the archive.
448       */
449      void begin (const std::string& name, file& archive, off_t offset);
450
451      /**
452       * End using the ELF file.
453       */
454      void end ();
455
456      /**
457       * Write the ELF file creating it if it is writable. You should have
458       * added the sections and the data segment descriptors to the sections
459       * before calling write.
460       */
461      void write ();
462
463      /**
464       * Load the header. Done automatically.
465       */
466      void load_header ();
467
468      /**
469       * Get the machine type.
470       */
471      unsigned int machinetype () const;
472
473      /**
474       * Get the type of ELF file.
475       */
476      unsigned int type () const;
477
478      /**
479       * Get the class of the object file.
480       */
481      unsigned int object_class () const;
482
483      /**
484       * Get the data type, ie LSB or MSB.
485       */
486      unsigned int data_type () const;
487
488      /**
489       * Is the file an archive format file ?
490       */
491      bool is_archive () const;
492
493      /**
494       * Is the file an executable ?
495       */
496      bool is_executable () const;
497
498      /**
499       * Is the file relocatable ?
500       */
501      bool is_relocatable() const;
502
503      /**
504       * The number of sections in the file.
505       */
506      int section_count () const;
507
508      /**
509       * Load the sections.
510       */
511      void load_sections ();
512
513      /**
514       * Get a filtered container of the sections. The key is the section
515       * type. If the sections are not loaded they are loaded. If the type is 0
516       * all sections are returned.
517       *
518       * @param filtered_secs The container the copy of the filtered sections
519       *                      are placed in.
520       * @param type The type of sections to filter on. If 0 all sections are
521       *             matched.
522       */
523      void get_sections (sections& filtered_secs, unsigned int type);
524
525      /**
526       * Return the section with given index.
527       *
528       * @param index The section's index to look for.
529       * @retval section The section matching the index.
530       */
531      section& get_section (int index);
532
533      /**
534       * Return the index of the string section.
535       */
536      int strings_section () const;
537
538      /**
539       * Get the string from the specified section at the requested offset.
540       *
541       * @param section The section to search for the string.
542       * @param offset The offset in the string section.
543       * @return std::string The string.
544       */
545      std::string get_string (int section, size_t offset);
546
547      /**
548       * Get the string from the ELF header declared string section at the
549       * requested offset.
550       *
551       * @param offset The offset in the string section.
552       * @return std::string The string.
553       */
554      std::string get_string (size_t offset);
555
556      /**
557       * Load the symbols.
558       */
559      void load_symbols ();
560
561      /**
562       * Get a filtered container of symbols given the various types. If the
563       * symbols are not loaded they are loaded.
564       *
565       * @param filtered_syms The filtered symbols found in the file. This is a
566       *                      container of pointers.
567       * @param unresolved Return unresolved symbols.
568       * @param local Return local symbols.
569       * @param weak Return weak symbols.
570       * @param global Return global symbols.
571       */
572      void get_symbols (rld::symbols::pointers& filtered_syms,
573                        bool                    unresolved = false,
574                        bool                    local = false,
575                        bool                    weak = true,
576                        bool                    global = true);
577
578      /**
579       * Get the symbol by index in the symtabl section.
580       */
581      const symbols::symbol& get_symbol (const int index) const;
582
583      /**
584       * Load the relocation records.
585       */
586      void load_relocations ();
587
588      /**
589       * Clear the relocation records.
590       */
591      void clear_relocations ();
592
593      /**
594       * Set the ELF header. Must be writable.
595       *
596       * The classes are:
597       *   ELFCLASSNONE  This class is invalid.
598       *   ELFCLASS32    This defines the 32-bit architecture.  It sup- ports
599       *                 machines with files and virtual address spa- ces up to
600       *                 4 Gigabytes.
601       *   ELFCLASS64    This defines the 64-bit architecture.
602       *
603       * The types are:
604       *   ET_NONE  An unknown type.
605       *   ET_REL   A relocatable file.
606       *   ET_EXEC  An executable file.
607       *   ET_DYN   A shared object.
608       *   ET_CORE  A core file.
609       *
610       * The machine types are:
611       *   TDB
612       *
613       * The datatypes are:
614       *   ELFDATA2LSB  Two's complement, little-endian.
615       *   ELFDATA2MSB  Two's complement, big-endian.
616       *
617       * @param type The type of ELF file, ie executable, relocatable etc.
618       * @param class_ The files ELF class.
619       * @param machinetype The type of machine code present in the ELF file.
620       * @param datatype The data type, ie LSB or MSB.
621       */
622      void set_header (elf_half      type,
623                       int           class_,
624                       elf_half      machinetype,
625                       unsigned char datatype);
626
627      /**
628       * Add a section to the ELF file if writable.
629       */
630      void add (section& sec);
631
632      /**
633       * Add a program header to the ELF file if writable.
634       */
635      void add (program_header& phdr);
636
637      /**
638       * Get the ELF reference.
639       */
640      elf* get_elf ();
641
642      /**
643       * Get the name of the file.
644       */
645      const std::string& name () const;
646
647      /**
648       * Is the file writable ?
649       */
650      bool is_writable () const;
651
652    private:
653
654      /**
655       * Begin using the ELF file.
656       *
657       * @param name The full name of the file.
658       * @param fd The file descriptor to read or write the file.
659       * @param writable The file is writeable. It cannot be part of an archive.
660       * @param archive The archive's ELF handle or 0 if not an archive.
661       * @param offset The offset of the ELF file in the archive if elf is non-zero.
662       */
663      void begin (const std::string& name,
664                  int                fd,
665                  const bool         writable,
666                  file*              archive,
667                  off_t              offset);
668
669      /**
670       * Check if the file is usable. Throw an exception if not.
671       *
672       * @param where Where the check is performed.
673       */
674      void check (const char* where) const;
675
676      /**
677       * Check if the file is usable and writable. Throw an exception if not.
678       *
679       * @param where Where the check is performed.
680       */
681      void check_writable (const char* where) const;
682
683      /**
684       * Check if the ELF header is valid. Throw an exception if not.
685       *
686       * @param where Where the check is performed.
687       */
688      void check_ehdr (const char* where) const;
689
690      /**
691       * Check if the ELF program header is valid. Throw an exception if not.
692       *
693       * @param where Where the check is performed.
694       */
695      void check_phdr (const char* where) const;
696
697      /**
698       * Generate libelf error.
699       *
700       * @param where Where the error is generated.
701       */
702      void error (const char* where) const;
703
704      int                  fd_;        //< The file handle.
705      std::string          name_;      //< The name of the file.
706      bool                 archive;    //< The ELF file is part of an archive.
707      bool                 writable;   //< The file is writeable.
708      elf*                 elf_;       //< The ELF handle.
709      unsigned int         mtype;      //< The machine type.
710      unsigned int         oclass;     //< The object class.
711      const char*          ident_str;  //< The ELF file's ident string.
712      size_t               ident_size; //< The size of the ident.
713      elf_ehdr*            ehdr;       //< The ELF header.
714      elf_phdr*            phdr;       //< The ELF program header.
715      section_table        secs;       //< The sections as a table.
716      program_headers      phdrs;      //< The program headers when creating
717                                       //  ELF files.
718      rld::symbols::bucket symbols;    //< The symbols. All tables point here.
719    };
720
721    /**
722     * Return the machine type label given the machine type.
723     *
724     * @param machinetype The ELF machine type.
725     */
726    const std::string machine_type (unsigned int machinetype);
727
728    /**
729     * Return the global machine type set by the check_file call as a string.
730     */
731    const std::string machine_type ();
732
733    /**
734     * Return the global class set by the check_file call.
735     */
736    unsigned int object_class ();
737
738    /**
739     * Return the global machine type set by the check_file call.
740     */
741    unsigned int object_machine_type ();
742
743    /**
744     * Return the global data type set by the check_file call.
745     */
746    unsigned int object_datatype ();
747
748    /**
749     * Check the file against the global machine type, object class and data
750     * type. If this is the first file checked it becomes the default all
751     * others are checked against. This is a simple way to make sure all files
752     * are the same type.
753     *
754     * @param file The check to check.
755     */
756    void check_file(const file& file);
757
758  }
759}
760
761#endif
Note: See TracBrowser for help on using the repository browser.