]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gold/output.cc
New drop, with first cut of section layout code.
[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>
6
7#include "object.h"
8#include "output.h"
9
10namespace gold
11{
12
13// Output_data methods.
14
15Output_data::~Output_data()
16{
17}
18
19// Output_data_const methods.
20
21void
22Output_data_const::write(Output_file* output, off_t off)
23{
24 output->write(off, data_.data(), data_.size());
25}
26
27// Output_section methods.
28
29// Construct an Output_section. NAME will point into a Stringpool.
30
31Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
32 elfcpp::Elf_Xword flags)
33 : name_(name),
34 addr_(0),
35 addralign_(0),
36 entsize_(0),
37 offset_(0),
38 size_(0),
39 link_(0),
40 info_(0),
41 type_(type),
42 flags_(flags)
43{
44}
45
46// Add an input section to an Output_section. We don't keep track of
47// input sections for an Output_section. Instead, each Object keeps
48// track of the Output_section for each of its input sections.
49
50template<int size, bool big_endian>
51off_t
52Output_section::add_input_section(Object* object, const char* secname,
53 const elfcpp::Shdr<size, big_endian>& shdr)
54{
55 elfcpp::Elf_Xword addralign = shdr.get_sh_addralign();
56 if ((addralign & (addralign - 1)) != 0)
57 {
58 fprintf(stderr, _("%s: %s: invalid alignment %lu for section \"%s\"\n"),
59 program_name, object->name().c_str(),
60 static_cast<unsigned long>(addralign), secname);
61 gold_exit(false);
62 }
63 this->size_ = (this->size_ + addralign - 1) &~ (addralign - 1);
64
65 if (addralign > this->addralign_)
66 this->addralign_ = addralign;
67
68 off_t ret = this->size_;
69 this->size_ += shdr.get_sh_size();
70
71 return ret;
72}
73
74// Output segment methods.
75
76Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
77 : output_sections_(),
78 vaddr_(0),
79 paddr_(0),
80 memsz_(0),
81 align_(0),
82 offset_(0),
83 filesz_(0),
84 type_(type),
85 flags_(flags)
86{
87}
88
89// Add an Output_section to an Output_segment.
90
91void
92Output_segment::add_output_section(Output_section* os)
93{
94 // So that PT_NOTE segments will work correctly, we need to ensure
95 // that all SHT_NOTE sections are adjacent. This will normally
96 // happen automatically, because all the SHT_NOTE input sections
97 // will wind up in the same output section. However, it is possible
98 // for multiple SHT_NOTE input sections to have different section
99 // flags, and thus be in different output sections, but for the
100 // different section flags to map into the same segment flags and
101 // thus the same output segment.
102 if (os->type() == elfcpp::SHT_NOTE)
103 {
104 for (Section_list::iterator p = this->output_sections_.begin();
105 p != this->output_sections_.end();
106 ++p)
107 {
108 if ((*p)->type() == elfcpp::SHT_NOTE)
109 {
110 ++p;
111 this->output_sections_.insert(p, os);
112 return;
113 }
114 }
115 }
116
117 this->output_sections_.push_back(os);
118}
119
120// Output_file methods.
121
122void
123Output_file::write(off_t, const void*, off_t)
124{
125 abort();
126}
127
128// Instantiate the templates we need. We could use the configure
129// script to restrict this to only the ones for implemented targets.
130
131template
132off_t
133Output_section::add_input_section<32, false>(
134 Object* object,
135 const char* secname,
136 const elfcpp::Shdr<32, false>& shdr);
137
138template
139off_t
140Output_section::add_input_section<32, true>(
141 Object* object,
142 const char* secname,
143 const elfcpp::Shdr<32, true>& shdr);
144
145template
146off_t
147Output_section::add_input_section<64, false>(
148 Object* object,
149 const char* secname,
150 const elfcpp::Shdr<64, false>& shdr);
151
152template
153off_t
154Output_section::add_input_section<64, true>(
155 Object* object,
156 const char* secname,
157 const elfcpp::Shdr<64, true>& shdr);
158
159} // End namespace gold.