OSDN Git Service

Implement --whole-archive.
[pf3gnuchains/pf3gnuchains3x.git] / gold / archive.h
1 // archive.h -- archive support for gold      -*- C++ -*-
2
3 #ifndef GOLD_ARCHIVE_H
4 #define GOLD_ARCHIVE_H
5
6 #include <string>
7 #include <vector>
8
9 #include "workqueue.h"
10
11 namespace gold
12 {
13
14 class General_options;
15 class Input_file;
16 class Input_objects;
17 class Input_group;
18 class Layout;
19 class Symbol_table;
20
21 // This class represents an archive--generally a libNAME.a file.
22 // Archives have a symbol table and a list of objects.
23
24 class Archive
25 {
26  public:
27   Archive(const std::string& name, Input_file* input_file)
28     : name_(name), input_file_(input_file), armap_(), extended_names_()
29   { }
30
31   // The length of the magic string at the start of an archive.
32   static const int sarmag = 8;
33
34   // The magic string at the start of an archive.
35   static const char armag[sarmag];
36
37   // The string expected at the end of an archive member header.
38   static const char arfmag[2];
39
40   // The name of the object.
41   const std::string&
42   name() const
43   { return this->name_; }
44
45   // Set up the archive: read the symbol map.
46   void
47   setup();
48
49   // Get a reference to the underlying file.
50   File_read&
51   file()
52   { return this->input_file_->file(); }
53
54   // Lock the underlying file.
55   void
56   lock()
57   { this->input_file_->file().lock(); }
58
59   // Unlock the underlying file.
60   void
61   unlock()
62   { this->input_file_->file().unlock(); }
63
64   // Return whether the underlying file is locked.
65   bool
66   is_locked() const
67   { return this->input_file_->file().is_locked(); }
68
69   // Select members from the archive as needed and add them to the
70   // link.
71   void
72   add_symbols(const General_options&, Symbol_table*, Layout*, Input_objects*);
73
74  private:
75   Archive(const Archive&);
76   Archive& operator=(const Archive&);
77
78   struct Archive_header;
79
80   // Get a view into the underlying file.
81   const unsigned char*
82   get_view(off_t start, off_t size, off_t* pbytes = NULL)
83   { return this->input_file_->file().get_view(start, size, pbytes); }
84
85   // Read the archive symbol map.
86   void
87   read_armap(off_t start, off_t size);
88
89   // Read an archive member header at OFF.  Return the size of the
90   // member, and set *PNAME to the name.
91   off_t
92   read_header(off_t off, std::string* pname);
93
94   // Interpret an archive header HDR at OFF.  Return the size of the
95   // member, and set *PNAME to the name.
96   off_t
97   interpret_header(const Archive_header* hdr, off_t off, std::string* pname);
98
99   // Include all the archive members in the link.
100   void
101   include_all_members(const General_options&, Symbol_table*, Layout*,
102                       Input_objects*);
103
104   // Include an archive member in the link.
105   void
106   include_member(const General_options&, Symbol_table*, Layout*,
107                  Input_objects*, off_t off);
108
109   // An entry in the archive map of symbols to object files.
110   struct Armap_entry
111   {
112     // The symbol name.
113     const char* name;
114     // The offset to the file.
115     off_t offset;
116   };
117
118   // Name of object as printed to user.
119   std::string name_;
120   // For reading the file.
121   Input_file* input_file_;
122   // The archive map.
123   std::vector<Armap_entry> armap_;
124   // The extended name table.
125   std::string extended_names_;
126   // Track which symbols in the archive map are for elements which
127   // have already been included in the link.
128   std::vector<bool> seen_;
129 };
130
131 // This class is used to read an archive and pick out the desired
132 // elements and add them to the link.
133
134 class Add_archive_symbols : public Task
135 {
136  public:
137   Add_archive_symbols(const General_options& options, Symbol_table* symtab,
138                       Layout* layout, Input_objects* input_objects,
139                       Archive* archive, Input_group* input_group,
140                       Task_token* this_blocker,
141                       Task_token* next_blocker)
142     : options_(options), symtab_(symtab), layout_(layout),
143       input_objects_(input_objects), archive_(archive),
144       input_group_(input_group), this_blocker_(this_blocker),
145       next_blocker_(next_blocker)
146   { }
147
148   ~Add_archive_symbols();
149
150   // The standard Task methods.
151
152   Is_runnable_type
153   is_runnable(Workqueue*);
154
155   Task_locker*
156   locks(Workqueue*);
157
158   void
159   run(Workqueue*);
160
161  private:
162   class Add_archive_symbols_locker;
163
164   const General_options& options_;
165   Symbol_table* symtab_;
166   Layout* layout_;
167   Input_objects* input_objects_;
168   Archive* archive_;
169   Input_group* input_group_;
170   Task_token* this_blocker_;
171   Task_token* next_blocker_;
172 };
173
174 } // End namespace gold.
175
176 #endif // !defined(GOLD_ARCHIVE_H)