Snapshot. Now able to produce a minimal executable which actually
[deliverable/binutils-gdb.git] / gold / output.cc
CommitLineData
a2fb1b05
ILT
1// output.cc -- manage the output file for gold
2
3#include "gold.h"
4
5#include <cstdlib>
61ba1cf9
ILT
6#include <cerrno>
7#include <fcntl.h>
8#include <unistd.h>
9#include <sys/mman.h>
75f65a3e 10#include <algorithm>
a2fb1b05
ILT
11
12#include "object.h"
13#include "output.h"
14
15namespace gold
16{
17
18// Output_data methods.
19
20Output_data::~Output_data()
21{
22}
23
75f65a3e
ILT
24// Set the address and offset.
25
26void
27Output_data::set_address(uint64_t addr, off_t off)
28{
29 this->address_ = addr;
30 this->offset_ = off;
31
32 // Let the child class know.
33 this->do_set_address(addr, off);
34}
35
36// Return the default alignment for a size--32 or 64.
37
38uint64_t
39Output_data::default_alignment(int size)
40{
41 if (size == 32)
42 return 4;
43 else if (size == 64)
44 return 8;
45 else
46 abort();
47}
48
a2fb1b05
ILT
49// Output_data_const methods.
50
51void
75f65a3e
ILT
52Output_data_const::do_write(Output_file* output)
53{
54 output->write(this->offset(), data_.data(), data_.size());
55}
56
57// Output_section_header methods. This currently assumes that the
58// segment and section lists are complete at construction time.
59
60Output_section_headers::Output_section_headers(
61 int size,
61ba1cf9 62 bool big_endian,
75f65a3e 63 const Layout::Segment_list& segment_list,
61ba1cf9
ILT
64 const Layout::Section_list& section_list,
65 const Stringpool* secnamepool)
75f65a3e 66 : size_(size),
61ba1cf9 67 big_endian_(big_endian),
75f65a3e 68 segment_list_(segment_list),
61ba1cf9
ILT
69 section_list_(section_list),
70 secnamepool_(secnamepool)
75f65a3e 71{
61ba1cf9
ILT
72 // Count all the sections. Start with 1 for the null section.
73 off_t count = 1;
75f65a3e
ILT
74 for (Layout::Segment_list::const_iterator p = segment_list.begin();
75 p != segment_list.end();
76 ++p)
77 count += (*p)->output_section_count();
78 count += section_list.size();
79
80 int shdr_size;
81 if (size == 32)
82 shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
83 else if (size == 64)
84 shdr_size = elfcpp::Elf_sizes<64>::shdr_size;
85 else
86 abort();
87
88 this->set_data_size(count * shdr_size);
89}
90
61ba1cf9
ILT
91// Write out the section headers.
92
75f65a3e 93void
61ba1cf9 94Output_section_headers::do_write(Output_file* of)
a2fb1b05 95{
61ba1cf9
ILT
96 if (this->size_ == 32)
97 {
98 if (this->big_endian_)
99 this->do_sized_write<32, true>(of);
100 else
101 this->do_sized_write<32, false>(of);
102 }
103 else if (this->size_ == 64)
104 {
105 if (this->big_endian_)
106 this->do_sized_write<64, true>(of);
107 else
108 this->do_sized_write<64, false>(of);
109 }
110 else
111 abort();
112}
113
114template<int size, bool big_endian>
115void
116Output_section_headers::do_sized_write(Output_file* of)
117{
118 off_t all_shdrs_size = this->data_size();
119 unsigned char* view = of->get_output_view(this->offset(), all_shdrs_size);
120
121 const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
122 unsigned char* v = view;
123
124 {
125 typename elfcpp::Shdr_write<size, big_endian> oshdr(v);
126 oshdr.put_sh_name(0);
127 oshdr.put_sh_type(elfcpp::SHT_NULL);
128 oshdr.put_sh_flags(0);
129 oshdr.put_sh_addr(0);
130 oshdr.put_sh_offset(0);
131 oshdr.put_sh_size(0);
132 oshdr.put_sh_link(0);
133 oshdr.put_sh_info(0);
134 oshdr.put_sh_addralign(0);
135 oshdr.put_sh_entsize(0);
136 }
137
138 v += shdr_size;
139
140 for (Layout::Segment_list::const_iterator p = this->segment_list_.begin();
141 p != this->segment_list_.end();
142 ++p)
143 v = (*p)->write_section_headers<size, big_endian>(this->secnamepool_, v);
144 for (Layout::Section_list::const_iterator p = this->section_list_.begin();
145 p != this->section_list_.end();
146 ++p)
147 {
148 elfcpp::Shdr_write<size, big_endian> oshdr(v);
149 (*p)->write_header(this->secnamepool_, &oshdr);
150 v += shdr_size;
151 }
152
153 of->write_output_view(this->offset(), all_shdrs_size, view);
a2fb1b05
ILT
154}
155
54dc6425
ILT
156// Output_segment_header methods.
157
61ba1cf9
ILT
158Output_segment_headers::Output_segment_headers(
159 int size,
160 bool big_endian,
161 const Layout::Segment_list& segment_list)
162 : size_(size), big_endian_(big_endian), segment_list_(segment_list)
163{
164 int phdr_size;
165 if (size == 32)
166 phdr_size = elfcpp::Elf_sizes<32>::phdr_size;
167 else if (size == 64)
168 phdr_size = elfcpp::Elf_sizes<64>::phdr_size;
169 else
170 abort();
171
172 this->set_data_size(segment_list.size() * phdr_size);
173}
174
54dc6425 175void
61ba1cf9 176Output_segment_headers::do_write(Output_file* of)
75f65a3e 177{
61ba1cf9
ILT
178 if (this->size_ == 32)
179 {
180 if (this->big_endian_)
181 this->do_sized_write<32, true>(of);
182 else
183 this->do_sized_write<32, false>(of);
184 }
185 else if (this->size_ == 64)
186 {
187 if (this->big_endian_)
188 this->do_sized_write<64, true>(of);
189 else
190 this->do_sized_write<64, false>(of);
191 }
192 else
193 abort();
194}
195
196template<int size, bool big_endian>
197void
198Output_segment_headers::do_sized_write(Output_file* of)
199{
200 const int phdr_size = elfcpp::Elf_sizes<size>::phdr_size;
201 off_t all_phdrs_size = this->segment_list_.size() * phdr_size;
202 unsigned char* view = of->get_output_view(this->offset(),
203 all_phdrs_size);
204 unsigned char* v = view;
205 for (Layout::Segment_list::const_iterator p = this->segment_list_.begin();
206 p != this->segment_list_.end();
207 ++p)
208 {
209 elfcpp::Phdr_write<size, big_endian> ophdr(v);
210 (*p)->write_header(&ophdr);
211 v += phdr_size;
212 }
213
214 of->write_output_view(this->offset(), all_phdrs_size, view);
75f65a3e
ILT
215}
216
217// Output_file_header methods.
218
219Output_file_header::Output_file_header(int size,
61ba1cf9 220 bool big_endian,
75f65a3e
ILT
221 const General_options& options,
222 const Target* target,
223 const Symbol_table* symtab,
224 const Output_segment_headers* osh)
225 : size_(size),
61ba1cf9 226 big_endian_(big_endian),
75f65a3e
ILT
227 options_(options),
228 target_(target),
229 symtab_(symtab),
61ba1cf9 230 segment_header_(osh),
75f65a3e
ILT
231 section_header_(NULL),
232 shstrtab_(NULL)
233{
61ba1cf9
ILT
234 int ehdr_size;
235 if (size == 32)
236 ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size;
237 else if (size == 64)
238 ehdr_size = elfcpp::Elf_sizes<64>::ehdr_size;
239 else
240 abort();
241
242 this->set_data_size(ehdr_size);
75f65a3e
ILT
243}
244
245// Set the section table information for a file header.
246
247void
248Output_file_header::set_section_info(const Output_section_headers* shdrs,
249 const Output_section* shstrtab)
250{
251 this->section_header_ = shdrs;
252 this->shstrtab_ = shstrtab;
253}
254
255// Write out the file header.
256
257void
61ba1cf9 258Output_file_header::do_write(Output_file* of)
54dc6425 259{
61ba1cf9
ILT
260 if (this->size_ == 32)
261 {
262 if (this->big_endian_)
263 this->do_sized_write<32, true>(of);
264 else
265 this->do_sized_write<32, false>(of);
266 }
267 else if (this->size_ == 64)
268 {
269 if (this->big_endian_)
270 this->do_sized_write<64, true>(of);
271 else
272 this->do_sized_write<64, false>(of);
273 }
274 else
275 abort();
276}
277
278// Write out the file header with appropriate size and endianess.
279
280template<int size, bool big_endian>
281void
282Output_file_header::do_sized_write(Output_file* of)
283{
284 assert(this->offset() == 0);
285
286 int ehdr_size = elfcpp::Elf_sizes<size>::ehdr_size;
287 unsigned char* view = of->get_output_view(0, ehdr_size);
288 elfcpp::Ehdr_write<size, big_endian> oehdr(view);
289
290 unsigned char e_ident[elfcpp::EI_NIDENT];
291 memset(e_ident, 0, elfcpp::EI_NIDENT);
292 e_ident[elfcpp::EI_MAG0] = elfcpp::ELFMAG0;
293 e_ident[elfcpp::EI_MAG1] = elfcpp::ELFMAG1;
294 e_ident[elfcpp::EI_MAG2] = elfcpp::ELFMAG2;
295 e_ident[elfcpp::EI_MAG3] = elfcpp::ELFMAG3;
296 if (size == 32)
297 e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS32;
298 else if (size == 64)
299 e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS64;
300 else
301 abort();
302 e_ident[elfcpp::EI_DATA] = (big_endian
303 ? elfcpp::ELFDATA2MSB
304 : elfcpp::ELFDATA2LSB);
305 e_ident[elfcpp::EI_VERSION] = elfcpp::EV_CURRENT;
306 // FIXME: Some targets may need to set EI_OSABI and EI_ABIVERSION.
307 oehdr.put_e_ident(e_ident);
308
309 elfcpp::ET e_type;
310 // FIXME: ET_DYN.
311 if (this->options_.is_relocatable())
312 e_type = elfcpp::ET_REL;
313 else
314 e_type = elfcpp::ET_EXEC;
315 oehdr.put_e_type(e_type);
316
317 oehdr.put_e_machine(this->target_->machine_code());
318 oehdr.put_e_version(elfcpp::EV_CURRENT);
319
320 Symbol* sym = this->symtab_->lookup("_start");
321 typename Sized_symbol<size>::Value_type v;
322 if (sym == NULL)
323 v = 0;
324 else
325 {
326 Sized_symbol<size>* ssym;
327 ssym = this->symtab_->get_sized_symbol<size>(sym);
328 v = ssym->value();
329 }
330 oehdr.put_e_entry(v);
331
332 oehdr.put_e_phoff(this->segment_header_->offset());
333 oehdr.put_e_shoff(this->section_header_->offset());
334
335 // FIXME: The target needs to set the flags.
336 oehdr.put_e_flags(0);
337
338 oehdr.put_e_ehsize(elfcpp::Elf_sizes<size>::ehdr_size);
339 oehdr.put_e_phentsize(elfcpp::Elf_sizes<size>::phdr_size);
340 oehdr.put_e_phnum(this->segment_header_->data_size()
341 / elfcpp::Elf_sizes<size>::phdr_size);
342 oehdr.put_e_shentsize(elfcpp::Elf_sizes<size>::shdr_size);
343 oehdr.put_e_shnum(this->section_header_->data_size()
344 / elfcpp::Elf_sizes<size>::shdr_size);
345 oehdr.put_e_shstrndx(this->shstrtab_->shndx());
346
347 of->write_output_view(0, ehdr_size, view);
54dc6425
ILT
348}
349
a2fb1b05
ILT
350// Output_section methods.
351
352// Construct an Output_section. NAME will point into a Stringpool.
353
354Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
61ba1cf9 355 elfcpp::Elf_Xword flags, unsigned int shndx)
a2fb1b05 356 : name_(name),
a2fb1b05
ILT
357 addralign_(0),
358 entsize_(0),
a2fb1b05
ILT
359 link_(0),
360 info_(0),
361 type_(type),
61ba1cf9
ILT
362 flags_(flags),
363 shndx_(shndx)
a2fb1b05
ILT
364{
365}
366
54dc6425
ILT
367Output_section::~Output_section()
368{
369}
370
a2fb1b05
ILT
371// Add an input section to an Output_section. We don't keep track of
372// input sections for an Output_section. Instead, each Object keeps
373// track of the Output_section for each of its input sections.
374
375template<int size, bool big_endian>
376off_t
377Output_section::add_input_section(Object* object, const char* secname,
378 const elfcpp::Shdr<size, big_endian>& shdr)
379{
380 elfcpp::Elf_Xword addralign = shdr.get_sh_addralign();
381 if ((addralign & (addralign - 1)) != 0)
382 {
383 fprintf(stderr, _("%s: %s: invalid alignment %lu for section \"%s\"\n"),
384 program_name, object->name().c_str(),
385 static_cast<unsigned long>(addralign), secname);
386 gold_exit(false);
387 }
a2fb1b05
ILT
388
389 if (addralign > this->addralign_)
390 this->addralign_ = addralign;
391
75f65a3e 392 off_t ssize = this->data_size();
54dc6425 393 ssize = (ssize + addralign - 1) &~ (addralign - 1);
a2fb1b05 394
75f65a3e
ILT
395 // SHF_TLS/SHT_NOBITS sections are handled specially: they are
396 // treated as having no size and taking up no space. We only use
397 // the real size when setting the pt_memsz field of the PT_TLS
398 // segment.
399 if ((this->flags_ & elfcpp::SHF_TLS) == 0
400 || this->type_ != elfcpp::SHT_NOBITS)
401 this->set_data_size(ssize + shdr.get_sh_size());
54dc6425 402
61ba1cf9
ILT
403 return ssize;
404}
405
406// Write the section header to *OSHDR.
407
408template<int size, bool big_endian>
409void
410Output_section::write_header(const Stringpool* secnamepool,
411 elfcpp::Shdr_write<size, big_endian>* oshdr) const
412{
413 oshdr->put_sh_name(secnamepool->get_offset(this->name_));
414 oshdr->put_sh_type(this->type_);
415 oshdr->put_sh_flags(this->flags_);
416 oshdr->put_sh_addr(this->address());
417 oshdr->put_sh_offset(this->offset());
418 oshdr->put_sh_size(this->data_size());
419 oshdr->put_sh_link(this->link_);
420 oshdr->put_sh_info(this->info_);
421 oshdr->put_sh_addralign(this->addralign_);
422 oshdr->put_sh_entsize(this->entsize_);
a2fb1b05
ILT
423}
424
75f65a3e
ILT
425// Output_section_symtab methods.
426
61ba1cf9
ILT
427Output_section_symtab::Output_section_symtab(const char* name, off_t size,
428 unsigned int shndx)
429 : Output_section(name, elfcpp::SHT_SYMTAB, 0, shndx)
75f65a3e
ILT
430{
431 this->set_data_size(size);
432}
433
434// Output_section_strtab methods.
435
436Output_section_strtab::Output_section_strtab(const char* name,
61ba1cf9
ILT
437 Stringpool* contents,
438 unsigned int shndx)
439 : Output_section(name, elfcpp::SHT_STRTAB, 0, shndx),
75f65a3e
ILT
440 contents_(contents)
441{
61ba1cf9 442 this->set_data_size(contents->get_strtab_size());
75f65a3e
ILT
443}
444
445void
61ba1cf9 446Output_section_strtab::do_write(Output_file* of)
75f65a3e 447{
61ba1cf9 448 this->contents_->write(of, this->offset());
75f65a3e
ILT
449}
450
a2fb1b05
ILT
451// Output segment methods.
452
453Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
54dc6425 454 : output_data_(),
75f65a3e 455 output_bss_(),
a2fb1b05
ILT
456 vaddr_(0),
457 paddr_(0),
458 memsz_(0),
459 align_(0),
460 offset_(0),
461 filesz_(0),
462 type_(type),
463 flags_(flags)
464{
465}
466
467// Add an Output_section to an Output_segment.
468
469void
75f65a3e
ILT
470Output_segment::add_output_section(Output_section* os,
471 elfcpp::Elf_Word seg_flags)
a2fb1b05 472{
75f65a3e
ILT
473 assert((os->flags() & elfcpp::SHF_ALLOC) != 0);
474
475 // Update the segment flags and alignment.
476 this->flags_ |= seg_flags;
477 uint64_t addralign = os->addralign();
478 if (addralign > this->align_)
479 this->align_ = addralign;
480
481 Output_segment::Output_data_list* pdl;
482 if (os->type() == elfcpp::SHT_NOBITS)
483 pdl = &this->output_bss_;
484 else
485 pdl = &this->output_data_;
54dc6425 486
a2fb1b05
ILT
487 // So that PT_NOTE segments will work correctly, we need to ensure
488 // that all SHT_NOTE sections are adjacent. This will normally
489 // happen automatically, because all the SHT_NOTE input sections
490 // will wind up in the same output section. However, it is possible
491 // for multiple SHT_NOTE input sections to have different section
492 // flags, and thus be in different output sections, but for the
493 // different section flags to map into the same segment flags and
494 // thus the same output segment.
54dc6425
ILT
495
496 // Note that while there may be many input sections in an output
497 // section, there are normally only a few output sections in an
498 // output segment. This loop is expected to be fast.
499
61ba1cf9 500 if (os->type() == elfcpp::SHT_NOTE && !pdl->empty())
a2fb1b05 501 {
75f65a3e
ILT
502 Layout::Data_list::iterator p = pdl->end();
503 do
54dc6425 504 {
75f65a3e 505 --p;
54dc6425
ILT
506 if ((*p)->is_section_type(elfcpp::SHT_NOTE))
507 {
508 ++p;
75f65a3e 509 pdl->insert(p, os);
54dc6425
ILT
510 return;
511 }
512 }
75f65a3e 513 while (p != pdl->begin());
54dc6425
ILT
514 }
515
516 // Similarly, so that PT_TLS segments will work, we need to group
75f65a3e
ILT
517 // SHF_TLS sections. An SHF_TLS/SHT_NOBITS section is a special
518 // case: we group the SHF_TLS/SHT_NOBITS sections right after the
519 // SHF_TLS/SHT_PROGBITS sections. This lets us set up PT_TLS
520 // correctly.
61ba1cf9 521 if ((os->flags() & elfcpp::SHF_TLS) != 0 && !this->output_data_.empty())
54dc6425 522 {
75f65a3e
ILT
523 pdl = &this->output_data_;
524 bool nobits = os->type() == elfcpp::SHT_NOBITS;
525 Layout::Data_list::iterator p = pdl->end();
526 do
a2fb1b05 527 {
75f65a3e
ILT
528 --p;
529 if ((*p)->is_section_flag_set(elfcpp::SHF_TLS)
530 && (nobits || !(*p)->is_section_type(elfcpp::SHT_NOBITS)))
a2fb1b05
ILT
531 {
532 ++p;
75f65a3e 533 pdl->insert(p, os);
a2fb1b05
ILT
534 return;
535 }
536 }
75f65a3e 537 while (p != pdl->begin());
a2fb1b05
ILT
538 }
539
75f65a3e
ILT
540 pdl->push_back(os);
541}
542
543// Add an Output_data (which is not an Output_section) to the start of
544// a segment.
545
546void
547Output_segment::add_initial_output_data(Output_data* od)
548{
549 uint64_t addralign = od->addralign();
550 if (addralign > this->align_)
551 this->align_ = addralign;
552
553 this->output_data_.push_front(od);
554}
555
556// Return the maximum alignment of the Output_data in Output_segment.
557// We keep this up to date as we add Output_sections and Output_data.
558
559uint64_t
560Output_segment::max_data_align() const
561{
562 return this->align_;
563}
564
565// Set the section addresses for an Output_segment. ADDR is the
566// address and *POFF is the file offset. Return the address of the
567// immediately following segment. Update *POFF.
568
569uint64_t
570Output_segment::set_section_addresses(uint64_t addr, off_t* poff)
571{
572 assert(this->type_ == elfcpp::PT_LOAD);
573
574 this->vaddr_ = addr;
575 this->paddr_ = addr;
576
577 off_t orig_off = *poff;
578 this->offset_ = orig_off;
579
580 addr = this->set_section_list_addresses(&this->output_data_, addr, poff);
581 this->filesz_ = *poff - orig_off;
582
583 off_t off = *poff;
584
61ba1cf9
ILT
585 uint64_t ret = this->set_section_list_addresses(&this->output_bss_, addr,
586 poff);
75f65a3e
ILT
587 this->memsz_ = *poff - orig_off;
588
589 // Ignore the file offset adjustments made by the BSS Output_data
590 // objects.
591 *poff = off;
61ba1cf9
ILT
592
593 return ret;
75f65a3e
ILT
594}
595
596// Set the addresses in a list of Output_data structures.
597
598uint64_t
599Output_segment::set_section_list_addresses(Output_data_list* pdl,
600 uint64_t addr, off_t* poff)
601{
602 off_t off = *poff;
603
604 for (Output_data_list::iterator p = pdl->begin();
605 p != pdl->end();
606 ++p)
607 {
608 uint64_t addralign = (*p)->addralign();
609 addr = (addr + addralign - 1) & ~ (addralign - 1);
610 off = (off + addralign - 1) & ~ (addralign - 1);
611 (*p)->set_address(addr, off);
612
613 uint64_t size = (*p)->data_size();
614 addr += size;
615 off += size;
616 }
617
618 *poff = off;
619 return addr;
620}
621
622// For a non-PT_LOAD segment, set the offset from the sections, if
623// any.
624
625void
626Output_segment::set_offset()
627{
628 assert(this->type_ != elfcpp::PT_LOAD);
629
630 if (this->output_data_.empty() && this->output_bss_.empty())
631 {
632 this->vaddr_ = 0;
633 this->paddr_ = 0;
634 this->memsz_ = 0;
635 this->align_ = 0;
636 this->offset_ = 0;
637 this->filesz_ = 0;
638 return;
639 }
640
641 const Output_data* first;
642 if (this->output_data_.empty())
643 first = this->output_bss_.front();
644 else
645 first = this->output_data_.front();
646 this->vaddr_ = first->address();
647 this->paddr_ = this->vaddr_;
648 this->offset_ = first->offset();
649
650 if (this->output_data_.empty())
651 this->filesz_ = 0;
652 else
653 {
654 const Output_data* last_data = this->output_data_.back();
655 this->filesz_ = (last_data->address()
656 + last_data->data_size()
657 - this->vaddr_);
658 }
659
660 const Output_data* last;
661 if (this->output_bss_.empty())
662 last = this->output_data_.back();
663 else
664 last = this->output_bss_.back();
665 this->memsz_ = (last->address()
666 + last->data_size()
667 - this->vaddr_);
668
669 // this->align_ was set as we added items.
670}
671
672// Return the number of Output_sections in an Output_segment.
673
674unsigned int
675Output_segment::output_section_count() const
676{
677 return (this->output_section_count_list(&this->output_data_)
678 + this->output_section_count_list(&this->output_bss_));
679}
680
681// Return the number of Output_sections in an Output_data_list.
682
683unsigned int
684Output_segment::output_section_count_list(const Output_data_list* pdl) const
685{
686 unsigned int count = 0;
687 for (Output_data_list::const_iterator p = pdl->begin();
688 p != pdl->end();
689 ++p)
690 {
691 if ((*p)->is_section())
692 ++count;
693 }
694 return count;
a2fb1b05
ILT
695}
696
61ba1cf9
ILT
697// Write the segment data into *OPHDR.
698
699template<int size, bool big_endian>
700void
701Output_segment::write_header(elfcpp::Phdr_write<size, big_endian>* ophdr) const
702{
703 ophdr->put_p_type(this->type_);
704 ophdr->put_p_offset(this->offset_);
705 ophdr->put_p_vaddr(this->vaddr_);
706 ophdr->put_p_paddr(this->paddr_);
707 ophdr->put_p_filesz(this->filesz_);
708 ophdr->put_p_memsz(this->memsz_);
709 ophdr->put_p_flags(this->flags_);
710 ophdr->put_p_align(this->align_);
711}
712
713// Write the section headers into V.
714
715template<int size, bool big_endian>
716unsigned char*
717Output_segment::write_section_headers(const Stringpool* secnamepool,
718 unsigned char* v) const
719{
720 v = this->write_section_headers_list<size, big_endian>(secnamepool,
721 &this->output_data_,
722 v);
723 v = this->write_section_headers_list<size, big_endian>(secnamepool,
724 &this->output_bss_,
725 v);
726 return v;
727}
728
729template<int size, bool big_endian>
730unsigned char*
731Output_segment::write_section_headers_list(const Stringpool* secnamepool,
732 const Output_data_list* pdl,
733 unsigned char* v) const
734{
735 const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
736 for (Output_data_list::const_iterator p = pdl->begin();
737 p != pdl->end();
738 ++p)
739 {
740 if ((*p)->is_section())
741 {
742 Output_section* ps = static_cast<const Output_section*>(*p);
743 elfcpp::Shdr_write<size, big_endian> oshdr(v);
744 ps->write_header(secnamepool, &oshdr);
745 v += shdr_size;
746 }
747 }
748 return v;
749}
750
a2fb1b05
ILT
751// Output_file methods.
752
61ba1cf9
ILT
753Output_file::Output_file(const General_options& options)
754 : options_(options),
755 name_(options.output_file_name()),
756 o_(-1),
757 file_size_(0),
758 base_(NULL)
759{
760}
761
762// Open the output file.
763
a2fb1b05 764void
61ba1cf9 765Output_file::open(off_t file_size)
a2fb1b05 766{
61ba1cf9
ILT
767 this->file_size_ = file_size;
768
769 int mode = this->options_.is_relocatable() ? 0666 : 0777;
770 int o = ::open(this->name_, O_RDWR | O_CREAT | O_TRUNC, mode);
771 if (o < 0)
772 {
773 fprintf(stderr, _("%s: %s: open: %s\n"),
774 program_name, this->name_, strerror(errno));
775 gold_exit(false);
776 }
777 this->o_ = o;
778
779 // Write out one byte to make the file the right size.
780 if (::lseek(o, file_size - 1, SEEK_SET) < 0)
781 {
782 fprintf(stderr, _("%s: %s: lseek: %s\n"),
783 program_name, this->name_, strerror(errno));
784 gold_exit(false);
785 }
786 char b = 0;
787 if (::write(o, &b, 1) != 1)
788 {
789 fprintf(stderr, _("%s: %s: write: %s\n"),
790 program_name, this->name_, strerror(errno));
791 gold_exit(false);
792 }
793
794 // Map the file into memory.
795 void* base = ::mmap(NULL, file_size, PROT_READ | PROT_WRITE,
796 MAP_SHARED, o, 0);
797 if (base == MAP_FAILED)
798 {
799 fprintf(stderr, _("%s: %s: mmap: %s\n"),
800 program_name, this->name_, strerror(errno));
801 gold_exit(false);
802 }
803 this->base_ = static_cast<unsigned char*>(base);
804}
805
806// Close the output file.
807
808void
809Output_file::close()
810{
811 if (::munmap(this->base_, this->file_size_) < 0)
812 {
813 fprintf(stderr, _("%s: %s: munmap: %s\n"),
814 program_name, this->name_, strerror(errno));
815 gold_exit(false);
816 }
817 this->base_ = NULL;
818
819 if (::close(this->o_) < 0)
820 {
821 fprintf(stderr, _("%s: %s: close: %s\n"),
822 program_name, this->name_, strerror(errno));
823 gold_exit(false);
824 }
825 this->o_ = -1;
a2fb1b05
ILT
826}
827
828// Instantiate the templates we need. We could use the configure
829// script to restrict this to only the ones for implemented targets.
830
831template
832off_t
833Output_section::add_input_section<32, false>(
834 Object* object,
835 const char* secname,
836 const elfcpp::Shdr<32, false>& shdr);
837
838template
839off_t
840Output_section::add_input_section<32, true>(
841 Object* object,
842 const char* secname,
843 const elfcpp::Shdr<32, true>& shdr);
844
845template
846off_t
847Output_section::add_input_section<64, false>(
848 Object* object,
849 const char* secname,
850 const elfcpp::Shdr<64, false>& shdr);
851
852template
853off_t
854Output_section::add_input_section<64, true>(
855 Object* object,
856 const char* secname,
857 const elfcpp::Shdr<64, true>& shdr);
858
859} // End namespace gold.
This page took 0.066371 seconds and 4 git commands to generate.