libdw: Add GNU DebugFission attributes, tags, forms and operands.
authorMark Wielaard <mark@klomp.org>
Mon, 14 May 2018 15:18:11 +0000 (17:18 +0200)
committerMark Wielaard <mark@klomp.org>
Sat, 19 May 2018 10:46:19 +0000 (12:46 +0200)
Most are handled just like their DWARF5 counterparts.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/dwarf.h
libdw/dwarf_formaddr.c
libdw/dwarf_formstring.c
libdw/dwarf_formudata.c
libdw/dwarf_getlocation.c
libdw/libdw_form.c
src/ChangeLog
src/readelf.c

index 42777b5..e41e5c8 100644 (file)
@@ -1,3 +1,23 @@
+2018-05-14  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf.h: Add GNU Debug Fission extensions. DW_AT_GNU_dwo_name,
+       DW_AT_GNU_dwo_id, DW_AT_GNU_ranges_base, DW_AT_GNU_addr_base,
+       DW_AT_GNU_pubnames, DW_AT_GNU_pubtypes. DW_FORM_GNU_addr_index,
+       DW_FORM_GNU_str_index. DW_OP_GNU_addr_index, DW_OP_GNU_const_index.
+       * dwarf_formaddr.c (dwarf_formaddr): Handle DW_FORM_GNU_addr_index
+       as DW_FORM_addrx.
+       (__libdw_cu_addr_base): Check for both DW_AT_GNU_addr_base and
+       DW_AT_addr_base.
+       * dwarf_formstring.c (dwarf_formstring): Handle DW_FORM_GNU_str_index
+       as DW_FORM_strx.
+       * dwarf_formudata.c (dwarf_formudata): Recognize DW_AT_GNU_addr_base
+       as addrptr. Recognize DW_AT_GNU_ranges_base as rangelistptr.
+       * dwarf_getlocation.c (__libdw_intern_expression): Handle
+       DW_OP_GNU_addr_index as DW_OP_addrx and DW_OP_GNU_const_index as
+       DW_OP_constx.
+       * libdw_form.c (__libdw_form_val_compute_len): Handle
+       DW_FORM_GNU_addr_index and DW_FORM_GNU_str_index taking an uleb128.
+
 2018-05-12  Mark Wielaard  <mark@klomp.org>
 
        * dwarf_begin_elf.c (check_section): Also recognize .dwo section
index fc9801b..c438399 100644 (file)
@@ -343,6 +343,13 @@ enum
     DW_AT_GNU_entry_view = 0x2138,
     DW_AT_GNU_macros = 0x2119,
     DW_AT_GNU_deleted = 0x211a,
+    /* GNU Debug Fission extensions.  */
+    DW_AT_GNU_dwo_name = 0x2130,
+    DW_AT_GNU_dwo_id = 0x2131,
+    DW_AT_GNU_ranges_base = 0x2132,
+    DW_AT_GNU_addr_base = 0x2133,
+    DW_AT_GNU_pubnames = 0x2134,
+    DW_AT_GNU_pubtypes = 0x2135,
 
     DW_AT_hi_user = 0x3fff
   };
@@ -404,6 +411,10 @@ enum
     DW_FORM_addrx3 = 0x2b,
     DW_FORM_addrx4 = 0x2c,
 
+    /* GNU Debug Fission extensions.  */
+    DW_FORM_GNU_addr_index = 0x1f01,
+    DW_FORM_GNU_str_index = 0x1f02,
+
     DW_FORM_GNU_ref_alt = 0x1f20, /* offset in alternate .debuginfo.  */
     DW_FORM_GNU_strp_alt = 0x1f21 /* offset in alternate .debug_str. */
   };
@@ -590,6 +601,11 @@ enum
     DW_OP_GNU_convert = 0xf7,
     DW_OP_GNU_reinterpret = 0xf9,
     DW_OP_GNU_parameter_ref = 0xfa,
+
+    /* GNU Debug Fission extensions.  */
+    DW_OP_GNU_addr_index = 0xfb,
+    DW_OP_GNU_const_index = 0xfc,
+
     DW_OP_GNU_variable_value = 0xfd,
 
     DW_OP_lo_user = 0xe0,      /* Implementation-defined range start.  */
index 25e6970..c917dea 100644 (file)
@@ -56,6 +56,7 @@ dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
 
       /* All others encode an index into the .debug_addr section where
         the address can be found.  */
