2006-09-27 Dave Brolley <brolley@redhat.com>
[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>
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
54dc6425
ILT
27// Output_segment_header methods.
28
29void
30Output_segment_headers::write(Output_file*, off_t)
31{
32 // FIXME: Unimplemented.
33 abort();
34}
35
a2fb1b05
ILT
36// Output_section methods.
37
38// Construct an Output_section. NAME will point into a Stringpool.
39
40Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
41 elfcpp::Elf_Xword flags)
42 : name_(name),
43 addr_(0),
44 addralign_(0),
45 entsize_(0),
46 offset_(0),
a2fb1b05
ILT
47 link_(0),
48 info_(0),
49 type_(type),
50 flags_(flags)
51{
52}
53
54dc6425
ILT
54Output_section::~Output_section()
55{
56}
57
a2fb1b05
ILT
58// Add an input section to an Output_section. We don't keep track of
59// input sections for an Output_section. Instead, each Object keeps
60// track of the Output_section for each of its input sections.
61
62template<int size, bool big_endian>
63off_t
64Output_section::add_input_section(Object* object, const char* secname,
65 const elfcpp::Shdr<size, big_endian>& shdr)
66{
67 elfcpp::Elf_Xword addralign = shdr.get_sh_addralign();
68 if ((addralign & (addralign - 1)) != 0)
69 {
70 fprintf(stderr, _("%s: %s: invalid alignment %lu for section \"%s\"\n"),
71 program_name, object->name().c_str(),
72 static_cast<unsigned long>(addralign), secname);
73 gold_exit(false);
74 }
a2fb1b05
ILT
75
76 if (addralign > this->addralign_)
77 this->addralign_ = addralign;
78
54dc6425
ILT
79 off_t ssize = this->get_size();
80 ssize = (ssize + addralign - 1) &~ (addralign - 1);
a2fb1b05 81
54dc6425
ILT
82 this->set_size(ssize + shdr.get_sh_size());
83
84 return size;
a2fb1b05
ILT
85}
86
87// Output segment methods.
88
89Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
54dc6425 90 : output_data_(),
a2fb1b05
ILT
91 vaddr_(0),
92 paddr_(0),
93 memsz_(0),
94 align_(0),
95 offset_(0),
96 filesz_(0),
97 type_(type),
98 flags_(flags)
99{
100}
101
102// Add an Output_section to an Output_segment.
103
104void
105Output_segment::add_output_section(Output_section* os)
106{
54dc6425
ILT
107 // Update the segment flags.
108 this->flags_ |= os->flags() & (elfcpp::PF_R | elfcpp::PF_W | elfcpp::PF_X);
109
a2fb1b05
ILT
110 // So that PT_NOTE segments will work correctly, we need to ensure
111 // that all SHT_NOTE sections are adjacent. This will normally
112 // happen automatically, because all the SHT_NOTE input sections
113 // will wind up in the same output section. However, it is possible
114 // for multiple SHT_NOTE input sections to have different section
115 // flags, and thus be in different output sections, but for the
116 // different section flags to map into the same segment flags and
117 // thus the same output segment.
54dc6425
ILT
118
119 // Note that while there may be many input sections in an output
120 // section, there are normally only a few output sections in an
121 // output segment. This loop is expected to be fast.
122
a2fb1b05
ILT
123 if (os->type() == elfcpp::SHT_NOTE)
124 {
54dc6425
ILT
125 for (Layout::Data_list::iterator p = this->output_data_.begin();
126 p != this->output_data_.end();
127 ++p)
128 {
129 if ((*p)->is_section_type(elfcpp::SHT_NOTE))
130 {
131 ++p;
132 this->output_data_.insert(p, os);
133 return;
134 }
135 }
136 }
137
138 // Similarly, so that PT_TLS segments will work, we need to group
139 // SHF_TLS sections.
140 if ((os->flags() & elfcpp::SHF_TLS) != 0)
141 {
142 for (Layout::Data_list::iterator p = this->output_data_.begin();
143 p != this->output_data_.end();
a2fb1b05
ILT
144 ++p)
145 {
54dc6425 146 if ((*p)->is_section_flag_set(elfcpp::SHF_TLS))
a2fb1b05
ILT
147 {
148 ++p;
54dc6425 149 this->output_data_.insert(p, os);
a2fb1b05
ILT
150 return;
151 }
152 }
153 }
154
54dc6425 155 this->output_data_.push_back(os);
a2fb1b05
ILT
156}
157
158// Output_file methods.
159
160void
161Output_file::write(off_t, const void*, off_t)
162{
163 abort();
164}
165
166// Instantiate the templates we need. We could use the configure
167// script to restrict this to only the ones for implemented targets.
168
169template
170off_t
171Output_section::add_input_section<32, false>(
172 Object* object,
173 const char* secname,
174 const elfcpp::Shdr<32, false>& shdr);
175
176template
177off_t
178Output_section::add_input_section<32, true>(
179 Object* object,
180 const char* secname,
181 const elfcpp::Shdr<32, true>& shdr);
182
183template
184off_t
185Output_section::add_input_section<64, false>(
186 Object* object,
187 const char* secname,
188 const elfcpp::Shdr<64, false>& shdr);
189
190template
191off_t
192Output_section::add_input_section<64, true>(
193 Object* object,
194 const char* secname,
195 const elfcpp::Shdr<64, true>& shdr);
196
197} // End namespace gold.
This page took 0.030233 seconds and 4 git commands to generate.