This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Add support for MIPS .rld_map section.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a8ecc9fe61d0fdb1f694c5f3fac910802468d43f

commit a8ecc9fe61d0fdb1f694c5f3fac910802468d43f
Author: Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
Date:   Mon Jun 20 12:10:53 2016 -0700

    Add support for MIPS .rld_map section.
    
    Includes DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL dynamic tags and
    __RLD_MAP symbol.
    
    2016-06-20  Vladimir Radosavljevic  <Vladimir.Radosavljevic@imgtec.com>
    
    elfcpp/
            * elfcpp.h (DT_MIPS_RLD_MAP_REL): New enum constant.
    gold/
            * mips.cc (Target_mips::Target_mips): Initialize rld_map_.
            (Target_mips::rld_map_): New data member.
            (Target_mips::do_finalize_sections): Add support for
            DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL dynamic tags,
            .rld_map section, and __RLD_MAP symbol.
            (Target_mips::do_dynamic_tag_custom_value): Add support for
            DT_MIPS_RLD_MAP_REL dynamic tag.
            * output.cc (Output_data_dynamic::get_entry_offset): New method
            definition.
            * output.h (Output_data_dynamic::get_entry_offset): New method
            declaration.

Diff:
---
 elfcpp/ChangeLog |  4 ++++
 elfcpp/elfcpp.h  |  2 ++
 gold/ChangeLog   | 14 ++++++++++++++
 gold/mips.cc     | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
 gold/output.cc   | 21 +++++++++++++++++++++
 gold/output.h    |  4 ++++
 6 files changed, 91 insertions(+), 5 deletions(-)

diff --git a/elfcpp/ChangeLog b/elfcpp/ChangeLog
index fa8594e..62e21b5 100644
--- a/elfcpp/ChangeLog
+++ b/elfcpp/ChangeLog
@@ -1,5 +1,9 @@
 2016-06-20  Vladimir Radosavljevic  <Vladimir.Radosavljevic@imgtec.com>
 
+        * elfcpp.h (DT_MIPS_RLD_MAP_REL): New enum constant.
+
+2016-06-20  Vladimir Radosavljevic  <Vladimir.Radosavljevic@imgtec.com>
+
 	* mips.h (R_MIPS_PC21_S2, R_MIPS_PC26_S2, R_MIPS_PC18_S3,
 	R_MIPS_PC19_S2, R_MIPS_PCHI16, R_MIPS_PCLO16): New enums for
 	Mips32r6 and Mips64r6 relocations.
diff --git a/elfcpp/elfcpp.h b/elfcpp/elfcpp.h
index f39a135..7469bd8 100644
--- a/elfcpp/elfcpp.h
+++ b/elfcpp/elfcpp.h
@@ -868,6 +868,8 @@ enum DT
   DT_MIPS_PLTGOT = 0x70000032,
   // Points to the base of a writable PLT.
   DT_MIPS_RWPLT = 0x70000034,
+  // Relative offset of run time loader map, used for debugging.
+  DT_MIPS_RLD_MAP_REL = 0x70000035,
 
   DT_AUXILIARY = 0x7ffffffd,
   DT_USED = 0x7ffffffe,
diff --git a/gold/ChangeLog b/gold/ChangeLog
index cf8289b..a4c9d6c 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,19 @@
 2016-06-20  Vladimir Radosavljevic  <Vladimir.Radosavljevic@imgtec.com>
 
+        * mips.cc (Target_mips::Target_mips): Initialize rld_map_.
+        (Target_mips::rld_map_): New data member.
+        (Target_mips::do_finalize_sections): Add support for
+        DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL dynamic tags,
+        .rld_map section, and __RLD_MAP symbol.
+        (Target_mips::do_dynamic_tag_custom_value): Add support for
+        DT_MIPS_RLD_MAP_REL dynamic tag.
+        * output.cc (Output_data_dynamic::get_entry_offset): New method
+        definition.
+        * output.h (Output_data_dynamic::get_entry_offset): New method
+        declaration.
+
+2016-06-20  Vladimir Radosavljevic  <Vladimir.Radosavljevic@imgtec.com>
+
         * mips.cc (Mips_relocate_functions::relpc16): Add unaligned check.
 
 2016-06-20  Vladimir Radosavljevic  <Vladimir.Radosavljevic@imgtec.com>
diff --git a/gold/mips.cc b/gold/mips.cc
index e2b7855..8893e31 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -3292,10 +3292,10 @@ class Target_mips : public Sized_target<size, big_endian>
  public:
   Target_mips(const Target::Target_info* info = &mips_info)
     : Sized_target<size, big_endian>(info), got_(NULL), gp_(NULL), plt_(NULL),
