+2021-05-12  Alan Modra  <amodra@gmail.com>
+
+       * dwarf.c (dwarf_vmatoa64, SAFE_BYTE_GET64, add64): Delete.
+       (skip_attr_bytes): Replace use of SAFE_BYTE_GET64 with
+       SAFE_BYTE_GET_AND_INC.
+       (read_and_display_attr_value): Likewise.  Print using dwarf_vmatoa.
+       (process_debug_info, process_cu_tu_index): Likewise.
+       * elfcomm.c (byte_put, byte_put_little_endian, byte_put_big_endian),
+       (byte_get, byte_get_little_endian, byte_get_big_endian),
+       (byte_get_signed): Make size param unsigned.  Remove code dealing
+       with 4-byte elf_vma.
+       (byte_get_64): Delete.
+       * elfcomm.h  (byte_put, byte_put_little_endian, byte_put_big_endian),
+       (byte_get, byte_get_little_endian, byte_get_big_endian),
+       (byte_get_signed): Update prototypes.
+       (byte_get_64): Delete.
+
 2021-05-12  Alan Modra  <amodra@gmail.com>
 
        PR 27836
 
     printf ("%*s", len + 1, "");
 }
 
-/* Format a 64-bit value, given as two 32-bit values, in hex.
-   For reentrancy, this uses a buffer provided by the caller.  */
-
-static const char *
-dwarf_vmatoa64 (dwarf_vma hvalue, dwarf_vma lvalue, char *buf,
-               unsigned int buf_len)
-{
-  int len = 0;
-
-  if (hvalue == 0)
-    snprintf (buf, buf_len, "%" DWARF_VMA_FMT "x", lvalue);
-  else
-    {
-      len = snprintf (buf, buf_len, "%" DWARF_VMA_FMT "x", hvalue);
-      snprintf (buf + len, buf_len - len,
-               "%08" DWARF_VMA_FMT "x", lvalue);
-    }
-
-  return 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.
     }                                                          \
   while (0)
 
-#define SAFE_BYTE_GET64(PTR, HIGH, LOW, END)           \
-  do                                                   \
-    {                                                  \
-      if ((PTR) <= (END) - 8)                          \
-       {                                               \
-         byte_get_64 ((PTR), (HIGH), (LOW));           \
-       }                                               \
-      else                                             \
-       {                                               \
-         * (LOW) = * (HIGH) = 0;                       \
-       }                                               \
-    }                                                  \
-  while (0)
-
 typedef struct State_Machine_Registers
 {
   dwarf_vma address;
   return NULL;
 }
 
