source: rtems-tools/linkers/rld-elf.h @ c46980e

4.104.115
Last change on this file since c46980e was fd8a2c5, checked in by Chris Johns <chrisj@…>, on 11/20/12 at 08:53:24

Add support to write a metadata ELF file.

This also adds support to the ELF classes that wrap libelf. While
this is now done and seems to work I will not be using an ELF
file to hold the metadata after all.

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