This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gold patch] Fix problem handling REL relocations when reading .debug_ranges


This patch fixes a bug where REL relocations are not properly handled
for the .debug_ranges section, when building .gdb_index.

Tested on x86 (32-bit) and committed.

-cary


2013-07-01  Cary Coutant  <ccoutant@google.com>

        * dwarf_reader.cc (Dwarf_ranges_table::read_ranges_table): Save
        reloc_type_.
        (Dwarf_ranges_table::read_range_list): Call lookup_reloc.
        (Dwarf_ranges_table::lookup_reloc): New function.
        * dwarf_reader.h (Dwarf_ranges_table::Dwarf_ranges_table): Initialize
        reloc_type_.
        (Dwarf_ranges_table::lookup_reloc): New function.
        (Dwarf_ranges_table::reloc_type_): New data member.


diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc
index 6b01b7f..4233954 100644
--- a/gold/dwarf_reader.cc
+++ b/gold/dwarf_reader.cc
@@ -374,6 +374,7 @@ Dwarf_ranges_table::read_ranges_table(
   this->ranges_reloc_mapper_ = make_elf_reloc_mapper(object, symtab,
      symtab_size);
   this->ranges_reloc_mapper_->initialize(reloc_shndx, reloc_type);
+  this->reloc_type_ = reloc_type;

   return true;
 }
@@ -430,11 +431,8 @@ Dwarf_ranges_table::read_range_list(
       unsigned int shndx2 = 0;
       if (this->ranges_reloc_mapper_ != NULL)
         {
-  shndx1 =
-      this->ranges_reloc_mapper_->get_reloc_target(offset, &start);
-  shndx2 =
-      this->ranges_reloc_mapper_->get_reloc_target(offset + addr_size,
-   &end);
+  shndx1 = this->lookup_reloc(offset, &start);
+  shndx2 = this->lookup_reloc(offset + addr_size, &end);
         }

       // End of list is marked by a pair of zeroes.
@@ -460,6 +458,24 @@ Dwarf_ranges_table::read_range_list(
   return ranges;
 }

+// Look for a relocation at offset OFF in the range table,
+// and return the section index and offset of the target.
+
+unsigned int
+Dwarf_ranges_table::lookup_reloc(off_t off, off_t* target_off)
+{
+  off_t value;
+  unsigned int shndx =
+      this->ranges_reloc_mapper_->get_reloc_target(off, &value);
+  if (shndx == 0)
+    return 0;
+  if (this->reloc_type_ == elfcpp::SHT_REL)
+    *target_off += value;
+  else
+    *target_off = value;
+  return shndx;
+}
+
 // class Dwarf_pubnames_table

 // Read the pubnames section SHNDX from the object file.
diff --git a/gold/dwarf_reader.h b/gold/dwarf_reader.h
index 13d278a..9ee483c 100644
--- a/gold/dwarf_reader.h
+++ b/gold/dwarf_reader.h
@@ -338,7 +338,7 @@ class Dwarf_ranges_table
   Dwarf_ranges_table(Dwarf_info_reader* dwinfo)
     : dwinfo_(dwinfo), ranges_shndx_(0), ranges_buffer_(NULL),
       ranges_buffer_end_(NULL), owns_ranges_buffer_(false),
-      ranges_reloc_mapper_(NULL), output_section_offset_(0)
+      ranges_reloc_mapper_(NULL), reloc_type_(0), output_section_offset_(0)
   { }

   ~Dwarf_ranges_table()
@@ -365,6 +365,11 @@ class Dwarf_ranges_table
   unsigned int ranges_shndx,
   off_t ranges_offset);

+  // Look for a relocation at offset OFF in the range table,
+  // and return the section index and offset of the target.
+  unsigned int
+  lookup_reloc(off_t off, off_t* target_off);
+
  private:
   // The Dwarf_info_reader, for reading data.
   Dwarf_info_reader* dwinfo_;
@@ -377,6 +382,8 @@ class Dwarf_ranges_table
   bool owns_ranges_buffer_;
   // Relocation mapper for the .debug_ranges section.
   Elf_reloc_mapper* ranges_reloc_mapper_;
+  // Type of the relocation section (SHT_REL or SHT_RELA).
+  unsigned int reloc_type_;
   // For incremental update links, this will hold the offset of the
   // input section within the output section.  Offsets read from
   // relocated data will be relative to the output section, and need


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]