Add support for the DW_FORM_strx* forms to the BFD library.
authorNick Clifton <nickc@redhat.com>
Fri, 5 Mar 2021 17:06:59 +0000 (17:06 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 5 Mar 2021 17:06:59 +0000 (17:06 +0000)
PR 27521
* dwarf2.c (is_str_attr): Add DW_FORM_strx* forms.
(read_indexed_string): Placeholder function.
(read_attribute_value): Handle DW_FORM_strx* and DW_FORM_addrx*
forms.

bfd/ChangeLog
bfd/dwarf2.c

index bc1a530a9dbcf0fbfb9abf1c72f1b3589b568fff..d4525f1e69673d2895126fd24dacfbf51249776a 100644 (file)
@@ -1,3 +1,11 @@
+2021-03-05  Nick Clifton  <nickc@redhat.com>
+
+       PR 27521
+       * dwarf2.c (is_str_attr): Add DW_FORM_strx* forms.
+       (read_indexed_string): Placeholder function.
+       (read_attribute_value): Handle DW_FORM_strx* and DW_FORM_addrx*
+       forms.
+
 2021-03-05  Alan Modra  <amodra@gmail.com>
 
        * reloc.c (bfd_perform_relocation): Revert 2021-01-12 and
index c0fb956e686fc5eea8b6cd3f1eacd24cd100e560..b42e641aa3b9247cb5aa323ee90f4efd18f60022 100644 (file)
@@ -1160,8 +1160,23 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash,
 static inline bfd_boolean
 is_str_attr (enum dwarf_form form)
 {
-  return (form == DW_FORM_string || form == DW_FORM_strp
-         || form == DW_FORM_line_strp || form == DW_FORM_GNU_strp_alt);
+  return (form == DW_FORM_string
+         || form == DW_FORM_strp
+         || form == DW_FORM_strx
+         || form == DW_FORM_strx1
+         || form == DW_FORM_strx2
+         || form == DW_FORM_strx3
+         || form == DW_FORM_strx4
+         || form == DW_FORM_line_strp
+         || form == DW_FORM_GNU_strp_alt);
+}
+
+static const char *
+read_indexed_string (bfd_uint64_t index ATTRIBUTE_UNUSED,
+                    struct comp_unit * unit ATTRIBUTE_UNUSED)
+{
+  /* FIXME: Add support for indexed strings.  */
+  return "<indexed strings not yet supported>";
 }
 
 /* Read and fill in the value of attribute ATTR as described by FORM.
@@ -1192,6 +1207,9 @@ read_attribute_value (struct attribute *  attr,
 
   switch (form)
     {
+    case DW_FORM_flag_present:
+      attr->u.val = 1;
+      break;
     case DW_FORM_ref_addr:
       /* DW_FORM_ref_addr is an address in DWARF2, and an offset in
         DWARF3.  */
@@ -1237,15 +1255,32 @@ read_attribute_value (struct attribute *  attr,
       info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
+    case DW_FORM_ref1:
+    case DW_FORM_flag:
+    case DW_FORM_data1:
+    case DW_FORM_addrx1:
+      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
+      info_ptr += 1;
+      break;
     case DW_FORM_data2:
+    case DW_FORM_ref2:
       attr->u.val = read_2_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 2;
       break;
+    case DW_FORM_addrx3:
+      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
+      attr->u.val &= 0xffffff;
+      info_ptr += 3;
+      break;
+    case DW_FORM_ref4:
     case DW_FORM_data4:
+    case DW_FORM_addrx4:
       attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 4;
       break;
     case DW_FORM_data8:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_sig8:
       attr->u.val = read_8_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 8;
       break;
@@ -1265,6 +1300,33 @@ read_attribute_value (struct attribute *  attr,
       attr->u.str = read_alt_indirect_string (unit, info_ptr, info_ptr_end, &bytes_read);
       info_ptr += bytes_read;
       break;
+    case DW_FORM_strx1:
+      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
+      info_ptr += 1;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx2:
+      attr->u.val = read_2_bytes (abfd, info_ptr, info_ptr_end);
+      info_ptr += 2;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx3:
+      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
+      info_ptr += 3;
+      attr->u.val &= 0xffffff;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx4:
+      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
+      info_ptr += 4;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx:
+      attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                        FALSE, info_ptr_end);
+      info_ptr += bytes_read;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
     case DW_FORM_exprloc:
     case DW_FORM_block:
       amt = sizeof (struct dwarf_block);
@@ -1287,48 +1349,14 @@ read_attribute_value (struct attribute *  attr,
       info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
-    case DW_FORM_data1:
-      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
-      info_ptr += 1;
-      break;
-    case DW_FORM_flag:
-      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
-      info_ptr += 1;
-      break;
-    case DW_FORM_flag_present:
-      attr->u.val = 1;
-      break;
     case DW_FORM_sdata:
       attr->u.sval = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
                                            TRUE, info_ptr_end);
       info_ptr += bytes_read;
       break;
-    case DW_FORM_udata:
-      attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
-                                          FALSE, info_ptr_end);
-      info_ptr += bytes_read;
-      break;
-    case DW_FORM_ref1:
-      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
-      info_ptr += 1;
-      break;
-    case DW_FORM_ref2:
-      attr->u.val = read_2_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 2;
-      break;
-    case DW_FORM_ref4:
-      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 4;
-      break;
-    case DW_FORM_ref8:
-      attr->u.val = read_8_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 8;
-      break;
-    case DW_FORM_ref_sig8:
-      attr->u.val = read_8_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 8;
-      break;
     case DW_FORM_ref_udata:
+    case DW_FORM_udata:
+    case DW_FORM_addrx:
       attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
                                           FALSE, info_ptr_end);
       info_ptr += bytes_read;
@@ -1361,6 +1389,7 @@ read_attribute_value (struct attribute *  attr,
       info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
+
     default:
       _bfd_error_handler (_("DWARF error: invalid or unhandled FORM value: %#x"),
                          form);