source: rtems-tools/linkers/rld-files.h @ fd8a2c5

4.104.11
Last change on this file since fd8a2c5 was fd8a2c5, checked in by Chris Johns <chrisj@…>, on Nov 20, 2012 at 8:53:24 AM

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