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

4.104.11
Last change on this file since 977c3de was 977c3de, checked in by Chris Johns <chrisj@…>, on Nov 17, 2012 at 6:34:33 AM

Refactor the ELF support to allow ELF write suppport.

The refactoring allows better reuse of the ELF support and cleans up
some hacks from the generic file and archive handling improving the
separation of the file handling from the file format, ie ELF. The
handling of ELF object files and ELF object files inside archives
is cleaner.

The refactor cleaned up the symbol handling where the symbols now
reside in the ELF file object and references are take in symbol
pointer containers and symbol table containers.

The main purpose of the refactor is to allow support for creating
and writing ELF files.

Also added an rtems-syms command where special symbol support
can be added.

  • Property mode set to 100644
File size: 10.1 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
30#include <rld.h>
31
32namespace rld
33{
34  namespace elf
35  {
36    /**
37     * Forward decl.
38     */
39    class file;
40
41    /**
42     * An ELF Section.
43     */
44    class section
45    {
46    public:
47      /**
48       * Construct the section getting the details.
49       *
50       * @param elf The ELF file this section is part of.
51       * @param index The sections index in the ELF file.
52       */
53      section (file& file_, int index);
54
55      /**
56       * Copy constructor.
57       */
58      section (const section& orig);
59
60      /**
61       * Default constructor.
62       */
63      section ();
64
65      /**
66       * The section's index in the ELF file.
67       *
68       * @return int The section number.
69       */
70      int index () const;
71
72      /**
73       * The name of the section.
74       *
75       * @return const std::string& The section's name.
76       */
77      const std::string& name () const;
78
79      /**
80       * The section's data.
81       */
82      elf_data* data ();
83
84      /**
85       * Get the type of the section.
86       */
87      elf_word type () const;
88
89      /**
90       * The section flags.
91       */
92      elf_xword flags () const;
93
94      /**
95       * In-memory address of the section.
96       */
97      elf_addr address () const;
98
99      /**
100       * Alignment constraint.
101       */
102      elf_xword alignment () const;
103
104      /**
105       * The file offset of the section.
106       */
107      elf_off offset () const;
108
109      /**
110       * The header table link.
111       */
112      elf_word link () const;
113
114      /**
115       * Extra information.
116       */
117      elf_word info () const;
118
119      /**
120       * Size of the section.
121       */
122      elf_xword size () const;
123
124      /**
125       * Size of the entries in the section.
126       */
127      elf_xword entry_size () const;
128
129      /**
130       * Number of entries.
131       */
132      int entries () const;
133
134    private:
135
136      /**
137       * Check the section is acrtual valid.
138       */
139      void check () const;
140
141      file*       file_;  //< The ELF file.
142      int         index_; //< The section header index.
143      std::string name_;  //< The section's name.
144      elf_scn*    scn;    //< ELF private section data.
145      elf_shdr    shdr;   //< The section header.
146      elf_data*   data_;  //< The section's data.
147    };
148
149    /**
150     * Container of ELF sections.
151     */
152    typedef std::list < section > sections;
153
154    /**
155     * An ELF file.
156     */
157    class file
158    {
159    public:
160      /**
161       * Construct an ELF file.
162       */
163      file ();
164
165      /**
166       * Destruct the ELF file object.
167       */
168      ~file ();
169
170      /**
171       * Begin using the ELF file.
172       *
173       * @param name The full name of the file.
174       * @param fd The file descriptor to read or write the file.
175       * @param writable The file is writeable. The default is false.
176       */
177      void begin (const std::string& name, int fd, const bool writable = false);
178
179      /**
180       * Begin using the ELF file in an archive.
181       *
182       * @param name The full name of the file.
183       * @param archive The file that is the archive.
184       * @param offset The offset of the ELF file in the archive.
185       */
186      void begin (const std::string& name, file& archive, off_t offset);
187
188      /**
189       * End using the ELF file.
190       */
191      void end ();
192
193      /**
194       * Load the header. Done automatically.
195       */
196      void load_header ();
197
198      /**
199       * Get the machine type.
200       */
201      unsigned int machinetype () const;
202
203      /**
204       * Get the type of ELF file.
205       */
206      unsigned int type () const;
207
208      /**
209       * Get the class of the object file.
210       */
211      unsigned int object_class () const;
212
213      /**
214       * Get the data type, ie LSB or MSB.
215       */
216      unsigned int data_type () const;
217
218      /**
219       * Is the file an archive format file ?
220       */
221      bool is_archive () const;
222
223      /**
224       * Is the file an executable ?
225       */
226      bool is_executable () const;
227
228      /**
229       * Is the file relocatable ?
230       */
231      bool is_relocatable() const;
232
233      /**
234       * The number of sections in the file.
235       */
236      int section_count () const;
237
238      /**
239       * Load the sections.
240       */
241      void load_sections ();
242
243      /**
244       * Get a filtered container of the sections. The key is the section
245       * type. If the sections are not loaded they are loaded. If the type is 0
246       * all sections are returned.
247       *
248       * @param filtered_secs The container the copy of the filtered sections
249       *                      are placed in.
250       * @param type The type of sections to filter on. If 0 all sections are
251       *             matched.
252       */
253      void get_sections (sections& filtered_secs, unsigned int type);
254
255      /**
256       * Return the index of the string section.
257       */
258      int strings_section () const;
259
260      /**
261       * Get the string from the specified section at the requested offset.
262       *
263       * @param section The section to search for the string.
264       * @param offset The offset in the string section.
265       * @return std::string The string.
266       */
267      std::string get_string (int section, size_t offset);
268
269      /**
270       * Get the string from the ELF header declared string section at the
271       * requested offset.
272       *
273       * @param offset The offset in the string section.
274       * @return std::string The string.
275       */
276      std::string get_string (size_t offset);
277
278      /**
279       * Load the symbols.
280       */
281      void load_symbols ();
282
283      /**
284       * Get a filtered container of symbols given the various types. If the
285       * symbols are not loaded they are loaded.
286       *
287       * @param filter_syms The filtered symbols found in the file. This is a
288       *                    container of pointers.
289       * @param local Return local symbols.
290       * @param weak Return weak symbols.
291       * @param global Return global symbols.
292       * @param unresolved Return unresolved symbols.
293       */
294      void get_symbols (rld::symbols::pointers& filtered_syms,
295                        bool                    unresolved = false,
296                        bool                    local = false,
297                        bool                    weak = true,
298                        bool                    global = true);
299
300      /**
301       * Get the ELF reference.
302       */
303      elf* get_elf ();
304
305      /**
306       * Get the name of the file.
307       */
308      const std::string& name () const;
309
310      /**
311       * Is the file writable ?
312       */
313      bool is_writable () const;
314
315    private:
316
317      /**
318       * Begin using the ELF file.
319       *
320       * @param name The full name of the file.
321       * @param fd The file descriptor to read or write the file.
322       * @param writable The file is writeable. It cannot be part of an archive.
323       * @param archive The archive's ELF handle or 0 if not an archive.
324       * @param offset The offset of the ELF file in the archive if elf is non-zero.
325       */
326      void begin (const std::string& name,
327                  int                fd,
328                  const bool         writable,
329                  file*              archive,
330                  off_t              offset);
331
332      /**
333       * Check if the file is usable. Throw an exception if not.
334       *
335       * @param where Where the check is performed.
336       */
337      void check (const char* where) const;
338
339      /**
340       * Check if the file is usable and writable. Throw an exception if not.
341       *
342       * @param where Where the check is performed.
343       */
344      void check_writable (const char* where) const;
345
346      /**
347       * Generate libelf error.
348       *
349       * @param where Where the error is generated.
350       */
351      void error (const char* where) const;
352
353      int                  fd_;        //< The file handle.
354      std::string          name_;      //< The name of the file.
355      bool                 archive;    //< The ELF file is part of an archive.
356      bool                 writable;   //< The file is writeable.
357      elf*                 elf_;       //< The ELF handle.
358      unsigned int         mtype;      //< The machine type.
359      unsigned int         oclass;     //< The object class.
360      const char*          ident_str;  //< The ELF file's ident string.
361      size_t               ident_size; //< The size of the ident.
362      elf_ehdr             ehdr;       //< The ELF header.
363      elf_phdr             phdr;       //< The ELF program header.
364      std::string          stab;       //< The string table.
365      sections             secs;       //< The sections.
366      rld::symbols::bucket symbols;    //< The symbols. All tables point here.
367    };
368
369    /**
370     * Return the machine type label given the machine type.
371     *
372     * @param machinetype The ELF machine type.
373     */
374    const std::string machine_type (unsigned int machinetype);
375
376    /**
377     * Return the global machine type set by the check_file call.
378     */
379    const std::string machine_type ();
380
381    /**
382     * Check the file against the global machine type, object class and data
383     * type. If this is the first file checked it becomes the default all
384     * others are checked against. This is a simple way to make sure all files
385     * are the same type.
386     *
387     * @param file The check to check.
388     */
389    void check_file(const file& file);
390
391  }
392}
393
394#endif
Note: See TracBrowser for help on using the repository browser.