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