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

4.104.11
Last change on this file since fe19d06 was fe19d06, checked in by Chris Johns <chrisj@…>, on Nov 20, 2012 at 11:40:01 PM

Fix archive GNU extension and make image read/write follow POSIX.

Fix the finding of a file name in the GNU extension for long names
in GNU archives so the correct location is referenced.

Made the image read and write routines keep reading if not all the
requested data is read or written due to possible signals.

  • Property mode set to 100644
File size: 19.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 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 or on disk.
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 the archive or on disk.
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 (void* 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     * Copy the in file to the out file.
784     *
785     * @param in The input file.
786     * @param out The output file.
787     * @param size The amount to copy. If 0 the whole on in is copied.
788     */
789    void copy_file (image& in, image& out, size_t size = 0);
790
791    /**
792     * Find the libraries given the list of libraries as bare name which
793     * have 'lib' and '.a' added.
794     */
795    void find_libraries (paths& libraries, paths& libpaths, paths& libs);
796
797  }
798}
799
800#endif
Note: See TracBrowser for help on using the repository browser.