Fix DWARF reader to use correct size for DW_FORM_ref_addr.
authorCary Coutant <ccoutant@gmail.com>
Mon, 20 Nov 2017 01:56:30 +0000 (17:56 -0800)
committerCary Coutant <ccoutant@gmail.com>
Mon, 20 Nov 2017 01:56:30 +0000 (17:56 -0800)
2017-11-19  Ian Lance Taylor  <iant@google.com>
    Cary Coutant  <ccoutant@gmail.com>

gold/
* gold/dwarf_reader.h (class Dwarf_info_reader): Add ref_addr_size
method.
* gold/dwarf_reader.cc (Dwarf_die::read_attributes): Use ref_addr_size
for DW_FORM_ref_addr_size.
(Dwarf_die::skip_attributes): Likewise.

gold/ChangeLog
gold/dwarf_reader.cc
gold/dwarf_reader.h

index bd842a67d8fb72ff42ec43e363adf74dd1db019a..263dffd1b127d9d3429c2a6de421090e8341c222 100644 (file)
@@ -1,3 +1,12 @@
+2017-11-19  Ian Lance Taylor  <iant@google.com>
+           Cary Coutant  <ccoutant@gmail.com>
+
+       * gold/dwarf_reader.h (class Dwarf_info_reader): Add ref_addr_size
+       method.
+       * gold/dwarf_reader.cc (Dwarf_die::read_attributes): Use ref_addr_size
+       for DW_FORM_ref_addr_size.
+       (Dwarf_die::skip_attributes): Likewise.
+
 2017-11-08  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gold/22291
index 8c0d593752f324cace1c7f6a90d7828084ce3a15..4da9c1e2be8511a7158ae9ea891d890a6e913f9b 100644 (file)
@@ -737,7 +737,6 @@ Dwarf_die::read_attributes()
              break;
            }
          case elfcpp::DW_FORM_addr:
-         case elfcpp::DW_FORM_ref_addr:
            {
              off_t sec_off;
              if (this->dwinfo_->address_size() == 4)
@@ -751,6 +750,20 @@ Dwarf_die::read_attributes()
              ref_form = true;
              break;
            }
+         case elfcpp::DW_FORM_ref_addr:
+           {
+             off_t sec_off;
+             if (this->dwinfo_->ref_addr_size() == 4)
+               sec_off = this->dwinfo_->read_from_pointer<32>(&pattr);
+             else
+               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;
+             attr_value.val.refval = sec_off;
+             ref_form = true;
+             break;
+           }
          case elfcpp::DW_FORM_block1:
            attr_value.aux.blocklen = *pattr++;
            attr_value.val.blockval = pattr;
@@ -947,9 +960,11 @@ Dwarf_die::skip_attributes()
            pattr += this->dwinfo_->offset_size();
            break;
          case elfcpp::DW_FORM_addr:
-         case elfcpp::DW_FORM_ref_addr:
            pattr += this->dwinfo_->address_size();
            break;
+         case elfcpp::DW_FORM_ref_addr:
+           pattr += this->dwinfo_->ref_addr_size();
+           break;
          case elfcpp::DW_FORM_block1:
            pattr += 1 + *pattr;
            break;
index b41e05762129507c76369a62d6ab03f330902bf5..31e76ce34719a86f4226a922095d47522bf7b620 100644 (file)
@@ -764,6 +764,13 @@ class Dwarf_info_reader
   address_size() const
   { return this->address_size_; }
 
+  // Return the size of a DW_FORM_ref_addr.
+  // In DWARF v2, this was the size of an address; in DWARF v3 and later,
+  // it is the size of an DWARF offset.
+  unsigned int
+  ref_addr_size() const
+  { return this->cu_version_ > 2 ? this->offset_size_ : this->address_size_; }
+
   // Set the section index of the .debug_abbrev section.
   // We use this if there are no relocations for the .debug_info section.
   // If not set, the code parse() routine will search for the section by name.