-/* Add INC to HIGH_BITS:LOW_BITS.  */
-static void
-add64 (dwarf_vma * high_bits, dwarf_vma * low_bits, dwarf_vma inc)
-{
-  dwarf_vma tmp = * low_bits;
-
-  tmp += inc;
-
-  /* FIXME: There is probably a better way of handling this:
-
-     We need to cope with dwarf_vma being a 32-bit or 64-bit
-     type.  Plus regardless of its size LOW_BITS is meant to
-     only hold 32-bits, so if there is overflow or wrap around
-     we must propagate into HIGH_BITS.  */
-  if (tmp < * low_bits)
-    {
-      ++ * high_bits;
-    }
-  else if (sizeof (tmp) > 8
-          && (tmp >> 31) > 1)
-    {
-      ++ * high_bits;
-      tmp &= 0xFFFFFFFF;
-    }
-
-  * low_bits = tmp;
-}
-
 static const char *
 fetch_alt_indirect_string (dwarf_vma offset)
 {
       break;
 
     case DW_FORM_ref8:
-      {
-       dwarf_vma high_bits;
-
-       SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
-       data += 8;
-       if (sizeof (uvalue) > 4)
-         uvalue += high_bits << 32;
-       else if (high_bits != 0)
-         {
-           /* FIXME: What to do ?  */
-           return NULL;
-         }
-       break;
-      }
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 8, end);
+      break;
 
     case DW_FORM_data8:
     case DW_FORM_ref_sig8:
                             int                     level)
 {
   dwarf_signed_vma svalue;
-  dwarf_vma        uvalue = 0;
-  unsigned char *  block_start = NULL;
-  unsigned char *  orig_data = data;
+  dwarf_vma uvalue = 0;
+  dwarf_vma uvalue_hi = 0;
+  unsigned char *block_start = NULL;
+  unsigned char *orig_data = data;
 
   if (data > end || (data == end && form != DW_FORM_flag_present))
     {
       SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
       break;
 
+    case DW_FORM_ref_sup8:
+    case DW_FORM_ref8:
+    case DW_FORM_data8:
+    case DW_FORM_ref_sig8:
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 8, end);
+      break;
+
+    case DW_FORM_data16:
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 8, end);
+      SAFE_BYTE_GET_AND_INC (uvalue_hi, data, 8, end);
+      if (byte_get != byte_get_little_endian)
+       {
+         dwarf_vma utmp = uvalue;
+         uvalue = uvalue_hi;
+         uvalue_hi = utmp;
+       }
+      break;
+
     case DW_FORM_sdata:
       READ_SLEB (svalue, data, end);
       uvalue = svalue;
     case DW_FORM_data8:
       if (!do_loc)
        {
-         dwarf_vma high_bits;
-         dwarf_vma utmp;
-         char buf[64];
-
-         SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
-         utmp = uvalue;
+         dwarf_vma utmp = uvalue;
          if (form == DW_FORM_ref8)
-           add64 (& high_bits, & utmp, cu_offset);
-         printf ("%c0x%s", delimiter,
-                 dwarf_vmatoa64 (high_bits, utmp, buf, sizeof (buf)));
+           utmp += cu_offset;
+         printf ("%c0x%s", delimiter, dwarf_vmatoa ("x", utmp));
        }
-
-      if ((do_loc || do_debug_loc || do_debug_ranges)
-         && num_debug_info_entries == 0)
-       {
-         if (sizeof (uvalue) == 8)
-           SAFE_BYTE_GET (uvalue, data, 8, end);
-         else
-           error (_("DW_FORM_data8 is unsupported when sizeof (dwarf_vma) != 8\n"));
-       }
-
-      data += 8;
       break;
 
     case DW_FORM_data16:
       if (!do_loc)
-       {
-         dwarf_vma left_high_bits, left_low_bits;
-         dwarf_vma right_high_bits, right_low_bits;
-
-         SAFE_BYTE_GET64 (data, &left_high_bits, &left_low_bits, end);
-         SAFE_BYTE_GET64 (data + 8, &right_high_bits, &right_low_bits, end);
-         if (byte_get == byte_get_little_endian)
-           {
-             /* Swap them.  */
-             left_high_bits ^= right_high_bits;
-             right_high_bits ^= left_high_bits;
-             left_high_bits ^= right_high_bits;
-             left_low_bits ^= right_low_bits;
-             right_low_bits ^= left_low_bits;
-             left_low_bits ^= right_low_bits;
-           }
-         printf (" 0x%08" DWARF_VMA_FMT "x%08" DWARF_VMA_FMT "x"
-                 "%08" DWARF_VMA_FMT "x%08" DWARF_VMA_FMT "x",
-                 left_high_bits, left_low_bits, right_high_bits,
-                 right_low_bits);
-       }
-      data += 16;
+       printf (" 0x%s%s",
+               uvalue_hi == 0 ? "" : dwarf_vmatoa ("x", uvalue_hi),
+               dwarf_vmatoa_1 ("x", uvalue, uvalue_hi == 0 ? 0 : 8));
       break;
 
     case DW_FORM_string:
 
     case DW_FORM_ref_sig8:
       if (!do_loc)
