source: rtems-tools/linkers/rld-files.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: 18.7 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 file manages access the image contained in various file
22 * formats.
23 *
24 * The base element is a file. It references a object file that is either
25 * inside an archive or stand alone. You access a object file by constructing a
26 * handle. A handle is the object file with the specific file descriptor
27 * created when the archive or object file was opened.
28 *
29 *
30 */
31
32#if !defined (_RLD_FILES_H_)
33#define _RLD_FILES_H_
34
35#include <list>
36#include <map>
37#include <string>
38#include <vector>
39
40#include <rld.h>
41
42namespace rld
43{
44  namespace files
45  {
46    /**
47     * Container of file paths.
48     */
49    typedef std::vector < std::string > paths;
50
51    /**
52     * Container of files.
53     */
54    typedef std::vector < file > files;
55
56    /**
57     * Container of archive files.
58     */
59    typedef std::map < std::string, archive* > archives;
60
61    /**
62     * Container of object files.
63     */
64    typedef std::map < std::string, object* > objects;
65
66    /**
67     * Container list of object files.
68     */
69    typedef std::list < object* > object_list;
70
71    /**
72     * Split a path from a string with a delimiter to the path container. Add
73     * only the paths that exist and ignore those that do not.
74     */
75    void path_split (const std::string& path,
76                     rld::files::paths& paths);
77
78    /**
79     * Make a path by joining the parts with required separator.
80     */
81    void path_join (const std::string& path_,
82                    const std::string& file_,
83                    std::string& joined);
84
85    /**
86     * Check the path is a file.
87     */
88    bool check_file (const std::string& path);
89
90    /**
91     * Check the path is a directory.
92     */
93    bool check_directory (const std::string& path);
94
95    /**
96     * Find the file given a container of paths and file names.
97     *
98     * @param path The path of the file if found else empty.
99     * @param name The name of the file to search for.
100     * @param search_paths The container of paths to search.
101     */
102    void find_file (std::string&       path,
103                    const std::string& name,
104                    paths&             search_paths);
105
106    /**
107     * A file is a single object file that is either in an archive or stand
108     * alone.
109     */
110    class file
111    {
112    public:
113      /**
114       * Construct the file from the component parts when part of an archive.
115       *
116       * @param aname The archive name.
117       * @param oname The object file name.
118       * @param offset The offset in the archive the object file starts.
119       * @param size The size of the archive the object file starts.
120       */
121      file (const std::string& aname,
122            const std::string& oname,
123            off_t              offset,
124            size_t             size);
125
126      /**
127       * Construct the name by splitting the full path into an archive,
128       * object file name and offset.
129       *
130       * @param path The path to the image.
131       * @param is_object If true (default) the name is for an object file.
132       */
133      file (const std::string& path, bool is_object = true);
134
135      /**
136       * Contruct an empty file.
137       */
138      file ();
139
140      /**
141       * Set a name from the path.
142       *
143       * @param path The path to the image.
144       * @param is_object If true (default) the name is for an object file.
145       */
146      void set (const std::string& path, bool is_object = true);
147
148      /**
149       * Is an archive returns true if the file is in an archive.
150       *
151       * @retval true The object file is in an archive.
152       * @retval false The object file is stand alone.
153       */
154      bool is_archive () const;
155
156      /**
157       * Is object file stand alone.
158       *
159       * @retval true The object file is stand alone.
160       * @retval false The object could be part of an archive.
161       */
162      bool is_object () const;
163
164      /**
165       * Valid returns true if there is a valid name.
166       *
167       * @retval true There is a valid name.
168       * @retval false There is not name assigned.
169       */
170      bool is_valid () const;
171
172      /**
173       * Exists returns true if the archive or object file is present on disk
174       * and a regular file.
175       *
176       * @retval true The file is valid and a regular file.
177       * @retval false The file is either not present, not accessable or not a
178       *               regular file.
179       */
180      bool exists () const;
181
182      /**
183       * The path maps to the real file on disk. The file may not be valid.
184       *
185       * @return const std::string The real path to the file on disk.
186       */
187      const std::string path () const;
188
189      /**
190       * The full path.
191       *
192       * @return const std::string The full path to the image.
193       */
194      const std::string full () const;
195
196      /**
197       * The base path. It is the basename of the full path.
198       *
199       * @return const std::string The basename of the full path to the image.
200       */
201      const std::string basename () const;
202
203      /**
204       * The archive name component. A length of 0 means there was not
205       * archive component.
206       */
207      const std::string& aname () const;
208
209      /**
210       * The object name. There is always an object name.
211       */
212      const std::string& oname () const;
213
214      /**
215       * The object's offset in the archive.
216       */
217      off_t offset () const;
218
219      /**
220       * The object's size in the archive.
221       */
222      size_t size () const;
223
224    private:
225      std::string aname_;  //< The archive name.
226      std::string oname_;  //< The object name.
227      off_t       offset_; //< The object's offset in the archive.
228      size_t      size_;   //< The object's size in teh archive.
229    };
230
231    /**
232     * Image is the base file type. A base class is used so we can have a
233     * single container of to hold types of images we need to support.
234     */
235    class image
236    {
237    public:
238      /**
239       * Construct the image.
240       *
241       * @param name The name of the image.
242       */
243      image (file& name);
244
245      /**
246       * Construct the image.
247       *
248       * @param name The file path.
249       * @param is_object If true (default) the name is for an object file.
250       */
251      image (const std::string& path, bool is_object = true);
252
253      /**
254       * Construct the image.
255       */
256      image ();
257
258      /**
259       * Destruct the image.
260       */
261      virtual ~image ();
262
263      /**
264       * Open the image. You can open the image more than once but you need to
265       * close it the same number of times.
266       */
267      virtual void open (file& name);
268
269      /**
270       * Open the image. You can open the image more than once but you need to
271       * close it the same number of times.
272       */
273      virtual void open (bool writable = false);
274
275      /**
276       * Close the image.
277       */
278      virtual void close ();
279
280      /**
281       * Read a block from the file.
282       */
283      virtual ssize_t read (uint8_t* buffer, size_t size);
284
285      /**
286       * Write a block from the file.
287       */
288      virtual ssize_t write (const void* buffer, size_t size);
289
290      /**
291       * Seek.
292       */
293      virtual void seek (off_t offset);
294
295      /**
296       * Seek and read.
297       */
298      virtual bool seek_read (off_t offset, uint8_t* buffer, size_t size);
299
300      /**
301       * Seek and write.
302       */
303      virtual bool seek_write (off_t offset, const void* buffer, size_t size);
304
305      /**
306       * The name of the image.
307       */
308      const file& name () const;
309
310      /**
311       * References to the image.
312       */
313      virtual int references () const;
314
315      /**
316       * The file size.
317       */
318      virtual size_t size () const;
319
320      /**
321       * The file descriptor.
322       */
323      virtual int fd () const;
324
325      /**
326       * The ELF reference.
327       */
328      elf::file& elf ();
329
330      /**
331       * A symbol in the image has been referenced.
332       */
333      virtual void symbol_referenced ();
334
335      /**
336       * Return the number of symbol references.
337       */
338      virtual int symbol_references () const;
339
340      /**
341       * The path maps to the real file on disk. The file may not be valid.
342       *
343       * @return const std::string The real path to the file on disk.
344       */
345      const std::string path () const {
346        return name ().path ();
347      }
348
349      /**
350       * Is the image open ?
351       *
352       * @retval true The image is open.
353       * @retval false The image is not open.
354       */
355      bool is_open () const {
356        return fd () != -1;
357      }
358
359      /**
360       * Is the image writable ?
361       *
362       * @retval true The image is writeable.
363       * @retval false The image is not writeable.
364       */
365      bool is_writeable () const {
366        return writeable;
367      }
368
369    private:
370
371      file      name_;       //< The name of the file.
372      int       references_; //< The number of handles open.
373      int       fd_;         //< The file descriptor of the archive.
374      elf::file elf_;        //< The libelf reference.
375      int       symbol_refs; //< The number of symbols references made.
376      bool      writeable;   //< The image is writable.
377    };
378
379    /**
380     * Copy the input section of the image to the output section. The file
381     * positions in the images must be set before making the call.
382     */
383    void copy (image& in, image& out, size_t size);
384
385    /**
386     * The archive class proivdes access to ELF object files that are held in a
387     * AR format file. GNU AR extensions are supported.
388     */
389    class archive:
390      public image
391    {
392    public:
393      /**
394       * Open a archive format file that contains ELF object files.
395       *
396       */
397      archive (const std::string& name);
398
399      /**
400       * Close the archive.
401       */
402      virtual ~archive ();
403
404      /**
405       * Begin the ELF session.
406       */
407      void begin ();
408
409      /**
410       * End the ELF session.
411       */
412      void end ();
413
414      /**
415       * Match the archive name.
416       *
417       * @param name The name of the archive to check.
418       * @retval true This is the archive.
419       * @retval false This is not the archive.
420       */
421      bool is (const std::string& name) const;
422
423      /**
424       * Check this is a valid archive.
425       */
426      bool is_valid ();
427
428      /**
429       * Load objects.
430       */
431      void load_objects (objects& objs);
432
433      /**
434       * Get the name.
435       */
436      const std::string& get_name () const;
437
438      /**
439       * Less than operator for the map container.
440       */
441      bool operator< (const archive& rhs) const;
442
443      /**
444       * Create a new archive. If referening an existing archive it is
445       * overwritten.
446       */
447      void create (object_list& objects);
448
449    private:
450
451      /**
452       * Read header.
453       */
454      bool read_header (off_t offset, uint8_t* header);
455
456      /**
457       * Add the object file from the archive to the object's container.
458       */
459      void add_object (objects&    objs,
460                       const char* name,
461                       off_t       offset,
462                       size_t      size);
463
464      /**
465       * Write a file header into the archive.
466       */
467      void write_header (const std::string& name,
468                         uint32_t           mtime,
469                         int                uid,
470                         int                gid,
471                         int                mode,
472                         size_t             size);
473
474      /**
475       * Cannot copy via a copy constructor.
476       */
477      archive (const archive& orig);
478
479      /**
480       * Cannot assign using the assignment operator..
481       */
482      archive& operator= (const archive& rhs);
483    };
484
485    /**
486     * The object file cab be in an archive or a file.
487     */
488    class object:
489      public image
490    {
491    public:
492      /**
493       * Construct an object image that is part of an archive.
494       *
495       * @param archive_ The archive the object file is part of.
496       * @param file_ The image file.
497       */
498      object (archive& archive_, file& file_);
499
500      /**
501       * Construct the object file.
502       *
503       * @param path The object file path.
504       */
505      object (const std::string& path);
506
507      /**
508       * Construct the object file.
509       */
510      object ();
511
512      /**
513       * Destruct the object file.
514       */
515      virtual ~object ();
516
517      /**
518       * Open the object file.
519       */
520      virtual void open ();
521
522      /**
523       * Close the object.
524       */
525      virtual void close ();
526
527      /**
528       * Begin the ELF session.
529       */
530      void begin ();
531
532      /**
533       * End the ELF session.
534       */
535      void end ();
536
537      /**
538       * Load the symbols into the symbols table.
539       *
540       * @param symbols The symbol table to load.
541       * @param local Include local symbols. The default is not to.
542       */
543      void load_symbols (rld::symbols::table& symbols, bool local = false);
544
545      /**
546       * Get the string from the string table.
547       */
548//      std::string get_string (int section, size_t offset);
549
550      /**
551       * References to the image.
552       */
553      virtual int references () const;
554
555      /**
556       * The file size.
557       */
558      virtual size_t size () const;
559
560      /**
561       * The file descriptor.
562       */
563      virtual int fd () const;
564
565      /**
566       * A symbol in the image has been referenced.
567       */
568      virtual void symbol_referenced ();
569
570      /**
571       * The archive the object file is contained in. If 0 the object file is
572       * not contained in an archive.
573       */
574      archive* get_archive ();
575
576#if 0
577      /**
578       * Number of sections in the object file.
579       */
580      int sections () const;
581
582      /**
583       * Section string index.
584       */
585      int section_strings () const;
586#endif
587
588      /**
589       * Return the unresolved symbol table for this object file.
590       */
591      rld::symbols::table& unresolved_symbols ();
592
593      /**
594       * Return the list external symbols.
595       */
596      rld::symbols::pointers& external_symbols ();
597
598    private:
599      archive*               archive_;   //< Points to the archive if part of
600                                         //  an archive.
601      rld::symbols::table    unresolved; //< This object's unresolved symbols.
602      rld::symbols::pointers externals;  //< This object's external symbols.
603
604      /**
605       * Cannot copy via a copy constructor.
606       */
607      object (const object& orig);
608
609      /**
610       * Cannot assign using the assignment operator.
611       */
612      object& operator= (const object& rhs);
613    };
614
615    /**
616     * A collection of objects files as a cache. This currently is not a cache
617     * but it could become one.
618     */
619    class cache
620    {
621    public:
622      /**
623       * Construct the cache.
624       */
625      cache ();
626
627      /**
628       * Destruct the objects.
629       */
630      virtual ~cache ();
631
632      /**
633       * Open the cache by collecting the file names, loading object headers
634       * and loading the archive file names.
635       */
636      void open ();
637
638      /**
639       * Close the cache.
640       */
641      void close ();
642
643      /**
644       * Add a file path to the cache.
645       */
646      void add (const std::string& path);
647
648      /**
649       * Add a container of path to the cache.
650       */
651      void add (paths& paths__);
652
653      /**
654       * Add a container of path to the cache.
655       */
656      void add_libraries (paths& paths__);
657
658      /**
659       * Being a session on an archive.
660       */
661      void archive_begin (const std::string& path);
662
663      /**
664       * End a session on an archive.
665       */
666      void archive_end (const std::string& path);
667
668      /**
669       * Being sessions on all archives.
670       */
671      void archives_begin ();
672
673      /**
674       * End the archive sessions.
675       */
676      void archives_end ();
677
678      /**
679       * Collect the object names and add them to the cache.
680       */
681      void collect_object_files ();
682
683      /**
684       * Collect the object file names by verifing the paths to the files are
685       * valid or read the object file names contained in any archives.
686       */
687      void collect_object_files (const std::string& path);
688
689      /**
690       * Load the symbols into the symbol table.
691       *
692       * @param symbols The symbol table to load.
693       * @param local Include local symbols. The default is not to.
694       */
695      void load_symbols (rld::symbols::table& symbols, bool locals = false);
696
697      /**
698       * Output the unresolved symbol table to the output stream.
699       */
700      void output_unresolved_symbols (std::ostream& out);
701
702      /**
703       * Get the archives.
704       */
705      archives& get_archives ();
706
707      /**
708       * Get the objects inlcuding those in archives.
709       */
710      objects& get_objects ();
711
712      /**
713       * Get the added objects. Does not include the ones in th archives.
714       */
715      void get_objects (object_list& list);
716
717      /**
718       * Get the paths.
719       */
720      const paths& get_paths () const;
721
722      /**
723       * Get the archive files.
724       */
725      void get_archive_files (files& afiles);
726
727      /**
728       * Get the object files including those in archives.
729       */
730      void get_object_files (files& ofiles);
731
732      /**
733       * Get the archive count.
734       */
735      int archive_count () const;
736
737      /**
738       * Get the object count.
739       */
740      int object_count () const;
741
742      /**
743       * Get the path count.
744       */
745      int path_count () const;
746
747      /**
748       * Output archive files.
749       */
750      void output_archive_files (std::ostream& out);
751
752      /**
753       * Output archive files.
754       */
755      void output_object_files (std::ostream& out);
756
757    protected:
758
759      /**
760       * Input a path into the cache.
761       */
762      virtual void input (const std::string& path);
763
764    private:
765      paths    paths_;    //< The names of the files to process.
766      archives archives_; //< The archive files.
767      objects  objects_;  //< The object files.
768      bool     opened;    //< The cache is open.
769    };
770
771    /**
772     * Find the libraries given the list of libraries as bare name which
773     * have 'lib' and '.a' added.
774     */
775    void find_libraries (paths& libraries, paths& libpaths, paths& libs);
776
777  }
778}
779
780#endif
Note: See TracBrowser for help on using the repository browser.