source: rtems-tools/rtemstoolkit/rld-elf.h

Last change on this file was f408c0f, checked in by Chris Johns <chrisj@…>, on 11/22/23 at 03:31:03

rtemstoolkit, linkers: Fix C++17 warnings

Closes #4970

  • Property mode set to 100644
File size: 22.5 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       * Default constructor.
179       */
180      section ();
181
182      /**
183       * Add a data segment descriptor to the section if the file is writable.
184       *
185       * These are following data types (from elf(3)):
186       *
187       *   ELF_T_ADDR     Machine addresses.
188       *   ELF_T_BYTE     Byte data.  The library will not attempt to translate
189       *                  byte data.
190       *   ELF_T_CAP      Software and hardware capability records.
191       *   ELF_T_DYN      Records used in a section of type SHT_DYNAMIC.
192       *   ELF_T_EHDR     ELF executable header.
193       *   ELF_T_HALF     16-bit unsigned words.
194       *   ELF_T_LWORD    64 bit unsigned words.
195       *   ELF_T_MOVE     ELF Move records.
196       *   ELF_T_NOTE     ELF Note structures.
197       *   ELF_T_OFF      File offsets.
198       *   ELF_T_PHDR     ELF program header table entries.
199       *   ELF_T_REL      ELF relocation entries.
200       *   ELF_T_RELA     ELF relocation entries with addends.
201       *   ELF_T_SHDR     ELF section header entries.
202       *   ELF_T_SWORD    Signed 32-bit words.
203       *   ELF_T_SXWORD   Signed 64-bit words.
204       *   ELF_T_SYMINFO  ELF symbol information.
205       *   ELF_T_SYM      ELF symbol table entries.
206       *   ELF_T_VDEF     Symbol version definition records.
207       *   ELF_T_VNEED    Symbol version requirement records.
208       *   ELF_T_WORD     Unsigned 32-bit words.
209       *   ELF_T_XWORD    Unsigned 64-bit words.
210       *
211       * @param type The type of data in the segment.
212       * @param alignment The in-file alignment of the data. Must be a power of 2.
213       * @param size The number of bytes in this data descriptor.
214       * @param buffer The data in memory.
215       * @param offset The offset within the containing section. Can be computed.
216       */
217      void add_data (elf_type  type,
218                     elf_xword alignment,
219                     elf_xword size,
220                     void*     buffer = 0,
221                     elf_off   offset = 0);
222
223       /**
224       * The section's index in the ELF file.
225       *
226       * @return int The section number.
227       */
228      int index () const;
229
230      /**
231       * The name of the section.
232       *
233       * @return const std::string& The section's name.
234       */
235      const std::string& name () const;
236
237      /**
238       * The section's data.
239       */
240      elf_data* data ();
241
242      /**
243       * Get the type of the section.
244       */
245      elf_word type () const;
246
247      /**
248       * The section flags.
249       */
250      elf_xword flags () const;
251
252      /**
253       * In-memory address of the section.
254       */
255      elf_addr address () const;
256
257      /**
258       * Alignment constraint.
259       */
260      elf_xword alignment () const;
261
262      /**
263       * The file offset of the section.
264       */
265      elf_off offset () const;
266
267      /**
268       * The header table link.
269       */
270      elf_word link () const;
271
272      /**
273       * Extra information.
274       */
275      elf_word info () const;
276
277      /**
278       * Size of the section.
279       */
280      elf_xword size () const;
281
282      /**
283       * Size of the entries in the section.
284       */
285      elf_xword entry_size () const;
286
287      /**
288       * Number of entries.
289       */
290      int entries () const;
291
292      /**
293       * Return true if the relocation record have an addend field.
294       *
295       * @retval true The relocation record have the addend field.
296       */
297      bool get_reloc_type () const;
298
299      /**
300       * Set the name index if writable. This is normally done
301       * automatically when adding the section to the file.
302       */
303      void set_name (unsigned int index);
304
305      /**
306       * Set the type of relocation records.
307       *
308       * @param rela If true the records are rela type.
309       */
310      void set_reloc_type (bool rela);
311
312      /**
313       * Add a relocation.
314       *
315       * @param reloc The relocation record to add.
316       */
317      void add (const relocation& reloc);
318
319      /**
320       * Get the relocations.
321       */
322      const relocations& get_relocations () const;
323
324    private:
325
326      /**
327       * Check the section is valid.
328       *
329       * @param where Where the check is being made.
330       */
331      void check (const char* where) const;
332
333      /**
334       * Check the section is valid and writable.
335       *
336       * @param where Where the check is being made.
337       */
338      void check_writable (const char* where) const;
339
340      file*       file_;  //< The ELF file.
341      int         index_; //< The section header index.
342      std::string name_;  //< The section's name.
343      elf_scn*    scn;    //< ELF private section data.
344      elf_shdr    shdr;   //< The section header.
345      elf_data*   data_;  //< The section's data.
346      bool        rela;   //< The type of relocation records.
347      relocations relocs; //< The relocation records.
348    };
349
350    /**
351     * Container of ELF section pointers.
352     */
353    typedef std::list < section* > sections;
354
355    /**
356     * Container of ELF section as a map, ie associative array.
357     */
358    typedef std::map < std::string, section > section_table;
359
360    /**
361     * An ELF program header.
362     */
363    class program_header
364    {
365    public:
366      /**
367       * Construct a program header.
368       */
369      program_header ();
370
371      /**
372       * Desctruct a program header.
373       */
374      ~program_header ();
375
376      /**
377       * Set the program header.
378       *
379       * @param type The type of segment.
380       * @param flags The segment's flags.
381       * @param offset The offet to segment.
382       * @param filesz The segment size in the file.
383       * @param memsz The segment size in memory.
384       * @param align The segment alignment.
385       * @param vaddr The virtual address in memory.
386       * @param paddr The physical address if any.
387       */
388      void set (elf_word type,
389                elf_word flags,
390                elf_off offset,
391                elf_xword filesz,
392                elf_xword memsz,
393                elf_xword align,
394                elf_addr vaddr,
395                elf_addr paddr = 0);
396
397    private:
398
399      elf_phdr phdr;  //< The ELF program header.
400    };
401
402    /**
403     * A container of program headers.
404     */
405    typedef std::list < program_header > program_headers;
406
407    /**
408     * An ELF file.
409     */
410    class file
411    {
412    public:
413     /**
414       * Construct an ELF file.
415       */
416      file ();
417
418      /**
419       * Destruct the ELF file object.
420       */
421      ~file ();
422
423      /**
424       * Begin using the ELF file.
425       *
426       * @param name The full name of the file.
427       * @param fd The file descriptor to read or write the file.
428       * @param writable The file is writeable. The default is false.
429       */
430      void begin (const std::string& name, int fd, const bool writable = false);
431
432      /**
433       * Begin using the ELF file in an archive.
434       *
435       * @param name The full name of the file.
436       * @param archive The file that is the archive.
437       * @param offset The offset of the ELF file in the archive.
438       */
439      void begin (const std::string& name, file& archive, off_t offset);
440
441      /**
442       * End using the ELF file.
443       */
444      void end ();
445
446      /**
447       * Write the ELF file creating it if it is writable. You should have
448       * added the sections and the data segment descriptors to the sections
449       * before calling write.
450       */
451      void write ();
452
453      /**
454       * Load the header. Done automatically.
455       */
456      void load_header ();
457
458      /**
459       * Get the machine type.
460       */
461      unsigned int machinetype () const;
462
463      /**
464       * Get the type of ELF file.
465       */
466      unsigned int type () const;
467
468      /**
469       * Get the class of the object file.
470       */
471      unsigned int object_class () const;
472
473      /**
474       * Get the data type, ie LSB or MSB.
475       */
476      unsigned int data_type () const;
477
478      /**
479       * Is the file an archive format file ?
480       */
481      bool is_archive () const;
482
483      /**
484       * Is the file an executable ?
485       */
486      bool is_executable () const;
487
488      /**
489       * Is the file relocatable ?
490       */
491      bool is_relocatable() const;
492
493      /**
494       * The number of sections in the file.
495       */
496      int section_count () const;
497
498      /**
499       * Load the sections.
500       */
501      void load_sections ();
502
503      /**
504       * Get a filtered container of the sections. The key is the section
505       * type. If the sections are not loaded they are loaded. If the type is 0
506       * all sections are returned.
507       *
508       * @param filtered_secs The container the copy of the filtered sections
509       *                      are placed in.
510       * @param type The type of sections to filter on. If 0 all sections are
511       *             matched.
512       */
513      void get_sections (sections& filtered_secs, unsigned int type);
514
515      /**
516       * Return the section with given index.
517       *
518       * @param index The section's index to look for.
519       * @retval section The section matching the index.
520       */
521      section& get_section (int index);
522
523      /**
524       * Return the index of the string section.
525       */
526      int strings_section () const;
527
528      /**
529       * Get the string from the specified section at the requested offset.
530       *
531       * @param section The section to search for the string.
532       * @param offset The offset in the string section.
533       * @return std::string The string.
534       */
535      std::string get_string (int section, size_t offset);
536
537      /**
538       * Get the string from the ELF header declared string section at the
539       * requested offset.
540       *
541       * @param offset The offset in the string section.
542       * @return std::string The string.
543       */
544      std::string get_string (size_t offset);
545
546      /**
547       * Load the symbols.
548       */
549      void load_symbols ();
550
551      /**
552       * Get a filtered container of symbols given the various types. If the
553       * symbols are not loaded they are loaded.
554       *
555       * @param filtered_syms The filtered symbols found in the file. This is a
556       *                      container of pointers.
557       * @param unresolved Return unresolved symbols.
558       * @param local Return local symbols.
559       * @param weak Return weak symbols.
560       * @param global Return global symbols.
561       */
562      void get_symbols (rld::symbols::pointers& filtered_syms,
563                        bool                    unresolved = false,
564                        bool                    local = false,
565                        bool                    weak = true,
566                        bool                    global = true);
567
568      /**
569       * Get the symbol by index in the symtabl section.
570       */
571      const symbols::symbol& get_symbol (const int index) const;
572
573      /**
574       * Load the relocation records.
575       */
576      void load_relocations ();
577
578      /**
579       * Clear the relocation records.
580       */
581      void clear_relocations ();
582
583      /**
584       * Set the ELF header. Must be writable.
585       *
586       * The classes are:
587       *   ELFCLASSNONE  This class is invalid.
588       *   ELFCLASS32    This defines the 32-bit architecture.  It sup- ports
589       *                 machines with files and virtual address spa- ces up to
590       *                 4 Gigabytes.
591       *   ELFCLASS64    This defines the 64-bit architecture.
592       *
593       * The types are:
594       *   ET_NONE  An unknown type.
595       *   ET_REL   A relocatable file.
596       *   ET_EXEC  An executable file.
597       *   ET_DYN   A shared object.
598       *   ET_CORE  A core file.
599       *
600       * The machine types are:
601       *   TDB
602       *
603       * The datatypes are:
604       *   ELFDATA2LSB  Two's complement, little-endian.
605       *   ELFDATA2MSB  Two's complement, big-endian.
606       *
607       * @param type The type of ELF file, ie executable, relocatable etc.
608       * @param class_ The files ELF class.
609       * @param machinetype The type of machine code present in the ELF file.
610       * @param datatype The data type, ie LSB or MSB.
611       */
612      void set_header (elf_half      type,
613                       int           class_,
614                       elf_half      machinetype,
615                       unsigned char datatype);
616
617      /**
618       * Add a section to the ELF file if writable.
619       */
620      void add (section& sec);
621
622      /**
623       * Add a program header to the ELF file if writable.
624       */
625      void add (program_header& phdr);
626
627      /**
628       * Get the ELF reference.
629       */
630      elf* get_elf ();
631
632      /**
633       * Get the name of the file.
634       */
635      const std::string& name () const;
636
637      /**
638       * Is the file writable ?
639       */
640      bool is_writable () const;
641
642      /**
643       * Obtain a reference to this object. End fails while references are
644       * held.
645       */
646      void reference_obtain ();
647
648      /**
649       * Release the reference to this object.
650       */
651      void reference_release ();
652
653      /**
654       * Get the machine size in bytes.
655       */
656      size_t machine_size () const;
657
658      /**
659       * Returns true if little endian.
660       */
661      bool is_little_endian () const;
662
663    private:
664
665      /**
666       * Begin using the ELF file.
667       *
668       * @param name The full name of the file.
669       * @param fd The file descriptor to read or write the file.
670       * @param writable The file is writeable. It cannot be part of an archive.
671       * @param archive The archive's ELF handle or 0 if not an archive.
672       * @param offset The offset of the ELF file in the archive if elf is non-zero.
673       */
674      void begin (const std::string& name,
675                  int                fd,
676                  const bool         writable,
677                  file*              archive,
678                  off_t              offset);
679
680      /**
681       * Check if the file is usable. Throw an exception if not.
682       *
683       * @param where Where the check is performed.
684       */
685      void check (const char* where) const;
686
687      /**
688       * Check if the file is usable and writable. Throw an exception if not.
689       *
690       * @param where Where the check is performed.
691       */
692      void check_writable (const char* where) const;
693
694      /**
695       * Check if the ELF header is valid. Throw an exception if not.
696       *
697       * @param where Where the check is performed.
698       */
699      void check_ehdr (const char* where) const;
700
701      /**
702       * Check if the ELF program header is valid. Throw an exception if not.
703       *
704       * @param where Where the check is performed.
705       */
706      void check_phdr (const char* where) const;
707
708      /**
709       * Generate libelf error.
710       *
711       * @param where Where the error is generated.
712       */
713      void error (const char* where) const;
714
715      int                  fd_;        //< The file handle.
716      int                  refs;       //< The reference count.
717      std::string          name_;      //< The name of the file.
718      bool                 archive;    //< The ELF file is part of an archive.
719      bool                 writable;   //< The file is writeable.
720      elf*                 elf_;       //< The ELF handle.
721      unsigned int         mtype;      //< The machine type.
722      unsigned int         oclass;     //< The object class.
723      const char*          ident_str;  //< The ELF file's ident string.
724      size_t               ident_size; //< The size of the ident.
725      elf_ehdr*            ehdr;       //< The ELF header.
726      elf_phdr*            phdr;       //< The ELF program header.
727      section_table        secs;       //< The sections as a table.
728      program_headers      phdrs;      //< The program headers when creating
729                                       //  ELF files.
730      rld::symbols::bucket symbols;    //< The symbols. All tables point here.
731    };
732
733    /**
734     * Return the machine type label given the machine type.
735     *
736     * @param machinetype The ELF machine type.
737     */
738    const std::string machine_type (unsigned int machinetype);
739
740    /**
741     * Return the global machine type set by the check_file call as a string.
742     */
743    const std::string machine_type ();
744
745    /**
746     * Return the global class set by the check_file call.
747     */
748    unsigned int object_class ();
749
750    /**
751     * Return the global machine type set by the check_file call.
752     */
753    unsigned int object_machine_type ();
754
755    /**
756     * Return the global data type set by the check_file call.
757     */
758    unsigned int object_datatype ();
759
760    /**
761     * Check the file against the global machine type, object class and data
762     * type. If this is the first file checked it becomes the default all
763     * others are checked against. This is a simple way to make sure all files
764     * are the same type.
765     *
766     * @param file The check to check.
767     */
768    void check_file(const file& file);
769
770  }
771}
772
773#endif
Note: See TracBrowser for help on using the repository browser.