Commit | Line | Data |
---|---|---|
bae7f79e ILT |
1 | // object.cc -- support for an object file for linking in gold |
2 | ||
6cb15b7f ILT |
3 | // Copyright 2006, 2007 Free Software Foundation, Inc. |
4 | // Written by Ian Lance Taylor <iant@google.com>. | |
5 | ||
6 | // This file is part of gold. | |
7 | ||
8 | // This program is free software; you can redistribute it and/or modify | |
9 | // it under the terms of the GNU General Public License as published by | |
10 | // the Free Software Foundation; either version 3 of the License, or | |
11 | // (at your option) any later version. | |
12 | ||
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | ||
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | |
21 | // MA 02110-1301, USA. | |
22 | ||
bae7f79e ILT |
23 | #include "gold.h" |
24 | ||
25 | #include <cerrno> | |
26 | #include <cstring> | |
645f8123 | 27 | #include <cstdarg> |
bae7f79e | 28 | |
14bfc3f5 | 29 | #include "target-select.h" |
5c2c6c95 | 30 | #include "dwarf_reader.h" |
a2fb1b05 | 31 | #include "layout.h" |
61ba1cf9 | 32 | #include "output.h" |
f6ce93d6 ILT |
33 | #include "symtab.h" |
34 | #include "object.h" | |
35 | #include "dynobj.h" | |
bae7f79e ILT |
36 | |
37 | namespace gold | |
38 | { | |
39 | ||
645f8123 ILT |
40 | // Class Object. |
41 | ||
dbe717ef ILT |
42 | // Set the target based on fields in the ELF file header. |
43 | ||
44 | void | |
45 | Object::set_target(int machine, int size, bool big_endian, int osabi, | |
46 | int abiversion) | |
47 | { | |
48 | Target* target = select_target(machine, size, big_endian, osabi, abiversion); | |
49 | if (target == NULL) | |
75f2446e ILT |
50 | gold_fatal(_("%s: unsupported ELF machine number %d"), |
51 | this->name().c_str(), machine); | |
dbe717ef ILT |
52 | this->target_ = target; |
53 | } | |
54 | ||
75f2446e ILT |
55 | // Report an error for this object file. This is used by the |
56 | // elfcpp::Elf_file interface, and also called by the Object code | |
57 | // itself. | |
645f8123 ILT |
58 | |
59 | void | |
75f2446e | 60 | Object::error(const char* format, ...) const |
645f8123 ILT |
61 | { |
62 | va_list args; | |
645f8123 | 63 | va_start(args, format); |
75f2446e ILT |
64 | char* buf = NULL; |
65 | if (vasprintf(&buf, format, args) < 0) | |
66 | gold_nomem(); | |
645f8123 | 67 | va_end(args); |
75f2446e ILT |
68 | gold_error(_("%s: %s"), this->name().c_str(), buf); |
69 | free(buf); | |
645f8123 ILT |
70 | } |
71 | ||
72 | // Return a view of the contents of a section. | |
73 | ||
74 | const unsigned char* | |
9eb9fa57 | 75 | Object::section_contents(unsigned int shndx, off_t* plen, bool cache) |
645f8123 ILT |
76 | { |
77 | Location loc(this->do_section_contents(shndx)); | |
78 | *plen = loc.data_size; | |
9eb9fa57 | 79 | return this->get_view(loc.file_offset, loc.data_size, cache); |
645f8123 ILT |
80 | } |
81 | ||
dbe717ef ILT |
82 | // Read the section data into SD. This is code common to Sized_relobj |
83 | // and Sized_dynobj, so we put it into Object. | |
84 | ||
85 | template<int size, bool big_endian> | |
86 | void | |
87 | Object::read_section_data(elfcpp::Elf_file<size, big_endian, Object>* elf_file, | |
88 | Read_symbols_data* sd) | |
89 | { | |
90 | const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; | |
91 | ||
92 | // Read the section headers. | |
93 | const off_t shoff = elf_file->shoff(); | |
94 | const unsigned int shnum = this->shnum(); | |
9eb9fa57 | 95 | sd->section_headers = this->get_lasting_view(shoff, shnum * shdr_size, true); |
dbe717ef ILT |
96 | |
97 | // Read the section names. | |
98 | const unsigned char* pshdrs = sd->section_headers->data(); | |
99 | const unsigned char* pshdrnames = pshdrs + elf_file->shstrndx() * shdr_size; | |
100 | typename elfcpp::Shdr<size, big_endian> shdrnames(pshdrnames); | |
101 | ||
102 | if (shdrnames.get_sh_type() != elfcpp::SHT_STRTAB) | |
75f2446e ILT |
103 | this->error(_("section name section has wrong type: %u"), |
104 | static_cast<unsigned int>(shdrnames.get_sh_type())); | |
dbe717ef ILT |
105 | |
106 | sd->section_names_size = shdrnames.get_sh_size(); | |
107 | sd->section_names = this->get_lasting_view(shdrnames.get_sh_offset(), | |
9eb9fa57 | 108 | sd->section_names_size, false); |
dbe717ef ILT |
109 | } |
110 | ||
111 | // If NAME is the name of a special .gnu.warning section, arrange for | |
112 | // the warning to be issued. SHNDX is the section index. Return | |
113 | // whether it is a warning section. | |
114 | ||
115 | bool | |
116 | Object::handle_gnu_warning_section(const char* name, unsigned int shndx, | |
117 | Symbol_table* symtab) | |
118 | { | |
119 | const char warn_prefix[] = ".gnu.warning."; | |
120 | const int warn_prefix_len = sizeof warn_prefix - 1; | |
121 | if (strncmp(name, warn_prefix, warn_prefix_len) == 0) | |
122 | { | |
123 | symtab->add_warning(name + warn_prefix_len, this, shndx); | |
124 | return true; | |
125 | } | |
126 | return false; | |
127 | } | |
128 | ||
f6ce93d6 | 129 | // Class Sized_relobj. |
bae7f79e ILT |
130 | |
131 | template<int size, bool big_endian> | |
f6ce93d6 | 132 | Sized_relobj<size, big_endian>::Sized_relobj( |
bae7f79e ILT |
133 | const std::string& name, |
134 | Input_file* input_file, | |
135 | off_t offset, | |
136 | const elfcpp::Ehdr<size, big_endian>& ehdr) | |
f6ce93d6 | 137 | : Relobj(name, input_file, offset), |
645f8123 | 138 | elf_file_(this, ehdr), |
dbe717ef | 139 | symtab_shndx_(-1U), |
61ba1cf9 ILT |
140 | local_symbol_count_(0), |
141 | output_local_symbol_count_(0), | |
75f65a3e | 142 | symbols_(NULL), |
61ba1cf9 | 143 | local_symbol_offset_(0), |
e727fa71 ILT |
144 | local_values_(), |
145 | local_got_offsets_() | |
bae7f79e | 146 | { |
bae7f79e ILT |
147 | } |
148 | ||
149 | template<int size, bool big_endian> | |
f6ce93d6 | 150 | Sized_relobj<size, big_endian>::~Sized_relobj() |
bae7f79e ILT |
151 | { |
152 | } | |
153 | ||
645f8123 | 154 | // Set up an object file based on the file header. This sets up the |
bae7f79e ILT |
155 | // target and reads the section information. |
156 | ||
157 | template<int size, bool big_endian> | |
158 | void | |
f6ce93d6 | 159 | Sized_relobj<size, big_endian>::setup( |
bae7f79e ILT |
160 | const elfcpp::Ehdr<size, big_endian>& ehdr) |
161 | { | |
dbe717ef ILT |
162 | this->set_target(ehdr.get_e_machine(), size, big_endian, |
163 | ehdr.get_e_ident()[elfcpp::EI_OSABI], | |
164 | ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]); | |
12e14209 | 165 | |
dbe717ef | 166 | const unsigned int shnum = this->elf_file_.shnum(); |
a2fb1b05 | 167 | this->set_shnum(shnum); |
dbe717ef | 168 | } |
12e14209 | 169 | |
dbe717ef ILT |
170 | // Find the SHT_SYMTAB section, given the section headers. The ELF |
171 | // standard says that maybe in the future there can be more than one | |
172 | // SHT_SYMTAB section. Until somebody figures out how that could | |
173 | // work, we assume there is only one. | |
12e14209 | 174 | |
dbe717ef ILT |
175 | template<int size, bool big_endian> |
176 | void | |
177 | Sized_relobj<size, big_endian>::find_symtab(const unsigned char* pshdrs) | |
178 | { | |
179 | const unsigned int shnum = this->shnum(); | |
180 | this->symtab_shndx_ = 0; | |
181 | if (shnum > 0) | |
bae7f79e | 182 | { |
dbe717ef ILT |
183 | // Look through the sections in reverse order, since gas tends |
184 | // to put the symbol table at the end. | |
185 | const unsigned char* p = pshdrs + shnum * This::shdr_size; | |
186 | unsigned int i = shnum; | |
187 | while (i > 0) | |
bae7f79e | 188 | { |
dbe717ef ILT |
189 | --i; |
190 | p -= This::shdr_size; | |
191 | typename This::Shdr shdr(p); | |
192 | if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB) | |
193 | { | |
194 | this->symtab_shndx_ = i; | |
195 | break; | |
196 | } | |
bae7f79e | 197 | } |
bae7f79e ILT |
198 | } |
199 | } | |
200 | ||
12e14209 | 201 | // Read the sections and symbols from an object file. |
bae7f79e ILT |
202 | |
203 | template<int size, bool big_endian> | |
12e14209 | 204 | void |
f6ce93d6 | 205 | Sized_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd) |
bae7f79e | 206 | { |
dbe717ef | 207 | this->read_section_data(&this->elf_file_, sd); |
12e14209 | 208 | |
dbe717ef ILT |
209 | const unsigned char* const pshdrs = sd->section_headers->data(); |
210 | ||
211 | this->find_symtab(pshdrs); | |
12e14209 | 212 | |
75f2446e ILT |
213 | sd->symbols = NULL; |
214 | sd->symbols_size = 0; | |
215 | sd->symbol_names = NULL; | |
216 | sd->symbol_names_size = 0; | |
217 | ||
645f8123 | 218 | if (this->symtab_shndx_ == 0) |
bae7f79e ILT |
219 | { |
220 | // No symbol table. Weird but legal. | |
12e14209 | 221 | return; |
bae7f79e ILT |
222 | } |
223 | ||
12e14209 ILT |
224 | // Get the symbol table section header. |
225 | typename This::Shdr symtabshdr(pshdrs | |
645f8123 | 226 | + this->symtab_shndx_ * This::shdr_size); |
a3ad94ed | 227 | gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB); |
bae7f79e | 228 | |
75f65a3e ILT |
229 | // We only need the external symbols. |
230 | const int sym_size = This::sym_size; | |
92e059d8 ILT |
231 | const unsigned int loccount = symtabshdr.get_sh_info(); |
232 | this->local_symbol_count_ = loccount; | |
233 | off_t locsize = loccount * sym_size; | |
75f65a3e ILT |
234 | off_t extoff = symtabshdr.get_sh_offset() + locsize; |
235 | off_t extsize = symtabshdr.get_sh_size() - locsize; | |
236 | ||
bae7f79e | 237 | // Read the symbol table. |
9eb9fa57 | 238 | File_view* fvsymtab = this->get_lasting_view(extoff, extsize, false); |
bae7f79e ILT |
239 | |
240 | // Read the section header for the symbol names. | |
dbe717ef ILT |
241 | unsigned int strtab_shndx = symtabshdr.get_sh_link(); |
242 | if (strtab_shndx >= this->shnum()) | |
bae7f79e | 243 | { |
75f2446e ILT |
244 | this->error(_("invalid symbol table name index: %u"), strtab_shndx); |
245 | return; | |
bae7f79e | 246 | } |
dbe717ef | 247 | typename This::Shdr strtabshdr(pshdrs + strtab_shndx * This::shdr_size); |
bae7f79e ILT |
248 | if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB) |
249 | { | |
75f2446e ILT |
250 | this->error(_("symbol table name section has wrong type: %u"), |
251 | static_cast<unsigned int>(strtabshdr.get_sh_type())); | |
252 | return; | |
bae7f79e ILT |
253 | } |
254 | ||
255 | // Read the symbol names. | |
256 | File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(), | |
9eb9fa57 | 257 | strtabshdr.get_sh_size(), true); |
bae7f79e | 258 | |
12e14209 ILT |
259 | sd->symbols = fvsymtab; |
260 | sd->symbols_size = extsize; | |
261 | sd->symbol_names = fvstrtab; | |
262 | sd->symbol_names_size = strtabshdr.get_sh_size(); | |
a2fb1b05 ILT |
263 | } |
264 | ||
265 | // Return whether to include a section group in the link. LAYOUT is | |
266 | // used to keep track of which section groups we have already seen. | |
267 | // INDEX is the index of the section group and SHDR is the section | |
268 | // header. If we do not want to include this group, we set bits in | |
269 | // OMIT for each section which should be discarded. | |
270 | ||
271 | template<int size, bool big_endian> | |
272 | bool | |
f6ce93d6 | 273 | Sized_relobj<size, big_endian>::include_section_group( |
a2fb1b05 ILT |
274 | Layout* layout, |
275 | unsigned int index, | |
276 | const elfcpp::Shdr<size, big_endian>& shdr, | |
277 | std::vector<bool>* omit) | |
278 | { | |
279 | // Read the section contents. | |
280 | const unsigned char* pcon = this->get_view(shdr.get_sh_offset(), | |
9eb9fa57 | 281 | shdr.get_sh_size(), false); |
a2fb1b05 ILT |
282 | const elfcpp::Elf_Word* pword = |
283 | reinterpret_cast<const elfcpp::Elf_Word*>(pcon); | |
284 | ||
285 | // The first word contains flags. We only care about COMDAT section | |
286 | // groups. Other section groups are always included in the link | |
287 | // just like ordinary sections. | |
f6ce93d6 | 288 | elfcpp::Elf_Word flags = elfcpp::Swap<32, big_endian>::readval(pword); |
a2fb1b05 ILT |
289 | if ((flags & elfcpp::GRP_COMDAT) == 0) |
290 | return true; | |
291 | ||
292 | // Look up the group signature, which is the name of a symbol. This | |
293 | // is a lot of effort to go to to read a string. Why didn't they | |
294 | // just use the name of the SHT_GROUP section as the group | |
295 | // signature? | |
296 | ||
297 | // Get the appropriate symbol table header (this will normally be | |
298 | // the single SHT_SYMTAB section, but in principle it need not be). | |
645f8123 ILT |
299 | const unsigned int link = shdr.get_sh_link(); |
300 | typename This::Shdr symshdr(this, this->elf_file_.section_header(link)); | |
a2fb1b05 ILT |
301 | |
302 | // Read the symbol table entry. | |
303 | if (shdr.get_sh_info() >= symshdr.get_sh_size() / This::sym_size) | |
304 | { | |
75f2446e ILT |
305 | this->error(_("section group %u info %u out of range"), |
306 | index, shdr.get_sh_info()); | |
307 | return false; | |
a2fb1b05 ILT |
308 | } |
309 | off_t symoff = symshdr.get_sh_offset() + shdr.get_sh_info() * This::sym_size; | |
9eb9fa57 | 310 | const unsigned char* psym = this->get_view(symoff, This::sym_size, true); |
a2fb1b05 ILT |
311 | elfcpp::Sym<size, big_endian> sym(psym); |
312 | ||
a2fb1b05 | 313 | // Read the symbol table names. |
645f8123 ILT |
314 | off_t symnamelen; |
315 | const unsigned char* psymnamesu; | |
9eb9fa57 ILT |
316 | psymnamesu = this->section_contents(symshdr.get_sh_link(), &symnamelen, |
317 | true); | |
a2fb1b05 ILT |
318 | const char* psymnames = reinterpret_cast<const char*>(psymnamesu); |
319 | ||
320 | // Get the section group signature. | |
645f8123 | 321 | if (sym.get_st_name() >= symnamelen) |
a2fb1b05 | 322 | { |
75f2446e ILT |
323 | this->error(_("symbol %u name offset %u out of range"), |
324 | shdr.get_sh_info(), sym.get_st_name()); | |
325 | return false; | |
a2fb1b05 ILT |
326 | } |
327 | ||
328 | const char* signature = psymnames + sym.get_st_name(); | |
329 | ||
ead1e424 ILT |
330 | // It seems that some versions of gas will create a section group |
331 | // associated with a section symbol, and then fail to give a name to | |
332 | // the section symbol. In such a case, use the name of the section. | |
333 | // FIXME. | |
645f8123 ILT |
334 | std::string secname; |
335 | if (signature[0] == '\0' && sym.get_st_type() == elfcpp::STT_SECTION) | |
ead1e424 | 336 | { |
645f8123 ILT |
337 | secname = this->section_name(sym.get_st_shndx()); |
338 | signature = secname.c_str(); | |
ead1e424 ILT |
339 | } |
340 | ||
a2fb1b05 ILT |
341 | // Record this section group, and see whether we've already seen one |
342 | // with the same signature. | |
343 | if (layout->add_comdat(signature, true)) | |
344 | return true; | |
345 | ||
346 | // This is a duplicate. We want to discard the sections in this | |
347 | // group. | |
348 | size_t count = shdr.get_sh_size() / sizeof(elfcpp::Elf_Word); | |
349 | for (size_t i = 1; i < count; ++i) | |
350 | { | |
f6ce93d6 ILT |
351 | elfcpp::Elf_Word secnum = |
352 | elfcpp::Swap<32, big_endian>::readval(pword + i); | |
a2fb1b05 ILT |
353 | if (secnum >= this->shnum()) |
354 | { | |
75f2446e ILT |
355 | this->error(_("section %u in section group %u out of range"), |
356 | secnum, index); | |
357 | continue; | |
a2fb1b05 ILT |
358 | } |
359 | (*omit)[secnum] = true; | |
360 | } | |
361 | ||
362 | return false; | |
363 | } | |
364 | ||
365 | // Whether to include a linkonce section in the link. NAME is the | |
366 | // name of the section and SHDR is the section header. | |
367 | ||
368 | // Linkonce sections are a GNU extension implemented in the original | |
369 | // GNU linker before section groups were defined. The semantics are | |
370 | // that we only include one linkonce section with a given name. The | |
371 | // name of a linkonce section is normally .gnu.linkonce.T.SYMNAME, | |
372 | // where T is the type of section and SYMNAME is the name of a symbol. | |
373 | // In an attempt to make linkonce sections interact well with section | |
374 | // groups, we try to identify SYMNAME and use it like a section group | |
375 | // signature. We want to block section groups with that signature, | |
376 | // but not other linkonce sections with that signature. We also use | |
377 | // the full name of the linkonce section as a normal section group | |
378 | // signature. | |
379 | ||
380 | template<int size, bool big_endian> | |
381 | bool | |
f6ce93d6 | 382 | Sized_relobj<size, big_endian>::include_linkonce_section( |
a2fb1b05 ILT |
383 | Layout* layout, |
384 | const char* name, | |
385 | const elfcpp::Shdr<size, big_endian>&) | |
386 | { | |
ad435a24 ILT |
387 | // In general the symbol name we want will be the string following |
388 | // the last '.'. However, we have to handle the case of | |
389 | // .gnu.linkonce.t.__i686.get_pc_thunk.bx, which was generated by | |
390 | // some versions of gcc. So we use a heuristic: if the name starts | |
391 | // with ".gnu.linkonce.t.", we use everything after that. Otherwise | |
392 | // we look for the last '.'. We can't always simply skip | |
393 | // ".gnu.linkonce.X", because we have to deal with cases like | |
394 | // ".gnu.linkonce.d.rel.ro.local". | |
395 | const char* const linkonce_t = ".gnu.linkonce.t."; | |
396 | const char* symname; | |
397 | if (strncmp(name, linkonce_t, strlen(linkonce_t)) == 0) | |
398 | symname = name + strlen(linkonce_t); | |
399 | else | |
400 | symname = strrchr(name, '.') + 1; | |
a783673b ILT |
401 | bool include1 = layout->add_comdat(symname, false); |
402 | bool include2 = layout->add_comdat(name, true); | |
403 | return include1 && include2; | |
a2fb1b05 ILT |
404 | } |
405 | ||
406 | // Lay out the input sections. We walk through the sections and check | |
407 | // whether they should be included in the link. If they should, we | |
408 | // pass them to the Layout object, which will return an output section | |
409 | // and an offset. | |
410 | ||
411 | template<int size, bool big_endian> | |
412 | void | |
7e1edb90 | 413 | Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, |
f6ce93d6 | 414 | Layout* layout, |
12e14209 | 415 | Read_symbols_data* sd) |
a2fb1b05 | 416 | { |
dbe717ef | 417 | const unsigned int shnum = this->shnum(); |
12e14209 ILT |
418 | if (shnum == 0) |
419 | return; | |
a2fb1b05 ILT |
420 | |
421 | // Get the section headers. | |
12e14209 | 422 | const unsigned char* pshdrs = sd->section_headers->data(); |
a2fb1b05 ILT |
423 | |
424 | // Get the section names. | |
12e14209 | 425 | const unsigned char* pnamesu = sd->section_names->data(); |
a2fb1b05 ILT |
426 | const char* pnames = reinterpret_cast<const char*>(pnamesu); |
427 | ||
428 | std::vector<Map_to_output>& map_sections(this->map_to_output()); | |
61ba1cf9 | 429 | map_sections.resize(shnum); |
a2fb1b05 | 430 | |
35cdfc9a ILT |
431 | // Whether we've seen a .note.GNU-stack section. |
432 | bool seen_gnu_stack = false; | |
433 | // The flags of a .note.GNU-stack section. | |
434 | uint64_t gnu_stack_flags = 0; | |
435 | ||
a2fb1b05 ILT |
436 | // Keep track of which sections to omit. |
437 | std::vector<bool> omit(shnum, false); | |
438 | ||
f6ce93d6 ILT |
439 | // Skip the first, dummy, section. |
440 | pshdrs += This::shdr_size; | |
441 | for (unsigned int i = 1; i < shnum; ++i, pshdrs += This::shdr_size) | |
a2fb1b05 | 442 | { |
75f65a3e | 443 | typename This::Shdr shdr(pshdrs); |
a2fb1b05 | 444 | |
12e14209 | 445 | if (shdr.get_sh_name() >= sd->section_names_size) |
a2fb1b05 | 446 | { |
75f2446e ILT |
447 | this->error(_("bad section name offset for section %u: %lu"), |
448 | i, static_cast<unsigned long>(shdr.get_sh_name())); | |
449 | return; | |
a2fb1b05 ILT |
450 | } |
451 | ||
452 | const char* name = pnames + shdr.get_sh_name(); | |
453 | ||
dbe717ef | 454 | if (this->handle_gnu_warning_section(name, i, symtab)) |
f6ce93d6 | 455 | { |
7e1edb90 | 456 | if (!parameters->output_is_object()) |
f6ce93d6 ILT |
457 | omit[i] = true; |
458 | } | |
459 | ||
35cdfc9a ILT |
460 | // The .note.GNU-stack section is special. It gives the |
461 | // protection flags that this object file requires for the stack | |
462 | // in memory. | |
463 | if (strcmp(name, ".note.GNU-stack") == 0) | |
464 | { | |
465 | seen_gnu_stack = true; | |
466 | gnu_stack_flags |= shdr.get_sh_flags(); | |
467 | omit[i] = true; | |
468 | } | |
469 | ||
a2fb1b05 ILT |
470 | bool discard = omit[i]; |
471 | if (!discard) | |
472 | { | |
473 | if (shdr.get_sh_type() == elfcpp::SHT_GROUP) | |
474 | { | |
475 | if (!this->include_section_group(layout, i, shdr, &omit)) | |
476 | discard = true; | |
477 | } | |
cba134d6 ILT |
478 | else if ((shdr.get_sh_flags() & elfcpp::SHF_GROUP) == 0 |
479 | && Layout::is_linkonce(name)) | |
a2fb1b05 ILT |
480 | { |
481 | if (!this->include_linkonce_section(layout, name, shdr)) | |
482 | discard = true; | |
483 | } | |
484 | } | |
485 | ||
486 | if (discard) | |
487 | { | |
488 | // Do not include this section in the link. | |
489 | map_sections[i].output_section = NULL; | |
490 | continue; | |
491 | } | |
492 | ||
493 | off_t offset; | |
ead1e424 | 494 | Output_section* os = layout->layout(this, i, name, shdr, &offset); |
a2fb1b05 ILT |
495 | |
496 | map_sections[i].output_section = os; | |
497 | map_sections[i].offset = offset; | |
12e14209 ILT |
498 | } |
499 | ||
35cdfc9a ILT |
500 | layout->layout_gnu_stack(seen_gnu_stack, gnu_stack_flags); |
501 | ||
12e14209 ILT |
502 | delete sd->section_headers; |
503 | sd->section_headers = NULL; | |
504 | delete sd->section_names; | |
505 | sd->section_names = NULL; | |
506 | } | |
507 | ||
508 | // Add the symbols to the symbol table. | |
509 | ||
510 | template<int size, bool big_endian> | |
511 | void | |
f6ce93d6 | 512 | Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab, |
12e14209 ILT |
513 | Read_symbols_data* sd) |
514 | { | |
515 | if (sd->symbols == NULL) | |
516 | { | |
a3ad94ed | 517 | gold_assert(sd->symbol_names == NULL); |
12e14209 ILT |
518 | return; |
519 | } | |
a2fb1b05 | 520 | |
12e14209 ILT |
521 | const int sym_size = This::sym_size; |
522 | size_t symcount = sd->symbols_size / sym_size; | |
f5c3f225 | 523 | if (static_cast<off_t>(symcount * sym_size) != sd->symbols_size) |
12e14209 | 524 | { |
75f2446e ILT |
525 | this->error(_("size of symbols is not multiple of symbol size")); |
526 | return; | |
a2fb1b05 | 527 | } |
12e14209 ILT |
528 | |
529 | this->symbols_ = new Symbol*[symcount]; | |
530 | ||
12e14209 ILT |
531 | const char* sym_names = |
532 | reinterpret_cast<const char*>(sd->symbol_names->data()); | |
193a53d9 | 533 | symtab->add_from_relobj(this, sd->symbols->data(), symcount, sym_names, |
dbe717ef | 534 | sd->symbol_names_size, this->symbols_); |
12e14209 ILT |
535 | |
536 | delete sd->symbols; | |
537 | sd->symbols = NULL; | |
538 | delete sd->symbol_names; | |
539 | sd->symbol_names = NULL; | |
bae7f79e ILT |
540 | } |
541 | ||
75f65a3e | 542 | // Finalize the local symbols. Here we record the file offset at |
61ba1cf9 | 543 | // which they should be output, we add their names to *POOL, and we |
b8e6aad9 ILT |
544 | // add their values to THIS->LOCAL_VALUES_. Return the symbol index. |
545 | // This function is always called from the main thread. The actual | |
546 | // output of the local symbols will occur in a separate task. | |
75f65a3e ILT |
547 | |
548 | template<int size, bool big_endian> | |
c06b7b0b ILT |
549 | unsigned int |
550 | Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, | |
551 | off_t off, | |
75f65a3e ILT |
552 | Stringpool* pool) |
553 | { | |
a3ad94ed | 554 | gold_assert(this->symtab_shndx_ != -1U); |
645f8123 | 555 | if (this->symtab_shndx_ == 0) |
61ba1cf9 ILT |
556 | { |
557 | // This object has no symbols. Weird but legal. | |
c06b7b0b | 558 | return index; |
61ba1cf9 ILT |
559 | } |
560 | ||
a3ad94ed | 561 | gold_assert(off == static_cast<off_t>(align_address(off, size >> 3))); |
61ba1cf9 | 562 | |
75f65a3e ILT |
563 | this->local_symbol_offset_ = off; |
564 | ||
565 | // Read the symbol table section header. | |
645f8123 ILT |
566 | const unsigned int symtab_shndx = this->symtab_shndx_; |
567 | typename This::Shdr symtabshdr(this, | |
568 | this->elf_file_.section_header(symtab_shndx)); | |
a3ad94ed | 569 | gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB); |
75f65a3e ILT |
570 | |
571 | // Read the local symbols. | |
75f65a3e | 572 | const int sym_size = This::sym_size; |
92e059d8 | 573 | const unsigned int loccount = this->local_symbol_count_; |
a3ad94ed | 574 | gold_assert(loccount == symtabshdr.get_sh_info()); |
75f65a3e ILT |
575 | off_t locsize = loccount * sym_size; |
576 | const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(), | |
9eb9fa57 | 577 | locsize, true); |
75f65a3e | 578 | |
c06b7b0b | 579 | this->local_values_.resize(loccount); |
61ba1cf9 | 580 | |
75f65a3e | 581 | // Read the symbol names. |
645f8123 ILT |
582 | const unsigned int strtab_shndx = symtabshdr.get_sh_link(); |
583 | off_t strtab_size; | |
584 | const unsigned char* pnamesu = this->section_contents(strtab_shndx, | |
9eb9fa57 ILT |
585 | &strtab_size, |
586 | true); | |
75f65a3e ILT |
587 | const char* pnames = reinterpret_cast<const char*>(pnamesu); |
588 | ||
589 | // Loop over the local symbols. | |
590 | ||
c06b7b0b | 591 | const std::vector<Map_to_output>& mo(this->map_to_output()); |
75f65a3e | 592 | unsigned int shnum = this->shnum(); |
61ba1cf9 | 593 | unsigned int count = 0; |
75f65a3e ILT |
594 | // Skip the first, dummy, symbol. |
595 | psyms += sym_size; | |
61ba1cf9 | 596 | for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size) |
75f65a3e ILT |
597 | { |
598 | elfcpp::Sym<size, big_endian> sym(psyms); | |
599 | ||
b8e6aad9 ILT |
600 | Symbol_value<size>& lv(this->local_values_[i]); |
601 | ||
75f65a3e | 602 | unsigned int shndx = sym.get_st_shndx(); |
b8e6aad9 | 603 | lv.set_input_shndx(shndx); |
75f65a3e | 604 | |
063f12a8 ILT |
605 | if (sym.get_st_type() == elfcpp::STT_SECTION) |
606 | lv.set_is_section_symbol(); | |
607 | ||
75f65a3e ILT |
608 | if (shndx >= elfcpp::SHN_LORESERVE) |
609 | { | |
61ba1cf9 | 610 | if (shndx == elfcpp::SHN_ABS) |
b8e6aad9 | 611 | lv.set_output_value(sym.get_st_value()); |
61ba1cf9 | 612 | else |
75f65a3e | 613 | { |
61ba1cf9 | 614 | // FIXME: Handle SHN_XINDEX. |
75f2446e ILT |
615 | this->error(_("unknown section index %u for local symbol %u"), |
616 | shndx, i); | |
617 | lv.set_output_value(0); | |
75f65a3e | 618 | } |
75f65a3e ILT |
619 | } |
620 | else | |
621 | { | |
622 | if (shndx >= shnum) | |
623 | { | |
75f2446e ILT |
624 | this->error(_("local symbol %u section index %u out of range"), |
625 | i, shndx); | |
626 | shndx = 0; | |
75f65a3e ILT |
627 | } |
628 | ||
b8e6aad9 ILT |
629 | Output_section* os = mo[shndx].output_section; |
630 | ||
631 | if (os == NULL) | |
61ba1cf9 | 632 | { |
b8e6aad9 ILT |
633 | lv.set_output_value(0); |
634 | lv.set_no_output_symtab_entry(); | |
61ba1cf9 ILT |
635 | continue; |
636 | } | |
637 | ||
b8e6aad9 ILT |
638 | if (mo[shndx].offset == -1) |
639 | lv.set_input_value(sym.get_st_value()); | |
640 | else | |
641 | lv.set_output_value(mo[shndx].output_section->address() | |
642 | + mo[shndx].offset | |
643 | + sym.get_st_value()); | |
75f65a3e ILT |
644 | } |
645 | ||
c06b7b0b ILT |
646 | // Decide whether this symbol should go into the output file. |
647 | ||
648 | if (sym.get_st_type() == elfcpp::STT_SECTION) | |
f6ce93d6 | 649 | { |
b8e6aad9 | 650 | lv.set_no_output_symtab_entry(); |
c06b7b0b ILT |
651 | continue; |
652 | } | |
645f8123 | 653 | |
c06b7b0b ILT |
654 | if (sym.get_st_name() >= strtab_size) |
655 | { | |
75f2446e ILT |
656 | this->error(_("local symbol %u section name out of range: %u >= %u"), |
657 | i, sym.get_st_name(), | |
658 | static_cast<unsigned int>(strtab_size)); | |
659 | lv.set_no_output_symtab_entry(); | |
660 | continue; | |
f6ce93d6 | 661 | } |
c06b7b0b ILT |
662 | |
663 | const char* name = pnames + sym.get_st_name(); | |
cfd73a4e | 664 | pool->add(name, true, NULL); |
b8e6aad9 | 665 | lv.set_output_symtab_index(index); |
c06b7b0b | 666 | ++index; |
c06b7b0b | 667 | ++count; |
75f65a3e ILT |
668 | } |
669 | ||
61ba1cf9 ILT |
670 | this->output_local_symbol_count_ = count; |
671 | ||
c06b7b0b | 672 | return index; |
75f65a3e ILT |
673 | } |
674 | ||
e727fa71 ILT |
675 | // Return the value of the local symbol symndx. |
676 | template<int size, bool big_endian> | |
677 | typename elfcpp::Elf_types<size>::Elf_Addr | |
678 | Sized_relobj<size, big_endian>::local_symbol_value(unsigned int symndx) const | |
679 | { | |
680 | gold_assert(symndx < this->local_symbol_count_); | |
681 | gold_assert(symndx < this->local_values_.size()); | |
682 | const Symbol_value<size>& lv(this->local_values_[symndx]); | |
683 | return lv.value(this, 0); | |
684 | } | |
685 | ||
b8e6aad9 | 686 | // Return the value of a local symbol defined in input section SHNDX, |
063f12a8 ILT |
687 | // with value VALUE, adding addend ADDEND. IS_SECTION_SYMBOL |
688 | // indicates whether the symbol is a section symbol. This handles | |
689 | // SHF_MERGE sections. | |
b8e6aad9 ILT |
690 | template<int size, bool big_endian> |
691 | typename elfcpp::Elf_types<size>::Elf_Addr | |
692 | Sized_relobj<size, big_endian>::local_value(unsigned int shndx, | |
693 | Address value, | |
063f12a8 | 694 | bool is_section_symbol, |
b8e6aad9 ILT |
695 | Address addend) const |
696 | { | |
697 | const std::vector<Map_to_output>& mo(this->map_to_output()); | |
698 | Output_section* os = mo[shndx].output_section; | |
699 | if (os == NULL) | |
700 | return addend; | |
701 | gold_assert(mo[shndx].offset == -1); | |
063f12a8 ILT |
702 | |
703 | // Do the mapping required by the output section. If this is not a | |
704 | // section symbol, then we want to map the symbol value, and then | |
705 | // include the addend. If this is a section symbol, then we need to | |
706 | // include the addend to figure out where in the section we are, | |
707 | // before we do the mapping. This will do the right thing provided | |
708 | // the assembler is careful to only convert a relocation in a merged | |
709 | // section to a section symbol if there is a zero addend. If the | |
710 | // assembler does not do this, then in general we can't know what to | |
711 | // do, because we can't distinguish the addend for the instruction | |
712 | // format from the addend for the section offset. | |
713 | ||
714 | if (is_section_symbol) | |
715 | return os->output_address(this, shndx, value + addend); | |
716 | else | |
717 | return addend + os->output_address(this, shndx, value); | |
b8e6aad9 ILT |
718 | } |
719 | ||
61ba1cf9 ILT |
720 | // Write out the local symbols. |
721 | ||
722 | template<int size, bool big_endian> | |
723 | void | |
f6ce93d6 | 724 | Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of, |
61ba1cf9 ILT |
725 | const Stringpool* sympool) |
726 | { | |
9e2dcb77 ILT |
727 | if (parameters->strip_all()) |
728 | return; | |
729 | ||
a3ad94ed | 730 | gold_assert(this->symtab_shndx_ != -1U); |
645f8123 | 731 | if (this->symtab_shndx_ == 0) |
61ba1cf9 ILT |
732 | { |
733 | // This object has no symbols. Weird but legal. | |
734 | return; | |
735 | } | |
736 | ||
737 | // Read the symbol table section header. | |
645f8123 ILT |
738 | const unsigned int symtab_shndx = this->symtab_shndx_; |
739 | typename This::Shdr symtabshdr(this, | |
740 | this->elf_file_.section_header(symtab_shndx)); | |
a3ad94ed | 741 | gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB); |
92e059d8 | 742 | const unsigned int loccount = this->local_symbol_count_; |
a3ad94ed | 743 | gold_assert(loccount == symtabshdr.get_sh_info()); |
61ba1cf9 ILT |
744 | |
745 | // Read the local symbols. | |
746 | const int sym_size = This::sym_size; | |
92e059d8 | 747 | off_t locsize = loccount * sym_size; |
61ba1cf9 | 748 | const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(), |
9eb9fa57 | 749 | locsize, false); |
61ba1cf9 | 750 | |
61ba1cf9 | 751 | // Read the symbol names. |
645f8123 ILT |
752 | const unsigned int strtab_shndx = symtabshdr.get_sh_link(); |
753 | off_t strtab_size; | |
754 | const unsigned char* pnamesu = this->section_contents(strtab_shndx, | |
9eb9fa57 ILT |
755 | &strtab_size, |
756 | true); | |
61ba1cf9 ILT |
757 | const char* pnames = reinterpret_cast<const char*>(pnamesu); |
758 | ||
759 | // Get a view into the output file. | |
760 | off_t output_size = this->output_local_symbol_count_ * sym_size; | |
761 | unsigned char* oview = of->get_output_view(this->local_symbol_offset_, | |
762 | output_size); | |
763 | ||
c06b7b0b ILT |
764 | const std::vector<Map_to_output>& mo(this->map_to_output()); |
765 | ||
a3ad94ed | 766 | gold_assert(this->local_values_.size() == loccount); |
61ba1cf9 | 767 | |
61ba1cf9 | 768 | unsigned char* ov = oview; |
c06b7b0b | 769 | psyms += sym_size; |
92e059d8 | 770 | for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size) |
61ba1cf9 ILT |
771 | { |
772 | elfcpp::Sym<size, big_endian> isym(psyms); | |
f6ce93d6 | 773 | |
b8e6aad9 | 774 | if (!this->local_values_[i].needs_output_symtab_entry()) |
f6ce93d6 | 775 | continue; |
61ba1cf9 ILT |
776 | |
777 | unsigned int st_shndx = isym.get_st_shndx(); | |
778 | if (st_shndx < elfcpp::SHN_LORESERVE) | |
779 | { | |
a3ad94ed | 780 | gold_assert(st_shndx < mo.size()); |
61ba1cf9 ILT |
781 | if (mo[st_shndx].output_section == NULL) |
782 | continue; | |
ead1e424 | 783 | st_shndx = mo[st_shndx].output_section->out_shndx(); |
61ba1cf9 ILT |
784 | } |
785 | ||
f6ce93d6 ILT |
786 | elfcpp::Sym_write<size, big_endian> osym(ov); |
787 | ||
a3ad94ed | 788 | gold_assert(isym.get_st_name() < strtab_size); |
c06b7b0b ILT |
789 | const char* name = pnames + isym.get_st_name(); |
790 | osym.put_st_name(sympool->get_offset(name)); | |
b8e6aad9 | 791 | osym.put_st_value(this->local_values_[i].value(this, 0)); |
61ba1cf9 ILT |
792 | osym.put_st_size(isym.get_st_size()); |
793 | osym.put_st_info(isym.get_st_info()); | |
794 | osym.put_st_other(isym.get_st_other()); | |
795 | osym.put_st_shndx(st_shndx); | |
796 | ||
797 | ov += sym_size; | |
798 | } | |
799 | ||
a3ad94ed | 800 | gold_assert(ov - oview == output_size); |
61ba1cf9 ILT |
801 | |
802 | of->write_output_view(this->local_symbol_offset_, output_size, oview); | |
803 | } | |
804 | ||
f7e2ee48 ILT |
805 | // Set *INFO to symbolic information about the offset OFFSET in the |
806 | // section SHNDX. Return true if we found something, false if we | |
807 | // found nothing. | |
808 | ||
809 | template<int size, bool big_endian> | |
810 | bool | |
811 | Sized_relobj<size, big_endian>::get_symbol_location_info( | |
812 | unsigned int shndx, | |
813 | off_t offset, | |
814 | Symbol_location_info* info) | |
815 | { | |
816 | if (this->symtab_shndx_ == 0) | |
817 | return false; | |
818 | ||
819 | off_t symbols_size; | |
820 | const unsigned char* symbols = this->section_contents(this->symtab_shndx_, | |
821 | &symbols_size, | |
822 | false); | |
823 | ||
824 | unsigned int symbol_names_shndx = this->section_link(this->symtab_shndx_); | |
825 | off_t names_size; | |
826 | const unsigned char* symbol_names_u = | |
827 | this->section_contents(symbol_names_shndx, &names_size, false); | |
828 | const char* symbol_names = reinterpret_cast<const char*>(symbol_names_u); | |
829 | ||
830 | const int sym_size = This::sym_size; | |
831 | const size_t count = symbols_size / sym_size; | |
832 | ||
833 | const unsigned char* p = symbols; | |
834 | for (size_t i = 0; i < count; ++i, p += sym_size) | |
835 | { | |
836 | elfcpp::Sym<size, big_endian> sym(p); | |
837 | ||
838 | if (sym.get_st_type() == elfcpp::STT_FILE) | |
839 | { | |
840 | if (sym.get_st_name() >= names_size) | |
841 | info->source_file = "(invalid)"; | |
842 | else | |
843 | info->source_file = symbol_names + sym.get_st_name(); | |
844 | } | |
845 | else if (sym.get_st_shndx() == shndx | |
846 | && static_cast<off_t>(sym.get_st_value()) <= offset | |
847 | && (static_cast<off_t>(sym.get_st_value() + sym.get_st_size()) | |
5c2c6c95 | 848 | > offset)) |
f7e2ee48 ILT |
849 | { |
850 | if (sym.get_st_name() > names_size) | |
851 | info->enclosing_symbol_name = "(invalid)"; | |
852 | else | |
853 | info->enclosing_symbol_name = symbol_names + sym.get_st_name(); | |
854 | return true; | |
855 | } | |
856 | } | |
857 | ||
858 | return false; | |
859 | } | |
860 | ||
54dc6425 ILT |
861 | // Input_objects methods. |
862 | ||
008db82e ILT |
863 | // Add a regular relocatable object to the list. Return false if this |
864 | // object should be ignored. | |
f6ce93d6 | 865 | |
008db82e | 866 | bool |
54dc6425 ILT |
867 | Input_objects::add_object(Object* obj) |
868 | { | |
008db82e | 869 | if (!obj->is_dynamic()) |
f6ce93d6 | 870 | this->relobj_list_.push_back(static_cast<Relobj*>(obj)); |
008db82e ILT |
871 | else |
872 | { | |
873 | // See if this is a duplicate SONAME. | |
874 | Dynobj* dynobj = static_cast<Dynobj*>(obj); | |
875 | ||
876 | std::pair<Unordered_set<std::string>::iterator, bool> ins = | |
877 | this->sonames_.insert(dynobj->soname()); | |
878 | if (!ins.second) | |
879 | { | |
880 | // We have already seen a dynamic object with this soname. | |
881 | return false; | |
882 | } | |
883 | ||
884 | this->dynobj_list_.push_back(dynobj); | |
885 | } | |
75f65a3e ILT |
886 | |
887 | Target* target = obj->target(); | |
888 | if (this->target_ == NULL) | |
889 | this->target_ = target; | |
890 | else if (this->target_ != target) | |
891 | { | |
75f2446e ILT |
892 | gold_error(_("%s: incompatible target"), obj->name().c_str()); |
893 | return false; | |
75f65a3e | 894 | } |
008db82e | 895 | |
9025d29d ILT |
896 | set_parameters_size_and_endianness(target->get_size(), |
897 | target->is_big_endian()); | |
898 | ||
008db82e | 899 | return true; |
54dc6425 ILT |
900 | } |
901 | ||
92e059d8 ILT |
902 | // Relocate_info methods. |
903 | ||
904 | // Return a string describing the location of a relocation. This is | |
905 | // only used in error messages. | |
906 | ||
907 | template<int size, bool big_endian> | |
908 | std::string | |
f7e2ee48 | 909 | Relocate_info<size, big_endian>::location(size_t, off_t offset) const |
92e059d8 | 910 | { |
5c2c6c95 ILT |
911 | // See if we can get line-number information from debugging sections. |
912 | std::string filename; | |
913 | std::string file_and_lineno; // Better than filename-only, if available. | |
914 | for (unsigned int shndx = 0; shndx < this->object->shnum(); ++shndx) | |
915 | if (this->object->section_name(shndx) == ".debug_line") | |
916 | { | |
917 | off_t debuglines_size; | |
918 | const unsigned char* debuglines = this->object->section_contents( | |
919 | shndx, &debuglines_size, false); | |
920 | if (debuglines) | |
921 | { | |
922 | Dwarf_line_info line_info(debuglines, debuglines_size); | |
923 | line_info.read_line_mappings<size, big_endian>(); | |
924 | file_and_lineno = line_info.addr2line(this->data_shndx, offset); | |
925 | } | |
926 | break; | |
927 | } | |
928 | ||
92e059d8 | 929 | std::string ret(this->object->name()); |
f7e2ee48 ILT |
930 | ret += ':'; |
931 | Symbol_location_info info; | |
932 | if (this->object->get_symbol_location_info(this->data_shndx, offset, &info)) | |
933 | { | |
934 | ret += " in function "; | |
5c2c6c95 ILT |
935 | // We could demangle this name before printing, but we don't |
936 | // bother because gcc runs linker output through a demangle | |
937 | // filter itself. The only advantage to demangling here is if | |
938 | // someone might call ld directly, rather than via gcc. If we | |
939 | // did want to demangle, cplus_demangle() is in libiberty. | |
f7e2ee48 ILT |
940 | ret += info.enclosing_symbol_name; |
941 | ret += ":"; | |
5c2c6c95 ILT |
942 | filename = info.source_file; |
943 | } | |
944 | ||
945 | if (!file_and_lineno.empty()) | |
946 | ret += file_and_lineno; | |
947 | else | |
948 | { | |
949 | if (!filename.empty()) | |
950 | ret += filename; | |
951 | ret += "("; | |
952 | ret += this->object->section_name(this->data_shndx); | |
953 | char buf[100]; | |
954 | // Offsets into sections have to be positive. | |
955 | snprintf(buf, sizeof(buf), "+0x%lx", static_cast<long>(offset)); | |
956 | ret += buf; | |
957 | ret += ")"; | |
f7e2ee48 | 958 | } |
92e059d8 ILT |
959 | return ret; |
960 | } | |
961 | ||
bae7f79e ILT |
962 | } // End namespace gold. |
963 | ||
964 | namespace | |
965 | { | |
966 | ||
967 | using namespace gold; | |
968 | ||
969 | // Read an ELF file with the header and return the appropriate | |
970 | // instance of Object. | |
971 | ||
972 | template<int size, bool big_endian> | |
973 | Object* | |
974 | make_elf_sized_object(const std::string& name, Input_file* input_file, | |
975 | off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr) | |
976 | { | |
977 | int et = ehdr.get_e_type(); | |
bae7f79e ILT |
978 | if (et == elfcpp::ET_REL) |
979 | { | |
f6ce93d6 ILT |
980 | Sized_relobj<size, big_endian>* obj = |
981 | new Sized_relobj<size, big_endian>(name, input_file, offset, ehdr); | |
bae7f79e ILT |
982 | obj->setup(ehdr); |
983 | return obj; | |
984 | } | |
dbe717ef ILT |
985 | else if (et == elfcpp::ET_DYN) |
986 | { | |
987 | Sized_dynobj<size, big_endian>* obj = | |
988 | new Sized_dynobj<size, big_endian>(name, input_file, offset, ehdr); | |
989 | obj->setup(ehdr); | |
990 | return obj; | |
991 | } | |
bae7f79e ILT |
992 | else |
993 | { | |
75f2446e ILT |
994 | gold_error(_("%s: unsupported ELF file type %d"), |
995 | name.c_str(), et); | |
996 | return NULL; | |
bae7f79e ILT |
997 | } |
998 | } | |
999 | ||
1000 | } // End anonymous namespace. | |
1001 | ||
1002 | namespace gold | |
1003 | { | |
1004 | ||
1005 | // Read an ELF file and return the appropriate instance of Object. | |
1006 | ||
1007 | Object* | |
1008 | make_elf_object(const std::string& name, Input_file* input_file, off_t offset, | |
1009 | const unsigned char* p, off_t bytes) | |
1010 | { | |
1011 | if (bytes < elfcpp::EI_NIDENT) | |
1012 | { | |
75f2446e ILT |
1013 | gold_error(_("%s: ELF file too short"), name.c_str()); |
1014 | return NULL; | |
bae7f79e ILT |
1015 | } |
1016 | ||
1017 | int v = p[elfcpp::EI_VERSION]; | |
1018 | if (v != elfcpp::EV_CURRENT) | |
1019 | { | |
1020 | if (v == elfcpp::EV_NONE) | |
75f2446e | 1021 | gold_error(_("%s: invalid ELF version 0"), name.c_str()); |
bae7f79e | 1022 | else |
75f2446e ILT |
1023 | gold_error(_("%s: unsupported ELF version %d"), name.c_str(), v); |
1024 | return NULL; | |
bae7f79e ILT |
1025 | } |
1026 | ||
1027 | int c = p[elfcpp::EI_CLASS]; | |
1028 | if (c == elfcpp::ELFCLASSNONE) | |
1029 | { | |
75f2446e ILT |
1030 | gold_error(_("%s: invalid ELF class 0"), name.c_str()); |
1031 | return NULL; | |
bae7f79e ILT |
1032 | } |
1033 | else if (c != elfcpp::ELFCLASS32 | |
1034 | && c != elfcpp::ELFCLASS64) | |
1035 | { | |
75f2446e ILT |
1036 | gold_error(_("%s: unsupported ELF class %d"), name.c_str(), c); |
1037 | return NULL; | |
bae7f79e ILT |
1038 | } |
1039 | ||
1040 | int d = p[elfcpp::EI_DATA]; | |
1041 | if (d == elfcpp::ELFDATANONE) | |
1042 | { | |
75f2446e ILT |
1043 | gold_error(_("%s: invalid ELF data encoding"), name.c_str()); |
1044 | return NULL; | |
bae7f79e ILT |
1045 | } |
1046 | else if (d != elfcpp::ELFDATA2LSB | |
1047 | && d != elfcpp::ELFDATA2MSB) | |
1048 | { | |
75f2446e ILT |
1049 | gold_error(_("%s: unsupported ELF data encoding %d"), name.c_str(), d); |
1050 | return NULL; | |
bae7f79e ILT |
1051 | } |
1052 | ||
1053 | bool big_endian = d == elfcpp::ELFDATA2MSB; | |
1054 | ||
1055 | if (c == elfcpp::ELFCLASS32) | |
1056 | { | |
1057 | if (bytes < elfcpp::Elf_sizes<32>::ehdr_size) | |
1058 | { | |
75f2446e ILT |
1059 | gold_error(_("%s: ELF file too short"), name.c_str()); |
1060 | return NULL; | |
bae7f79e ILT |
1061 | } |
1062 | if (big_endian) | |
1063 | { | |
193a53d9 | 1064 | #ifdef HAVE_TARGET_32_BIG |
bae7f79e ILT |
1065 | elfcpp::Ehdr<32, true> ehdr(p); |
1066 | return make_elf_sized_object<32, true>(name, input_file, | |
1067 | offset, ehdr); | |
193a53d9 | 1068 | #else |
75f2446e ILT |
1069 | gold_error(_("%s: not configured to support " |
1070 | "32-bit big-endian object"), | |
1071 | name.c_str()); | |
1072 | return NULL; | |
193a53d9 | 1073 | #endif |
bae7f79e ILT |
1074 | } |
1075 | else | |
1076 | { | |
193a53d9 | 1077 | #ifdef HAVE_TARGET_32_LITTLE |
bae7f79e ILT |
1078 | elfcpp::Ehdr<32, false> ehdr(p); |
1079 | return make_elf_sized_object<32, false>(name, input_file, | |
1080 | offset, ehdr); | |
193a53d9 | 1081 | #else |
75f2446e ILT |
1082 | gold_error(_("%s: not configured to support " |
1083 | "32-bit little-endian object"), | |
1084 | name.c_str()); | |
1085 | return NULL; | |
193a53d9 | 1086 | #endif |
bae7f79e ILT |
1087 | } |
1088 | } | |
1089 | else | |
1090 | { | |
1091 | if (bytes < elfcpp::Elf_sizes<32>::ehdr_size) | |
1092 | { | |
75f2446e ILT |
1093 | gold_error(_("%s: ELF file too short"), name.c_str()); |
1094 | return NULL; | |
bae7f79e ILT |
1095 | } |
1096 | if (big_endian) | |
1097 | { | |
193a53d9 | 1098 | #ifdef HAVE_TARGET_64_BIG |
bae7f79e ILT |
1099 | elfcpp::Ehdr<64, true> ehdr(p); |
1100 | return make_elf_sized_object<64, true>(name, input_file, | |
1101 | offset, ehdr); | |
193a53d9 | 1102 | #else |
75f2446e ILT |
1103 | gold_error(_("%s: not configured to support " |
1104 | "64-bit big-endian object"), | |
1105 | name.c_str()); | |
1106 | return NULL; | |
193a53d9 | 1107 | #endif |
bae7f79e ILT |
1108 | } |
1109 | else | |
1110 | { | |
193a53d9 | 1111 | #ifdef HAVE_TARGET_64_LITTLE |
bae7f79e ILT |
1112 | elfcpp::Ehdr<64, false> ehdr(p); |
1113 | return make_elf_sized_object<64, false>(name, input_file, | |
1114 | offset, ehdr); | |
193a53d9 | 1115 | #else |
75f2446e ILT |
1116 | gold_error(_("%s: not configured to support " |
1117 | "64-bit little-endian object"), | |
1118 | name.c_str()); | |
1119 | return NULL; | |
193a53d9 | 1120 | #endif |
bae7f79e ILT |
1121 | } |
1122 | } | |
1123 | } | |
1124 | ||
1125 | // Instantiate the templates we need. We could use the configure | |
1126 | // script to restrict this to only the ones for implemented targets. | |
1127 | ||
193a53d9 | 1128 | #ifdef HAVE_TARGET_32_LITTLE |
bae7f79e | 1129 | template |
f6ce93d6 | 1130 | class Sized_relobj<32, false>; |
193a53d9 | 1131 | #endif |
bae7f79e | 1132 | |
193a53d9 | 1133 | #ifdef HAVE_TARGET_32_BIG |
bae7f79e | 1134 | template |
f6ce93d6 | 1135 | class Sized_relobj<32, true>; |
193a53d9 | 1136 | #endif |
bae7f79e | 1137 | |
193a53d9 | 1138 | #ifdef HAVE_TARGET_64_LITTLE |
bae7f79e | 1139 | template |
f6ce93d6 | 1140 | class Sized_relobj<64, false>; |
193a53d9 | 1141 | #endif |
bae7f79e | 1142 | |
193a53d9 | 1143 | #ifdef HAVE_TARGET_64_BIG |
bae7f79e | 1144 | template |
f6ce93d6 | 1145 | class Sized_relobj<64, true>; |
193a53d9 | 1146 | #endif |
bae7f79e | 1147 | |
193a53d9 | 1148 | #ifdef HAVE_TARGET_32_LITTLE |
92e059d8 ILT |
1149 | template |
1150 | struct Relocate_info<32, false>; | |
193a53d9 | 1151 | #endif |
92e059d8 | 1152 | |
193a53d9 | 1153 | #ifdef HAVE_TARGET_32_BIG |
92e059d8 ILT |
1154 | template |
1155 | struct Relocate_info<32, true>; | |
193a53d9 | 1156 | #endif |
92e059d8 | 1157 | |
193a53d9 | 1158 | #ifdef HAVE_TARGET_64_LITTLE |
92e059d8 ILT |
1159 | template |
1160 | struct Relocate_info<64, false>; | |
193a53d9 | 1161 | #endif |
92e059d8 | 1162 | |
193a53d9 | 1163 | #ifdef HAVE_TARGET_64_BIG |
92e059d8 ILT |
1164 | template |
1165 | struct Relocate_info<64, true>; | |
193a53d9 | 1166 | #endif |
92e059d8 | 1167 | |
bae7f79e | 1168 | } // End namespace gold. |