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