-      got_plt_(NULL), rel_dyn_(NULL), copy_relocs_(), dyn_relocs_(),
-      la25_stub_(NULL), mips_mach_extensions_(), mips_stubs_(NULL),
-      attributes_section_data_(NULL), abiflags_(NULL), mach_(0), layout_(NULL),
-      got16_addends_(), has_abiflags_section_(false),
+      got_plt_(NULL), rel_dyn_(NULL), rld_map_(NULL), copy_relocs_(),
+      dyn_relocs_(), la25_stub_(NULL), mips_mach_extensions_(),
+      mips_stubs_(NULL), attributes_section_data_(NULL), abiflags_(NULL),
+      mach_(0), layout_(NULL), got16_addends_(), has_abiflags_section_(false),
       entry_symbol_is_compressed_(false), insn32_(false)
   {
     this->add_machine_extensions();
@@ -4181,6 +4181,8 @@ class Target_mips : public Sized_target<size, big_endian>
   Output_data_space* got_plt_;
   // The dynamic reloc section.
   Reloc_section* rel_dyn_;
+  // The .rld_map section.
+  Output_data_zero_fill* rld_map_;
   // Relocs saved to avoid a COPY reloc.
   Mips_copy_relocs<elfcpp::SHT_REL, size, big_endian> copy_relocs_;
 
@@ -9760,8 +9762,37 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
     if (this->plt_ != NULL)
       // DT_MIPS_PLTGOT dynamic tag
       odyn->add_section_address(elfcpp::DT_MIPS_PLTGOT, this->got_plt_);
+
+    if (!parameters->options().shared())
+      {
+        this->rld_map_ = new Output_data_zero_fill(size / 8, size / 8);
+
+        layout->add_output_section_data(".rld_map", elfcpp::SHT_PROGBITS,
+                                        (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
+                                        this->rld_map_, ORDER_INVALID, false);
+
+        // __RLD_MAP will be filled in by the runtime loader to contain
+        // a pointer to the _r_debug structure.
+        Symbol* rld_map = symtab->define_in_output_data("__RLD_MAP", NULL,
+                                            Symbol_table::PREDEFINED,
+                                            this->rld_map_,
+                                            0, 0, elfcpp::STT_OBJECT,
+                                            elfcpp::STB_GLOBAL,
+                                            elfcpp::STV_DEFAULT, 0,
+                                            false, false);
+
+        rld_map->set_needs_dynsym_entry();
+
+        if (!parameters->options().pie())
+          // This member holds the absolute address of the debug pointer.
+          odyn->add_section_address(elfcpp::DT_MIPS_RLD_MAP, this->rld_map_);
+        else
+          // This member holds the offset to the debug pointer,
+          // relative to the address of the tag.
+          odyn->add_custom(elfcpp::DT_MIPS_RLD_MAP_REL);
+      }
   }
- }
+}
 
 // Get the custom dynamic tag value.
 template<int size, bool big_endian>
@@ -9797,6 +9828,16 @@ Target_mips<size, big_endian>::do_dynamic_tag_custom_value(elfcpp::DT tag) const
           return this->get_dt_mips_symtabno();
       }
 
+    case elfcpp::DT_MIPS_RLD_MAP_REL:
+      {
+        // The MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
+        // relative to the address of the tag.
+        Output_data_dynamic* const odyn = this->layout_->dynamic_data();
+        unsigned int entry_offset =
+          odyn->get_entry_offset(elfcpp::DT_MIPS_RLD_MAP_REL);
+        gold_assert(entry_offset != -1U);
+        return this->rld_map_->address() - (odyn->address() + entry_offset);
+      }
     default:
       gold_error(_("Unknown dynamic tag 0x%x"), (unsigned int)tag);
     }
diff --git a/gold/output.cc b/gold/output.cc
index 077e2c4..0a9e58f 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1882,6 +1882,27 @@ Output_data_dynamic::do_adjust_output_section(Output_section* os)
     gold_unreachable();
 }
 
+// Get a dynamic entry offset.
+
+unsigned int
+Output_data_dynamic::get_entry_offset(elfcpp::DT tag) const
+{
+  int dyn_size;
+
+  if (parameters->target().get_size() == 32)
+    dyn_size = elfcpp::Elf_sizes<32>::dyn_size;
+  else if (parameters->target().get_size() == 64)
+    dyn_size = elfcpp::Elf_sizes<64>::dyn_size;
+  else
+    gold_unreachable();
+
+  for (size_t i = 0; i < entries_.size(); ++i)
+    if (entries_[i].tag() == tag)
+      return i * dyn_size;
+
+  return -1U;
+}
+
 // Set the final data size.
 
 void
diff --git a/gold/output.h b/gold/output.h
index 0b96a03..d8a8aaa 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -2781,6 +2781,10 @@ class Output_data_dynamic : public Output_section_data
   add_custom(elfcpp::DT tag)
   { this->add_entry(Dynamic_entry(tag)); }
 
+  // Get a dynamic entry offset.
+  unsigned int
+  get_entry_offset(elfcpp::DT tag) const;
+
  protected:
   // Adjust the output section to set the entry size.
   void


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