-       {
-         dwarf_vma high_bits;
-         char buf[64];
-
-         SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
-         if (do_wide)
-           /* We have already displayed the form name.  */
-           printf ("%c: 0x%s", delimiter,
-                   dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
-         else
-           printf ("%csignature: 0x%s", delimiter,
-                   dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
-       }
-      data += 8;
+       printf ("%c%s: 0x%s", delimiter, do_wide ? "" : "signature",
+               dwarf_vmatoa ("x", uvalue));
       break;
 
     case DW_FORM_GNU_addr_index:
       unsigned long sec_off;
       unsigned int offset_size;
       unsigned int initial_length_size;
-      dwarf_vma signature_high = 0;
-      dwarf_vma signature_low = 0;
+      dwarf_vma signature = 0;
       dwarf_vma type_offset = 0;
       struct cu_tu_set *this_set;
       dwarf_vma abbrev_base;
 
       if (do_types)
        {
-         SAFE_BYTE_GET64 (hdrptr, &signature_high, &signature_low, end);
-         hdrptr += 8;
+         SAFE_BYTE_GET_AND_INC (signature, hdrptr, 8, end);
          SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end);
        }
 
          printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
          if (do_types)
            {
-             char buf[64];
-
              printf (_("   Signature:     0x%s\n"),
-                     dwarf_vmatoa64 (signature_high, signature_low,
-                                     buf, sizeof (buf)));
+                     dwarf_vmatoa ("x", signature));
              printf (_("   Type Offset:   0x%s\n"),
                      dwarf_vmatoa ("x", type_offset));
            }
   unsigned int nslots;
   unsigned int i;
   unsigned int j;
-  dwarf_vma signature_high;
-  dwarf_vma signature_low;
-  char buf[64];
+  dwarf_vma signature;
 
   /* PR 17512: file: 002-168123-0.004.  */
   if (phdr == NULL)
          unsigned char *shndx_list;
          unsigned int shndx;
 
