Display more information when decoding DW_AT_endianity, DW_AT_decimal_sign, DW_AT_def...
authorNick Clifton <nickc@redhat.com>
Wed, 11 Oct 2017 11:02:51 +0000 (12:02 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 11 Oct 2017 11:02:51 +0000 (12:02 +0100)
* dwarf.c (read_and_display_attr_value): Handle DW_AT_endianity,
DW_END_default, DW_END_big, DW_END_little, DW_ATE_UCS,
DW_ATE_ASCII, DW_CC_pass_by_reference, DW_CC_pass_by_value,
DW_CC_GNU_renesas_sh, DW_CC_GNU_borland_fastcall_i386,
DW_AT_decimal_sign, DW_AT_defaulted, DW_AT_discr_list.
(get_TAG_name): Report user generated tag values.
* testsuite/binutils-all/dwarf-attributes.S: New test.
* testsuite/binutils-all/dwarf-attributes.W. Expected output from
readelf.
* testsuite/binutils-all/readelf.exp: Run the new test.

binutils/ChangeLog
binutils/dwarf.c
binutils/testsuite/binutils-all/dwarf-attributes.S [new file with mode: 0644]
binutils/testsuite/binutils-all/dwarf-attributes.W [new file with mode: 0644]
binutils/testsuite/binutils-all/readelf.exp

index 25be68a69ca8b2614d65f7ea2dd15cf3b6b5a1fa..c01d4f31486698b60410bb539d6dbd0a91775c7a 100644 (file)
@@ -1,3 +1,17 @@
+2017-10-11  Peeter Joot  <peeter.joot@lzlabs.com>
+       Nick Clifton  <nickc@redhat.com>
+
+       * dwarf.c (read_and_display_attr_value): Handle DW_AT_endianity,
+       DW_END_default, DW_END_big, DW_END_little, DW_ATE_UCS,
+       DW_ATE_ASCII, DW_CC_pass_by_reference, DW_CC_pass_by_value,
+       DW_CC_GNU_renesas_sh, DW_CC_GNU_borland_fastcall_i386,
+       DW_AT_decimal_sign, DW_AT_defaulted, DW_AT_discr_list.
+       (get_TAG_name): Report user generated tag values.
+       * testsuite/binutils-all/dwarf-attributes.S: New test.
+       * testsuite/binutils-all/dwarf-attributes.W. Expected output from
+       readelf.
+       * testsuite/binutils-all/readelf.exp: Run the new test.
+
 2017-10-10  Tom Tromey  <tom@tromey.com>
 
        * dwarf-mode.el: Bump to version 1.4.
index 2506d533b690ebfc001df24238a8fae695dbbfa2..06702ef42dd96d7b69fc26a59045f6118e08cc2d 100644 (file)
@@ -963,13 +963,16 @@ process_abbrev_section (unsigned char *start, unsigned char *end)
 static const char *
 get_TAG_name (unsigned long tag)
 {
-  const char *name = get_DW_TAG_name ((unsigned int)tag);
+  const char *name = get_DW_TAG_name ((unsigned int) tag);
 
   if (name == NULL)
     {
       static char buffer[100];
 
-      snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %lx"), tag);
+      if (tag >= DW_TAG_lo_user && tag <= DW_TAG_hi_user)
+       snprintf (buffer, sizeof (buffer), _("User TAG value: %#lx"), tag);
+      else
+       snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %#lx"), tag);
       return buffer;
     }
 
@@ -2238,6 +2241,12 @@ read_and_display_attr_value (unsigned long attribute,
        case DW_ATE_edited:             printf ("(edited)"); break;
        case DW_ATE_signed_fixed:       printf ("(signed_fixed)"); break;
        case DW_ATE_unsigned_fixed:     printf ("(unsigned_fixed)"); break;
+         /* DWARF 4 values:  */
+       case DW_ATE_UTF:                printf ("(unicode string)"); break;
+         /* DWARF 5 values:  */
+       case DW_ATE_UCS:                printf ("(UCS)"); break;
+       case DW_ATE_ASCII:              printf ("(ASCII)"); break;
+
          /* HP extensions:  */
        case DW_ATE_HP_float80:         printf ("(HP_float80)"); break;
        case DW_ATE_HP_complex_float80: printf ("(HP_complex_float80)"); break;
@@ -2246,8 +2255,6 @@ read_and_display_attr_value (unsigned long attribute,
        case DW_ATE_HP_floathpintel:    printf ("(HP_floathpintel)"); break;
        case DW_ATE_HP_imaginary_float80:       printf ("(HP_imaginary_float80)"); break;
        case DW_ATE_HP_imaginary_float128:      printf ("(HP_imaginary_float128)"); break;
-         /* DWARF 4 values:  */
-       case DW_ATE_UTF:                printf ("(unicode string)"); break;
 
        default:
          if (uvalue >= DW_ATE_lo_user
@@ -2283,6 +2290,22 @@ read_and_display_attr_value (unsigned long attribute,
        }
       break;
 
+    case DW_AT_endianity:
+      printf ("\t");
+      switch (uvalue)
+       {
+       case DW_END_default:            printf ("(default)"); break;
+       case DW_END_big:                printf ("(big)"); break;
+       case DW_END_little:             printf ("(little)"); break;
+       default:
+         if (uvalue >= DW_END_lo_user && uvalue <= DW_END_hi_user)
+           printf (_("(user specified)"));
+         else
+           printf (_("(unknown endianity)"));
+         break;
+       }
+      break;
+
     case DW_AT_virtuality:
       printf ("\t");
       switch (uvalue)
@@ -2313,6 +2336,10 @@ read_and_display_attr_value (unsigned long attribute,
        case DW_CC_normal:      printf ("(normal)"); break;
        case DW_CC_program:     printf ("(program)"); break;
        case DW_CC_nocall:      printf ("(nocall)"); break;
+       case DW_CC_pass_by_reference: printf ("(pass by ref)"); break;
+       case DW_CC_pass_by_value: printf ("(pass by value)"); break;
+       case DW_CC_GNU_renesas_sh: printf ("(Rensas SH)"); break;
+       case DW_CC_GNU_borland_fastcall_i386: printf ("(Borland fastcall i386)"); break;
        default:
          if (uvalue >= DW_CC_lo_user
              && uvalue <= DW_CC_hi_user)
@@ -2326,12 +2353,47 @@ read_and_display_attr_value (unsigned long attribute,
       printf ("\t");
       switch (uvalue)
        {
+       case 255:
        case -1: printf (_("(undefined)")); break;
        case 0:  printf ("(row major)"); break;
        case 1:  printf ("(column major)"); break;
        }
       break;
 
+    case DW_AT_decimal_sign:
+      printf ("\t");
+      switch (uvalue)
+       {
+       case DW_DS_unsigned:            printf (_("(unsigned)")); break;
+       case DW_DS_leading_overpunch:   printf (_("(leading overpunch)")); break;
+       case DW_DS_trailing_overpunch:  printf (_("(trailing overpunch)")); break;
+       case DW_DS_leading_separate:    printf (_("(leading separate)")); break;
+       case DW_DS_trailing_separate:   printf (_("(trailing separate)")); break;
+       default:                        printf (_("(unrecognised)")); break;
+       }
+      break;
+
+    case DW_AT_defaulted:
+      printf ("\t");
+      switch (uvalue)
+       {
+       case DW_DEFAULTED_no:           printf (_("(no)")); break;
+       case DW_DEFAULTED_in_class:     printf (_("(in class)")); break;
+       case DW_DEFAULTED_out_of_class: printf (_("(out of class)")); break;
+       default:                        printf (_("(unrecognised)")); break;
+       }
+      break;
+
+    case DW_AT_discr_list:
+      printf ("\t");
+      switch (uvalue)
+       {
+       case DW_DSC_label:  printf (_("(label)")); break;
+       case DW_DSC_range:  printf (_("(range)")); break;
+       default:            printf (_("(unrecognised)")); break;
+       }
+      break;
+      
     case DW_AT_frame_base:
       have_frame_base = 1;
       /* Fall through.  */
diff --git a/binutils/testsuite/binutils-all/dwarf-attributes.S b/binutils/testsuite/binutils-all/dwarf-attributes.S
new file mode 100644 (file)
index 0000000..1d88a7c
--- /dev/null
@@ -0,0 +1,133 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+/* This file is intended to check the encoding and decoding of DWARF attributes.
+   Currently only numeric attributes are tested, but this file should be extended
+   to cover other types of attribute as well.  */
+       
+       .file   "dwarf-attributes.S"
+
+       .section        .debug_info,"",%progbits
+       .4byte  .Ldebug_info_end - .Ldebug_info_start   /* Length of Compilation Unit Info.  */
+
+.Ldebug_info_start:
+       .2byte   0x5    /* DWARF version number.  */
+       .byte    0x1    /* DW_UT_compile.  */
+       .byte    0x4    /* Pointer Size (in bytes).  */
+       .4byte   .Ldebug_abbrevs /* Offset Into Abbrev. Section.  */
+
+       /* Start of DIE 0xc.  */
+
+       .uleb128 0x1    /* Using abbrev #1 */
+       .byte  1        /* Ordering: column major.  */
+       .2byte 1        /* Language: C89.  */
+       .byte  1        /* Visibility: local.  */
+       .byte  1        /* Inline: inlined.  */
+       .byte  1        /* Accessibility: public.  */
+       .byte  1        /* Calling convention: normal.  */
+       .byte  1        /* Discriminate list: range.  */
+       .byte  1        /* Encoding: address.  */
+       .byte  1        /* Identifier case: up.  */
+       .byte  1        /* Virtuality: virtual.  */
+       .byte  1        /* Decimal sign: unsigned.  */
+       .byte  1        /* Endianity: big.  */
+       .byte  1        /* Defaulted: in class.  */
+       
+       .uleb128 0x1    /* Using abbrev #1 */
+       .byte  0        /* Ordering: row major */
+       .2byte 0x0016   /* Language: Go.  */
+       .byte  2        /* Visibility: exported.  */
+       .byte  0        /* Inline: not.  */
+       .byte  2        /* Accessibility: protected.  */
+       .byte  5        /* Calling convention: pass by value.  */
+       .byte  0        /* Discriminate list: label.  */
+       .byte  0x12     /* Encoding: ASCII.  */
+       .byte  0        /* Identifier case: sensitive.  */
+       .byte  0        /* Virtuality: none.  */
+       .byte  2        /* Decimal sign: leading overpunch.  */
+       .byte  0        /* Endianity: default.  */
+       .byte  0        /* Defaulted: no.  */
+
+       .uleb128 0x1    /* Using abbrev #1 */
+       .byte  -1       /* Ordering: undefined.  */
+       .2byte 0x8001   /* Language: MIPS Assembler.  */
+       .byte  3        /* Visibility: qualified.  */
+       .byte  3        /* Inline: declared.  */
+       .byte  3        /* Accessibility: private.  */
+       .byte  0x40     /* Calling convention: Renesas SH.  */
+       .byte  1        /* Discriminate list: range.  */
+       .byte  0x81     /* Encoding: user specified.  */
+       .byte  3        /* Identifier case: insensitive.  */
+       .byte  2        /* Virtuality: pure.  */
+       .byte  5        /* Decimal sign: trailing separate.  */
+       .byte  0x50     /* Endianity: user specified.  */
+       .byte  2        /* Defaulted: out of class.  */
+       
+       .byte   0       /* End of children of DIE 0xc.  */
+.Ldebug_info_end:
+
+
+       .section        .debug_abbrev,"",%progbits
+.Ldebug_abbrevs:
+       .uleb128 0x1    /* (abbrev code) */
+       .uleb128 0x5555 /* (TAG: DW_TAG_lo_user + 0x1555) */
+       .byte   0       /* DW_children_no */
+
+       /* Attributes to be tested.  Sorted by attribute value.  */
+       
+       .uleb128 0x9    /* (DW_AT_ordering) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x13   /* (DW_AT_language) */
+       .uleb128 0x05   /* (DW_FORM_data2) */
+
+       .uleb128 0x17   /* (DW_AT_visibility) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x20   /* (DW_AT_inline) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x32   /* (DW_AT_accessibility) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x36   /* (DW_AT_calling_convention) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x3d   /* (DW_AT_discr_lists) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x3e   /* (DW_AT_encoding) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+
+       .uleb128 0x42   /* (DW_AT_identifier_case) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x4c   /* (DW_AT_virtuality) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x5e   /* (DW_AT_decimal_sign) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x65   /* (DW_AT_endianity) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */
+       
+       .uleb128 0x8b   /* (DW_AT_defaulted) */
+       .uleb128 0x0b   /* (DW_FORM_data1) */   
+
+       .byte   0       /* End of abbreviation.  */
+       .byte   0
+
+       .byte   0       /* End of abbreviations.  */
diff --git a/binutils/testsuite/binutils-all/dwarf-attributes.W b/binutils/testsuite/binutils-all/dwarf-attributes.W
new file mode 100644 (file)
index 0000000..d10e0c6
--- /dev/null
@@ -0,0 +1,49 @@
+Contents of the .debug_info section:
+
+  Compilation Unit @ offset 0x0:
+   Length:        0x36 \(32-bit\)
+   Version:       5
+   Abbrev Offset: 0x0
+   Pointer Size:  4
+ <0><c>: Abbrev Number: 1 \(User TAG value: 0x5555\)
+    <d>   DW_AT_ordering    : 1        \(column major\)
+    <e>   DW_AT_language    : 1        \(ANSI C\)
+    <10>   DW_AT_visibility  : 1       \(local\)
+    <11>   DW_AT_inline      : 1       \(inlined\)
+    <12>   DW_AT_accessibility: 1      \(public\)
+    <13>   DW_AT_calling_convention: 1 \(normal\)
+    <14>   DW_AT_discr_list  : 1       \(range\)
+    <15>   DW_AT_encoding    : 1       \(machine address\)
+    <16>   DW_AT_identifier_case: 1    \(up_case\)
+    <17>   DW_AT_virtuality  : 1       \(virtual\)
+    <18>   DW_AT_decimal_sign: 1       \(unsigned\)
+    <19>   DW_AT_endianity   : 1       \(big\)
+    <1a>   DW_AT_defaulted   : 1       \(in class\)
+ <0><1b>: Abbrev Number: 1 \(User TAG value: 0x5555\)
+    <1c>   DW_AT_ordering    : 0       \(row major\)
+    <1d>   DW_AT_language    : 22      \(Go\)
+    <1f>   DW_AT_visibility  : 2       \(exported\)
+    <20>   DW_AT_inline      : 0       \(not inlined\)
+    <21>   DW_AT_accessibility: 2      \(protected\)
+    <22>   DW_AT_calling_convention: 5 \(pass by value\)
+    <23>   DW_AT_discr_list  : 0       \(label\)
+    <24>   DW_AT_encoding    : 18      \(ASCII\)
+    <25>   DW_AT_identifier_case: 0    \(case_sensitive\)
+    <26>   DW_AT_virtuality  : 0       \(none\)
+    <27>   DW_AT_decimal_sign: 2       \(leading overpunch\)
+    <28>   DW_AT_endianity   : 0       \(default\)
+    <29>   DW_AT_defaulted   : 0       \(no\)
+ <0><2a>: Abbrev Number: 1 \(User TAG value: 0x5555\)
+    <2b>   DW_AT_ordering    : 255     \(undefined\)
+    <2c>   DW_AT_language    : 32769   \(MIPS assembler\)
+    <2e>   DW_AT_visibility  : 3       \(qualified\)
+    <2f>   DW_AT_inline      : 3       \(declared as inline and inlined\)
+    <30>   DW_AT_accessibility: 3      \(private\)
+    <31>   DW_AT_calling_convention: 64        \(Rensas SH\)
+    <32>   DW_AT_discr_list  : 1       \(range\)
+    <33>   DW_AT_encoding    : 129     \(HP_complex_float80\)
+    <34>   DW_AT_identifier_case: 3    \(case_insensitive\)
+    <35>   DW_AT_virtuality  : 2       \(pure_virtual\)
+    <36>   DW_AT_decimal_sign: 5       \(trailing separate\)
+    <37>   DW_AT_endianity   : 80      \(user specified\)
+    <38>   DW_AT_defaulted   : 2       \(out of class\)
index 81d180922539247893972b97d60569c76fd06d31..10fd8d8da7feb4595576a55f49db0d3d5c05dfca 100644 (file)
@@ -420,14 +420,15 @@ if {![binutils_assemble $srcdir/$subdir/z.s tmpdir/z.o]} then {
     readelf_test {--decompress --hex-dump .debug_loc} $tempfile readelf.z  {}
 }
 
-# Skip the next test for the RISCV architectures because they do not
-# support .ULEB128 pseudo-ops with non-constant values.
+# Skip the next test for the RISCV architectures because they
+# do not support .ULEB128 pseudo-ops with non-constant values.
 if ![istarget "riscv*-*-*"] then {
 
     set hpux ""
     if [istarget "hppa*64*-*-hpux*"] {
        set hpux "--defsym HPUX=1"
     }
+
     # Assemble the DWARF-5 test file.
     if {![binutils_assemble_flags $srcdir/$subdir/dw5.S tmpdir/dw5.o $hpux]} then {
        unresolved "readelf -wiaoRlL dw5 (failed to assemble)"
@@ -447,3 +448,21 @@ if ![istarget "riscv*-*-*"] then {
        readelf_test -wiaoRlL $tempfile dw5.W { nds32*-elf }
     }
 }
+
+# Assemble the DWARF-5 attributes test file.
+if {![binutils_assemble_flags $srcdir/$subdir/dwarf-attributes.S tmpdir/dwarf-attributes.o ""]} then {
+    unresolved "readelf -wi dwarf-attributes (failed to assemble)"
+} else {
+    # Download it.
+    if ![is_remote host] {
+       set tempfile tmpdir/dwarf-attributes.o
+    } else {
+       set tempfile [remote_download host tmpdir/dwarf-attributes.o]
+    }
+
+    # First, determine the size, so specific output matchers can be used.
+    readelf_find_size $tempfile
+
+    # Make sure that readelf can decode the contents.
+    readelf_test -wi $tempfile dwarf-attributes.W {}
+}