source: rtems-tools/rtemstoolkit/rld-elf.h @ 558cab8

Last change on this file since 558cab8 was 558cab8, checked in by Chris Johns <chrisj@…>, on May 8, 2018 at 5:09:38 AM

rtemstoolkit: Add libdwarf C++ interface.

Provide a C++ interface to libdwarf to:

  • Manage DWARF debug data
  • Manage CU
  • Manage DIE
  • Handle CU line addresses
  • Handle CU source files

Update #3417

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