Use startswith more for strncmp function calls.
[binutils-gdb.git] / binutils / dwarf.c
index 3cbd19710d78bbe3725f485d0defa2fdaa74be88..293d33ec9acb849d34e7f74b0b465e06b1320194 100644 (file)
@@ -21,7 +21,7 @@
 #include "sysdep.h"
 #include "libiberty.h"
 #include "bfd.h"
-#include "bfd_stdint.h"
+#include <stdint.h>
 #include "bucomm.h"
 #include "elfcomm.h"
 #include "elf/common.h"
 #include <elfutils/debuginfod.h>
 #endif
 
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
 #undef MAX
 #undef MIN
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
@@ -71,8 +78,8 @@ typedef struct dwo_info
   struct dwo_info * next;
 } dwo_info;
 
-static dwo_info *   first_dwo_info = NULL;
-static bfd_boolean  need_dwo_info;
+static dwo_info *first_dwo_info = NULL;
+static bool need_dwo_info;
 
 separate_info * first_separate_info = NULL;
 
@@ -99,8 +106,8 @@ int do_debug_addr;
 int do_debug_cu_index;
 int do_wide;
 int do_debug_links;
-int do_follow_links;
-bfd_boolean do_checks;
+int do_follow_links = DEFAULT_FOR_FOLLOW_LINKS;
+bool do_checks;
 
 int dwarf_cutoff_level = -1;
 unsigned long dwarf_start_die;
@@ -138,13 +145,13 @@ static int tu_count = 0;
 static struct cu_tu_set *cu_sets = NULL;
 static struct cu_tu_set *tu_sets = NULL;
 
-static bfd_boolean load_cu_tu_indexes (void *);
+static bool load_cu_tu_indexes (void *);
 
 /* An array that indicates for a given level of CU nesting whether
    the latest DW_AT_type seen for that level was a signed type or
    an unsigned type.  */
 #define MAX_CU_NESTING (1 << 8)
-static bfd_boolean level_type_signed[MAX_CU_NESTING];
+static bool level_type_signed[MAX_CU_NESTING];
 
 /* Values for do_debug_lines.  */
 #define FLAG_DEBUG_LINES_RAW    1
