daily update
[deliverable/binutils-gdb.git] / gold / output.h
CommitLineData
a2fb1b05
ILT
1// output.h -- manage the output file for gold -*- C++ -*-
2
3#ifndef GOLD_OUTPUT_H
4#define GOLD_OUTPUT_H
5
6#include <list>
ead1e424 7#include <vector>
a2fb1b05
ILT
8
9#include "elfcpp.h"
54dc6425 10#include "layout.h"
c06b7b0b 11#include "reloc-types.h"
a2fb1b05
ILT
12
13namespace gold
14{
15
61ba1cf9 16class General_options;
a2fb1b05 17class Object;
a3ad94ed 18class Symbol;
a2fb1b05 19class Output_file;
c06b7b0b 20class Output_section;
a3ad94ed 21class Target;
54dc6425
ILT
22template<int size, bool big_endian>
23class Sized_target;
c06b7b0b
ILT
24template<int size, bool big_endian>
25class Sized_relobj;
54dc6425
ILT
26
27// An abtract class for data which has to go into the output file.
a2fb1b05
ILT
28
29class Output_data
30{
31 public:
75f65a3e 32 explicit Output_data(off_t data_size = 0)
61ba1cf9 33 : address_(0), data_size_(data_size), offset_(-1)
a2fb1b05
ILT
34 { }
35
36 virtual
37 ~Output_data();
38
ead1e424
ILT
39 // Return the address. This is only valid after Layout::finalize is
40 // finished.
75f65a3e
ILT
41 uint64_t
42 address() const
43 { return this->address_; }
44
ead1e424
ILT
45 // Return the size of the data. This must be valid after
46 // Layout::finalize calls set_address, but need not be valid before
47 // then.
a2fb1b05 48 off_t
75f65a3e
ILT
49 data_size() const
50 { return this->data_size_; }
51
ead1e424
ILT
52 // Return the file offset. This is only valid after
53 // Layout::finalize is finished.
75f65a3e
ILT
54 off_t
55 offset() const
56 { return this->offset_; }
57
58 // Return the required alignment.
59 uint64_t
60 addralign() const
61 { return this->do_addralign(); }
62
63 // Return whether this is an Output_section.
64 bool
65 is_section() const
66 { return this->do_is_section(); }
67
68 // Return whether this is an Output_section of the specified type.
69 bool
70 is_section_type(elfcpp::Elf_Word stt) const
71 { return this->do_is_section_type(stt); }
72
73 // Return whether this is an Output_section with the specified flag
74 // set.
75 bool
76 is_section_flag_set(elfcpp::Elf_Xword shf) const
77 { return this->do_is_section_flag_set(shf); }
78
ead1e424
ILT
79 // Return the output section index, if there is an output section.
80 unsigned int
81 out_shndx() const
82 { return this->do_out_shndx(); }
83
84 // Set the output section index, if this is an output section.
85 void
86 set_out_shndx(unsigned int shndx)
87 { this->do_set_out_shndx(shndx); }
88
89 // Set the address and file offset of this data. This is called
90 // during Layout::finalize.
75f65a3e
ILT
91 void
92 set_address(uint64_t addr, off_t off);
93
ead1e424
ILT
94 // Write the data to the output file. This is called after
95 // Layout::finalize is complete.
75f65a3e
ILT
96 void
97 write(Output_file* file)
98 { this->do_write(file); }
a2fb1b05 99
a3ad94ed
ILT
100 // This is called by Layout::finalize to note that all sizes must
101 // now be fixed.
102 static void
103 layout_complete()
104 { Output_data::sizes_are_fixed = true; }
105
75f65a3e
ILT
106 protected:
107 // Functions that child classes may or in some cases must implement.
108
109 // Write the data to the output file.
a2fb1b05 110 virtual void
75f65a3e
ILT
111 do_write(Output_file*) = 0;
112
113 // Return the required alignment.
114 virtual uint64_t
115 do_addralign() const = 0;
116
117 // Return whether this is an Output_section.
118 virtual bool
119 do_is_section() const
120 { return false; }
a2fb1b05 121
54dc6425 122 // Return whether this is an Output_section of the specified type.
75f65a3e 123 // This only needs to be implement by Output_section.
54dc6425 124 virtual bool
75f65a3e 125 do_is_section_type(elfcpp::Elf_Word) const
54dc6425
ILT
126 { return false; }
127
75f65a3e
ILT
128 // Return whether this is an Output_section with the specific flag
129 // set. This only needs to be implemented by Output_section.
54dc6425 130 virtual bool
75f65a3e 131 do_is_section_flag_set(elfcpp::Elf_Xword) const
54dc6425
ILT
132 { return false; }
133
ead1e424
ILT
134 // Return the output section index, if there is an output section.
135 virtual unsigned int
136 do_out_shndx() const
a3ad94ed 137 { gold_unreachable(); }
ead1e424
ILT
138
139 // Set the output section index, if this is an output section.
140 virtual void
141 do_set_out_shndx(unsigned int)
a3ad94ed 142 { gold_unreachable(); }
ead1e424 143
75f65a3e 144 // Set the address and file offset of the data. This only needs to
a3ad94ed
ILT
145 // be implemented if the child needs to know. The child class can
146 // set its size in this call.
75f65a3e
ILT
147 virtual void
148 do_set_address(uint64_t, off_t)
149 { }
150
151 // Functions that child classes may call.
152
a2fb1b05
ILT
153 // Set the size of the data.
154 void
75f65a3e 155 set_data_size(off_t data_size)
a3ad94ed
ILT
156 {
157 gold_assert(!Output_data::sizes_are_fixed);
158 this->data_size_ = data_size;
159 }
75f65a3e
ILT
160
161 // Return default alignment for a size--32 or 64.
162 static uint64_t
163 default_alignment(int size);
a2fb1b05
ILT
164
165 private:
166 Output_data(const Output_data&);
167 Output_data& operator=(const Output_data&);
168
a3ad94ed
ILT
169 // This is used for verification, to make sure that we don't try to
170 // change any sizes after we set the section addresses.
171 static bool sizes_are_fixed;
172
75f65a3e
ILT
173 // Memory address in file (not always meaningful).
174 uint64_t address_;
a2fb1b05 175 // Size of data in file.
75f65a3e
ILT
176 off_t data_size_;
177 // Offset within file.
178 off_t offset_;
a2fb1b05
ILT
179};
180
54dc6425
ILT
181// Output the section headers.
182
183class Output_section_headers : public Output_data
184{
185 public:
75f65a3e 186 Output_section_headers(int size,
61ba1cf9 187 bool big_endian,
75f65a3e 188 const Layout::Segment_list&,
61ba1cf9
ILT
189 const Layout::Section_list&,
190 const Stringpool*);
54dc6425
ILT
191
192 // Write the data to the file.
193 void
75f65a3e
ILT
194 do_write(Output_file*);
195
196 // Return the required alignment.
197 uint64_t
198 do_addralign() const
199 { return Output_data::default_alignment(this->size_); }
54dc6425
ILT
200
201 private:
61ba1cf9
ILT
202 // Write the data to the file with the right size and endianness.
203 template<int size, bool big_endian>
204 void
205 do_sized_write(Output_file*);
206
75f65a3e 207 int size_;
61ba1cf9 208 bool big_endian_;
54dc6425 209 const Layout::Segment_list& segment_list_;
a3ad94ed 210 const Layout::Section_list& unattached_section_list_;
61ba1cf9 211 const Stringpool* secnamepool_;
54dc6425
ILT
212};
213
214// Output the segment headers.
215
216class Output_segment_headers : public Output_data
217{
218 public:
61ba1cf9
ILT
219 Output_segment_headers(int size, bool big_endian,
220 const Layout::Segment_list& segment_list);
54dc6425
ILT
221
222 // Write the data to the file.
223 void
75f65a3e
ILT
224 do_write(Output_file*);
225
226 // Return the required alignment.
227 uint64_t
228 do_addralign() const
229 { return Output_data::default_alignment(this->size_); }
54dc6425
ILT
230
231 private:
61ba1cf9
ILT
232 // Write the data to the file with the right size and endianness.
233 template<int size, bool big_endian>
234 void
235 do_sized_write(Output_file*);
236
75f65a3e 237 int size_;
61ba1cf9 238 bool big_endian_;
54dc6425
ILT
239 const Layout::Segment_list& segment_list_;
240};
241
242// Output the ELF file header.
243
244class Output_file_header : public Output_data
245{
246 public:
75f65a3e 247 Output_file_header(int size,
61ba1cf9 248 bool big_endian,
75f65a3e 249 const General_options&,
54dc6425
ILT
250 const Target*,
251 const Symbol_table*,
75f65a3e
ILT
252 const Output_segment_headers*);
253
254 // Add information about the section headers. We lay out the ELF
255 // file header before we create the section headers.
256 void set_section_info(const Output_section_headers*,
257 const Output_section* shstrtab);
54dc6425
ILT
258
259 // Write the data to the file.
260 void
75f65a3e
ILT
261 do_write(Output_file*);
262
263 // Return the required alignment.
264 uint64_t
265 do_addralign() const
266 { return Output_data::default_alignment(this->size_); }
267
268 // Set the address and offset--we only implement this for error
269 // checking.
270 void
271 do_set_address(uint64_t, off_t off) const
a3ad94ed 272 { gold_assert(off == 0); }
54dc6425
ILT
273
274 private:
61ba1cf9
ILT
275 // Write the data to the file with the right size and endianness.
276 template<int size, bool big_endian>
277 void
278 do_sized_write(Output_file*);
279
75f65a3e 280 int size_;
61ba1cf9 281 bool big_endian_;
54dc6425
ILT
282 const General_options& options_;
283 const Target* target_;
284 const Symbol_table* symtab_;
61ba1cf9 285 const Output_segment_headers* segment_header_;
54dc6425
ILT
286 const Output_section_headers* section_header_;
287 const Output_section* shstrtab_;
288};
289
ead1e424
ILT
290// Output sections are mainly comprised of input sections. However,
291// there are cases where we have data to write out which is not in an
292// input section. Output_section_data is used in such cases. This is
293// an abstract base class.
294
295class Output_section_data : public Output_data
296{
297 public:
298 Output_section_data(off_t data_size, uint64_t addralign)
299 : Output_data(data_size), output_section_(NULL), addralign_(addralign)
300 { }
301
302 Output_section_data(uint64_t addralign)
303 : Output_data(0), output_section_(NULL), addralign_(addralign)
304 { }
305
306 // Record the output section.
307 void
308 set_output_section(Output_section* os)
309 {
a3ad94ed 310 gold_assert(this->output_section_ == NULL);
ead1e424
ILT
311 this->output_section_ = os;
312 }
313
314 protected:
315 // The child class must implement do_write.
316
317 // Return the required alignment.
318 uint64_t
319 do_addralign() const
320 { return this->addralign_; }
321
322 // Return the section index of the output section.
323 unsigned int
324 do_out_shndx() const;
325
326 private:
327 // The output section for this section.
328 const Output_section* output_section_;
329 // The required alignment.
330 uint64_t addralign_;
331};
332
dbe717ef
ILT
333// A simple case of Output_data in which we have constant data to
334// output.
ead1e424 335
dbe717ef 336class Output_data_const : public Output_section_data
ead1e424
ILT
337{
338 public:
dbe717ef
ILT
339 Output_data_const(const std::string& data, uint64_t addralign)
340 : Output_section_data(data.size(), addralign), data_(data)
341 { }
342
343 Output_data_const(const char* p, off_t len, uint64_t addralign)
344 : Output_section_data(len, addralign), data_(p, len)
345 { }
346
347 Output_data_const(const unsigned char* p, off_t len, uint64_t addralign)
348 : Output_section_data(len, addralign),
349 data_(reinterpret_cast<const char*>(p), len)
350 { }
351
a3ad94ed
ILT
352 // Add more data.
353 void
354 add_data(const std::string& add)
355 {
356 this->data_.append(add);
357 this->set_data_size(this->data_.size());
358 }
359
360 // Write the data to the output file.
dbe717ef 361 void
a3ad94ed 362 do_write(Output_file*);
dbe717ef
ILT
363
364 private:
365 std::string data_;
366};
367
a3ad94ed
ILT
368// Another version of Output_data with constant data, in which the
369// buffer is allocated by the caller.
dbe717ef 370
a3ad94ed 371class Output_data_const_buffer : public Output_section_data
dbe717ef
ILT
372{
373 public:
a3ad94ed
ILT
374 Output_data_const_buffer(const unsigned char* p, off_t len,
375 uint64_t addralign)
376 : Output_section_data(len, addralign), p_(p)
377 { }
378
379 // Write the data the output file.
380 void
381 do_write(Output_file*);
382
383 private:
384 const unsigned char* p_;
385};
386
387// A place holder for data written out via some other mechanism.
388
389class Output_data_space : public Output_section_data
390{
391 public:
392 Output_data_space(off_t data_size, uint64_t addralign)
393 : Output_section_data(data_size, addralign)
394 { }
395
396 explicit Output_data_space(uint64_t addralign)
ead1e424
ILT
397 : Output_section_data(addralign)
398 { }
399
400 // Set the size.
401 void
a3ad94ed
ILT
402 set_space_size(off_t space_size)
403 { this->set_data_size(space_size); }
ead1e424 404
a3ad94ed 405 // Write out the data--this must be handled elsewhere.
ead1e424
ILT
406 void
407 do_write(Output_file*)
408 { }
409};
410
a3ad94ed
ILT
411// A string table which goes into an output section.
412
413class Output_data_strtab : public Output_section_data
414{
415 public:
416 Output_data_strtab(Stringpool* strtab)
417 : Output_section_data(1), strtab_(strtab)
418 { }
419
420 // This is called to set the address and file offset. Here we make
421 // sure that the Stringpool is finalized.
422 void
423 do_set_address(uint64_t, off_t);
424
425 // Write out the data.
426 void
427 do_write(Output_file*);
428
429 private:
430 Stringpool* strtab_;
431};
432
c06b7b0b
ILT
433// This POD class is used to represent a single reloc in the output
434// file. This could be a private class within Output_data_reloc, but
435// the templatization is complex enough that I broke it out into a
436// separate class. The class is templatized on either elfcpp::SHT_REL
437// or elfcpp::SHT_RELA, and also on whether this is a dynamic
438// relocation or an ordinary relocation.
439
440// A relocation can be against a global symbol, a local symbol, an
441// output section, or the undefined symbol at index 0. We represent
442// the latter by using a NULL global symbol.
443
444template<int sh_type, bool dynamic, int size, bool big_endian>
445class Output_reloc;
446
447template<bool dynamic, int size, bool big_endian>
448class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
449{
450 public:
451 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
452
453 // An uninitialized entry. We need this because we want to put
454 // instances of this class into an STL container.
455 Output_reloc()
456 : local_sym_index_(INVALID_CODE)
457 { }
458
459 // A reloc against a global symbol.
a3ad94ed
ILT
460 Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
461 Address address)
462 : local_sym_index_(GSYM_CODE), type_(type), od_(od), address_(address)
c06b7b0b
ILT
463 { this->u_.gsym = gsym; }
464
465 // A reloc against a local symbol.
466 Output_reloc(Sized_relobj<size, big_endian>* object,
467 unsigned int local_sym_index,
a3ad94ed
ILT
468 unsigned int type,
469 Output_data* od,
470 Address address)
471 : local_sym_index_(local_sym_index), type_(type), od_(od),
472 address_(address)
c06b7b0b 473 {
a3ad94ed
ILT
474 gold_assert(local_sym_index != GSYM_CODE
475 && local_sym_index != INVALID_CODE);
c06b7b0b
ILT
476 this->u_.object = object;
477 }
478
479 // A reloc against the STT_SECTION symbol of an output section.
a3ad94ed
ILT
480 Output_reloc(Output_section* os, unsigned int type, Output_data* od,
481 Address address)
482 : local_sym_index_(SECTION_CODE), type_(type), od_(od), address_(address)
c06b7b0b
ILT
483 { this->u_.os = os; }
484
485 // Write the reloc entry to an output view.
486 void
487 write(unsigned char* pov) const;
488
489 // Write the offset and info fields to Write_rel.
490 template<typename Write_rel>
491 void write_rel(Write_rel*) const;
492
493 private:
494 // Return the symbol index. We can't do a double template
495 // specialization, so we do a secondary template here.
496 unsigned int
497 get_symbol_index() const;
498
499 // Codes for local_sym_index_.
500 enum
501 {
502 // Global symbol.
503 GSYM_CODE = -1U,
504 // Output section.
505 SECTION_CODE = -2U,
506 // Invalid uninitialized entry.
507 INVALID_CODE = -3U
508 };
509
510 union
511 {
512 // For a local symbol, the object. We will never generate a
513 // relocation against a local symbol in a dynamic object; that
514 // doesn't make sense. And our callers will always be
515 // templatized, so we use Sized_relobj here.
516 Sized_relobj<size, big_endian>* object;
517 // For a global symbol, the symbol. If this is NULL, it indicates
518 // a relocation against the undefined 0 symbol.
519 Symbol* gsym;
520 // For a relocation against an output section, the output section.
521 Output_section* os;
522 } u_;
523 // For a local symbol, the local symbol index. This is GSYM_CODE
524 // for a global symbol, or INVALID_CODE for an uninitialized value.
525 unsigned int local_sym_index_;
a3ad94ed 526 // The reloc type--a processor specific code.
c06b7b0b 527 unsigned int type_;
a3ad94ed
ILT
528 // If this is not NULL, then the relocation is against the contents
529 // of this output data.
530 Output_data* od_;
531 // The reloc address--if od_ is not NULL, this is the offset from
532 // the start of od_.
c06b7b0b
ILT
533 Address address_;
534};
535
536// The SHT_RELA version of Output_reloc<>. This is just derived from
537// the SHT_REL version of Output_reloc, but it adds an addend.
538
539template<bool dynamic, int size, bool big_endian>
540class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
541{
542 public:
543 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
544 typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
545
546 // An uninitialized entry.
547 Output_reloc()
548 : rel_()
549 { }
550
551 // A reloc against a global symbol.
a3ad94ed
ILT
552 Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
553 Address address, Addend addend)
554 : rel_(gsym, type, od, address), addend_(addend)
c06b7b0b
ILT
555 { }
556
557 // A reloc against a local symbol.
558 Output_reloc(Sized_relobj<size, big_endian>* object,
559 unsigned int local_sym_index,
a3ad94ed
ILT
560 unsigned int type, Output_data* od, Address address,
561 Addend addend)
562 : rel_(object, local_sym_index, type, od, address), addend_(addend)
c06b7b0b
ILT
563 { }
564
565 // A reloc against the STT_SECTION symbol of an output section.
a3ad94ed
ILT
566 Output_reloc(Output_section* os, unsigned int type, Output_data* od,
567 Address address, Addend addend)
568 : rel_(os, type, od, address), addend_(addend)
c06b7b0b
ILT
569 { }
570
571 // Write the reloc entry to an output view.
572 void
573 write(unsigned char* pov) const;
574
575 private:
576 // The basic reloc.
577 Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_;
578 // The addend.
579 Addend addend_;
580};
581
582// Output_data_reloc is used to manage a section containing relocs.
583// SH_TYPE is either elfcpp::SHT_REL or elfcpp::SHT_RELA. DYNAMIC
584// indicates whether this is a dynamic relocation or a normal
585// relocation. Output_data_reloc_base is a base class.
586// Output_data_reloc is the real class, which we specialize based on
587// the reloc type.
588
589template<int sh_type, bool dynamic, int size, bool big_endian>
590class Output_data_reloc_base : public Output_section_data
591{
592 public:
593 typedef Output_reloc<sh_type, dynamic, size, big_endian> Output_reloc_type;
594 typedef typename Output_reloc_type::Address Address;
595 static const int reloc_size =
596 Reloc_types<sh_type, size, big_endian>::reloc_size;
597
598 // Construct the section.
599 Output_data_reloc_base()
600 : Output_section_data(Output_data::default_alignment(size))
601 { }
602
603 // Write out the data.
604 void
605 do_write(Output_file*);
606
607 protected:
608 // Add a relocation entry.
609 void
610 add(const Output_reloc_type& reloc)
611 {
612 this->relocs_.push_back(reloc);
613 this->set_data_size(this->relocs_.size() * reloc_size);
614 }
615
616 private:
617 typedef std::vector<Output_reloc_type> Relocs;
618
619 Relocs relocs_;
620};
621
622// The class which callers actually create.
623
624template<int sh_type, bool dynamic, int size, bool big_endian>
625class Output_data_reloc;
626
627// The SHT_REL version of Output_data_reloc.
628
629template<bool dynamic, int size, bool big_endian>
630class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
631 : public Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>
632{
633 private:
634 typedef Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size,
635 big_endian> Base;
636
637 public:
638 typedef typename Base::Output_reloc_type Output_reloc_type;
639 typedef typename Output_reloc_type::Address Address;
640
641 Output_data_reloc()
642 : Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>()
643 { }
644
645 // Add a reloc against a global symbol.
646 void
a3ad94ed
ILT
647 add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address)
648 { this->add(Output_reloc_type(gsym, type, od, address)); }
c06b7b0b
ILT
649
650 // Add a reloc against a local symbol.
651 void
652 add_local(Sized_relobj<size, big_endian>* object,
a3ad94ed
ILT
653 unsigned int local_sym_index, unsigned int type,
654 Output_data* od, Address address)
655 { this->add(Output_reloc_type(object, local_sym_index, type, od, address)); }
c06b7b0b
ILT
656
657 // A reloc against the STT_SECTION symbol of an output section.
658 void
a3ad94ed
ILT
659 add_output_section(Output_section* os, unsigned int type,
660 Output_data* od, Address address)
661 { this->add(Output_reloc_type(os, type, od, address)); }
c06b7b0b
ILT
662};
663
664// The SHT_RELA version of Output_data_reloc.
665
666template<bool dynamic, int size, bool big_endian>
667class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
668 : public Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>
669{
670 private:
671 typedef Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size,
672 big_endian> Base;
673
674 public:
675 typedef typename Base::Output_reloc_type Output_reloc_type;
676 typedef typename Output_reloc_type::Address Address;
677 typedef typename Output_reloc_type::Addend Addend;
678
679 Output_data_reloc()
680 : Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>()
681 { }
682
683 // Add a reloc against a global symbol.
684 void
a3ad94ed
ILT
685 add_global(Symbol* gsym, unsigned int type, Output_data* od,
686 Address address, Addend addend)
687 { this->add(Output_reloc_type(gsym, type, od, address, addend)); }
c06b7b0b
ILT
688
689 // Add a reloc against a local symbol.
690 void
691 add_local(Sized_relobj<size, big_endian>* object,
692 unsigned int local_sym_index, unsigned int type,
a3ad94ed 693 Output_data* od, Address address, Addend addend)
c06b7b0b 694 {
a3ad94ed 695 this->add(Output_reloc_type(object, local_sym_index, type, od, address,
c06b7b0b
ILT
696 addend));
697 }
698
699 // A reloc against the STT_SECTION symbol of an output section.
700 void
a3ad94ed
ILT
701 add_output_section(Output_section* os, unsigned int type, Output_data* od,
702 Address address, Addend addend)
703 { this->add(Output_reloc_type(os, type, od, address, addend)); }
c06b7b0b
ILT
704};
705
dbe717ef
ILT
706// Output_data_got is used to manage a GOT. Each entry in the GOT is
707// for one symbol--either a global symbol or a local symbol in an
ead1e424 708// object. The target specific code adds entries to the GOT as
dbe717ef 709// needed.
ead1e424
ILT
710
711template<int size, bool big_endian>
dbe717ef 712class Output_data_got : public Output_section_data
ead1e424
ILT
713{
714 public:
715 typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
716
a3ad94ed 717 Output_data_got(const General_options* options)
ead1e424 718 : Output_section_data(Output_data::default_alignment(size)),
a3ad94ed 719 options_(options), entries_()
ead1e424
ILT
720 { }
721
dbe717ef
ILT
722 // Add an entry for a global symbol to the GOT. Return true if this
723 // is a new GOT entry, false if the symbol was already in the GOT.
724 bool
725 add_global(Symbol* gsym);
ead1e424
ILT
726
727 // Add an entry for a local symbol to the GOT. This returns the
728 // offset of the new entry from the start of the GOT.
729 unsigned int
730 add_local(Object* object, unsigned int sym_index)
731 {
732 this->entries_.push_back(Got_entry(object, sym_index));
733 this->set_got_size();
734 return this->last_got_offset();
735 }
736
737 // Add a constant to the GOT. This returns the offset of the new
738 // entry from the start of the GOT.
739 unsigned int
740 add_constant(Valtype constant)
741 {
742 this->entries_.push_back(Got_entry(constant));
743 this->set_got_size();
744 return this->last_got_offset();
745 }
746
747 // Write out the GOT table.
748 void
749 do_write(Output_file*);
750
751 private:
752 // This POD class holds a single GOT entry.
753 class Got_entry
754 {
755 public:
756 // Create a zero entry.
757 Got_entry()
758 : local_sym_index_(CONSTANT_CODE)
759 { this->u_.constant = 0; }
760
761 // Create a global symbol entry.
a3ad94ed 762 explicit Got_entry(Symbol* gsym)
ead1e424
ILT
763 : local_sym_index_(GSYM_CODE)
764 { this->u_.gsym = gsym; }
765
766 // Create a local symbol entry.
767 Got_entry(Object* object, unsigned int local_sym_index)
768 : local_sym_index_(local_sym_index)
769 {
a3ad94ed
ILT
770 gold_assert(local_sym_index != GSYM_CODE
771 && local_sym_index != CONSTANT_CODE);
ead1e424
ILT
772 this->u_.object = object;
773 }
774
775 // Create a constant entry. The constant is a host value--it will
776 // be swapped, if necessary, when it is written out.
a3ad94ed 777 explicit Got_entry(Valtype constant)
ead1e424
ILT
778 : local_sym_index_(CONSTANT_CODE)
779 { this->u_.constant = constant; }
780
781 // Write the GOT entry to an output view.
782 void
a3ad94ed 783 write(const General_options*, unsigned char* pov) const;
ead1e424
ILT
784
785 private:
786 enum
787 {
788 GSYM_CODE = -1U,
789 CONSTANT_CODE = -2U
790 };
791
792 union
793 {
794 // For a local symbol, the object.
795 Object* object;
796 // For a global symbol, the symbol.
797 Symbol* gsym;
798 // For a constant, the constant.
799 Valtype constant;
800 } u_;
c06b7b0b
ILT
801 // For a local symbol, the local symbol index. This is GSYM_CODE
802 // for a global symbol, or CONSTANT_CODE for a constant.
ead1e424
ILT
803 unsigned int local_sym_index_;
804 };
805
806 typedef std::vector<Got_entry> Got_entries;
807
808 // Return the offset into the GOT of GOT entry I.
809 unsigned int
810 got_offset(unsigned int i) const
811 { return i * (size / 8); }
812
813 // Return the offset into the GOT of the last entry added.
814 unsigned int
815 last_got_offset() const
816 { return this->got_offset(this->entries_.size() - 1); }
817
818 // Set the size of the section.
819 void
820 set_got_size()
821 { this->set_data_size(this->got_offset(this->entries_.size())); }
822
a3ad94ed
ILT
823 // Options.
824 const General_options* options_;
ead1e424
ILT
825 // The list of GOT entries.
826 Got_entries entries_;
827};
828
a3ad94ed
ILT
829// Output_data_dynamic is used to hold the data in SHT_DYNAMIC
830// section.
831
832class Output_data_dynamic : public Output_section_data
833{
834 public:
835 Output_data_dynamic(const Target* target, Stringpool* pool)
836 : Output_section_data(Output_data::default_alignment(target->get_size())),
837 target_(target), entries_(), pool_(pool)
838 { }
839
840 // Add a new dynamic entry with a fixed numeric value.
841 void
842 add_constant(elfcpp::DT tag, unsigned int val)
843 { this->add_entry(Dynamic_entry(tag, val)); }
844
845 // Add a new dynamic entry with the address of a section.
846 void
847 add_section_address(elfcpp::DT tag, Output_section* os)
848 { this->add_entry(Dynamic_entry(tag, os, false)); }
849
850 // Add a new dynamic entry with the size of a section.
851 void
852 add_section_size(elfcpp::DT tag, Output_section* os)
853 { this->add_entry(Dynamic_entry(tag, os, true)); }
854
855 // Add a new dynamic entry with the address of a symbol.
856 void
857 add_symbol(elfcpp::DT tag, Symbol* sym)
858 { this->add_entry(Dynamic_entry(tag, sym)); }
859
860 // Add a new dynamic entry with a string.
861 void
862 add_string(elfcpp::DT tag, const char* str)
863 { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, NULL))); }
864
865 // Set the final data size.
866 void
867 do_set_address(uint64_t, off_t);
868
869 // Write out the dynamic entries.
870 void
871 do_write(Output_file*);
872
873 private:
874 // This POD class holds a single dynamic entry.
875 class Dynamic_entry
876 {
877 public:
878 // Create an entry with a fixed numeric value.
879 Dynamic_entry(elfcpp::DT tag, unsigned int val)
880 : tag_(tag), classification_(DYNAMIC_NUMBER)
881 { this->u_.val = val; }
882
883 // Create an entry with the size or address of a section.
884 Dynamic_entry(elfcpp::DT tag, Output_section* os, bool section_size)
885 : tag_(tag),
886 classification_(section_size
887 ? DYNAMIC_SECTION_SIZE
888 : DYNAMIC_SECTION_ADDRESS)
889 { this->u_.os = os; }
890
891 // Create an entry with the address of a symbol.
892 Dynamic_entry(elfcpp::DT tag, Symbol* sym)
893 : tag_(tag), classification_(DYNAMIC_SYMBOL)
894 { this->u_.sym = sym; }
895
896 // Create an entry with a string.
897 Dynamic_entry(elfcpp::DT tag, const char* str)
898 : tag_(tag), classification_(DYNAMIC_STRING)
899 { this->u_.str = str; }
900
901 // Write the dynamic entry to an output view.
902 template<int size, bool big_endian>
903 void
904 write(unsigned char* pov, const Stringpool*) const;
905
906 private:
907 enum Classification
908 {
909 // Number.
910 DYNAMIC_NUMBER,
911 // Section address.
912 DYNAMIC_SECTION_ADDRESS,
913 // Section size.
914 DYNAMIC_SECTION_SIZE,
915 // Symbol adress.
916 DYNAMIC_SYMBOL,
917 // String.
918 DYNAMIC_STRING
919 };
920
921 union
922 {
923 // For DYNAMIC_NUMBER.
924 unsigned int val;
925 // For DYNAMIC_SECTION_ADDRESS and DYNAMIC_SECTION_SIZE.
926 Output_section* os;
927 // For DYNAMIC_SYMBOL.
928 Symbol* sym;
929 // For DYNAMIC_STRING.
930 const char* str;
931 } u_;
932 // The dynamic tag.
933 elfcpp::DT tag_;
934 // The type of entry.
935 Classification classification_;
936 };
937
938 // Add an entry to the list.
939 void
940 add_entry(const Dynamic_entry& entry)
941 { this->entries_.push_back(entry); }
942
943 // Sized version of write function.
944 template<int size, bool big_endian>
945 void
946 sized_write(Output_file* of);
947
948 // The type of the list of entries.
949 typedef std::vector<Dynamic_entry> Dynamic_entries;
950
951 // The target.
952 const Target* target_;
953 // The entries.
954 Dynamic_entries entries_;
955 // The pool used for strings.
956 Stringpool* pool_;
957};
958
a2fb1b05
ILT
959// An output section. We don't expect to have too many output
960// sections, so we don't bother to do a template on the size.
961
54dc6425 962class Output_section : public Output_data
a2fb1b05
ILT
963{
964 public:
965 // Create an output section, giving the name, type, and flags.
61ba1cf9 966 Output_section(const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword,
ead1e424 967 bool may_add_data);
54dc6425 968 virtual ~Output_section();
a2fb1b05 969
ead1e424
ILT
970 // Add a new input section SHNDX, named NAME, with header SHDR, from
971 // object OBJECT. Return the offset within the output section.
a2fb1b05
ILT
972 template<int size, bool big_endian>
973 off_t
f6ce93d6 974 add_input_section(Relobj* object, unsigned int shndx, const char *name,
a2fb1b05
ILT
975 const elfcpp::Shdr<size, big_endian>& shdr);
976
ead1e424 977 // Add generated data ODATA to this output section.
c06b7b0b 978 void
ead1e424
ILT
979 add_output_section_data(Output_section_data* posd);
980
a2fb1b05
ILT
981 // Return the section name.
982 const char*
983 name() const
984 { return this->name_; }
985
986 // Return the section type.
987 elfcpp::Elf_Word
988 type() const
989 { return this->type_; }
990
991 // Return the section flags.
992 elfcpp::Elf_Xword
993 flags() const
994 { return this->flags_; }
995
ead1e424 996 // Return the section index in the output file.
61ba1cf9 997 unsigned int
ead1e424
ILT
998 do_out_shndx() const
999 { return this->out_shndx_; }
1000
1001 // Set the output section index.
1002 void
1003 do_set_out_shndx(unsigned int shndx)
1004 { this->out_shndx_ = shndx; }
61ba1cf9 1005
a3ad94ed
ILT
1006 // Return the entsize field.
1007 uint64_t
1008 entsize() const
1009 { return this->entsize_; }
1010
61ba1cf9
ILT
1011 // Set the entsize field.
1012 void
1013 set_entsize(uint64_t v)
1014 { this->entsize_ = v; }
1015
1016 // Set the link field.
1017 void
1018 set_link(unsigned int v)
1019 { this->link_ = v; }
1020
1021 // Set the info field.
1022 void
1023 set_info(unsigned int v)
1024 { this->info_ = v; }
1025
1026 // Set the addralign field.
1027 void
1028 set_addralign(uint64_t v)
1029 { this->addralign_ = v; }
1030
c06b7b0b
ILT
1031 // Indicate that we need a symtab index.
1032 void
1033 set_needs_symtab_index()
1034 { this->needs_symtab_index_ = true; }
1035
1036 // Return whether we need a symtab index.
1037 bool
1038 needs_symtab_index() const
1039 { return this->needs_symtab_index_; }
1040
1041 // Get the symtab index.
1042 unsigned int
1043 symtab_index() const
1044 {
a3ad94ed 1045 gold_assert(this->symtab_index_ != 0);
c06b7b0b
ILT
1046 return this->symtab_index_;
1047 }
1048
1049 // Set the symtab index.
1050 void
1051 set_symtab_index(unsigned int index)
1052 {
a3ad94ed 1053 gold_assert(index != 0);
c06b7b0b
ILT
1054 this->symtab_index_ = index;
1055 }
1056
1057 // Indicate that we need a dynsym index.
1058 void
1059 set_needs_dynsym_index()
1060 { this->needs_dynsym_index_ = true; }
1061
1062 // Return whether we need a dynsym index.
1063 bool
1064 needs_dynsym_index() const
1065 { return this->needs_dynsym_index_; }
1066
1067 // Get the dynsym index.
1068 unsigned int
1069 dynsym_index() const
1070 {
a3ad94ed 1071 gold_assert(this->dynsym_index_ != 0);
c06b7b0b
ILT
1072 return this->dynsym_index_;
1073 }
1074
1075 // Set the dynsym index.
1076 void
1077 set_dynsym_index(unsigned int index)
1078 {
a3ad94ed 1079 gold_assert(index != 0);
c06b7b0b
ILT
1080 this->dynsym_index_ = index;
1081 }
1082
ead1e424
ILT
1083 // Set the address of the Output_section. For a typical
1084 // Output_section, there is nothing to do, but if there are any
1085 // Output_section_data objects we need to set the final addresses
1086 // here.
1087 void
1088 do_set_address(uint64_t, off_t);
1089
54dc6425 1090 // Write the data to the file. For a typical Output_section, this
ead1e424
ILT
1091 // does nothing: the data is written out by calling Object::Relocate
1092 // on each input object. But if there are any Output_section_data
1093 // objects we do need to write them out here.
a3ad94ed 1094 void
ead1e424 1095 do_write(Output_file*);
54dc6425 1096
75f65a3e
ILT
1097 // Return the address alignment--function required by parent class.
1098 uint64_t
1099 do_addralign() const
1100 { return this->addralign_; }
1101
1102 // Return whether this is an Output_section.
1103 bool
1104 do_is_section() const
1105 { return true; }
1106
54dc6425
ILT
1107 // Return whether this is a section of the specified type.
1108 bool
75f65a3e 1109 do_is_section_type(elfcpp::Elf_Word type) const
54dc6425
ILT
1110 { return this->type_ == type; }
1111
1112 // Return whether the specified section flag is set.
1113 bool
75f65a3e 1114 do_is_section_flag_set(elfcpp::Elf_Xword flag) const
54dc6425
ILT
1115 { return (this->flags_ & flag) != 0; }
1116
61ba1cf9
ILT
1117 // Write the section header into *OPHDR.
1118 template<int size, bool big_endian>
1119 void
1120 write_header(const Stringpool*, elfcpp::Shdr_write<size, big_endian>*) const;
1121
a2fb1b05 1122 private:
ead1e424
ILT
1123 // In some cases we need to keep a list of the input sections
1124 // associated with this output section. We only need the list if we
1125 // might have to change the offsets of the input section within the
1126 // output section after we add the input section. The ordinary
1127 // input sections will be written out when we process the object
1128 // file, and as such we don't need to track them here. We do need
1129 // to track Output_section_data objects here. We store instances of
1130 // this structure in a std::vector, so it must be a POD. There can
1131 // be many instances of this structure, so we use a union to save
1132 // some space.
1133 class Input_section
1134 {
1135 public:
1136 Input_section()
1137 : shndx_(0), p2align_(0), data_size_(0)
1138 { this->u_.object = NULL; }
1139
f6ce93d6 1140 Input_section(Relobj* object, unsigned int shndx, off_t data_size,
ead1e424
ILT
1141 uint64_t addralign)
1142 : shndx_(shndx),
1143 p2align_(ffsll(static_cast<long long>(addralign))),
1144 data_size_(data_size)
1145 {
a3ad94ed 1146 gold_assert(shndx != -1U);
ead1e424
ILT
1147 this->u_.object = object;
1148 }
1149
1150 Input_section(Output_section_data* posd)
1151 : shndx_(-1U),
1152 p2align_(ffsll(static_cast<long long>(posd->addralign()))),
1153 data_size_(0)
1154 { this->u_.posd = posd; }
1155
1156 // The required alignment.
1157 uint64_t
1158 addralign() const
a3ad94ed
ILT
1159 {
1160 return (this->p2align_ == 0
1161 ? 0
1162 : static_cast<uint64_t>(1) << (this->p2align_ - 1));
1163 }
ead1e424
ILT
1164
1165 // Return the required size.
1166 off_t
1167 data_size() const;
1168
1169 // Set the address and file offset. This is called during
1170 // Layout::finalize. SECOFF is the file offset of the enclosing
1171 // section.
1172 void
1173 set_address(uint64_t addr, off_t off, off_t secoff);
1174
1175 // Write out the data. This does nothing for an input section.
1176 void
1177 write(Output_file*);
1178
1179 private:
1180 // Whether this is an input section.
1181 bool
1182 is_input_section() const
1183 { return this->shndx_ != -1U; }
1184
1185 // For an ordinary input section, this is the section index in
1186 // the input file. For an Output_section_data, this is -1U.
1187 unsigned int shndx_;
1188 // The required alignment, stored as a power of 2.
1189 unsigned int p2align_;
1190 // For an ordinary input section, the section size.
1191 off_t data_size_;
1192 union
1193 {
1194 // If shndx_ != -1U, this points to the object which holds the
1195 // input section.
f6ce93d6 1196 Relobj* object;
ead1e424
ILT
1197 // If shndx_ == -1U, this is the data to write out.
1198 Output_section_data* posd;
1199 } u_;
1200 };
1201
1202 typedef std::vector<Input_section> Input_section_list;
1203
a2fb1b05
ILT
1204 // Most of these fields are only valid after layout.
1205
1206 // The name of the section. This will point into a Stringpool.
1207 const char* name_;
75f65a3e 1208 // The section address is in the parent class.
a2fb1b05
ILT
1209 // The section alignment.
1210 uint64_t addralign_;
1211 // The section entry size.
1212 uint64_t entsize_;
75f65a3e 1213 // The file offset is in the parent class.
a2fb1b05
ILT
1214 // The section link field.
1215 unsigned int link_;
1216 // The section info field.
1217 unsigned int info_;
1218 // The section type.
1219 elfcpp::Elf_Word type_;
1220 // The section flags.
1221 elfcpp::Elf_Xword flags_;
61ba1cf9 1222 // The section index.
ead1e424 1223 unsigned int out_shndx_;
c06b7b0b
ILT
1224 // If there is a STT_SECTION for this output section in the normal
1225 // symbol table, this is the symbol index. This starts out as zero.
1226 // It is initialized in Layout::finalize() to be the index, or -1U
1227 // if there isn't one.
1228 unsigned int symtab_index_;
1229 // If there is a STT_SECTION for this output section in the dynamic
1230 // symbol table, this is the symbol index. This starts out as zero.
1231 // It is initialized in Layout::finalize() to be the index, or -1U
1232 // if there isn't one.
1233 unsigned int dynsym_index_;
ead1e424
ILT
1234 // The input sections. This will be empty in cases where we don't
1235 // need to keep track of them.
1236 Input_section_list input_sections_;
1237 // The offset of the first entry in input_sections_.
1238 off_t first_input_offset_;
1239 // Whether we permit adding data.
c06b7b0b
ILT
1240 bool may_add_data_ : 1;
1241 // Whether this output section needs a STT_SECTION symbol in the
1242 // normal symbol table. This will be true if there is a relocation
1243 // which needs it.
1244 bool needs_symtab_index_ : 1;
1245 // Whether this output section needs a STT_SECTION symbol in the
1246 // dynamic symbol table. This will be true if there is a dynamic
1247 // relocation which needs it.
1248 bool needs_dynsym_index_ : 1;
a2fb1b05
ILT
1249};
1250
1251// An output segment. PT_LOAD segments are built from collections of
1252// output sections. Other segments typically point within PT_LOAD
1253// segments, and are built directly as needed.
1254
1255class Output_segment
1256{
1257 public:
1258 // Create an output segment, specifying the type and flags.
1259 Output_segment(elfcpp::Elf_Word, elfcpp::Elf_Word);
1260
1261 // Return the virtual address.
1262 uint64_t
1263 vaddr() const
1264 { return this->vaddr_; }
1265
1266 // Return the physical address.
1267 uint64_t
1268 paddr() const
1269 { return this->paddr_; }
1270
1271 // Return the segment type.
1272 elfcpp::Elf_Word
1273 type() const
1274 { return this->type_; }
1275
1276 // Return the segment flags.
1277 elfcpp::Elf_Word
1278 flags() const
1279 { return this->flags_; }
1280
92e059d8
ILT
1281 // Return the memory size.
1282 uint64_t
1283 memsz() const
1284 { return this->memsz_; }
1285
ead1e424
ILT
1286 // Return the file size.
1287 off_t
1288 filesz() const
1289 { return this->filesz_; }
1290
75f65a3e
ILT
1291 // Return the maximum alignment of the Output_data.
1292 uint64_t
ead1e424 1293 addralign();
75f65a3e 1294
a2fb1b05
ILT
1295 // Add an Output_section to this segment.
1296 void
dbe717ef
ILT
1297 add_output_section(Output_section* os, elfcpp::Elf_Word seg_flags)
1298 { this->add_output_section(os, seg_flags, false); }
1299
1300 // Add an Output_section to the start of this segment.
1301 void
1302 add_initial_output_section(Output_section* os, elfcpp::Elf_Word seg_flags)
1303 { this->add_output_section(os, seg_flags, true); }
75f65a3e
ILT
1304
1305 // Add an Output_data (which is not an Output_section) to the start
1306 // of this segment.
1307 void
1308 add_initial_output_data(Output_data*);
1309
1310 // Set the address of the segment to ADDR and the offset to *POFF
1311 // (aligned if necessary), and set the addresses and offsets of all
ead1e424
ILT
1312 // contained output sections accordingly. Set the section indexes
1313 // of all contained output sections starting with *PSHNDX. Return
1314 // the address of the immediately following segment. Update *POFF
1315 // and *PSHNDX. This should only be called for a PT_LOAD segment.
75f65a3e 1316 uint64_t
ead1e424 1317 set_section_addresses(uint64_t addr, off_t* poff, unsigned int* pshndx);
75f65a3e
ILT
1318
1319 // Set the offset of this segment based on the section. This should
1320 // only be called for a non-PT_LOAD segment.
1321 void
1322 set_offset();
1323
1324 // Return the number of output sections.
1325 unsigned int
1326 output_section_count() const;
a2fb1b05 1327
61ba1cf9
ILT
1328 // Write the segment header into *OPHDR.
1329 template<int size, bool big_endian>
1330 void
ead1e424 1331 write_header(elfcpp::Phdr_write<size, big_endian>*);
61ba1cf9
ILT
1332
1333 // Write the section headers of associated sections into V.
1334 template<int size, bool big_endian>
1335 unsigned char*
5482377d 1336 write_section_headers(const Stringpool*,
ead1e424
ILT
1337 unsigned char* v,
1338 unsigned int* pshndx ACCEPT_SIZE_ENDIAN) const;
61ba1cf9 1339
a2fb1b05
ILT
1340 private:
1341 Output_segment(const Output_segment&);
1342 Output_segment& operator=(const Output_segment&);
1343
54dc6425 1344 typedef std::list<Output_data*> Output_data_list;
a2fb1b05 1345
dbe717ef
ILT
1346 // Add an Output_section to this segment, specifying front or back.
1347 void
1348 add_output_section(Output_section*, elfcpp::Elf_Word seg_flags,
1349 bool front);
1350
ead1e424
ILT
1351 // Find the maximum alignment in an Output_data_list.
1352 static uint64_t
1353 maximum_alignment(const Output_data_list*);
1354
75f65a3e
ILT
1355 // Set the section addresses in an Output_data_list.
1356 uint64_t
ead1e424
ILT
1357 set_section_list_addresses(Output_data_list*, uint64_t addr, off_t* poff,
1358 unsigned int* pshndx);
75f65a3e
ILT
1359
1360 // Return the number of Output_sections in an Output_data_list.
1361 unsigned int
1362 output_section_count_list(const Output_data_list*) const;
1363
61ba1cf9
ILT
1364 // Write the section headers in the list into V.
1365 template<int size, bool big_endian>
1366 unsigned char*
1367 write_section_headers_list(const Stringpool*, const Output_data_list*,
ead1e424
ILT
1368 unsigned char* v,
1369 unsigned int* pshdx ACCEPT_SIZE_ENDIAN) const;
61ba1cf9 1370
75f65a3e 1371 // The list of output data with contents attached to this segment.
54dc6425 1372 Output_data_list output_data_;
75f65a3e
ILT
1373 // The list of output data without contents attached to this segment.
1374 Output_data_list output_bss_;
a2fb1b05
ILT
1375 // The segment virtual address.
1376 uint64_t vaddr_;
1377 // The segment physical address.
1378 uint64_t paddr_;
1379 // The size of the segment in memory.
1380 uint64_t memsz_;
1381 // The segment alignment.
1382 uint64_t align_;
1383 // The offset of the segment data within the file.
1384 off_t offset_;
1385 // The size of the segment data in the file.
1386 off_t filesz_;
1387 // The segment type;
1388 elfcpp::Elf_Word type_;
1389 // The segment flags.
1390 elfcpp::Elf_Word flags_;
ead1e424
ILT
1391 // Whether we have set align_.
1392 bool is_align_known_;
a2fb1b05
ILT
1393};
1394
61ba1cf9 1395// This class represents the output file.
a2fb1b05
ILT
1396
1397class Output_file
1398{
1399 public:
61ba1cf9
ILT
1400 Output_file(const General_options& options);
1401
1402 // Open the output file. FILE_SIZE is the final size of the file.
1403 void
1404 open(off_t file_size);
1405
1406 // Close the output file and make sure there are no error.
1407 void
1408 close();
1409
1410 // We currently always use mmap which makes the view handling quite
1411 // simple. In the future we may support other approaches.
a2fb1b05
ILT
1412
1413 // Write data to the output file.
1414 void
61ba1cf9
ILT
1415 write(off_t offset, const void* data, off_t len)
1416 { memcpy(this->base_ + offset, data, len); }
1417
1418 // Get a buffer to use to write to the file, given the offset into
1419 // the file and the size.
1420 unsigned char*
1421 get_output_view(off_t start, off_t size)
1422 {
a3ad94ed 1423 gold_assert(start >= 0 && size >= 0 && start + size <= this->file_size_);
61ba1cf9
ILT
1424 return this->base_ + start;
1425 }
1426
1427 // VIEW must have been returned by get_output_view. Write the
1428 // buffer to the file, passing in the offset and the size.
1429 void
1430 write_output_view(off_t, off_t, unsigned char*)
1431 { }
1432
1433 private:
1434 // General options.
1435 const General_options& options_;
1436 // File name.
1437 const char* name_;
1438 // File descriptor.
1439 int o_;
1440 // File size.
1441 off_t file_size_;
1442 // Base of file mapped into memory.
1443 unsigned char* base_;
a2fb1b05
ILT
1444};
1445
1446} // End namespace gold.
1447
1448#endif // !defined(GOLD_OUTPUT_H)
This page took 0.088576 seconds and 4 git commands to generate.