+      case DW_FORM_GNU_addr_index:
       case DW_FORM_addrx:
        if (datap >= endp)
          {
@@ -142,7 +143,8 @@ Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu)
     {
       Dwarf_Die cu_die = CUDIE(cu);
       Dwarf_Attribute attr;
-      if (dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
+      if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
+         || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
        {
          Dwarf_Word off;
          if (dwarf_formudata (&attr, &off) == 0)
index 251784d..c3e892a 100644 (file)
@@ -1,5 +1,5 @@
 /* Return string associated with given attribute.
-   Copyright (C) 2003-2010, 2013, 2018 Red Hat, Inc.
+   Copyright (C) 2003-2010, 2013, 2017, 2018 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -94,6 +94,7 @@ dwarf_formstring (Dwarf_Attribute *attrp)
       switch (attrp->form)
        {
        case DW_FORM_strx:
+       case DW_FORM_GNU_str_index:
          if (datap >= endp)
            {
            invalid:
index 62352ee..19d34f8 100644 (file)
@@ -168,6 +168,7 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
 
            case DW_AT_ranges:
            case DW_AT_start_scope:
+           case DW_AT_GNU_ranges_base:
              /* rangelistptr */
              if (__libdw_formptr (attr, IDX_debug_ranges,
                                   DWARF_E_NO_DEBUG_RANGES, NULL,
@@ -184,6 +185,7 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
              break;
 
            case DW_AT_addr_base:
+           case DW_AT_GNU_addr_base:
              /* addrptr */
              if (__libdw_formptr (attr, IDX_debug_addr,
                                   DWARF_E_NO_DEBUG_ADDR, NULL,
index f577675..116fa71 100644 (file)
@@ -456,7 +456,9 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
        case DW_OP_reinterpret:
        case DW_OP_GNU_reinterpret:
        case DW_OP_addrx:
+       case DW_OP_GNU_addr_index:
        case DW_OP_constx:
+       case DW_OP_GNU_const_index:
          get_uleb128 (newloc->number, data, end_data);
          break;
 
index ebe6002..584c846 100644 (file)
@@ -109,6 +109,8 @@ __libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form,
     case DW_FORM_loclistx:
     case DW_FORM_rnglistx:
     case DW_FORM_strx:
+    case DW_FORM_GNU_addr_index:
+    case DW_FORM_GNU_str_index:
       get_uleb128 (u128, valp, endp);
       result = valp - startp;
       break;
index bf07a79..4f08312 100644 (file)
@@ -1,3 +1,12 @@
+2018-05-14  Mark Wielaard  <mark@klomp.org>
+
+       * readelf.c (print_ops): Handle DW_OP_GNU_addr_index and
+       DW_OP_GNU_const_index.
+       (attr_callback): Handle DW_FORM_GNU_addr_index as DW_FORM_addrx.
+       Handle DW_FORM_GNU_str_index as DW_FORM_constx. Add as_hex_id.
+       Handle DW_AT_GNU_dwo_id as_hex_id.
+       (print_form_data): Handle DW_FORM_GNU_str_index as DW_FORM_strx.
+
 2018-05-12  Mark Wielaard  <mark@klomp.org>
 
        * readelf.c (print_debug): Also recognize .dwo section name variants.
index f34dd36..6d503c7 100644 (file)
@@ -4341,7 +4341,9 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
        case DW_OP_plus_uconst:
        case DW_OP_constu:
        case DW_OP_addrx:
-       case DW_OP_constx:;
+       case DW_OP_GNU_addr_index:
+       case DW_OP_constx:
+       case DW_OP_GNU_const_index:;
          const unsigned char *start = data;
          uint64_t uleb;
          NEED (1);
@@ -6115,6 +6117,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
     case DW_FORM_addrx2:
     case DW_FORM_addrx3:
     case DW_FORM_addrx4:
+    case DW_FORM_GNU_addr_index:
       if (!cbargs->silent)
        {
          Dwarf_Addr addr;
@@ -6151,6 +6154,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
     case DW_FORM_strx4:
     case DW_FORM_string:
     case DW_FORM_GNU_strp_alt:
+    case DW_FORM_GNU_str_index:
       if (cbargs->silent)
        break;
       const char *str = dwarf_formstring (attrp);
@@ -6203,6 +6207,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
        goto attrval_out;
 
       const char *valuestr = NULL;
+      bool as_hex_id = false;
       switch (attr)
        {
          /* This case can take either a constant or a loclistptr.  */
@@ -6330,6 +6335,10 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
              valuestr = "???";
          }
          break;
+       case DW_AT_GNU_dwo_id:
+         as_hex_id = true;
+         break;
+
        default:
          /* Nothing.  */
          break;
@@ -6357,7 +6366,13 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
            if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
              goto attrval_out;
 
-         if (valuestr == NULL)
+         if (as_hex_id)
+           {
+             printf ("           %*s%-20s (%s) 0x%.16" PRIx64 "\n",
+                     (int) (level * 2), "", dwarf_attr_name (attr),
+                     dwarf_form_name (form), num);
+           }
+         else if (valuestr == NULL)
            {
              printf ("           %*s%-20s (%s)",
                      (int) (level * 2), "", dwarf_attr_name (attr),
@@ -6940,6 +6955,7 @@ print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
       break;
 
     case DW_FORM_strx:
+    case DW_FORM_GNU_str_index:
       if (readendp - readp < 1)
        goto invalid_data;
       get_uleb128 (val, readp, readendp);