X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fdwarf_reader.cc;h=ec0e845564863af809005a07dbf619a634d42d7a;hb=95830fd17d6ae253d8f6c2595188cadd59058799;hp=6245dc81991e7c6e9fcb8b9558241b2480e6fe67;hpb=57923f48a1e2e9129fdb3dd536b38e8d1cd46089;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc index 6245dc8199..ec0e845564 100644 --- a/gold/dwarf_reader.cc +++ b/gold/dwarf_reader.cc @@ -28,7 +28,6 @@ #include "elfcpp_swap.h" #include "dwarf.h" #include "object.h" -#include "parameters.h" #include "reloc.h" #include "dwarf_reader.h" #include "int_encoding.h" @@ -58,7 +57,7 @@ Sized_elf_reloc_mapper::symbol_section( unsigned int symndx, Address* value, bool* is_ordinary) { const int symsize = elfcpp::Elf_sizes::sym_size; - gold_assert((symndx + 1) * symsize <= this->symtab_size_); + gold_assert(static_cast((symndx + 1) * symsize) <= this->symtab_size_); elfcpp::Sym elfsym(this->symtab_ + symndx * symsize); *value = elfsym.get_st_value(); return this->object_->adjust_sym_shndx(symndx, elfsym.get_st_shndx(), @@ -90,34 +89,53 @@ Sized_elf_reloc_mapper::do_get_reloc_target( } static inline Elf_reloc_mapper* -make_elf_reloc_mapper(Object* object, const unsigned char* symtab, +make_elf_reloc_mapper(Relobj* object, const unsigned char* symtab, off_t symtab_size) { - switch (parameters->size_and_endianness()) + if (object->elfsize() == 32) { -#ifdef HAVE_TARGET_32_LITTLE - case Parameters::TARGET_32_LITTLE: - return new Sized_elf_reloc_mapper<32, false>(object, symtab, - symtab_size); -#endif + if (object->is_big_endian()) + { #ifdef HAVE_TARGET_32_BIG - case Parameters::TARGET_32_BIG: - return new Sized_elf_reloc_mapper<32, true>(object, symtab, - symtab_size); + return new Sized_elf_reloc_mapper<32, true>(object, symtab, + symtab_size); +#else + gold_unreachable(); #endif -#ifdef HAVE_TARGET_64_LITTLE - case Parameters::TARGET_64_LITTLE: - return new Sized_elf_reloc_mapper<64, false>(object, symtab, - symtab_size); + } + else + { +#ifdef HAVE_TARGET_32_LITTLE + return new Sized_elf_reloc_mapper<32, false>(object, symtab, + symtab_size); +#else + gold_unreachable(); #endif + } + } + else if (object->elfsize() == 64) + { + if (object->is_big_endian()) + { #ifdef HAVE_TARGET_64_BIG - case Parameters::TARGET_64_BIG: - return new Sized_elf_reloc_mapper<64, true>(object, symtab, - symtab_size); + return new Sized_elf_reloc_mapper<64, true>(object, symtab, + symtab_size); +#else + gold_unreachable(); #endif - default: - gold_unreachable(); + } + else + { +#ifdef HAVE_TARGET_64_LITTLE + return new Sized_elf_reloc_mapper<64, false>(object, symtab, + symtab_size); +#else + gold_unreachable(); +#endif + } } + else + gold_unreachable(); } // class Dwarf_abbrev_table @@ -394,13 +412,17 @@ Dwarf_ranges_table::read_range_list( // Read the raw contents of the section. if (addr_size == 4) { - start = read_from_pointer<32>(this->ranges_buffer_ + offset); - end = read_from_pointer<32>(this->ranges_buffer_ + offset + 4); + start = this->dwinfo_->read_from_pointer<32>(this->ranges_buffer_ + + offset); + end = this->dwinfo_->read_from_pointer<32>(this->ranges_buffer_ + + offset + 4); } else { - start = read_from_pointer<64>(this->ranges_buffer_ + offset); - end = read_from_pointer<64>(this->ranges_buffer_ + offset + 8); + start = this->dwinfo_->read_from_pointer<64>(this->ranges_buffer_ + + offset); + end = this->dwinfo_->read_from_pointer<64>(this->ranges_buffer_ + + offset + 8); } // Check for relocations and adjust the values. @@ -492,11 +514,11 @@ Dwarf_pubnames_table::read_header(off_t offset) const unsigned char* pinfo = this->buffer_ + offset; // Read the unit_length field. - uint32_t unit_length = read_from_pointer<32>(pinfo); + uint32_t unit_length = this->dwinfo_->read_from_pointer<32>(pinfo); pinfo += 4; if (unit_length == 0xffffffff) { - unit_length = read_from_pointer<64>(pinfo); + unit_length = this->dwinfo_->read_from_pointer<64>(pinfo); pinfo += 8; this->offset_size_ = 8; } @@ -504,11 +526,11 @@ Dwarf_pubnames_table::read_header(off_t offset) this->offset_size_ = 4; // Check the version. - unsigned int version = read_from_pointer<16>(pinfo); + unsigned int version = this->dwinfo_->read_from_pointer<16>(pinfo); pinfo += 2; if (version != 2) return false; - + // Skip the debug_info_offset and debug_info_size fields. pinfo += 2 * this->offset_size_; @@ -530,9 +552,9 @@ Dwarf_pubnames_table::next_name() // the end of the list. uint32_t offset; if (this->offset_size_ == 4) - offset = read_from_pointer<32>(&pinfo); + offset = this->dwinfo_->read_from_pointer<32>(&pinfo); else - offset = read_from_pointer<64>(&pinfo); + offset = this->dwinfo_->read_from_pointer<64>(&pinfo); if (offset == 0) return NULL; @@ -613,9 +635,6 @@ Dwarf_die::read_attributes() attr_value.aux.shndx = 0; switch(form) { - case elfcpp::DW_FORM_null: - attr_value.val.intval = 0; - break; case elfcpp::DW_FORM_flag_present: attr_value.val.intval = 1; break; @@ -623,9 +642,9 @@ Dwarf_die::read_attributes() { off_t str_off; if (this->dwinfo_->offset_size() == 4) - str_off = read_from_pointer<32>(&pattr); + str_off = this->dwinfo_->read_from_pointer<32>(&pattr); else - str_off = read_from_pointer<64>(&pattr); + str_off = this->dwinfo_->read_from_pointer<64>(&pattr); unsigned int shndx = this->dwinfo_->lookup_reloc(attr_off, &str_off); attr_value.aux.shndx = shndx; @@ -636,9 +655,9 @@ Dwarf_die::read_attributes() { off_t sec_off; if (this->dwinfo_->offset_size() == 4) - sec_off = read_from_pointer<32>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<32>(&pattr); else - sec_off = read_from_pointer<64>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<64>(&pattr); unsigned int shndx = this->dwinfo_->lookup_reloc(attr_off, &sec_off); attr_value.aux.shndx = shndx; @@ -651,9 +670,9 @@ Dwarf_die::read_attributes() { off_t sec_off; if (this->dwinfo_->address_size() == 4) - sec_off = read_from_pointer<32>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<32>(&pattr); else - sec_off = read_from_pointer<64>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<64>(&pattr); unsigned int shndx = this->dwinfo_->lookup_reloc(attr_off, &sec_off); attr_value.aux.shndx = shndx; @@ -667,12 +686,14 @@ Dwarf_die::read_attributes() pattr += attr_value.aux.blocklen; break; case elfcpp::DW_FORM_block2: - attr_value.aux.blocklen = read_from_pointer<16>(&pattr); + attr_value.aux.blocklen = + this->dwinfo_->read_from_pointer<16>(&pattr); attr_value.val.blockval = pattr; pattr += attr_value.aux.blocklen; break; case elfcpp::DW_FORM_block4: - attr_value.aux.blocklen = read_from_pointer<32>(&pattr); + attr_value.aux.blocklen = + this->dwinfo_->read_from_pointer<32>(&pattr); attr_value.val.blockval = pattr; pattr += attr_value.aux.blocklen; break; @@ -691,16 +712,18 @@ Dwarf_die::read_attributes() ref_form = true; break; case elfcpp::DW_FORM_data2: - attr_value.val.intval = read_from_pointer<16>(&pattr); + attr_value.val.intval = + this->dwinfo_->read_from_pointer<16>(&pattr); break; case elfcpp::DW_FORM_ref2: - attr_value.val.refval = read_from_pointer<16>(&pattr); + attr_value.val.refval = + this->dwinfo_->read_from_pointer<16>(&pattr); ref_form = true; break; case elfcpp::DW_FORM_data4: { off_t sec_off; - sec_off = read_from_pointer<32>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<32>(&pattr); unsigned int shndx = this->dwinfo_->lookup_reloc(attr_off, &sec_off); attr_value.aux.shndx = shndx; @@ -710,7 +733,7 @@ Dwarf_die::read_attributes() case elfcpp::DW_FORM_ref4: { off_t sec_off; - sec_off = read_from_pointer<32>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<32>(&pattr); unsigned int shndx = this->dwinfo_->lookup_reloc(attr_off, &sec_off); attr_value.aux.shndx = shndx; @@ -721,7 +744,7 @@ Dwarf_die::read_attributes() case elfcpp::DW_FORM_data8: { off_t sec_off; - sec_off = read_from_pointer<64>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<64>(&pattr); unsigned int shndx = this->dwinfo_->lookup_reloc(attr_off, &sec_off); attr_value.aux.shndx = shndx; @@ -729,12 +752,13 @@ Dwarf_die::read_attributes() break; } case elfcpp::DW_FORM_ref_sig8: - attr_value.val.uintval = read_from_pointer<64>(&pattr); + attr_value.val.uintval = + this->dwinfo_->read_from_pointer<64>(&pattr); break; case elfcpp::DW_FORM_ref8: { off_t sec_off; - sec_off = read_from_pointer<64>(&pattr); + sec_off = this->dwinfo_->read_from_pointer<64>(&pattr); unsigned int shndx = this->dwinfo_->lookup_reloc(attr_off, &sec_off); attr_value.aux.shndx = shndx; @@ -748,6 +772,8 @@ Dwarf_die::read_attributes() pattr += len; break; case elfcpp::DW_FORM_udata: + case elfcpp::DW_FORM_GNU_addr_index: + case elfcpp::DW_FORM_GNU_str_index: attr_value.val.uintval = read_unsigned_LEB_128(pattr, &len); pattr += len; break; @@ -824,8 +850,6 @@ Dwarf_die::read_attributes() off_t Dwarf_die::skip_attributes() { - typedef Dwarf_abbrev_table::Attribute Attribute; - gold_assert(this->abbrev_code_ != NULL); const unsigned char* pdie = @@ -845,7 +869,6 @@ Dwarf_die::skip_attributes() } switch(form) { - case elfcpp::DW_FORM_null: case elfcpp::DW_FORM_flag_present: break; case elfcpp::DW_FORM_strp: @@ -862,14 +885,14 @@ Dwarf_die::skip_attributes() case elfcpp::DW_FORM_block2: { uint16_t block_size; - block_size = read_from_pointer<16>(&pattr); + block_size = this->dwinfo_->read_from_pointer<16>(&pattr); pattr += block_size; break; } case elfcpp::DW_FORM_block4: { uint32_t block_size; - block_size = read_from_pointer<32>(&pattr); + block_size = this->dwinfo_->read_from_pointer<32>(&pattr); pattr += block_size; break; } @@ -901,6 +924,8 @@ Dwarf_die::skip_attributes() break; case elfcpp::DW_FORM_ref_udata: case elfcpp::DW_FORM_udata: + case elfcpp::DW_FORM_GNU_addr_index: + case elfcpp::DW_FORM_GNU_str_index: read_unsigned_LEB_128(pattr, &len); pattr += len; break; @@ -985,7 +1010,6 @@ Dwarf_die::int_attribute(unsigned int attr) return 0; switch (attr_val->form) { - case elfcpp::DW_FORM_null: case elfcpp::DW_FORM_flag_present: case elfcpp::DW_FORM_data1: case elfcpp::DW_FORM_flag: @@ -1007,7 +1031,6 @@ Dwarf_die::uint_attribute(unsigned int attr) return 0; switch (attr_val->form) { - case elfcpp::DW_FORM_null: case elfcpp::DW_FORM_flag_present: case elfcpp::DW_FORM_data1: case elfcpp::DW_FORM_flag: @@ -1140,30 +1163,21 @@ Dwarf_info_reader::check_buffer(const unsigned char* p) const void Dwarf_info_reader::parse() { - switch (parameters->size_and_endianness()) + if (this->object_->is_big_endian()) { -#ifdef HAVE_TARGET_32_LITTLE - case Parameters::TARGET_32_LITTLE: - this->do_parse(); - break; -#endif -#ifdef HAVE_TARGET_32_BIG - case Parameters::TARGET_32_BIG: - this->do_parse(); - break; +#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) + this->do_parse(); +#else + gold_unreachable(); #endif -#ifdef HAVE_TARGET_64_LITTLE - case Parameters::TARGET_64_LITTLE: - this->do_parse(); - break; -#endif -#ifdef HAVE_TARGET_64_BIG - case Parameters::TARGET_64_BIG: - this->do_parse(); - break; + } + else + { +#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) + this->do_parse(); +#else + gold_unreachable(); #endif - default: - gold_unreachable(); } } @@ -1190,7 +1204,7 @@ Dwarf_info_reader::do_parse() this->reloc_mapper_->initialize(this->reloc_shndx_, this->reloc_type_); // Loop over compilation units (or type units). - unsigned int abbrev_shndx = 0; + unsigned int abbrev_shndx = this->abbrev_shndx_; off_t abbrev_offset = 0; const unsigned char* pinfo = this->buffer_; while (pinfo < this->buffer_end_) @@ -1347,6 +1361,33 @@ Dwarf_info_reader::do_read_string_table(unsigned int string_shndx) return true; } +// Read a possibly unaligned integer of SIZE. +template +inline typename elfcpp::Valtype_base::Valtype +Dwarf_info_reader::read_from_pointer(const unsigned char* source) +{ + typename elfcpp::Valtype_base::Valtype return_value; + if (this->object_->is_big_endian()) + return_value = elfcpp::Swap_unaligned::readval(source); + else + return_value = elfcpp::Swap_unaligned::readval(source); + return return_value; +} + +// Read a possibly unaligned integer of SIZE. Update SOURCE after read. +template +inline typename elfcpp::Valtype_base::Valtype +Dwarf_info_reader::read_from_pointer(const unsigned char** source) +{ + typename elfcpp::Valtype_base::Valtype return_value; + if (this->object_->is_big_endian()) + return_value = elfcpp::Swap_unaligned::readval(*source); + else + return_value = elfcpp::Swap_unaligned::readval(*source); + *source += valsize / 8; + return return_value; +} + // Look for a relocation at offset ATTR_OFF in the dwarf info, // and return the section index and offset of the target.