]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Emitting valid .debug_str, backpatching more general now
authorPetr Machata <pmachata@redhat.com>
Thu, 6 Aug 2009 14:41:16 +0000 (16:41 +0200)
committerPetr Machata <pmachata@redhat.com>
Thu, 6 Aug 2009 14:41:16 +0000 (16:41 +0200)
libdw/c++/dwarf_output
libdw/c++/output-shape.cc
src/Makefile.am
src/writer.cc
tests/Makefile.am

index 085f67356363e81974ddd91fb48a726d01625cdb..8170f8cfd0728c651fcb43f5f554c4a830510eb0 100644 (file)
@@ -167,6 +167,11 @@ namespace elfutils
       return ebl_strtabadd (_m_strtab, str, 0);
     }
 
+    Ebl_Strent *add (std::string const &str)
+    {
+      return ebl_strtabadd (_m_strtab, str.c_str (), str.length () + 1);
+    }
+
   private:
     Ebl_Strtab *_m_strtab;
   };
@@ -689,19 +694,85 @@ namespace elfutils
       throw std::logic_error ("copying dwarf_output requires a collector");
     }
 
+  public:
+
+    class gap
+    {
+      unsigned char *_m_ptr;
+      size_t _m_len;
+
+    public:
+      gap (section_appender &appender, size_t len)
+       : _m_ptr (appender.alloc (len)), _m_len (len)
+      {}
+      gap (unsigned char *ptr, size_t len)
+       : _m_ptr (ptr), _m_len (len)
+      {}
+      void patch (uint64_t value) const;
+    };
+
+    // [(gap, string entry)]
+    typedef std::vector<std::pair<gap, ::Ebl_Strent *> > str_backpatch_vec;
+
+    struct backpatch_strp
+    {
+      void operator () (std::pair<gap, ::Ebl_Strent *> const &v)
+      {
+       v.first.patch (ebl_strtaboffset (v.second));
+      }
+    };
+
+  private:
     // die offset -> file address
     typedef std::map< ::Dwarf_Off, ::Dwarf_Off> die_off_map;
 
-    // [((pointer, length), die offset)]
-    typedef std::vector<std::pair<std::pair<unsigned char *, size_t>,
-                                 ::Dwarf_Off> > backpatch_vec;
-    static void recursively_dump (section_appender &appender,
-                                 dwarf_output_collector &c,
-                                 debug_info_entry const &die,
-                                 unsigned level,
-                                 bool a_addr_64,
-                                 die_off_map &die_off,
-                                 backpatch_vec &backpatch);
+    // [(gap, die offset)]
+    typedef std::vector<std::pair<gap, ::Dwarf_Off> > die_backpatch_vec;
+
+    class backpatch_die_ref
+    {
+      die_off_map const &die_off;
+    public:
+      backpatch_die_ref (die_off_map const &m) : die_off (m) {}
+      void operator () (std::pair<gap, ::Dwarf_Off> const &v)
+      {
+       die_off_map::const_iterator ot = die_off.find (v.second);
+       assert (ot != die_off.end ());
+       v.first.patch (ot->second);
+      }
+    };
+
+    class recursive_dumper
+    {
+      dwarf_output_collector &c;
+      section_appender &appender;
+      strtab &debug_str;
+      bool addr_64;
+      die_off_map &die_off;
+      die_backpatch_vec &die_backpatch;
+      str_backpatch_vec &str_backpatch;
+
+      recursive_dumper (recursive_dumper const &copy); // nocopy
+
+    public:
+      recursive_dumper (dwarf_output_collector &a_c,
+                       section_appender &a_appender,
+                       strtab &a_debug_str,
+                       bool a_addr_64,
+                       die_off_map &a_die_off,
+                       die_backpatch_vec &a_die_backpatch,
+                       str_backpatch_vec &a_str_backpatch)
+       : c (a_c),
+         appender (a_appender),
+         debug_str (a_debug_str),
+         addr_64 (a_addr_64),
+         die_off (a_die_off),
+         die_backpatch (a_die_backpatch),
+         str_backpatch (a_str_backpatch)
+      {}
+
+      void dump (debug_info_entry const &die, unsigned level);
+    };
 
   public:
     // Constructor for an empty file, can add to its compile_units ().
@@ -733,6 +804,8 @@ namespace elfutils
 
     void output_debug_info (section_appender &appender,
                            dwarf_output_collector &dw,
+                           strtab &debug_str,
+                           str_backpatch_vec &str_backpatch,
                            bool addr_64);
   };
 
