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