Initial CVS checkin of gold
[deliverable/binutils-gdb.git] / gold / object.cc
CommitLineData
bae7f79e
ILT
1// object.cc -- support for an object file for linking in gold
2
3#include "gold.h"
4
5#include <cerrno>
6#include <cstring>
7#include <cassert>
8
9#include "object.h"
10
11namespace gold
12{
13
14// Class Object.
15
16const unsigned char*
17Object::get_view(off_t start, off_t size)
18{
19 return this->input_file_->file().get_view(start + this->offset_, size);
20}
21
22void
23Object::read(off_t start, off_t size, void* p)
24{
25 this->input_file_->file().read(start + this->offset_, size, p);
26}
27
28File_view*
29Object::get_lasting_view(off_t start, off_t size)
30{
31 return this->input_file_->file().get_lasting_view(start + this->offset_,
32 size);
33}
34
35// Class Sized_object.
36
37template<int size, bool big_endian>
38Sized_object<size, big_endian>::Sized_object(
39 const std::string& name,
40 Input_file* input_file,
41 off_t offset,
42 const elfcpp::Ehdr<size, big_endian>& ehdr)
43 : Object(name, input_file, offset),
44 osabi_(ehdr.get_e_ident()[elfcpp::EI_OSABI]),
45 abiversion_(ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]),
46 machine_(ehdr.get_e_machine()),
47 flags_(ehdr.get_e_flags()),
48 target_(NULL),
49 shoff_(ehdr.get_e_shoff()),
50 shnum_(0),
51 shstrndx_(0),
52 symtab_shnum_(0)
53{
54 if (ehdr.get_e_ehsize() != elfcpp::Elf_sizes<size>::ehdr_size)
55 {
56 fprintf(stderr, _("%s: %s: bad e_ehsize field (%d != %d)\n"),
57 program_name, this->name().c_str(), ehdr.get_e_ehsize(),
58 elfcpp::Elf_sizes<size>::ehdr_size);
59 gold_exit(false);
60 }
61 if (ehdr.get_e_shentsize() != elfcpp::Elf_sizes<size>::shdr_size)
62 {
63 fprintf(stderr, _("%s: %s: bad e_shentsize field (%d != %d)\n"),
64 program_name, this->name().c_str(), ehdr.get_e_shentsize(),
65 elfcpp::Elf_sizes<size>::shdr_size);
66 gold_exit(false);
67 }
68}
69
70template<int size, bool big_endian>
71Sized_object<size, big_endian>::~Sized_object()
72{
73}
74
75// Set up an object file bsaed on the file header. This sets up the
76// target and reads the section information.
77
78template<int size, bool big_endian>
79void
80Sized_object<size, big_endian>::setup(
81 const elfcpp::Ehdr<size, big_endian>& ehdr)
82{
83 // this->target_ = select_target(this->machine_, size, big_endian,
84 // this->osabi_, this->abiversion_);
85 unsigned int shnum = ehdr.get_e_shnum();
86 unsigned int shstrndx = ehdr.get_e_shstrndx();
87 if ((shnum == 0 || shstrndx == elfcpp::SHN_XINDEX)
88 && this->shoff_ != 0)
89 {
90 const unsigned char* p = this->get_view
91 (this->shoff_, elfcpp::Elf_sizes<size>::shdr_size);
92 elfcpp::Shdr<size, big_endian> shdr(p);
93 if (shnum == 0)
94 shnum = shdr.get_sh_size();
95 if (shstrndx == elfcpp::SHN_XINDEX)
96 shstrndx = shdr.get_sh_link();
97 }
98 this->shnum_ = shnum;
99 this->shstrndx_ = shstrndx;
100
101 if (shnum == 0)
102 return;
103
104 // Find the SHT_SYMTAB section.
105 const unsigned char* p = this->get_view
106 (this->shoff_, shnum * elfcpp::Elf_sizes<size>::shdr_size);
107 // Skip the first section, which is always empty.
108 p += elfcpp::Elf_sizes<size>::shdr_size;
109 for (unsigned int i = 1; i < shnum; ++i)
110 {
111 elfcpp::Shdr<size, big_endian> shdr(p);
112 if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
113 {
114 this->symtab_shnum_ = i;
115 break;
116 }
117 p += elfcpp::Elf_sizes<size>::shdr_size;
118 }
119}
120
121// Read the symbols and relocations from an object file.
122
123template<int size, bool big_endian>
124Read_symbols_data
125Sized_object<size, big_endian>::do_read_symbols()
126{
127 if (this->symtab_shnum_ == 0)
128 {
129 // No symbol table. Weird but legal.
130 Read_symbols_data ret;
131 ret.symbols = NULL;
132 ret.symbols_size = 0;
133 ret.symbol_names = NULL;
134 ret.symbol_names_size = 0;
135 return ret;
136 }
137
138 int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
139
140 // Read the symbol table section header.
141 off_t symtabshdroff = this->shoff_ + (this->symtab_shnum_ * shdr_size);
142 const unsigned char* psymtabshdr = this->get_view(symtabshdroff, shdr_size);
143 elfcpp::Shdr<size, big_endian> symtabshdr(psymtabshdr);
144 assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
145
146 // Read the symbol table.
147 File_view* fvsymtab = this->get_lasting_view(symtabshdr.get_sh_offset(),
148 symtabshdr.get_sh_size());
149
150 // Read the section header for the symbol names.
151 unsigned int strtab_shnum = symtabshdr.get_sh_link();
152 if (strtab_shnum == 0 || strtab_shnum >= this->shnum_)
153 {
154 fprintf(stderr, _("%s: %s: invalid symbol table name index: %u\n"),
155 program_name, this->name().c_str(), strtab_shnum);
156 gold_exit(false);
157 }
158 off_t strtabshdroff = this->shoff_ + (strtab_shnum * shdr_size);
159 const unsigned char *pstrtabshdr = this->get_view(strtabshdroff, shdr_size);
160 elfcpp::Shdr<size, big_endian> strtabshdr(pstrtabshdr);
161 if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB)
162 {
163 fprintf(stderr,
164 _("%s: %s: symbol table name section has wrong type: %u\n"),
165 program_name, this->name().c_str(),
166 static_cast<unsigned int>(strtabshdr.get_sh_type()));
167 gold_exit(false);
168 }
169
170 // Read the symbol names.
171 File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
172 strtabshdr.get_sh_size());
173
174 Read_symbols_data ret;
175 ret.symbols = fvsymtab;
176 ret.symbols_size = symtabshdr.get_sh_size();
177 ret.symbol_names = fvstrtab;
178 ret.symbol_names_size = strtabshdr.get_sh_size();
179
180 return ret;
181}
182
183// Add the symbols to the symbol table.
184
185template<int size, bool big_endian>
186void
187Sized_object<size, big_endian>::do_add_symbols(Read_symbols_data sd)
188{
189 if (sd.symbols == NULL)
190 {
191 assert(sd.symbol_names == NULL);
192 return;
193 }
194
195 int sym_size = elfcpp::Elf_sizes<size>::sym_size;
196 const unsigned char* symstart = sd.symbols->data();
197 const unsigned char* symend = symstart + sd.symbols_size;
198 for (const unsigned char* p = symstart; p < symend; p += sym_size)
199 {
200 elfcpp::Sym<size, big_endian> sym(p);
201
202 unsigned int nameoff = sym.get_st_name();
203 if (nameoff >= sd.symbol_names_size)
204 {
205 fprintf(stderr,
206 _("%s: %s: invalid symbol name offset %u for symbol %d\n"),
207 program_name, this->name().c_str(), nameoff,
208 (p - symstart) / sym_size);
209 gold_exit(false);
210 }
211 const unsigned char* name = sd.symbol_names->data() + nameoff;
212 printf("%s\n", name);
213 }
214}
215
216} // End namespace gold.
217
218namespace
219{
220
221using namespace gold;
222
223// Read an ELF file with the header and return the appropriate
224// instance of Object.
225
226template<int size, bool big_endian>
227Object*
228make_elf_sized_object(const std::string& name, Input_file* input_file,
229 off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
230{
231 int et = ehdr.get_e_type();
232 if (et != elfcpp::ET_REL && et != elfcpp::ET_DYN)
233 {
234 fprintf(stderr, "%s: %s: unsupported ELF type %d\n",
235 program_name, name.c_str(), static_cast<int>(et));
236 gold_exit(false);
237 }
238
239 if (et == elfcpp::ET_REL)
240 {
241 Sized_object<size, big_endian>* obj =
242 new Sized_object<size, big_endian>(name, input_file, offset, ehdr);
243 obj->setup(ehdr);
244 return obj;
245 }
246 else
247 {
248 // elfcpp::ET_DYN
249 fprintf(stderr, _("%s: %s: dynamic objects are not yet supported\n"),
250 program_name, name.c_str());
251 gold_exit(false);
252// Sized_dynobj<size, big_endian>* obj =
253// new Sized_dynobj<size, big_endian>(this->input_.name(), input_file,
254// offset, ehdr);
255// obj->setup(ehdr);
256// return obj;
257 }
258}
259
260} // End anonymous namespace.
261
262namespace gold
263{
264
265// Read an ELF file and return the appropriate instance of Object.
266
267Object*
268make_elf_object(const std::string& name, Input_file* input_file, off_t offset,
269 const unsigned char* p, off_t bytes)
270{
271 if (bytes < elfcpp::EI_NIDENT)
272 {
273 fprintf(stderr, _("%s: %s: ELF file too short\n"),
274 program_name, name.c_str());
275 gold_exit(false);
276 }
277
278 int v = p[elfcpp::EI_VERSION];
279 if (v != elfcpp::EV_CURRENT)
280 {
281 if (v == elfcpp::EV_NONE)
282 fprintf(stderr, _("%s: %s: invalid ELF version 0\n"),
283 program_name, name.c_str());
284 else
285 fprintf(stderr, _("%s: %s: unsupported ELF version %d\n"),
286 program_name, name.c_str(), v);
287 gold_exit(false);
288 }
289
290 int c = p[elfcpp::EI_CLASS];
291 if (c == elfcpp::ELFCLASSNONE)
292 {
293 fprintf(stderr, _("%s: %s: invalid ELF class 0\n"),
294 program_name, name.c_str());
295 gold_exit(false);
296 }
297 else if (c != elfcpp::ELFCLASS32
298 && c != elfcpp::ELFCLASS64)
299 {
300 fprintf(stderr, _("%s: %s: unsupported ELF class %d\n"),
301 program_name, name.c_str(), c);
302 gold_exit(false);
303 }
304
305 int d = p[elfcpp::EI_DATA];
306 if (d == elfcpp::ELFDATANONE)
307 {
308 fprintf(stderr, _("%s: %s: invalid ELF data encoding\n"),
309 program_name, name.c_str());
310 gold_exit(false);
311 }
312 else if (d != elfcpp::ELFDATA2LSB
313 && d != elfcpp::ELFDATA2MSB)
314 {
315 fprintf(stderr, _("%s: %s: unsupported ELF data encoding %d\n"),
316 program_name, name.c_str(), d);
317 gold_exit(false);
318 }
319
320 bool big_endian = d == elfcpp::ELFDATA2MSB;
321
322 if (c == elfcpp::ELFCLASS32)
323 {
324 if (bytes < elfcpp::Elf_sizes<32>::ehdr_size)
325 {
326 fprintf(stderr, _("%s: %s: ELF file too short\n"),
327 program_name, name.c_str());
328 gold_exit(false);
329 }
330 if (big_endian)
331 {
332 elfcpp::Ehdr<32, true> ehdr(p);
333 return make_elf_sized_object<32, true>(name, input_file,
334 offset, ehdr);
335 }
336 else
337 {
338 elfcpp::Ehdr<32, false> ehdr(p);
339 return make_elf_sized_object<32, false>(name, input_file,
340 offset, ehdr);
341 }
342 }
343 else
344 {
345 if (bytes < elfcpp::Elf_sizes<32>::ehdr_size)
346 {
347 fprintf(stderr, _("%s: %s: ELF file too short\n"),
348 program_name, name.c_str());
349 gold_exit(false);
350 }
351 if (big_endian)
352 {
353 elfcpp::Ehdr<64, true> ehdr(p);
354 return make_elf_sized_object<64, true>(name, input_file,
355 offset, ehdr);
356 }
357 else
358 {
359 elfcpp::Ehdr<64, false> ehdr(p);
360 return make_elf_sized_object<64, false>(name, input_file,
361 offset, ehdr);
362 }
363 }
364}
365
366// Instantiate the templates we need. We could use the configure
367// script to restrict this to only the ones for implemented targets.
368
369template
370class Sized_object<32, false>;
371
372template
373class Sized_object<32, true>;
374
375template
376class Sized_object<64, false>;
377
378template
379class Sized_object<64, true>;
380
381} // End namespace gold.
This page took 0.03571 seconds and 4 git commands to generate.