-         SAFE_BYTE_GET64 (phash, &signature_high, &signature_low, limit);
-         if (signature_high != 0 || signature_low != 0)
+         SAFE_BYTE_GET (signature, phash, 8, limit);
+         if (signature != 0)
            {
              SAFE_BYTE_GET (j, pindex, 4, limit);
              shndx_list = ppool + j * 4;
 
              if (do_display)
                printf (_("  [%3d] Signature:  0x%s  Sections: "),
-                       i, dwarf_vmatoa64 (signature_high, signature_low,
-                                          buf, sizeof (buf)));
+                       i, dwarf_vmatoa ("x", signature));
              for (;;)
                {
                  if (shndx_list >= limit)
 
       for (i = 0; i < nslots; i++)
        {
-         SAFE_BYTE_GET64 (ph, &signature_high, &signature_low, limit);
+         SAFE_BYTE_GET (signature, ph, 8, limit);
 
          SAFE_BYTE_GET (row, pi, 4, limit);
          if (row != 0)
 
              if (do_display)
                printf (_("  [%3d] 0x%s"),
-                       i, dwarf_vmatoa64 (signature_high, signature_low,
-                                          buf, sizeof (buf)));
+                       i, dwarf_vmatoa ("x", signature));
              for (j = 0; j < ncols; j++)
                {
                  SAFE_BYTE_GET (val, prow + j * 4, 4, limit);
 
       for (i = 0; i < nslots; i++)
        {
-         SAFE_BYTE_GET64 (ph, &signature_high, &signature_low, limit);
+         SAFE_BYTE_GET (signature, ph, 8, limit);
 
          SAFE_BYTE_GET (row, pi, 4, limit);
          if (row != 0)
 
              if (do_display)
                printf (_("  [%3d] 0x%s"),
-                       i, dwarf_vmatoa64 (signature_high, signature_low,
-                                          buf, sizeof (buf)));
+                       i, dwarf_vmatoa ("x", signature));
 
              for (j = 0; j < ncols; j++)
                {
 
   va_end (args);
 }
 
-void (*byte_put) (unsigned char *, elf_vma, int);
+void (*byte_put) (unsigned char *, elf_vma, unsigned int);
 
 void
-byte_put_little_endian (unsigned char * field, elf_vma value, int size)
+byte_put_little_endian (unsigned char * field, elf_vma value, unsigned int size)
 {
-  if (size <= 0 || size > 8)
+  if (size > sizeof (elf_vma))
     {
       error (_("Unhandled data length: %d\n"), size);
       abort ();
 }
 
 void
-byte_put_big_endian (unsigned char * field, elf_vma value, int size)
+byte_put_big_endian (unsigned char * field, elf_vma value, unsigned int size)
 {
-  if (size <= 0 || size > 8)
+  if (size > sizeof (elf_vma))
     {
       error (_("Unhandled data length: %d\n"), size);
       abort ();
     }
 }
 
-elf_vma (*byte_get) (const unsigned char *, int);
+elf_vma (*byte_get) (const unsigned char *, unsigned int);
 
 elf_vma
-byte_get_little_endian (const unsigned char *field, int size)
+byte_get_little_endian (const unsigned char *field, unsigned int size)
 {
   switch (size)
     {
        |    (((unsigned long) (field[3])) << 24);
 
     case 5:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return  ((elf_vma) (field[0]))
          |    (((elf_vma) (field[1])) << 8)
          |    (((elf_vma) (field[2])) << 16)
          |    (((elf_vma) (field[3])) << 24)
          |    (((elf_vma) (field[4])) << 32);
-      else if (sizeof (elf_vma) == 4)
-       /* We want to extract data from an 8 byte wide field and
-          place it into a 4 byte wide field.  Since this is a little
-          endian source we can just use the 4 byte extraction code.  */
-       return  ((unsigned long) (field[0]))
-         |    (((unsigned long) (field[1])) << 8)
-         |    (((unsigned long) (field[2])) << 16)
-         |    (((unsigned long) (field[3])) << 24);
       /* Fall through.  */
 
     case 6:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return  ((elf_vma) (field[0]))
          |    (((elf_vma) (field[1])) << 8)
          |    (((elf_vma) (field[2])) << 16)
          |    (((elf_vma) (field[3])) << 24)
          |    (((elf_vma) (field[4])) << 32)
          |    (((elf_vma) (field[5])) << 40);
-      else if (sizeof (elf_vma) == 4)
-       /* We want to extract data from an 8 byte wide field and
-          place it into a 4 byte wide field.  Since this is a little
-          endian source we can just use the 4 byte extraction code.  */
-       return  ((unsigned long) (field[0]))
-         |    (((unsigned long) (field[1])) << 8)
-         |    (((unsigned long) (field[2])) << 16)
-         |    (((unsigned long) (field[3])) << 24);
       /* Fall through.  */
 
     case 7:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return  ((elf_vma) (field[0]))
          |    (((elf_vma) (field[1])) << 8)
          |    (((elf_vma) (field[2])) << 16)
          |    (((elf_vma) (field[4])) << 32)
          |    (((elf_vma) (field[5])) << 40)
          |    (((elf_vma) (field[6])) << 48);
-      else if (sizeof (elf_vma) == 4)
-       /* We want to extract data from an 8 byte wide field and
-          place it into a 4 byte wide field.  Since this is a little
-          endian source we can just use the 4 byte extraction code.  */
-       return  ((unsigned long) (field[0]))
-         |    (((unsigned long) (field[1])) << 8)
-         |    (((unsigned long) (field[2])) << 16)
-         |    (((unsigned long) (field[3])) << 24);
       /* Fall through.  */
 
     case 8:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return  ((elf_vma) (field[0]))
          |    (((elf_vma) (field[1])) << 8)
          |    (((elf_vma) (field[2])) << 16)
          |    (((elf_vma) (field[5])) << 40)
          |    (((elf_vma) (field[6])) << 48)
          |    (((elf_vma) (field[7])) << 56);
-      else if (sizeof (elf_vma) == 4)
-       /* We want to extract data from an 8 byte wide field and
-          place it into a 4 byte wide field.  Since this is a little
-          endian source we can just use the 4 byte extraction code.  */
-       return  ((unsigned long) (field[0]))
-         |    (((unsigned long) (field[1])) << 8)
-         |    (((unsigned long) (field[2])) << 16)
-         |    (((unsigned long) (field[3])) << 24);
       /* Fall through.  */
 
     default:
 }
 
 elf_vma
-byte_get_big_endian (const unsigned char *field, int size)
+byte_get_big_endian (const unsigned char *field, unsigned int size)
 {
   switch (size)
     {
        |   (((unsigned long) (field[0])) << 24);
 
     case 5:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return ((elf_vma) (field[4]))
          |   (((elf_vma) (field[3])) << 8)
          |   (((elf_vma) (field[2])) << 16)
          |   (((elf_vma) (field[1])) << 24)
          |   (((elf_vma) (field[0])) << 32);
-      else if (sizeof (elf_vma) == 4)
-       {
-         /* Although we are extracting data from an 8 byte wide field,
-            we are returning only 4 bytes of data.  */
-         field += 1;
-         return ((unsigned long) (field[3]))
-           |   (((unsigned long) (field[2])) << 8)
-           |   (((unsigned long) (field[1])) << 16)
-           |   (((unsigned long) (field[0])) << 24);
-       }
       /* Fall through.  */
 
     case 6:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return ((elf_vma) (field[5]))
          |   (((elf_vma) (field[4])) << 8)
          |   (((elf_vma) (field[3])) << 16)
          |   (((elf_vma) (field[2])) << 24)
          |   (((elf_vma) (field[1])) << 32)
          |   (((elf_vma) (field[0])) << 40);
-      else if (sizeof (elf_vma) == 4)
-       {
-         /* Although we are extracting data from an 8 byte wide field,
-            we are returning only 4 bytes of data.  */
-         field += 2;
-         return ((unsigned long) (field[3]))
-           |   (((unsigned long) (field[2])) << 8)
-           |   (((unsigned long) (field[1])) << 16)
-           |   (((unsigned long) (field[0])) << 24);
-       }
       /* Fall through.  */
 
     case 7:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return ((elf_vma) (field[6]))
          |   (((elf_vma) (field[5])) << 8)
          |   (((elf_vma) (field[4])) << 16)
          |   (((elf_vma) (field[2])) << 32)
          |   (((elf_vma) (field[1])) << 40)
          |   (((elf_vma) (field[0])) << 48);
-      else if (sizeof (elf_vma) == 4)
-       {
-         /* Although we are extracting data from an 8 byte wide field,
-            we are returning only 4 bytes of data.  */
-         field += 3;
-         return ((unsigned long) (field[3]))
-           |   (((unsigned long) (field[2])) << 8)
-           |   (((unsigned long) (field[1])) << 16)
-           |   (((unsigned long) (field[0])) << 24);
-       }
       /* Fall through.  */
 
     case 8:
-      if (sizeof (elf_vma) == 8)
+      if (sizeof (elf_vma) >= 8)
        return ((elf_vma) (field[7]))
          |   (((elf_vma) (field[6])) << 8)
          |   (((elf_vma) (field[5])) << 16)
          |   (((elf_vma) (field[2])) << 40)
          |   (((elf_vma) (field[1])) << 48)
          |   (((elf_vma) (field[0])) << 56);
-      else if (sizeof (elf_vma) == 4)
-       {
-         /* Although we are extracting data from an 8 byte wide field,
-            we are returning only 4 bytes of data.  */
-         field += 4;
-         return ((unsigned long) (field[3]))
-           |   (((unsigned long) (field[2])) << 8)
-           |   (((unsigned long) (field[1])) << 16)
-           |   (((unsigned long) (field[0])) << 24);
-       }
       /* Fall through.  */
 
     default:
 }
 
 elf_vma
-byte_get_signed (const unsigned char *field, int size)
+byte_get_signed (const unsigned char *field, unsigned int size)
 {
   elf_vma x = byte_get (field, size);
 
     }
 }
 
-/* Return the high-order 32-bits and the low-order 32-bits
-   of an 8-byte value separately.  */
-
-void
-byte_get_64 (const unsigned char *field, elf_vma *high, elf_vma *low)
-{
-  if (byte_get == byte_get_big_endian)
-    {
-      *high = byte_get_big_endian (field, 4);
-      *low = byte_get_big_endian (field + 4, 4);
-    }
-  else
-    {
-      *high = byte_get_little_endian (field + 4, 4);
-      *low = byte_get_little_endian (field, 4);
-    }
-  return;
-}
-
 /* Return the path name for a proxy entry in a thin archive, adjusted
    relative to the path name of the thin archive itself if necessary.
    Always returns a pointer to malloc'ed memory.  */
 
 
 typedef unsigned HOST_WIDEST_INT elf_vma;
 
-extern void (*byte_put) (unsigned char *, elf_vma, int);
-extern void byte_put_little_endian (unsigned char *, elf_vma, int);
-extern void byte_put_big_endian (unsigned char *, elf_vma, int);
-
-extern elf_vma (*byte_get) (const unsigned char *, int);
-extern elf_vma byte_get_signed (const unsigned char *, int);
-extern elf_vma byte_get_little_endian (const unsigned char *, int);
-extern elf_vma byte_get_big_endian (const unsigned char *, int);
-extern void byte_get_64 (const unsigned char *, elf_vma *, elf_vma *);
+extern void (*byte_put) (unsigned char *, elf_vma, unsigned int);
+extern void byte_put_little_endian (unsigned char *, elf_vma, unsigned int);
+extern void byte_put_big_endian (unsigned char *, elf_vma, unsigned int);
+
+extern elf_vma (*byte_get) (const unsigned char *, unsigned int);
+extern elf_vma byte_get_signed (const unsigned char *, unsigned int);
+extern elf_vma byte_get_little_endian (const unsigned char *, unsigned int);
+extern elf_vma byte_get_big_endian (const unsigned char *, unsigned int);
 
 #define BYTE_PUT(field, val)   byte_put (field, val, sizeof (field))
 #define BYTE_GET(field)                byte_get (field, sizeof (field))
 
+2021-05-12  Alan Modra  <amodra@gmail.com>
+
+       * testsuite/gas/elf/dwarf-5-file0.d: Update.
+       * testsuite/gas/i386/dwarf5-line-1.d: Update.
+
 2021-05-11  Sergey Belyashov  <sergey.belyashov@gmail.com>
 
        PR 27823
 
 
  The File Name Table \(offset 0x.*, lines 3, columns 3\):
   Entry        Dir     MD5                             Name
-  0    0 0x00000000000000000000000000000000    \(indirect line string, offset: 0x.*\): master source file
-  1    1 0x00000000000000000000000000000000    \(indirect line string, offset: 0x.*\): secondary source file
+  0    0 0x0   \(indirect line string, offset: 0x.*\): master source file
+  1    1 0x0   \(indirect line string, offset: 0x.*\): secondary source file
   2    2 0x95828e8bc4f7404dbf7526fb7bd0f192    \(indirect line string, offset: 0x.*\): foo.c
 #pass
 
 
  The File Name Table \(offset 0x.*, lines 2, columns 3\):
   Entry        Dir     MD5                             Name
   0    0 0xbbd69fc03ce253b2dbaab2522dd519ae    \(indirect line string, offset: 0x.*\): core.c
-  1    0 0x00000000000000000000000000000000    \(indirect line string, offset: 0x.*\): types.h
+  1    0 0x0   \(indirect line string, offset: 0x.*\): types.h
 
  Line Number Statements:
   \[0x.*\]  Extended opcode 2: set Address to 0x0