1 // object.cc -- support for an object file for linking in gold
17 Object::get_view(off_t start, off_t size)
19 return this->input_file_->file().get_view(start + this->offset_, size);
23 Object::read(off_t start, off_t size, void* p)
25 this->input_file_->file().read(start + this->offset_, size, p);
29 Object::get_lasting_view(off_t start, off_t size)
31 return this->input_file_->file().get_lasting_view(start + this->offset_,
35 // Class Sized_object.
37 template<int size, bool big_endian>
38 Sized_object<size, big_endian>::Sized_object(
39 const std::string& name,
40 Input_file* input_file,
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()),
49 shoff_(ehdr.get_e_shoff()),
54 if (ehdr.get_e_ehsize() != elfcpp::Elf_sizes<size>::ehdr_size)
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);
61 if (ehdr.get_e_shentsize() != elfcpp::Elf_sizes<size>::shdr_size)
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);
70 template<int size, bool big_endian>
71 Sized_object<size, big_endian>::~Sized_object()
75 // Set up an object file bsaed on the file header. This sets up the
76 // target and reads the section information.
78 template<int size, bool big_endian>
80 Sized_object<size, big_endian>::setup(
81 const elfcpp::Ehdr<size, big_endian>& ehdr)
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)
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);
94 shnum = shdr.get_sh_size();
95 if (shstrndx == elfcpp::SHN_XINDEX)
96 shstrndx = shdr.get_sh_link();
99 this->shstrndx_ = shstrndx;
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)
111 elfcpp::Shdr<size, big_endian> shdr(p);
112 if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
114 this->symtab_shnum_ = i;
117 p += elfcpp::Elf_sizes<size>::shdr_size;
121 // Read the symbols and relocations from an object file.
123 template<int size, bool big_endian>
125 Sized_object<size, big_endian>::do_read_symbols()
127 if (this->symtab_shnum_ == 0)
129 // No symbol table. Weird but legal.
130 Read_symbols_data ret;
132 ret.symbols_size = 0;
133 ret.symbol_names = NULL;
134 ret.symbol_names_size = 0;
138 int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
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);
146 // Read the symbol table.
147 File_view* fvsymtab = this->get_lasting_view(symtabshdr.get_sh_offset(),
148 symtabshdr.get_sh_size());
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_)
154 fprintf(stderr, _("%s: %s: invalid symbol table name index: %u\n"),
155 program_name, this->name().c_str(), strtab_shnum);
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)
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()));
170 // Read the symbol names.
171 File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
172 strtabshdr.get_sh_size());
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();
183 // Add the symbols to the symbol table.
185 template<int size, bool big_endian>
187 Sized_object<size, big_endian>::do_add_symbols(Read_symbols_data sd)
189 if (sd.symbols == NULL)
191 assert(sd.symbol_names == NULL);
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)
200 elfcpp::Sym<size, big_endian> sym(p);
202 unsigned int nameoff = sym.get_st_name();
203 if (nameoff >= sd.symbol_names_size)
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);
211 const unsigned char* name = sd.symbol_names->data() + nameoff;
212 printf("%s\n", name);
216 } // End namespace gold.
221 using namespace gold;
223 // Read an ELF file with the header and return the appropriate
224 // instance of Object.
226 template<int size, bool big_endian>
228 make_elf_sized_object(const std::string& name, Input_file* input_file,
229 off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
231 int et = ehdr.get_e_type();
232 if (et != elfcpp::ET_REL && et != elfcpp::ET_DYN)
234 fprintf(stderr, "%s: %s: unsupported ELF type %d\n",
235 program_name, name.c_str(), static_cast<int>(et));
239 if (et == elfcpp::ET_REL)
241 Sized_object<size, big_endian>* obj =
242 new Sized_object<size, big_endian>(name, input_file, offset, ehdr);
249 fprintf(stderr, _("%s: %s: dynamic objects are not yet supported\n"),
250 program_name, name.c_str());
252 // Sized_dynobj<size, big_endian>* obj =
253 // new Sized_dynobj<size, big_endian>(this->input_.name(), input_file,
260 } // End anonymous namespace.
265 // Read an ELF file and return the appropriate instance of Object.
268 make_elf_object(const std::string& name, Input_file* input_file, off_t offset,
269 const unsigned char* p, off_t bytes)
271 if (bytes < elfcpp::EI_NIDENT)
273 fprintf(stderr, _("%s: %s: ELF file too short\n"),
274 program_name, name.c_str());
278 int v = p[elfcpp::EI_VERSION];
279 if (v != elfcpp::EV_CURRENT)
281 if (v == elfcpp::EV_NONE)
282 fprintf(stderr, _("%s: %s: invalid ELF version 0\n"),
283 program_name, name.c_str());
285 fprintf(stderr, _("%s: %s: unsupported ELF version %d\n"),
286 program_name, name.c_str(), v);
290 int c = p[elfcpp::EI_CLASS];
291 if (c == elfcpp::ELFCLASSNONE)
293 fprintf(stderr, _("%s: %s: invalid ELF class 0\n"),
294 program_name, name.c_str());
297 else if (c != elfcpp::ELFCLASS32
298 && c != elfcpp::ELFCLASS64)
300 fprintf(stderr, _("%s: %s: unsupported ELF class %d\n"),
301 program_name, name.c_str(), c);
305 int d = p[elfcpp::EI_DATA];
306 if (d == elfcpp::ELFDATANONE)
308 fprintf(stderr, _("%s: %s: invalid ELF data encoding\n"),
309 program_name, name.c_str());
312 else if (d != elfcpp::ELFDATA2LSB
313 && d != elfcpp::ELFDATA2MSB)
315 fprintf(stderr, _("%s: %s: unsupported ELF data encoding %d\n"),
316 program_name, name.c_str(), d);
320 bool big_endian = d == elfcpp::ELFDATA2MSB;
322 if (c == elfcpp::ELFCLASS32)
324 if (bytes < elfcpp::Elf_sizes<32>::ehdr_size)
326 fprintf(stderr, _("%s: %s: ELF file too short\n"),
327 program_name, name.c_str());
332 elfcpp::Ehdr<32, true> ehdr(p);
333 return make_elf_sized_object<32, true>(name, input_file,
338 elfcpp::Ehdr<32, false> ehdr(p);
339 return make_elf_sized_object<32, false>(name, input_file,
345 if (bytes < elfcpp::Elf_sizes<32>::ehdr_size)
347 fprintf(stderr, _("%s: %s: ELF file too short\n"),
348 program_name, name.c_str());
353 elfcpp::Ehdr<64, true> ehdr(p);
354 return make_elf_sized_object<64, true>(name, input_file,
359 elfcpp::Ehdr<64, false> ehdr(p);
360 return make_elf_sized_object<64, false>(name, input_file,
366 // Instantiate the templates we need. We could use the configure
367 // script to restrict this to only the ones for implemented targets.
370 class Sized_object<32, false>;
373 class Sized_object<32, true>;
376 class Sized_object<64, false>;
379 class Sized_object<64, true>;
381 } // End namespace gold.