index 4b6fed70d50bdf3edaa6c16be2d731b439f0cfa1..42f44b9b55b771d4f63a46c2d5a124782af5ce9b 100644 (file)
@@ -69,7 +69,7 @@ attr_form (int tag, const dwarf_output::attribute &attr)
 
     case dwarf::VS_string:
     case dwarf::VS_identifier:
-      return DW_FORM_string;
+      return DW_FORM_strp;
 
     case dwarf::VS_constant:
       if (! attr.second.constant_is_integer ())
@@ -102,14 +102,14 @@ attr_form (int tag, const dwarf_output::attribute &attr)
          return DW_FORM_udata;
 
        case DW_AT_comp_dir:
-         return DW_FORM_string;
+         return DW_FORM_strp;
 
        case DW_AT_name:
          switch (tag)
            {
            case DW_TAG_compile_unit:
            case DW_TAG_partial_unit:
-             return DW_FORM_string;
+             return DW_FORM_strp;
            }
          break;
        }
@@ -339,13 +339,13 @@ dwarf_output::output_debug_abbrev (section_appender &appender,
 }
 
 void
-dwarf_output::recursively_dump (section_appender &appender,
-                               dwarf_output_collector &c,
-                               debug_info_entry const &die,
-                               unsigned level,
-                               bool  addr_64,
-                               dwarf_output::die_off_map &die_off,
-                               dwarf_output::backpatch_vec &backpatch)
+dwarf_output::gap::patch (uint64_t value) const
+{
+  ::dw_write_var (_m_ptr, _m_len, value);
+}
+
+void
+dwarf_output::recursive_dumper::dump (debug_info_entry const &die, unsigned level)
 {
   static char const spaces[] =
     "                                                            "
@@ -458,7 +458,6 @@ dwarf_output::recursively_dump (section_appender &appender,
              || form == DW_FORM_string
              || form == DW_FORM_strp)
            {
-             assert (form == DW_FORM_string); // XXX temporary
              std::string const &str =
                vs == dwarf::VS_string
                ? value.string ()
@@ -466,8 +465,20 @@ dwarf_output::recursively_dump (section_appender &appender,
                   ? value.source_file ().name ()
                   : value.identifier ());
 
-             std::copy (str.begin (), str.end (), inserter);
-             *inserter++ = 0;
+             if (form == DW_FORM_string)
+               {
+                 std::copy (str.begin (), str.end (), inserter);
+                 *inserter++ = 0;
+               }
+             else
+               {
+                 assert (form == DW_FORM_strp);
+
+                 // xxx dwarf_64
+                 str_backpatch.push_back
+                   (std::make_pair (gap (appender, 4),
+                                    debug_str.add (str)));
+               }
            }
          else if (vs == dwarf::VS_source_file
                   && form == DW_FORM_udata)
@@ -486,12 +497,9 @@ dwarf_output::recursively_dump (section_appender &appender,
        case dwarf::VS_reference:
          {
            assert (form == DW_FORM_ref_addr);
-           // Emit zero, patch later.
            // XXX dwarf64
-           unsigned char *ptr = appender.alloc (4);
-           ::dw_write<4> (ptr, 0);
-           backpatch.push_back
-             (std::make_pair (std::make_pair (ptr, 4),
+           die_backpatch.push_back
+             (std::make_pair (gap (appender, 4),
                               value.reference ()->offset ()));
          }
          break;
@@ -517,8 +525,7 @@ dwarf_output::recursively_dump (section_appender &appender,
     {
       for (compile_unit::children_type::const_iterator jt
             = die.children ().begin (); jt != die.children ().end (); ++jt)
-       recursively_dump (appender, c, *jt, level + 1, addr_64,
-                         die_off, backpatch);
+       dump (*jt, level + 1);
       *inserter++ = 0;
     }
 }
@@ -526,6 +533,8 @@ dwarf_output::recursively_dump (section_appender &appender,
 void
 dwarf_output::output_debug_info (section_appender &appender,
                                 dwarf_output_collector &c,
+                                strtab &debug_str,
+                                str_backpatch_vec &str_backpatch,
                                 bool addr_64)
 {
   /* We request appender directly, because we depend on .alloc method
@@ -563,20 +572,15 @@ dwarf_output::output_debug_info (section_appender &appender,
       *inserter++ = addr_64 ? 8 : 4;
 
       die_off_map die_off;
-      backpatch_vec backpatch;
+      die_backpatch_vec die_backpatch;
 
       //std::cout << "UNIT " << it->_m_cu_die << std::endl;
-      recursively_dump (appender, c, *it->_m_cu_die, 0, addr_64,
-                       die_off, backpatch);
+      recursive_dumper (c, appender, debug_str, addr_64,
+                       die_off, die_backpatch, str_backpatch)
+       .dump (*it->_m_cu_die, 0);
 
-      /* Do the back-patching.  */
-      for (backpatch_vec::const_iterator bt = backpatch.begin ();
-          bt != backpatch.end (); ++bt)
-       {
-         die_off_map::const_iterator ot = die_off.find (bt->second);
-         assert (ot != die_off.end ());
-         ::dw_write_var (bt->first.first, bt->first.second, ot->second);
-       }
+      std::for_each (die_backpatch.begin (), die_backpatch.end (),
+                    backpatch_die_ref (die_off));
 
       /* Back-patch length.  */
       size_t length = appender.size () - cu_start - 4; // -4 for length info. XXX dwarf64
index 535447c38f12851ab7c9a74bcc3dac415b0bda68..1fb1436e1b71c1433af6ffb6149518a1c038a703 100644 (file)
@@ -148,7 +148,7 @@ ranlib_LDADD = libar.a $(libelf) $(libeu) $(libmudflap)
 strings_LDADD = $(libelf) $(libeu) $(libmudflap)
 ar_LDADD = libar.a $(libelf) $(libeu) $(libmudflap)
 unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libmudflap) -ldl
-dwarfcmp_LDADD = $(libdwpp) $(libmudflap) -ldl
+dwarfcmp_LDADD = $(libdwpp) $(libmudflap) $(libebl) -ldl
 writer_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) $(libdwpp) -ldl
 dwarflint_LDADD  = $(libebl) $(libelf) $(libdwpp) $(libeu) $(libmudflap) -ldl
 
index 100d2339af370322aca33e335d8731fd5835d131..cb84b4f60376d5a26bbeb1a4725b8b7980499ab5 100644 (file)
@@ -501,6 +501,7 @@ handle_elf (Elf *elf, size_t alloc_unit,
 
   bool addr_64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
   elfutils::strtab debug_strtab (false);
+  elfutils::dwarf_output::str_backpatch_vec str_backpatch;
 
   for (size_t i = 0; debug_sections[i] != NULL; ++i)
     {
@@ -517,7 +518,9 @@ handle_elf (Elf *elf, size_t alloc_unit,
       if (i == si_abbrev)
        dwout.output_debug_abbrev (appender, collector, addr_64);
       else if (i == si_info)
-       dwout.output_debug_info (appender, collector, addr_64);
+       dwout.output_debug_info (appender, collector,
+                                debug_strtab, str_backpatch,
+                                addr_64);
       // xxx
 
       /* We have to set the section size.  */
@@ -534,6 +537,9 @@ handle_elf (Elf *elf, size_t alloc_unit,
     data_info.shdr.sh_size = debug_strtab.finalize (data_info.newscn)->d_size;
 
     shdr_info.push_back (data_info);
+
+    std::for_each (str_backpatch.begin (), str_backpatch.end (),
+                  elfutils::dwarf_output::backpatch_strp ());
   }
 
   // .shstrtab
index 8f4ffe25d075ab516abb0af4ac0bd74e2042bbbb..c7e56a1d087775af6209017364ce9a1543f6409c 100644 (file)
@@ -196,10 +196,10 @@ endif !STANDALONE
 libdwpp = ../libdw/libdwpp.a $(libdw)
 
 dwarf_print_SOURCES = dwarf-print.cc ../src/dwarfstrings.c
-dwarf_print_LDADD = $(libdwpp) $(libmudflap) -ldl
+dwarf_print_LDADD = $(libdwpp) $(libmudflap) $(libebl) -ldl
 
 dwarf_edit_SOURCES = dwarf_edit.cc ../src/dwarfstrings.c
-dwarf_edit_LDADD = $(libdwpp) $(libmudflap) -ldl
+dwarf_edit_LDADD = $(libdwpp) $(libmudflap) $(libebl) -ldl
 
 arextract_LDADD = $(libelf) $(libmudflap)
 arsymtest_LDADD = $(libelf) $(libmudflap)