]>
Commit | Line | Data |
---|---|---|
a2fb1b05 ILT |
1 | // layout.h -- lay out output file sections for gold -*- C++ -*- |
2 | ||
3 | #ifndef GOLD_LAYOUT_H | |
4 | #define GOLD_LAYOUT_H | |
5 | ||
6 | #include <list> | |
7 | #include <string> | |
8 | #include <utility> | |
9 | #include <vector> | |
10 | ||
11 | #include "options.h" | |
12 | #include "workqueue.h" | |
13 | #include "object.h" | |
14 | #include "stringpool.h" | |
15 | ||
16 | namespace gold | |
17 | { | |
18 | ||
54dc6425 | 19 | class Input_objects; |
75f65a3e | 20 | class Symbol_table; |
a2fb1b05 | 21 | class Output_section; |
54dc6425 | 22 | class Output_section_symtab; |
75f65a3e | 23 | class Output_section_headers; |
a2fb1b05 | 24 | class Output_segment; |
54dc6425 | 25 | class Output_data; |
61ba1cf9 | 26 | class Target; |
a2fb1b05 ILT |
27 | |
28 | // This Task handles mapping the input sections to output sections and | |
29 | // laying them out in memory. | |
30 | ||
31 | class Layout_task : public Task | |
32 | { | |
33 | public: | |
34 | // OPTIONS is the command line options, INPUT_OBJECTS is the list of | |
35 | // input objects, THIS_BLOCKER is a token which blocks this task | |
36 | // from executing until all the input symbols have been read. | |
54dc6425 ILT |
37 | Layout_task(const General_options& options, |
38 | const Input_objects* input_objects, | |
75f65a3e | 39 | Symbol_table* symtab, |
a2fb1b05 | 40 | Task_token* this_blocker) |
75f65a3e | 41 | : options_(options), input_objects_(input_objects), symtab_(symtab), |
a2fb1b05 ILT |
42 | this_blocker_(this_blocker) |
43 | { } | |
44 | ||
45 | ~Layout_task(); | |
46 | ||
47 | // The standard Task methods. | |
48 | ||
49 | Is_runnable_type | |
50 | is_runnable(Workqueue*); | |
51 | ||
52 | Task_locker* | |
53 | locks(Workqueue*); | |
54 | ||
55 | void | |
56 | run(Workqueue*); | |
57 | ||
58 | private: | |
59 | Layout_task(const Layout_task&); | |
60 | Layout_task& operator=(const Layout_task&); | |
61 | ||
62 | const General_options& options_; | |
54dc6425 | 63 | const Input_objects* input_objects_; |
75f65a3e | 64 | Symbol_table* symtab_; |
a2fb1b05 ILT |
65 | Task_token* this_blocker_; |
66 | }; | |
67 | ||
68 | // This class handles the details of laying out input sections. | |
69 | ||
70 | class Layout | |
71 | { | |
72 | public: | |
54dc6425 ILT |
73 | Layout(const General_options& options); |
74 | ||
75 | // Initialize the object. | |
76 | void | |
77 | init(); | |
a2fb1b05 ILT |
78 | |
79 | // Given an input section named NAME with data in SHDR from the | |
80 | // object file OBJECT, return the output section where this input | |
81 | // section should go. Set *OFFSET to the offset within the output | |
82 | // section. | |
83 | template<int size, bool big_endian> | |
84 | Output_section* | |
85 | layout(Object *object, const char* name, | |
86 | const elfcpp::Shdr<size, big_endian>& shdr, off_t* offset); | |
87 | ||
61ba1cf9 ILT |
88 | // Return the Stringpool used for symbol names. |
89 | const Stringpool* | |
90 | sympool() const | |
91 | { return &this->sympool_; } | |
92 | ||
a2fb1b05 ILT |
93 | // Return whether a section is a .gnu.linkonce section, given the |
94 | // section name. | |
95 | static inline bool | |
96 | is_linkonce(const char* name) | |
97 | { return strncmp(name, ".gnu.linkonce", sizeof(".gnu.linkonce") - 1) == 0; } | |
98 | ||
99 | // Record the signature of a comdat section, and return whether to | |
100 | // include it in the link. The GROUP parameter is true for a | |
101 | // section group signature, false for a signature derived from a | |
102 | // .gnu.linkonce section. | |
103 | bool | |
104 | add_comdat(const char*, bool group); | |
105 | ||
54dc6425 | 106 | // Finalize the layout after all the input sections have been added. |
75f65a3e ILT |
107 | off_t |
108 | finalize(const Input_objects*, Symbol_table*); | |
54dc6425 | 109 | |
61ba1cf9 ILT |
110 | // Write out data not associated with an input file or the symbol |
111 | // table. | |
112 | void | |
113 | write_data(Output_file*) const; | |
114 | ||
54dc6425 ILT |
115 | // The list of segments. |
116 | ||
117 | typedef std::vector<Output_segment*> Segment_list; | |
118 | ||
119 | // The list of sections not attached to a segment. | |
120 | ||
121 | typedef std::list<Output_section*> Section_list; | |
122 | ||
123 | // The list of information to write out which is not attached to | |
124 | // either a section or a segment. | |
125 | typedef std::list<Output_data*> Data_list; | |
126 | ||
a2fb1b05 ILT |
127 | private: |
128 | Layout(const Layout&); | |
129 | Layout& operator=(const Layout&); | |
130 | ||
131 | // Mapping from .gnu.linkonce section names to output section names. | |
132 | struct Linkonce_mapping | |
133 | { | |
134 | const char* from; | |
135 | int fromlen; | |
136 | const char* to; | |
137 | }; | |
138 | static const Linkonce_mapping linkonce_mapping[]; | |
139 | static const int linkonce_mapping_count; | |
140 | ||
75f65a3e ILT |
141 | // Find the first read-only PT_LOAD segment, creating one if |
142 | // necessary. | |
143 | Output_segment* | |
144 | find_first_load_seg(); | |
145 | ||
146 | // Set the final file offsets of all the segments. | |
147 | off_t | |
148 | set_segment_offsets(const Target*, Output_segment*); | |
149 | ||
150 | // Set the final file offsets of all the sections not associated | |
151 | // with a segment. | |
152 | off_t | |
153 | set_section_offsets(off_t); | |
54dc6425 ILT |
154 | |
155 | // Create the output sections for the symbol table. | |
156 | void | |
61ba1cf9 | 157 | create_symtab_sections(int size, const Input_objects*, Symbol_table*, off_t*, |
75f65a3e ILT |
158 | Output_section** osymtab, |
159 | Output_section** ostrtab); | |
54dc6425 | 160 | |
75f65a3e ILT |
161 | // Create the .shstrtab section. |
162 | Output_section* | |
163 | create_shstrtab(); | |
164 | ||
165 | // Create the section header table. | |
166 | Output_section_headers* | |
61ba1cf9 | 167 | create_shdrs(int size, bool big_endian, off_t*); |
54dc6425 | 168 | |
a2fb1b05 ILT |
169 | // Return whether to include this section in the link. |
170 | template<int size, bool big_endian> | |
171 | bool | |
172 | include_section(Object* object, const char* name, | |
173 | const elfcpp::Shdr<size, big_endian>&); | |
174 | ||
175 | // Return the output section name to use for a linkonce section | |
176 | // name. | |
177 | static const char* | |
178 | linkonce_output_name(const char* name); | |
179 | ||
180 | // Create a new Output_section. | |
181 | Output_section* | |
182 | make_output_section(const char* name, elfcpp::Elf_Word type, | |
183 | elfcpp::Elf_Xword flags); | |
184 | ||
185 | // Return whether SEG1 comes before SEG2 in the output file. | |
186 | static bool | |
b3168e9d | 187 | segment_precedes(const Output_segment* seg1, const Output_segment* seg2); |
a2fb1b05 ILT |
188 | |
189 | // Map from section flags to segment flags. | |
190 | static elfcpp::Elf_Word | |
191 | section_flags_to_segment(elfcpp::Elf_Xword flags); | |
192 | ||
193 | // A mapping used for group signatures. | |
194 | typedef Unordered_map<std::string, bool> Signatures; | |
195 | ||
196 | // Mapping from input section name/type/flags to output section. We | |
197 | // use canonicalized strings here. | |
198 | ||
199 | typedef std::pair<const char*, | |
200 | std::pair<elfcpp::Elf_Word, elfcpp::Elf_Xword> > Key; | |
201 | ||
202 | struct Hash_key | |
203 | { | |
204 | size_t | |
205 | operator()(const Key& k) const; | |
206 | }; | |
207 | ||
208 | typedef Unordered_map<Key, Output_section*, Hash_key> Section_name_map; | |
209 | ||
210 | // A comparison class for segments. | |
211 | ||
212 | struct Compare_segments | |
213 | { | |
214 | bool | |
215 | operator()(const Output_segment* seg1, const Output_segment* seg2) | |
216 | { return Layout::segment_precedes(seg1, seg2); } | |
217 | }; | |
218 | ||
a2fb1b05 ILT |
219 | // A reference to the options on the command line. |
220 | const General_options& options_; | |
61ba1cf9 ILT |
221 | // The index of the last output section. |
222 | unsigned int last_shndx_; | |
a2fb1b05 ILT |
223 | // The output section names. |
224 | Stringpool namepool_; | |
75f65a3e ILT |
225 | // The output symbol names. |
226 | Stringpool sympool_; | |
a2fb1b05 ILT |
227 | // The list of group sections and linkonce sections which we have seen. |
228 | Signatures signatures_; | |
229 | // The mapping from input section name/type/flags to output sections. | |
230 | Section_name_map section_name_map_; | |
231 | // The list of output segments. | |
232 | Segment_list segment_list_; | |
233 | // The list of output sections which are not attached to any output | |
234 | // segment. | |
235 | Section_list section_list_; | |
61ba1cf9 ILT |
236 | // The list of sections which require special output because they |
237 | // are not comprised of input sections. | |
238 | Data_list special_output_list_; | |
239 | }; | |
240 | ||
241 | // This task handles writing out data which is not part of a section | |
242 | // or segment. | |
243 | ||
244 | class Write_data_task : public Task | |
245 | { | |
246 | public: | |
247 | Write_data_task(const Layout* layout, Output_file* of, | |
248 | Task_token* final_blocker) | |
249 | : layout_(layout), of_(of), final_blocker_(final_blocker) | |
250 | { } | |
251 | ||
252 | // The standard Task methods. | |
253 | ||
254 | Is_runnable_type | |
255 | is_runnable(Workqueue*); | |
256 | ||
257 | Task_locker* | |
258 | locks(Workqueue*); | |
259 | ||
260 | void | |
261 | run(Workqueue*); | |
262 | ||
263 | private: | |
264 | const Layout* layout_; | |
265 | Output_file* of_; | |
266 | Task_token* final_blocker_; | |
267 | }; | |
268 | ||
269 | // This task handles writing out the global symbols. | |
270 | ||
271 | class Write_symbols_task : public Task | |
272 | { | |
273 | public: | |
274 | Write_symbols_task(const Symbol_table* symtab, const Target* target, | |
275 | const Stringpool* sympool, Output_file* of, | |
276 | Task_token* final_blocker) | |
277 | : symtab_(symtab), target_(target), sympool_(sympool), of_(of), | |
278 | final_blocker_(final_blocker) | |
279 | { } | |
280 | ||
281 | // The standard Task methods. | |
282 | ||
283 | Is_runnable_type | |
284 | is_runnable(Workqueue*); | |
285 | ||
286 | Task_locker* | |
287 | locks(Workqueue*); | |
288 | ||
289 | void | |
290 | run(Workqueue*); | |
291 | ||
292 | private: | |
293 | const Symbol_table* symtab_; | |
294 | const Target* target_; | |
295 | const Stringpool* sympool_; | |
296 | Output_file* of_; | |
297 | Task_token* final_blocker_; | |
298 | }; | |
299 | ||
300 | // This task handles closing the file. | |
301 | ||
302 | class Close_task : public Task | |
303 | { | |
304 | public: | |
305 | Close_task(Output_file* of, Task_token* final_blocker) | |
306 | : of_(of), final_blocker_(final_blocker) | |
307 | { } | |
308 | ||
309 | // The standard task methods. | |
310 | ||
311 | Is_runnable_type | |
312 | is_runnable(Workqueue*); | |
313 | ||
314 | Task_locker* | |
315 | locks(Workqueue*); | |
316 | ||
317 | void | |
318 | run(Workqueue*); | |
319 | ||
320 | private: | |
321 | Output_file* of_; | |
322 | Task_token* final_blocker_; | |
a2fb1b05 ILT |
323 | }; |
324 | ||
325 | } // End namespace gold. | |
326 | ||
327 | #endif // !defined(GOLD_LAYOUT_H) |