@@ -326,7 +333,7 @@ dwarf_vmatoa64 (dwarf_vma hvalue, dwarf_vma lvalue, char *buf,
 /* Read in a LEB128 encoded value starting at address DATA.
    If SIGN is true, return a signed LEB128 value.
    If LENGTH_RETURN is not NULL, return in it the number of bytes read.
-   If STATUS_RETURN in not NULL, return with bit 0 (LSB) set if the
+   If STATUS_RETURN is not NULL, return with bit 0 (LSB) set if the
    terminating byte was not found and with bit 1 set if the value
    overflows a dwarf_vma.
    No bytes will be read at address END or beyond.  */
@@ -334,7 +341,7 @@ dwarf_vmatoa64 (dwarf_vma hvalue, dwarf_vma lvalue, char *buf,
 dwarf_vma
 read_leb128 (unsigned char *data,
             const unsigned char *const end,
-            bfd_boolean sign,
+            bool sign,
             unsigned int *length_return,
             int *status_return)
 {
@@ -346,37 +353,31 @@ read_leb128 (unsigned char *data,
   while (data < end)
     {
       unsigned char byte = *data++;
-      bfd_boolean cont = (byte & 0x80) ? TRUE : FALSE;
+      unsigned char lost, mask;
 
-      byte &= 0x7f;
       num_read++;
 
-      if (shift < sizeof (result) * 8)
+      if (shift < CHAR_BIT * sizeof (result))
        {
-         result |= ((dwarf_vma) byte) << shift;
-         if (sign)
-           {
-             if ((((dwarf_signed_vma) result >> shift) & 0x7f) != byte)
-               /* Overflow.  */
-               status |= 2;
-           }
-         else if ((result >> shift) != byte)
-           {
-             /* Overflow.  */
-             status |= 2;
-           }
-
+         result |= ((dwarf_vma) (byte & 0x7f)) << shift;
+         /* These bits overflowed.  */
+         lost = byte ^ (result >> shift);
+         /* And this is the mask of possible overflow bits.  */
+         mask = 0x7f ^ ((dwarf_vma) 0x7f << shift >> shift);
          shift += 7;
        }
-      else if (byte != 0)
+      else
        {
-         status |= 2;
+         lost = byte;
+         mask = 0x7f;
        }
+      if ((lost & mask) != (sign && (dwarf_signed_vma) result < 0 ? mask : 0))
+       status |= 2;
 
-      if (!cont)
+      if ((byte & 0x80) == 0)
        {
          status &= ~1;
-         if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+         if (sign && shift < CHAR_BIT * sizeof (result) && (byte & 0x40))
            result |= -((dwarf_vma) 1 << shift);
          break;
        }
@@ -689,7 +690,7 @@ fetch_indirect_string (dwarf_vma offset)
 
   if (offset >= section->size)
     {
-      warn (_("DW_FORM_strp offset too big: %s\n"),
+      warn (_("DW_FORM_strp offset too big: 0x%s\n"),
            dwarf_vmatoa ("x", offset));
       return (const unsigned char *) _("<offset is too big>");
     }
@@ -717,7 +718,7 @@ fetch_indirect_line_string (dwarf_vma offset)
 
   if (offset >= section->size)
     {
-      warn (_("DW_FORM_line_strp offset too big: %s\n"),
+      warn (_("DW_FORM_line_strp offset too big: 0x%s\n"),
            dwarf_vmatoa ("x", offset));
       return (const unsigned char *) _("<offset is too big>");
     }
@@ -736,7 +737,7 @@ fetch_indirect_line_string (dwarf_vma offset)
 
 static const char *
 fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
-                     dwarf_vma offset_size, bfd_boolean dwo)
+                     dwarf_vma offset_size, bool dwo)
 {
   enum dwarf_section_display_enum str_sec_idx = dwo ? str_dwo : str;
   enum dwarf_section_display_enum idx_sec_idx = dwo ? str_index_dwo : str_index;
@@ -802,7 +803,7 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
 
   if (index_offset >= length)
     {
-      warn (_("DW_FORM_GNU_str_index offset too big: %s vs %s\n"),
+      warn (_("DW_FORM_GNU_str_index offset too big: 0x%s vs 0x%s\n"),
            dwarf_vmatoa ("x", index_offset),
            dwarf_vmatoa ("x", length));
       return _("<index offset is too big>");
@@ -812,7 +813,7 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
   str_offset -= str_section->address;
   if (str_offset >= str_section->size)
     {
-      warn (_("DW_FORM_GNU_str_index indirect offset too big: %s\n"),
+      warn (_("DW_FORM_GNU_str_index indirect offset too big: 0x%s\n"),
            dwarf_vmatoa ("x", str_offset));
       return _("<indirect index offset is too big>");
     }
@@ -838,7 +839,7 @@ fetch_indexed_value (dwarf_vma offset, dwarf_vma bytes)
 
   if (offset + bytes > section->size)
     {
-      warn (_("Offset into section %s too big: %s\n"),
+      warn (_("Offset into section %s too big: 0x%s\n"),
            section->name, dwarf_vmatoa ("x", offset));
       return "<offset too big>";
     }
@@ -2001,16 +2002,27 @@ skip_attr_bytes (unsigned long          form,
     case DW_FORM_ref1:
     case DW_FORM_flag:
     case DW_FORM_data1:
+    case DW_FORM_strx1:
+    case DW_FORM_addrx1:
       SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
       break;
 
+    case DW_FORM_strx3:
+    case DW_FORM_addrx3:
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 3, end);
+      break;
+
     case DW_FORM_ref2:
     case DW_FORM_data2:
+    case DW_FORM_strx2:
+    case DW_FORM_addrx2:
       SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
       break;
 
     case DW_FORM_ref4:
     case DW_FORM_data4:
+    case DW_FORM_strx4:
+    case DW_FORM_addrx4:
       SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
       break;
 
@@ -2022,7 +2034,9 @@ skip_attr_bytes (unsigned long          form,
     case DW_FORM_ref_udata:
     case DW_FORM_udata:
     case DW_FORM_GNU_str_index:
+    case DW_FORM_strx:
     case DW_FORM_GNU_addr_index:
+    case DW_FORM_addrx:
       READ_ULEB (uvalue, data, end);
       break;
 
@@ -2130,6 +2144,10 @@ get_type_abbrev_from_form (unsigned long                 form,
        }
       break;
 
+    case DW_FORM_ref_sup4:
+    case DW_FORM_ref_sup8:
+      break;
+
     case DW_FORM_ref1:
     case DW_FORM_ref2:
     case DW_FORM_ref4:
@@ -2196,20 +2214,20 @@ get_type_abbrev_from_form (unsigned long                 form,
    found starting at DATA.  */
 
 static void
-get_type_signedness (abbrev_entry *         entry,
-                    const struct dwarf_section * section,
-                    unsigned char *        data,
-                    unsigned const char *  end,
-                    dwarf_vma              cu_offset,
-                    dwarf_vma              pointer_size,
-                    dwarf_vma              offset_size,
-                    int                    dwarf_version,
-                    bfd_boolean *          is_signed,
-                    unsigned int           nesting)
+get_type_signedness (abbrev_entry *entry,
+                    const struct dwarf_section *section,
+                    unsigned char *data,
+                    unsigned const char *end,
+                    dwarf_vma cu_offset,
+                    dwarf_vma pointer_size,
+                    dwarf_vma offset_size,
+                    int dwarf_version,
+                    bool *is_signed,
+                    unsigned int nesting)
 {
   abbrev_attr *   attr;
 
-  * is_signed = FALSE;
+  * is_signed = false;
 
 #define MAX_NESTING 20
   if (nesting > MAX_NESTING)
@@ -2277,7 +2295,7 @@ get_type_signedness (abbrev_entry *         entry,
            case DW_ATE_unsigned:
            case DW_ATE_unsigned_char:
            case DW_ATE_unsigned_fixed:
-             * is_signed = FALSE;
+             * is_signed = false;
              break;
 
            default:
@@ -2288,7 +2306,7 @@ get_type_signedness (abbrev_entry *         entry,
            case DW_ATE_imaginary_float:
            case DW_ATE_decimal_float:
            case DW_ATE_signed_fixed:
-             * is_signed = TRUE;
+             * is_signed = true;
              break;
            }
          break;
@@ -2297,10 +2315,10 @@ get_type_signedness (abbrev_entry *         entry,
 }
 
 static void
-read_and_print_leb128 (unsigned char *        data,
-                      unsigned int *         bytes_read,
-                      unsigned const char *  end,
-                      bfd_boolean            is_signed)
+read_and_print_leb128 (unsigned char *data,
+                      unsigned int *bytes_read,
+                      unsigned const char *end,
+                      bool is_signed)
 {
   int status;
   dwarf_vma val = read_leb128 (data, end, is_signed, bytes_read, &status);
@@ -2345,9 +2363,9 @@ display_discr_list (unsigned long          form,
       return;
     }
 
-  bfd_boolean is_signed =
+  bool is_signed =
     (level > 0 && level <= MAX_CU_NESTING)
-    ? level_type_signed [level - 1] : FALSE;
+    ? level_type_signed [level - 1] : false;
 
   printf ("(");
   while (uvalue)
@@ -2386,7 +2404,7 @@ display_discr_list (unsigned long          form,
 
        default:
          printf ("<corrupt>\n");
-         warn (_("corrupt discr_list - unrecognised discriminant byte %#x\n"),
+         warn (_("corrupt discr_list - unrecognized discriminant byte %#x\n"),
                discriminant);
          return;
        }
@@ -2459,6 +2477,7 @@ read_and_display_attr_value (unsigned long           attribute,
       SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
       break;
 
+    case DW_FORM_strp_sup:
     case DW_FORM_strp:
     case DW_FORM_line_strp:
     case DW_FORM_sec_offset:
@@ -2474,16 +2493,28 @@ read_and_display_attr_value (unsigned long           attribute,
     case DW_FORM_ref1:
     case DW_FORM_flag:
     case DW_FORM_data1:
+    case DW_FORM_strx1:
+    case DW_FORM_addrx1:
       SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
       break;
 
     case DW_FORM_ref2:
     case DW_FORM_data2:
+    case DW_FORM_strx2:
+    case DW_FORM_addrx2:
       SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
       break;
 
+    case DW_FORM_strx3:
+    case DW_FORM_addrx3:
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 3, end);
+      break;
+
+    case DW_FORM_ref_sup4:
     case DW_FORM_ref4:
     case DW_FORM_data4:
+    case DW_FORM_strx4:
+    case DW_FORM_addrx4:
       SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
       break;
 
@@ -2493,9 +2524,11 @@ read_and_display_attr_value (unsigned long           attribute,
       break;
 
     case DW_FORM_GNU_str_index:
+    case DW_FORM_strx:
     case DW_FORM_ref_udata:
     case DW_FORM_udata:
     case DW_FORM_GNU_addr_index:
+    case DW_FORM_addrx:
       READ_ULEB (uvalue, data, end);
       break;
 
@@ -2535,6 +2568,7 @@ read_and_display_attr_value (unsigned long           attribute,
     case DW_FORM_ref1:
     case DW_FORM_ref2:
     case DW_FORM_ref4:
+    case DW_FORM_ref_sup4:
     case DW_FORM_ref_udata:
       if (!do_loc)
        printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset));
@@ -2562,6 +2596,7 @@ read_and_display_attr_value (unsigned long           attribute,
        printf ("%c%s", delimiter, dwarf_vmatoa ("d", implicit_const));
       break;
 
+    case DW_FORM_ref_sup8:
     case DW_FORM_ref8:
     case DW_FORM_data8:
       if (!do_loc)
@@ -2685,10 +2720,15 @@ read_and_display_attr_value (unsigned long           attribute,
       break;
 
     case DW_FORM_GNU_str_index:
+    case DW_FORM_strx:
+    case DW_FORM_strx1:
+    case DW_FORM_strx2:
+    case DW_FORM_strx3:
+    case DW_FORM_strx4:
       if (!do_loc)
        {
-         const char * suffix = strrchr (section->name, '.');
-         bfd_boolean  dwo = (suffix && strcmp (suffix, ".dwo") == 0) ? TRUE : FALSE;
+         const char *suffix = strrchr (section->name, '.');
+         bool dwo = suffix && strcmp (suffix, ".dwo") == 0;
 
          if (do_wide)
            /* We have already displayed the form name.  */
@@ -2740,22 +2780,44 @@ read_and_display_attr_value (unsigned long           attribute,
       break;
 
     case DW_FORM_GNU_addr_index:
+    case DW_FORM_addrx:
+    case DW_FORM_addrx1:
+    case DW_FORM_addrx2:
+    case DW_FORM_addrx3:
+    case DW_FORM_addrx4:
       if (!do_loc)
        {
+         dwarf_vma base;
+         dwarf_vma offset;
+
+         if (debug_info_p == NULL)
+           base = 0;
+         else if (debug_info_p->addr_base == DEBUG_INFO_UNAVAILABLE)
+           base = 0;
+         else
+           base = debug_info_p->addr_base;
+
+         offset = base + uvalue * pointer_size;
+
          if (do_wide)
            /* We have already displayed the form name.  */
            printf (_("%c(index: 0x%s): %s"), delimiter,
                    dwarf_vmatoa ("x", uvalue),
-                   fetch_indexed_value (uvalue * pointer_size, pointer_size));
+                   fetch_indexed_value (offset, pointer_size));
          else
            printf (_("%c(addr_index: 0x%s): %s"), delimiter,
                    dwarf_vmatoa ("x", uvalue),
-                   fetch_indexed_value (uvalue * pointer_size, pointer_size));
+                   fetch_indexed_value (offset, pointer_size));
        }
       break;
 
+    case DW_FORM_strp_sup:
+      if (!do_loc)
+       printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset));
+      break;
+      
     default:
-      warn (_("Unrecognized form: %lu\n"), form);
+      warn (_("Unrecognized form: 0x%lx\n"), form);
       break;
     }
 
@@ -2844,6 +2906,7 @@ read_and_display_attr_value (unsigned long           attribute,
          break;
 
        case DW_AT_GNU_addr_base:
+       case DW_AT_addr_base:
          debug_info_p->addr_base = uvalue;
          break;
 
@@ -2885,7 +2948,12 @@ read_and_display_attr_value (unsigned long           attribute,
                add_dwo_name ((const char *) fetch_alt_indirect_string (uvalue), cu_offset);
                break;
              case DW_FORM_GNU_str_index:
-               add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, FALSE), cu_offset);
+             case DW_FORM_strx:
+             case DW_FORM_strx1:
+             case DW_FORM_strx2:
+             case DW_FORM_strx3:
+             case DW_FORM_strx4:
+               add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false), cu_offset);
                break;
              case DW_FORM_string:
                add_dwo_name ((const char *) orig_data, cu_offset);
@@ -2912,7 +2980,12 @@ read_and_display_attr_value (unsigned long           attribute,
                add_dwo_dir ((const char *) fetch_indirect_line_string (uvalue), cu_offset);
                break;
              case DW_FORM_GNU_str_index:
-               add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, FALSE), cu_offset);
+             case DW_FORM_strx:
+             case DW_FORM_strx1:
+             case DW_FORM_strx2:
+             case DW_FORM_strx3:
+             case DW_FORM_strx4:
+               add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false), cu_offset);
                break;
              case DW_FORM_string:
                add_dwo_dir ((const char *) orig_data, cu_offset);
@@ -2954,10 +3027,10 @@ read_and_display_attr_value (unsigned long           attribute,
       if (level >= 0 && level < MAX_CU_NESTING
          && uvalue < (size_t) (end - start))
        {
-         bfd_boolean is_signed = FALSE;
-         abbrev_entry *  type_abbrev;
-         unsigned char * type_data;
-         unsigned long   type_cu_offset;
+         bool is_signed = false;
+         abbrev_entry *type_abbrev;
+         unsigned char *type_data;
+         unsigned long type_cu_offset;
 
          type_abbrev = get_type_abbrev_from_form (form, uvalue, cu_offset,
                                                   section, NULL, & type_data, & type_cu_offset);
@@ -3349,7 +3422,7 @@ read_and_display_attr (unsigned long           attribute,
    following debug links, then attempt to load the requested section
    from one of the separate debug info files.  */
 
-static bfd_boolean
+static bool
 load_debug_section_with_follow (enum dwarf_section_display_enum sec_enum,
                                void * handle)
 {
@@ -3368,7 +3441,7 @@ load_debug_section_with_follow (enum dwarf_section_display_enum sec_enum,
              }
        }
 
-      return TRUE;
+      return true;
     }
 
   if (do_follow_links)
@@ -3383,16 +3456,16 @@ load_debug_section_with_follow (enum dwarf_section_display_enum sec_enum,
 
              /* FIXME: We should check to see if any of the remaining debug info
                 files also contain this section, and, umm, do something about it.  */
-             return TRUE;
+             return true;
            }
        }
     }
 
-  return FALSE;
+  return false;
 }
 
 static void
-introduce (struct dwarf_section * section, bfd_boolean raw)
+introduce (struct dwarf_section * section, bool raw)
 {
   if (raw)
     {
@@ -3422,12 +3495,12 @@ introduce (struct dwarf_section * section, bfd_boolean raw)
    Returns TRUE upon success.  Otherwise an error or warning message is
    printed and FALSE is returned.  */
 
-static bfd_boolean
-process_debug_info (struct dwarf_section *           section,
-                   void *                           file,
-                   enum dwarf_section_display_enum  abbrev_sec,
-                   bfd_boolean                      do_loc,
-                   bfd_boolean                      do_types)
+static bool
+process_debug_info (struct dwarf_section * section,
+                   void *file,
+                   enum dwarf_section_display_enum abbrev_sec,
+                   bool do_loc,
+                   bool do_types)
 {
   unsigned char *start = section->start;
   unsigned char *end = start + section->size;
@@ -3459,7 +3532,7 @@ process_debug_info (struct dwarf_section *           section,
            {
              warn (_("Reserved length value (0x%s) found in section %s\n"),
                    dwarf_vmatoa ("x", length), section->name);
-             return FALSE;
+             return false;
            }
          else
            section_begin += length + 4;
@@ -3471,14 +3544,14 @@ process_debug_info (struct dwarf_section *           section,
            {
              warn (_("Corrupt unit length (0x%s) found in section %s\n"),
                    dwarf_vmatoa ("x", length), section->name);
-             return FALSE;
+             return false;
            }
        }
 
       if (num_units == 0)
        {
          error (_("No comp units in %s section ?\n"), section->name);
-         return FALSE;
+         return false;
        }
 
       /* Then allocate an array to hold the information.  */
@@ -3489,7 +3562,7 @@ process_debug_info (struct dwarf_section *           section,
          error (_("Not enough memory for a debug info array of %u entries\n"),
                 num_units);
          alloc_num_debug_info_entries = num_debug_info_entries = 0;
-         return FALSE;
+         return false;
        }
 
       /* PR 17531: file: 92ca3797.
@@ -3517,11 +3590,11 @@ process_debug_info (struct dwarf_section *           section,
     {
       warn (_("Unable to locate %s section!\n"),
            debug_displays [abbrev_sec].section.uncompressed_name);
-      return FALSE;
+      return false;
     }
 
   if (!do_loc && dwarf_start_die == 0)
-    introduce (section, FALSE);
+    introduce (section, false);
 
   free_all_abbrevs ();
   free (cu_abbrev_map);
@@ -3692,11 +3765,13 @@ process_debug_info (struct dwarf_section *           section,
       if (compunit.cu_version < 5)
        SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end);
 
+      bool do_dwo_id = false;
+      uint64_t dwo_id = 0;
       if (compunit.cu_unit_type == DW_UT_split_compile
          || compunit.cu_unit_type == DW_UT_skeleton)
        {
-         uint64_t dwo_id;
          SAFE_BYTE_GET_AND_INC (dwo_id, hdrptr, 8, end);
+         do_dwo_id = true;
        }
 
       /* PR 17512: file: 001-108546-0.001:0.1.  */
@@ -3769,6 +3844,8 @@ process_debug_info (struct dwarf_section *           section,
              printf (_("   Type Offset:   0x%s\n"),
                      dwarf_vmatoa ("x", type_offset));
            }
+         if (do_dwo_id)
+           printf (_("   DWO ID:        0x%s\n"), dwarf_vmatoa ("x", dwo_id));
          if (this_set != NULL)
            {
              dwarf_vma *offsets = this_set->section_offsets;
@@ -3908,7 +3985,7 @@ process_debug_info (struct dwarf_section *           section,
                    }
                }
              if (dwarf_start_die != 0 && level < saved_level)
-               return TRUE;
+               return true;
              continue;
            }
 
@@ -3950,7 +4027,7 @@ process_debug_info (struct dwarf_section *           section,
                }
              warn (_("DIE at offset 0x%lx refers to abbreviation number %lu which does not exist\n"),
                    die_offset, abbrev_number);
-             return FALSE;
+             return false;
            }
 
          if (!do_loc && do_printing)
@@ -4050,7 +4127,7 @@ process_debug_info (struct dwarf_section *           section,
   if (!do_loc)
     printf ("\n");
 
-  return TRUE;
+  return true;
 }
 
 /* Locate and scan the .debug_info section in the file and record the pointer
@@ -4075,12 +4152,12 @@ load_debug_info (void * file)
   (void) load_cu_tu_indexes (file);
 
   if (load_debug_section_with_follow (info, file)
-      && process_debug_info (&debug_displays [info].section, file, abbrev, TRUE, FALSE))
+      && process_debug_info (&debug_displays [info].section, file, abbrev, true, false))
     return num_debug_info_entries;
 
   if (load_debug_section_with_follow (info_dwo, file)
       && process_debug_info (&debug_displays [info_dwo].section, file,
-                            abbrev_dwo, TRUE, FALSE))
+                            abbrev_dwo, true, false))
     return num_debug_info_entries;
 
   num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
@@ -4205,12 +4282,12 @@ read_debug_line_header (struct dwarf_section * section,
 }
 
 static unsigned char *
-display_formatted_table (unsigned char *                   data,
-                        unsigned char *                   start,
-                        unsigned char *                   end,
-                        const DWARF2_Internal_LineInfo *  linfo,
-                        struct dwarf_section *            section,
-                        bfd_boolean                       is_dir)
+display_formatted_table (unsigned char *data,
+                        unsigned char *start,
+                        unsigned char *end,
+                        const DWARF2_Internal_LineInfo *linfo,
+                        struct dwarf_section *section,
+                        bool is_dir)
 {
   unsigned char *format_start, format_count, *format, formati;
   dwarf_vma data_count, datai;
@@ -4329,6 +4406,81 @@ display_formatted_table (unsigned char *                   data,
   return data;
 }
 
+static int
+display_debug_sup (struct dwarf_section *  section,
+                  void *                  file ATTRIBUTE_UNUSED)
+{
+  unsigned char * start = section->start;
+  unsigned char * end = section->start + section->size;
+  unsigned int version;
+  char is_supplementary;
+  const unsigned char * sup_filename;
+  size_t sup_filename_len;
+  unsigned int num_read;
+  int status;
+  dwarf_vma checksum_len;
+
+
+  introduce (section, true);
+  if (section->size < 4)
+    {
+      error (_("corrupt .debug_sup section: size is too small\n"));
+      return 0;
+    }
+
+  /* Read the data.  */
+  SAFE_BYTE_GET_AND_INC (version, start, 2, end);
+  if (version < 5)
+    warn (_("corrupt .debug_sup section: version < 5"));
+
+  SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end);
+  if (is_supplementary != 0 && is_supplementary != 1)
+    warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));    
+
+  sup_filename = start;
+  if (is_supplementary && sup_filename[0] != 0)
+    warn (_("corrupt .debug_sup section: filename not empty in supplementary section\n"));
+
+  sup_filename_len = strnlen ((const char *) start, end - start);
+  if (sup_filename_len == (size_t) (end - start))
+    {
+      error (_("corrupt .debug_sup section: filename is not NUL terminated\n"));
+      return 0;
+    }
+  start += sup_filename_len + 1;
+
+  checksum_len = read_leb128 (start, end, false /* unsigned */, & num_read, & status);
+  if (status)
+    {
+      error (_("corrupt .debug_sup section: bad LEB128 field for checksum length\n"));
+      checksum_len = 0;
+    }
+  start += num_read;
+  if (checksum_len > (dwarf_vma) (end - start))
+    {
+      error (_("corrupt .debug_sup section: checksum length is longer than the remaining section length\n"));
+      checksum_len = end - start;
+    }
+  else if (checksum_len < (dwarf_vma) (end - start))
+    {
+      warn (_("corrupt .debug_sup section: there are 0x%lx extra, unused bytes at the end of the section\n"),
+           (long) ((end - start) - checksum_len));
+    }
+
+  printf (_("  Version:      %u\n"), version);
+  printf (_("  Is Supp:      %u\n"), is_supplementary);
+  printf (_("  Filename:     %s\n"), sup_filename);
+  printf (_("  Checksum Len: %lu\n"), (long) checksum_len);
+  if (checksum_len > 0)
+    {
+      printf (_("  Checksum:     "));
+      while (checksum_len--)
+       printf ("0x%x ", * start++ );
+      printf ("\n");
+    }
+  return 1;
+}
+
 static int
 display_debug_lines_raw (struct dwarf_section *  section,
                         unsigned char *         data,
@@ -4338,7 +4490,7 @@ display_debug_lines_raw (struct dwarf_section *  section,
   unsigned char *start = section->start;
   int verbose_view = 0;
 
-  introduce (section, TRUE);
+  introduce (section, true);
 
   while (data < end)
     {
@@ -4348,7 +4500,7 @@ display_debug_lines_raw (struct dwarf_section *  section,
       unsigned char *end_of_sequence;
       int i;
 
-      if (const_strneq (section->name, ".debug_line.")
+      if (startswith (section->name, ".debug_line.")
          /* Note: the following does not apply to .debug_line.dwo sections.
             These are full debug_line sections.  */
          && strcmp (section->name, ".debug_line.dwo") != 0)
@@ -4434,9 +4586,9 @@ display_debug_lines_raw (struct dwarf_section *  section,
              load_debug_section_with_follow (line_str, file);
 
              data = display_formatted_table (data, start, end, &linfo, section,
-                                             TRUE);
+                                             true);
              data = display_formatted_table (data, start, end, &linfo, section,
-                                             FALSE);
+                                             false);
            }
          else
            {
@@ -4758,7 +4910,7 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 {
   static DWARF2_Internal_LineInfo saved_linfo;
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   while (data < end)
     {
@@ -4772,7 +4924,7 @@ display_debug_lines_decoded (struct dwarf_section *  section,
       unsigned char **directory_table = NULL;
       dwarf_vma n_directories = 0;
 
-      if (const_strneq (section->name, ".debug_line.")
+      if (startswith (section->name, ".debug_line.")
          /* Note: the following does not apply to .debug_line.dwo sections.
             These are full debug_line sections.  */
          && strcmp (section->name, ".debug_line.dwo") != 0)
@@ -5586,7 +5738,7 @@ display_debug_pubnames_worker (struct dwarf_section *section,
      we test for that later on.  */
   load_debug_info (file);
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   while (start < end)
     {
@@ -5731,7 +5883,7 @@ display_debug_macinfo (struct dwarf_section *section,
   unsigned char *curr = start;
   enum dwarf_macinfo_record_type op;
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   while (curr < end)
     {
@@ -5893,17 +6045,22 @@ display_debug_macro (struct dwarf_section *section,
   unsigned char *end = start + section->size;
   unsigned char *curr = start;
   unsigned char *extended_op_buf[256];
+  bool is_dwo = false;
+  const char *suffix = strrchr (section->name, '.');
+
+  if (suffix && strcmp (suffix, ".dwo") == 0)
+    is_dwo = true;
 
   load_debug_section_with_follow (str, file);
   load_debug_section_with_follow (line, file);
   load_debug_section_with_follow (str_index, file);
-
-  introduce (section, FALSE);
+  
+  introduce (section, false);
 
   while (curr < end)
     {
       unsigned int lineno, version, flags;
-      unsigned int offset_size = 4;
+      unsigned int offset_size;
       const unsigned char *string;
       dwarf_vma line_offset = 0, sec_offset = curr - start, offset;
       unsigned char **extended_ops = NULL;
@@ -5911,14 +6068,13 @@ display_debug_macro (struct dwarf_section *section,
       SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
       if (version != 4 && version != 5)
        {
-         error (_("Only GNU extension to DWARF 4 or 5 of %s is currently supported.\n"),
-                section->name);
+         error (_("Expected to find a version number of 4 or 5 in section %s but found %d instead\n"),
+                section->name, version);
          return 0;
        }
 
       SAFE_BYTE_GET_AND_INC (flags, curr, 1, end);
-      if (flags & 1)
-       offset_size = 8;
+      offset_size = (flags & 1) ? 8 : 4;
       printf (_("  Offset:                      0x%lx\n"),
              (unsigned long) sec_offset);
       printf (_("  Version:                     %d\n"), version);
@@ -6050,7 +6206,10 @@ display_debug_macro (struct dwarf_section *section,
 
            case DW_MACRO_define_strp:
              READ_ULEB (lineno, curr, end);
-             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
+             if (version == 4 && is_dwo)
+               READ_ULEB (offset, curr, end);
+             else
+               SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              string = fetch_indirect_string (offset);
              printf (_(" DW_MACRO_define_strp - lineno : %d macro : %s\n"),
                      lineno, string);
@@ -6058,7 +6217,10 @@ display_debug_macro (struct dwarf_section *section,
 
            case DW_MACRO_undef_strp:
              READ_ULEB (lineno, curr, end);
-             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
+             if (version == 4 && is_dwo)
+               READ_ULEB (offset, curr, end);
+             else
+               SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              string = fetch_indirect_string (offset);
              printf (_(" DW_MACRO_undef_strp - lineno : %d macro : %s\n"),
                      lineno, string);
@@ -6095,7 +6257,7 @@ display_debug_macro (struct dwarf_section *section,
              READ_ULEB (lineno, curr, end);
              READ_ULEB (offset, curr, end);
              string = (const unsigned char *)
-               fetch_indexed_string (offset, NULL, offset_size, FALSE);
+               fetch_indexed_string (offset, NULL, offset_size, false);
              if (op == DW_MACRO_define_strx)
                printf (" DW_MACRO_define_strx ");
              else
@@ -6164,7 +6326,7 @@ display_debug_abbrev (struct dwarf_section *section,
   unsigned char *start = section->start;
   const unsigned char *end = start + section->size;
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   do
     {
@@ -6217,7 +6379,7 @@ display_debug_abbrev (struct dwarf_section *section,
 /* Return true when ADDR is the maximum address, when addresses are
    POINTER_SIZE bytes long.  */
 
-static bfd_boolean
+static bool
 is_max_address (dwarf_vma addr, unsigned int pointer_size)
 {
   dwarf_vma mask = ~(~(dwarf_vma) 1 << (pointer_size * 8 - 1));
@@ -6782,12 +6944,12 @@ display_debug_loc (struct dwarf_section *section, void *file)
   unsigned char *next = start, *vnext = vstart;
   unsigned int *array = NULL;
   const char *suffix = strrchr (section->name, '.');
-  bfd_boolean is_dwo = FALSE;
+  bool is_dwo = false;
   int is_loclists = strstr (section->name, "debug_loclists") != NULL;
   dwarf_vma expected_start = 0;
 
   if (suffix && strcmp (suffix, ".dwo") == 0)
-    is_dwo = TRUE;
+    is_dwo = true;
 
   bytes = section->size;
 
@@ -6904,7 +7066,7 @@ display_debug_loc (struct dwarf_section *section, void *file)
   if (!locs_sorted)
     array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int));
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   if (reloc_at (section, 0))
     printf (_(" Warning: This section has relocations - addresses seen here may not be accurate.\n\n"));
@@ -7050,7 +7212,7 @@ display_debug_str (struct dwarf_section *section,
       return 0;
     }
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   while (bytes)
     {
@@ -7097,19 +7259,19 @@ display_debug_str (struct dwarf_section *section,
 static int
 display_debug_info (struct dwarf_section *section, void *file)
 {
-  return process_debug_info (section, file, section->abbrev_sec, FALSE, FALSE);
+  return process_debug_info (section, file, section->abbrev_sec, false, false);
 }
 
 static int
 display_debug_types (struct dwarf_section *section, void *file)
 {
-  return process_debug_info (section, file, section->abbrev_sec, FALSE, TRUE);
+  return process_debug_info (section, file, section->abbrev_sec, false, true);
 }
 
 static int
 display_trace_info (struct dwarf_section *section, void *file)
 {
-  return process_debug_info (section, file, section->abbrev_sec, FALSE, TRUE);
+  return process_debug_info (section, file, section->abbrev_sec, false, true);
 }
 
 static int
@@ -7119,7 +7281,7 @@ display_debug_aranges (struct dwarf_section *section,
   unsigned char *start = section->start;
   unsigned char *end = start + section->size;
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   /* It does not matter if this load fails,
      we test for that later on.  */
@@ -7264,6 +7426,7 @@ display_debug_addr (struct dwarf_section *section,
   unsigned char *end;
   unsigned int i;
   unsigned int count;
+  unsigned char * header;
 
   if (section->size == 0)
     {
@@ -7278,7 +7441,7 @@ display_debug_addr (struct dwarf_section *section,
       return 0;
     }
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   /* PR  17531: file: cf38d01b.
      We use xcalloc because a corrupt file may not have initialised all of the
@@ -7304,6 +7467,7 @@ display_debug_addr (struct dwarf_section *section,
   debug_addr_info [count]->addr_base = section->size;
   qsort (debug_addr_info, count, sizeof (debug_info *), comp_addr_base);
 
+  header = section->start;
   for (i = 0; i < count; i++)
     {
       unsigned int idx;
@@ -7314,7 +7478,38 @@ display_debug_addr (struct dwarf_section *section,
 
       printf (_("\tIndex\tAddress\n"));
       entry = section->start + debug_addr_info [i]->addr_base;
-      end = section->start + debug_addr_info [i + 1]->addr_base;
+      if (debug_addr_info [i]->dwarf_version >= 5)
+       {
+         size_t           header_size = entry - header;
+         unsigned char *  curr_header = header;
+         dwarf_vma        length;
+         int              version;
+         int              segment_selector_size;
+
+         if (header_size != 8 && header_size != 16)
+           {
+             warn (_("Corrupt %s section: expecting header size of 8 or 16, but found %ld instead\n"),
+                   section->name, (long) header_size);
+             return 0;
+           }
+
+         SAFE_BYTE_GET_AND_INC (length, curr_header, 4, entry);
+         if (length == 0xffffffff)
+           SAFE_BYTE_GET (length, curr_header, 8, entry);
+         end = curr_header + length;
+
+         SAFE_BYTE_GET_AND_INC (version, curr_header, 2, entry);
+         if (version != 5)
+           warn (_("Corrupt %s section: expecting version number 5 in header but found %d instead\n"),
+                 section->name, version);
+
+         SAFE_BYTE_GET_AND_INC (address_size, curr_header, 1, entry);
+         SAFE_BYTE_GET_AND_INC (segment_selector_size, curr_header, 1, entry);
+         address_size += segment_selector_size;
+       }
+      else
+       end = section->start + debug_addr_info [i + 1]->addr_base;
+      header = end;
       idx = 0;
       while (entry < end)
        {
@@ -7350,15 +7545,15 @@ display_debug_str_offsets (struct dwarf_section *section,
   unsigned char *end = start + section->size;
   unsigned char *curr = start;
 
-  const char * suffix = strrchr (section->name, '.');
-  bfd_boolean  dwo = (suffix && strcmp (suffix, ".dwo") == 0) ? TRUE : FALSE;
+  const char *suffix = strrchr (section->name, '.');
+  bool dwo = suffix && strcmp (suffix, ".dwo") == 0;
 
   if (dwo)
     load_debug_section_with_follow (str_dwo, file);
   else
     load_debug_section_with_follow (str, file);
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   while (curr < end)
     {
@@ -7375,18 +7570,22 @@ display_debug_str_offsets (struct dwarf_section *section,
       else
        entry_length = 4;
 
+      unsigned char *entries_end;
       if (length == 0)
        {
          /* This is probably an old style .debug_str_offset section which
             just contains offsets and no header (and the first offset is 0).  */
          length = section->size;
          curr   = section->start;
+         entries_end = end;
 
          printf (_("    Length: %#lx\n"), (unsigned long) length);
          printf (_("       Index   Offset [String]\n"));
        }
       else
        {
+         entries_end = curr + length;
+
          int version;
          SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
          if (version != 5)
@@ -7402,11 +7601,15 @@ display_debug_str_offsets (struct dwarf_section *section,
          printf (_("       Index   Offset [String]\n"));
        }
 
-      for (idx = 0; length >= entry_length && curr < end; idx++)
+      for (idx = 0; curr < entries_end; idx++)
        {
          dwarf_vma offset;
          const unsigned char * string;
 
+         if (curr + entry_length > entries_end)
+           /* Not enough space to read one entry_length, give up.  */
+           return 0;
+
          SAFE_BYTE_GET_AND_INC (offset, curr, entry_length, end);
          if (dwo)
            string = (const unsigned char *)
@@ -7722,7 +7925,7 @@ display_debug_ranges (struct dwarf_section *section,
     warn (_("Range lists in %s section start at 0x%lx\n"),
          section->name, (unsigned long) range_entries[0].ranges_offset);
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   printf (_("    Offset   Begin    End\n"));
 
@@ -8464,12 +8667,12 @@ display_debug_frames (struct dwarf_section *section,
   Frame_Chunk *chunks = NULL, *forward_refs = NULL;
   Frame_Chunk *remembered_state = NULL;
   Frame_Chunk *rs;
-  bfd_boolean is_eh = strcmp (section->name, ".eh_frame") == 0;
+  bool is_eh = strcmp (section->name, ".eh_frame") == 0;
   unsigned int max_regs = 0;
   const char *bad_reg = _("bad register: ");
   unsigned int saved_eh_addr_size = eh_addr_size;
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   while (start < end)
     {
@@ -8485,7 +8688,7 @@ display_debug_frames (struct dwarf_section *section,
       unsigned int encoded_ptr_size = saved_eh_addr_size;
       unsigned int offset_size;
       unsigned int initial_length_size;
-      bfd_boolean all_nops;
+      bool all_nops;
       static Frame_Chunk fde_fc;
 
       saved_start = start;
@@ -8914,7 +9117,7 @@ display_debug_frames (struct dwarf_section *section,
          start = tmp;
        }
 
-      all_nops = TRUE;
+      all_nops = true;
 
       /* Now we know what registers are used, make a second pass over
         the chunk, this time actually printing out the info.  */
@@ -8940,7 +9143,7 @@ display_debug_frames (struct dwarf_section *section,
 
          /* Make a note if something other than DW_CFA_nop happens.  */
          if (op != DW_CFA_nop)
-           all_nops = FALSE;
+           all_nops = false;
 
          /* Warning: if you add any more cases to this switch, be
             sure to add them to the corresponding switch above.  */
@@ -9451,7 +9654,7 @@ display_debug_names (struct dwarf_section *section, void *file)
   const unsigned char *const section_end = section->start + section->size;
   unsigned char *unit_end;
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   load_debug_section_with_follow (str, file);
 
@@ -9464,7 +9667,7 @@ display_debug_names (struct dwarf_section *section, void *file)
       uint32_t augmentation_string_size;
       unsigned int i;
       unsigned long sec_off;
-      bfd_boolean augmentation_printable;
+      bool augmentation_printable;
       const char *augmentation_string;
 
       unit_start = hdrptr;
@@ -9532,7 +9735,7 @@ display_debug_names (struct dwarf_section *section, void *file)
 
       printf (_("Augmentation string:"));
 
-      augmentation_printable = TRUE;
+      augmentation_printable = true;
       augmentation_string = (const char *) hdrptr;
 
       for (i = 0; i < augmentation_string_size; i++)
@@ -9543,7 +9746,7 @@ display_debug_names (struct dwarf_section *section, void *file)
          printf (" %02x", uc);
 
          if (uc != 0 && !ISPRINT (uc))
-           augmentation_printable = FALSE;
+           augmentation_printable = false;
        }
 
       if (augmentation_printable)
@@ -9807,7 +10010,7 @@ display_debug_links (struct dwarf_section *  section,
   const unsigned char * filename;
   unsigned int          filelen;
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   /* The .gnu_debuglink section is formatted as:
       (c-string)  Filename.
@@ -9828,7 +10031,7 @@ display_debug_links (struct dwarf_section *  section,
 
   printf (_("  Separate debug info file: %s\n"), filename);
 
-  if (const_strneq (section->name, ".gnu_debuglink"))
+  if (startswith (section->name, ".gnu_debuglink"))
     {
       unsigned int          crc32;
       unsigned int          crc_offset;
@@ -9852,7 +10055,7 @@ display_debug_links (struct dwarf_section *  section,
          return 0;
        }
     }
-  else /* const_strneq (section->name, ".gnu_debugaltlink") */
+  else /* startswith (section->name, ".gnu_debugaltlink") */
     {
       const unsigned char * build_id = section->start + filelen + 1;
       bfd_size_type         build_id_len = section->size - (filelen + 1);
@@ -9890,7 +10093,7 @@ display_gdb_index (struct dwarf_section *section,
 
   /* The documentation for the format of this file is in gdb/dwarf2read.c.  */
 
-  introduce (section, FALSE);
+  introduce (section, false);
 
   if (section->size < 6 * sizeof (uint32_t))
     {
@@ -10229,7 +10432,7 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
 
   if (do_display)
     {
-      introduce (section, FALSE);
+      introduce (section, false);
 
       printf (_("  Version:                 %u\n"), version);
       if (version >= 2)
@@ -10311,7 +10514,7 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
       unsigned char *poffsets = ppool + (size_t) ncols * 4;
       unsigned char *psizes = poffsets + (size_t) nused * ncols * 4;
       unsigned char *pend = psizes + (size_t) nused * ncols * 4;
-      bfd_boolean is_tu_index;
+      bool is_tu_index;
       struct cu_tu_set *this_set = NULL;
       unsigned int row;
       unsigned char *prow;
@@ -10503,25 +10706,25 @@ static int cu_tu_indexes_read = -1; /* Tri-state variable.  */
    section sets that we can use to associate a .debug_info.dwo section
    with its associated .debug_abbrev.dwo section in a .dwp file.  */
 
-static bfd_boolean
+static bool
 load_cu_tu_indexes (void *file)
 {
   /* If we have already loaded (or tried to load) the CU and TU indexes
      then do not bother to repeat the task.  */
   if (cu_tu_indexes_read == -1)
     {
-      cu_tu_indexes_read = TRUE;
+      cu_tu_indexes_read = true;
 
       if (load_debug_section_with_follow (dwp_cu_index, file))
        if (! process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0))
-         cu_tu_indexes_read = FALSE;
+         cu_tu_indexes_read = false;
 
       if (load_debug_section_with_follow (dwp_tu_index, file))
        if (! process_cu_tu_index (&debug_displays [dwp_tu_index].section, 0))
-         cu_tu_indexes_read = FALSE;
+         cu_tu_indexes_read = false;
     }
 
-  return (bfd_boolean) cu_tu_indexes_read;
+  return (bool) cu_tu_indexes_read;
 }
 
 /* Find the set of sections that includes section SHNDX.  */
@@ -10702,10 +10905,10 @@ calc_gnu_debuglink_crc32 (unsigned long          crc,
   return ~crc & 0xffffffff;
 }
 
-typedef bfd_boolean (*   check_func_type) (const char *, void *);
-typedef const char * (*  parse_func_type) (struct dwarf_section *, void *);
+typedef bool (*check_func_type) (const char *, void *);
+typedef const char *(* parse_func_type) (struct dwarf_section *, void *);
 
-static bfd_boolean
+static bool
 check_gnu_debuglink (const char * pathname, void * crc_pointer)
 {
   static unsigned char buffer [8 * 1024];
@@ -10716,7 +10919,7 @@ check_gnu_debuglink (const char * pathname, void * crc_pointer)
 
   sep_data = open_debug_file (pathname);
   if (sep_data == NULL)
-    return FALSE;
+    return false;
 
   /* Yes - we are opening the file twice...  */
   f = fopen (pathname, "rb");
@@ -10725,7 +10928,7 @@ check_gnu_debuglink (const char * pathname, void * crc_pointer)
       /* Paranoia: This should never happen.  */
       close_debug_file (sep_data);
       warn (_("Unable to reopen separate debug info file: %s\n"), pathname);
-      return FALSE;
+      return false;
     }
 
   while ((count = fread (buffer, 1, sizeof (buffer), f)) > 0)
@@ -10738,10 +10941,10 @@ check_gnu_debuglink (const char * pathname, void * crc_pointer)
       close_debug_file (sep_data);
       warn (_("Separate debug info file %s found, but CRC does not match - ignoring\n"),
            pathname);
-      return FALSE;
+      return false;
     }
 
-  return TRUE;
+  return true;
 }
 
 static const char *
@@ -10764,18 +10967,18 @@ parse_gnu_debuglink (struct dwarf_section * section, void * data)
   return name;
 }
 
-static bfd_boolean
+static bool
 check_gnu_debugaltlink (const char * filename, void * data ATTRIBUTE_UNUSED)
 {
   void * sep_data = open_debug_file (filename);
 
   if (sep_data == NULL)
-    return FALSE;
+    return false;
 
   /* FIXME: We should now extract the build-id in the separate file
      and check it...  */
 
-  return TRUE;
+  return true;
 }
 
 typedef struct build_id_data
@@ -10827,7 +11030,7 @@ add_separate_debug_file (const char * filename, void * handle)
    file. If successful, store the path of the file in filename and
    return TRUE, otherwise return FALSE.  */
 
-static bfd_boolean
+static bool
 debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
                                       char ** filename,
                                       void * file)
@@ -10849,16 +11052,16 @@ debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
       filelen = strnlen ((const char *)section->start, section->size);
       if (filelen == section->size)
         /* Corrupt debugaltlink.  */
-        return FALSE;
+        return false;
 
       build_id = section->start + filelen + 1;
       build_id_len = section->size - (filelen + 1);
 
       if (build_id_len == 0)
-        return FALSE;
+        return false;
     }
   else
-    return FALSE;
+    return false;
 
   if (build_id)
     {
@@ -10867,7 +11070,7 @@ debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
 
       client = debuginfod_begin ();
       if (client == NULL)
-        return FALSE;
+        return false;
 
       /* Query debuginfod servers for the target file. If found its path
          will be stored in filename.  */
@@ -10884,11 +11087,11 @@ debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
           /* File successfully retrieved. Close fd since we want to
              use open_debug_file () on filename instead.  */
           close (fd);
-          return TRUE;
+          return true;
         }
     }
 
-  return FALSE;
+  return false;
 }
 #endif
 
@@ -11017,44 +11220,52 @@ load_separate_debug_info (const char *            main_filename,
   }
 #endif
 
-  /* Failed to find the file.  */
-  warn (_("could not find separate debug file '%s'\n"), separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+  if (do_debug_links)
+    {
+      /* Failed to find the file.  */
+      warn (_("could not find separate debug file '%s'\n"),
+           separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 
 #ifdef EXTRA_DEBUG_ROOT2
-  sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT2, separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+      sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT2,
+              separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 #endif
 
 #ifdef EXTRA_DEBUG_ROOT1
-  sprintf (debug_filename, "%s/%s/%s", EXTRA_DEBUG_ROOT1, canon_dir, separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+      sprintf (debug_filename, "%s/%s/%s", EXTRA_DEBUG_ROOT1,
+              canon_dir, separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 
-  sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT1, separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+      sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT1,
+              separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 #endif
 
-  sprintf (debug_filename, "%s.debug/%s", canon_dir, separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+      sprintf (debug_filename, "%s.debug/%s", canon_dir,
+              separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 
-  sprintf (debug_filename, "%s%s", canon_dir, separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+      sprintf (debug_filename, "%s%s", canon_dir, separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 
-  sprintf (debug_filename, ".debug/%s", separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+      sprintf (debug_filename, ".debug/%s", separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 
-  sprintf (debug_filename, "%s", separate_filename);
-  warn (_("tried: %s\n"), debug_filename);
+      sprintf (debug_filename, "%s", separate_filename);
+      warn (_("tried: %s\n"), debug_filename);
 
 #if HAVE_LIBDEBUGINFOD
-  {
-    char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);
-    if (urls == NULL)
-      urls = "";
+      {
+       char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);
+       if (urls == NULL)
+         urls = "";
 
-    warn (_("tried: DEBUGINFOD_URLS=%s\n"), urls);
-  }
+       warn (_("tried: DEBUGINFOD_URLS=%s\n"), urls);
+      }
 #endif
+    }
 
   free (canon_dir);
   free (debug_filename);
@@ -11076,7 +11287,8 @@ load_separate_debug_info (const char *            main_filename,
   /* FIXME: We do not check to see if there are any other separate debug info
      files that would also match.  */
 
-  printf (_("%s: Found separate debug info file: %s\n\n"), main_filename, debug_filename);
+  if (do_debug_links)
+    printf (_("\n%s: Found separate debug info file: %s\n"), main_filename, debug_filename);
   add_separate_debug_file (debug_filename, debug_handle);
 
   /* Do not free debug_filename - it might be referenced inside
@@ -11118,9 +11330,62 @@ load_dwo_file (const char * main_filename, const char * name, const char * dir,
   return separate_handle;
 }
 
+static void
+load_debug_sup_file (const char * main_filename, void * file)
+{
+  if (! load_debug_section (debug_sup, file))
+    return; /* No .debug_sup section.  */
+
+  struct dwarf_section * section;
+  section = & debug_displays [debug_sup].section;
+  assert (section != NULL);
+
+  if (section->start == NULL || section->size < 5)
+    {
+      warn (_(".debug_sup section is corrupt/empty\n"));
+      return;
+    }
+
+  if (section->start[2] != 0)
+    return; /* This is a supplementary file.  */
+
+  const char * filename = (const char *) section->start + 3;
+  if (strnlen (filename, section->size - 3) == section->size - 3)
+    {
+      warn (_("filename in .debug_sup section is corrupt\n"));
+      return;
+    }
+
+  if (filename[0] != '/' && strchr (main_filename, '/'))
+    {
+      char * new_name;
+      if (asprintf (& new_name, "%.*s/%s",
+                   (int) (strrchr (main_filename, '/') - main_filename),
+                   main_filename,
+                   filename) < 3)
+       warn (_("unable to construct path for supplementary debug file"));
+      else
+       filename = new_name;
+    }
+
+  void * handle;
+  handle = open_debug_file (filename);
+  if (handle == NULL)
+    {
+      warn (_("unable to open file '%s' referenced from .debug_sup section\n"), filename);
+      return;
+    }
+
+  printf (_("%s: Found supplementary debug file: %s\n\n"), main_filename, filename);
+
+  /* FIXME: Compare the checksums, if present.  */
+  add_separate_debug_file (filename, handle);
+}
+
 /* Load a debuglink section and/or a debugaltlink section, if either are present.
    Recursively check the loaded files for more of these sections.
-   FIXME: Should also check for DWO_* entries in the newlu loaded files.  */
+   Also follow any links in .debug_sup sections.
+   FIXME: Should also check for DWO_* entries in the newly loaded files.  */
 
 static void
 check_for_and_load_links (void * file, const char * filename)
@@ -11162,6 +11427,8 @@ check_for_and_load_links (void * file, const char * filename)
                                    first_separate_info->filename);
        }
     }
+
+  load_debug_sup_file (filename, file);
 }
 
 /* Load the separate debug info file(s) attached to FILE, if any exist.
@@ -11169,12 +11436,12 @@ check_for_and_load_links (void * file, const char * filename)
    If TRUE is returned then the linked list starting at first_separate_info
    will be populated with open file handles.  */
 
-bfd_boolean
+bool
 load_separate_debug_files (void * file, const char * filename)
 {
   /* Skip this operation if we are not interested in debug links.  */
   if (! do_follow_links && ! do_debug_links)
-    return FALSE;
+    return false;
 
   /* See if there are any dwo links.  */
   if (load_debug_section (str, file)
@@ -11184,13 +11451,13 @@ load_separate_debug_files (void * file, const char * filename)
       free_dwo_info ();
 
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
-                             TRUE, FALSE))
+                             true, false))
        {
-         bfd_boolean introduced = FALSE;
-         dwo_info *   dwinfo;
-         const char * dir = NULL;
-         const char * id = NULL;
-         const char * name = NULL;
+         bool introduced = false;
+         dwo_info *dwinfo;
+         const char *dir = NULL;
+         const char *id = NULL;
+         const char *name = NULL;
 
          for (dwinfo = first_dwo_info; dwinfo != NULL; dwinfo = dwinfo->next)
            {
@@ -11233,7 +11500,7 @@ load_separate_debug_files (void * file, const char * filename)
                        {
                          printf (_("The %s section contains link(s) to dwo file(s):\n\n"),
                                  debug_displays [info].section.uncompressed_name);
-                         introduced = TRUE;
+                         introduced = true;
                        }
 
                      printf (_("  Name:      %s\n"), name);
@@ -11257,7 +11524,7 @@ load_separate_debug_files (void * file, const char * filename)
   if (! do_follow_links)
     /* The other debug links will be displayed by display_debug_links()
        so we do not need to do any further processing here.  */
-    return FALSE;
+    return false;
 
   /* FIXME: We do not check for the presence of both link sections in the same file.  */
   /* FIXME: We do not check for the presence of multiple, same-name debuglink sections.  */
@@ -11265,10 +11532,10 @@ load_separate_debug_files (void * file, const char * filename)
 
   check_for_and_load_links (file, filename);
   if (first_separate_info != NULL)
-    return TRUE;
+    return true;
 
   do_follow_links = 0;
-  return FALSE;
+  return false;
 }
 
 void
@@ -11361,6 +11628,7 @@ dwarf_select_sections_by_names (const char *names)
       { "links", & do_debug_links, 1 },
       { "loc",  & do_debug_loc, 1 },
       { "macro", & do_debug_macinfo, 1 },
+      { "no-follow-links", & do_follow_links, 0 },
       { "pubnames", & do_debug_pubnames, 1 },
       { "pubtypes", & do_debug_pubtypes, 1 },
       /* This entry is for compatibility
@@ -11390,7 +11658,7 @@ dwarf_select_sections_by_names (const char *names)
          if (strncmp (p, entry->option, len) == 0
              && (p[len] == ',' || p[len] == '\0'))
            {
-             * entry->variable |= entry->val;
+             * entry->variable = entry->val;
 
              /* The --debug-dump=frames-interp option also
                 enables the --debug-dump=frames option.  */
@@ -11431,6 +11699,7 @@ dwarf_select_sections_by_letters (const char *letters)
       case 'g':        do_gdb_index = 1; break;
       case 'i':        do_debug_info = 1; break;
       case 'K': do_follow_links = 1; break;
+      case 'N': do_follow_links = 0; break;
       case 'k':        do_debug_links = 1; break;
       case 'l':        do_debug_lines |= FLAG_DEBUG_LINES_RAW; break;
       case 'L':        do_debug_lines |= FLAG_DEBUG_LINES_DECODED; break;
@@ -11477,59 +11746,60 @@ dwarf_select_sections_all (void)
   do_debug_str_offsets = 1;
 }
 
-#define NO_ABBREVS   NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL
-#define ABBREV(N)    NULL, NULL, NULL, 0, 0, N, NULL, 0, NULL
+#define NO_ABBREVS   NULL, NULL, NULL, 0, 0, 0, NULL, 0
+#define ABBREV(N)    NULL, NULL, NULL, 0, 0, N, NULL, 0
 
 /* N.B. The order here must match the order in section_display_enum.  */
 
 struct dwarf_section_display debug_displays[] =
 {
-  { { ".debug_abbrev",     ".zdebug_abbrev",   NO_ABBREVS },      display_debug_abbrev,   &do_debug_abbrevs,   FALSE },
-  { { ".debug_aranges",            ".zdebug_aranges",  NO_ABBREVS },      display_debug_aranges,  &do_debug_aranges,   TRUE },
-  { { ".debug_frame",       ".zdebug_frame",   NO_ABBREVS },      display_debug_frames,   &do_debug_frames,    TRUE },
-  { { ".debug_info",       ".zdebug_info",     ABBREV (abbrev)},  display_debug_info,     &do_debug_info,      TRUE },
-  { { ".debug_line",       ".zdebug_line",     NO_ABBREVS },      display_debug_lines,    &do_debug_lines,     TRUE },
-  { { ".debug_pubnames",    ".zdebug_pubnames",        NO_ABBREVS },      display_debug_pubnames, &do_debug_pubnames,  FALSE },
-  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubnames, FALSE },
-  { { ".eh_frame",         "",                 NO_ABBREVS },      display_debug_frames,   &do_debug_frames,    TRUE },
-  { { ".debug_macinfo",            ".zdebug_macinfo",  NO_ABBREVS },      display_debug_macinfo,  &do_debug_macinfo,   FALSE },
-  { { ".debug_macro",      ".zdebug_macro",    NO_ABBREVS },      display_debug_macro,    &do_debug_macinfo,   TRUE },
-  { { ".debug_str",        ".zdebug_str",      NO_ABBREVS },      display_debug_str,      &do_debug_str,       FALSE },
-  { { ".debug_line_str",    ".zdebug_line_str",        NO_ABBREVS },      display_debug_str,      &do_debug_str,       FALSE },
-  { { ".debug_loc",        ".zdebug_loc",      NO_ABBREVS },      display_debug_loc,      &do_debug_loc,       TRUE },
-  { { ".debug_loclists",    ".zdebug_loclists",        NO_ABBREVS },      display_debug_loc,      &do_debug_loc,       TRUE },
-  { { ".debug_pubtypes",    ".zdebug_pubtypes",        NO_ABBREVS },      display_debug_pubnames, &do_debug_pubtypes,  FALSE },
-  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubtypes, FALSE },
-  { { ".debug_ranges",     ".zdebug_ranges",   NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,    TRUE },
-  { { ".debug_rnglists",    ".zdebug_rnglists",        NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,    TRUE },
-  { { ".debug_static_func", ".zdebug_static_func", NO_ABBREVS },   display_debug_not_supported, NULL,          FALSE },
-  { { ".debug_static_vars", ".zdebug_static_vars", NO_ABBREVS },   display_debug_not_supported, NULL,          FALSE },
-  { { ".debug_types",      ".zdebug_types",    ABBREV (abbrev) }, display_debug_types,    &do_debug_info,      TRUE },
-  { { ".debug_weaknames",   ".zdebug_weaknames", NO_ABBREVS },     display_debug_not_supported, NULL,          FALSE },
-  { { ".gdb_index",        "",                 NO_ABBREVS },      display_gdb_index,      &do_gdb_index,       FALSE },
-  { { ".debug_names",      "",                 NO_ABBREVS },      display_debug_names,    &do_gdb_index,       FALSE },
-  { { ".trace_info",       "",                 ABBREV (trace_abbrev) }, display_trace_info, &do_trace_info,    TRUE },
-  { { ".trace_abbrev",     "",                 NO_ABBREVS },      display_debug_abbrev,   &do_trace_abbrevs,   FALSE },
-  { { ".trace_aranges",            "",                 NO_ABBREVS },      display_debug_aranges,  &do_trace_aranges,   FALSE },
-  { { ".debug_info.dwo",    ".zdebug_info.dwo",        ABBREV (abbrev_dwo) }, display_debug_info, &do_debug_info,      TRUE },
-  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NO_ABBREVS },    display_debug_abbrev,   &do_debug_abbrevs,  FALSE },
-  { { ".debug_types.dwo",   ".zdebug_types.dwo", ABBREV (abbrev_dwo) }, display_debug_types, &do_debug_info,   TRUE },
-  { { ".debug_line.dwo",    ".zdebug_line.dwo", NO_ABBREVS },      display_debug_lines,    &do_debug_lines,    TRUE },
-  { { ".debug_loc.dwo",            ".zdebug_loc.dwo",  NO_ABBREVS },      display_debug_loc,      &do_debug_loc,       TRUE },
-  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NO_ABBREVS },     display_debug_macro,    &do_debug_macinfo,  TRUE },
-  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NO_ABBREVS },   display_debug_macinfo,  &do_debug_macinfo,  FALSE },
-  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NO_ABBREVS },      display_debug_str,      &do_debug_str,      TRUE },
-  { { ".debug_str_offsets", ".zdebug_str_offsets", NO_ABBREVS },   display_debug_str_offsets, &do_debug_str_offsets, TRUE },
-  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NO_ABBREVS }, display_debug_str_offsets, &do_debug_str_offsets, TRUE },
-  { { ".debug_addr",       ".zdebug_addr",     NO_ABBREVS },      display_debug_addr,     &do_debug_addr,      TRUE },
-  { { ".debug_cu_index",    "",                        NO_ABBREVS },      display_cu_index,       &do_debug_cu_index,  FALSE },
-  { { ".debug_tu_index",    "",                        NO_ABBREVS },      display_cu_index,       &do_debug_cu_index,  FALSE },
-  { { ".gnu_debuglink",     "",                 NO_ABBREVS },      display_debug_links,    &do_debug_links,     FALSE },
-  { { ".gnu_debugaltlink",  "",                 NO_ABBREVS },      display_debug_links,    &do_debug_links,     FALSE },
+  { { ".debug_abbrev",     ".zdebug_abbrev",   NO_ABBREVS },      display_debug_abbrev,   &do_debug_abbrevs,   false },
+  { { ".debug_aranges",            ".zdebug_aranges",  NO_ABBREVS },      display_debug_aranges,  &do_debug_aranges,   true },
+  { { ".debug_frame",       ".zdebug_frame",   NO_ABBREVS },      display_debug_frames,   &do_debug_frames,    true },
+  { { ".debug_info",       ".zdebug_info",     ABBREV (abbrev)},  display_debug_info,     &do_debug_info,      true },
+  { { ".debug_line",       ".zdebug_line",     NO_ABBREVS },      display_debug_lines,    &do_debug_lines,     true },
+  { { ".debug_pubnames",    ".zdebug_pubnames",        NO_ABBREVS },      display_debug_pubnames, &do_debug_pubnames,  false },
+  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubnames, false },
+  { { ".eh_frame",         "",                 NO_ABBREVS },      display_debug_frames,   &do_debug_frames,    true },
+  { { ".debug_macinfo",            ".zdebug_macinfo",  NO_ABBREVS },      display_debug_macinfo,  &do_debug_macinfo,   false },
+  { { ".debug_macro",      ".zdebug_macro",    NO_ABBREVS },      display_debug_macro,    &do_debug_macinfo,   true },
+  { { ".debug_str",        ".zdebug_str",      NO_ABBREVS },      display_debug_str,      &do_debug_str,       false },
+  { { ".debug_line_str",    ".zdebug_line_str",        NO_ABBREVS },      display_debug_str,      &do_debug_str,       false },
+  { { ".debug_loc",        ".zdebug_loc",      NO_ABBREVS },      display_debug_loc,      &do_debug_loc,       true },
+  { { ".debug_loclists",    ".zdebug_loclists",        NO_ABBREVS },      display_debug_loc,      &do_debug_loc,       true },
+  { { ".debug_pubtypes",    ".zdebug_pubtypes",        NO_ABBREVS },      display_debug_pubnames, &do_debug_pubtypes,  false },
+  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NO_ABBREVS }, display_debug_gnu_pubnames, &do_debug_pubtypes, false },
+  { { ".debug_ranges",     ".zdebug_ranges",   NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,    true },
+  { { ".debug_rnglists",    ".zdebug_rnglists",        NO_ABBREVS },      display_debug_ranges,   &do_debug_ranges,    true },
+  { { ".debug_static_func", ".zdebug_static_func", NO_ABBREVS },   display_debug_not_supported, NULL,          false },
+  { { ".debug_static_vars", ".zdebug_static_vars", NO_ABBREVS },   display_debug_not_supported, NULL,          false },
+  { { ".debug_types",      ".zdebug_types",    ABBREV (abbrev) }, display_debug_types,    &do_debug_info,      true },
+  { { ".debug_weaknames",   ".zdebug_weaknames", NO_ABBREVS },     display_debug_not_supported, NULL,          false },
+  { { ".gdb_index",        "",                 NO_ABBREVS },      display_gdb_index,      &do_gdb_index,       false },
+  { { ".debug_names",      "",                 NO_ABBREVS },      display_debug_names,    &do_gdb_index,       false },
+  { { ".trace_info",       "",                 ABBREV (trace_abbrev) }, display_trace_info, &do_trace_info,    true },
+  { { ".trace_abbrev",     "",                 NO_ABBREVS },      display_debug_abbrev,   &do_trace_abbrevs,   false },
+  { { ".trace_aranges",            "",                 NO_ABBREVS },      display_debug_aranges,  &do_trace_aranges,   false },
+  { { ".debug_info.dwo",    ".zdebug_info.dwo",        ABBREV (abbrev_dwo) }, display_debug_info, &do_debug_info,      true },
+  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NO_ABBREVS },    display_debug_abbrev,   &do_debug_abbrevs,  false },
+  { { ".debug_types.dwo",   ".zdebug_types.dwo", ABBREV (abbrev_dwo) }, display_debug_types, &do_debug_info,   true },
+  { { ".debug_line.dwo",    ".zdebug_line.dwo", NO_ABBREVS },      display_debug_lines,    &do_debug_lines,    true },
+  { { ".debug_loc.dwo",            ".zdebug_loc.dwo",  NO_ABBREVS },      display_debug_loc,      &do_debug_loc,       true },
+  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NO_ABBREVS },     display_debug_macro,    &do_debug_macinfo,  true },
+  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NO_ABBREVS },   display_debug_macinfo,  &do_debug_macinfo,  false },
+  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NO_ABBREVS },      display_debug_str,      &do_debug_str,      true },
+  { { ".debug_str_offsets", ".zdebug_str_offsets", NO_ABBREVS },   display_debug_str_offsets, &do_debug_str_offsets, true },
+  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NO_ABBREVS }, display_debug_str_offsets, &do_debug_str_offsets, true },
+  { { ".debug_addr",       ".zdebug_addr",     NO_ABBREVS },      display_debug_addr,     &do_debug_addr,      true },
+  { { ".debug_cu_index",    "",                        NO_ABBREVS },      display_cu_index,       &do_debug_cu_index,  false },
+  { { ".debug_tu_index",    "",                        NO_ABBREVS },      display_cu_index,       &do_debug_cu_index,  false },
+  { { ".gnu_debuglink",     "",                 NO_ABBREVS },      display_debug_links,    &do_debug_links,     false },
+  { { ".gnu_debugaltlink",  "",                 NO_ABBREVS },      display_debug_links,    &do_debug_links,     false },
+  { { ".debug_sup",         "",                        NO_ABBREVS },      display_debug_sup,      &do_debug_links,     false },
   /* Separate debug info files can containt their own .debug_str section,
      and this might be in *addition* to a .debug_str section already present
      in the main file.  Hence we need to have two entries for .debug_str.  */
-  { { ".debug_str",        ".zdebug_str",      NO_ABBREVS },      display_debug_str,      &do_debug_str,       FALSE },
+  { { ".debug_str",        ".zdebug_str",      NO_ABBREVS },      display_debug_str,      &do_debug_str,       false },
 };
 
 /* A static assertion.  */