public inbox for dwz@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Support for clang-generated DWARF5 sections .debug_addr/.debug_str_offsets
@ 2021-05-16 11:29 E, Nagajyothi
  2021-05-19 17:22 ` E, Nagajyothi
  0 siblings, 1 reply; 2+ messages in thread
From: E, Nagajyothi @ 2021-05-16 11:29 UTC (permalink / raw)
  To: Mark Wielaard, dwz
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar, E,
	Nagajyothi, Parasuraman, Hariharan

[-- Attachment #1: Type: text/plain, Size: 3441 bytes --]

[AMD Official Use Only - Internal Distribution Only]

Hi,

Please review and commit the attached patch to support clang-generated DWARF5 debug sections .debug_addr and .debug_str_offsets.
This patch does not address ODR and multifile support, which will be added through subsequent patches. Due to this, the ODR tests and cycle.sh of the testsuite fail during 'make check'.

The accompanying testsuite patch may be used while running
	 make check CC="clang -gdwarf-5" CXX="clang++ -gdwarf-5"
to avoid test failures due to readelf, as readelf does not support some of the strx forms generated by clang.

Thanks,
Nagajyothi

-----Original Message-----
From: Mark Wielaard <mark@klomp.org> 
Sent: Thursday, February 18, 2021 8:15 PM
To: E, Nagajyothi <Nagajyothi.E@amd.com>; dwz@sourceware.org
Cc: George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>
Subject: Re: Plan to contribute for supporting split dwarf (-gsplit-dwarf) in dwz

[CAUTION: External Email]

Hi Nagajyothi,

On Wed, 2021-02-17 at 05:53 +0000, E, Nagajyothi via Dwz wrote:
> I am working on adding support for the dwarf5 .debug_str_offsets, 
> .debug_addr sections and the related forms DW_FORM_strx[1234], DW_FORM_addrx[1234].
> Please let me know if anyone has already started work on these.

Thanks, I don't believe anybody is working on this right now.

There is already a bug for .debug_addr/DW_FORM_addrx[1234] support:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceware.org%2Fbugzilla%2Fshow_bug.cgi%3Fid%3D27375&amp;data=04%7C01%7CNagajyothi.E%40amd.com%7C37c0fb4399464264b01808d8d41bcb9c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637492563147320988%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=7AjB%2BXKo9J5gTlW1CeEhHXZykYKB2vFZ%2BTnBQvW4%2BIA%3D&amp;reserved=0
I think this shouldn't be too hard. Any DIE that references an address cannot be moved to an alt file, so simply mark it with die_no_multifile. We do try to optimize DW_AT_low/high_pc attribute pairs, so double check that doesn't interfere with DW_FORM_addrx[1234] processing.

Also note that there are two new location operations DW_OP_addrx and DW_OP_constx that can reference the .debug_addr section index.

As a followup you could try optimizing things, but then you need to keep track of all the addresses used and see if there are duplicates that could be turned into a (smaller) DW_FORM_addrx[1234] index. But I would keep that separate from the initial implementation.

For .debug_str_offset/DW_FORM_strx[1234] I opened a new bug.
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceware.org%2Fbugzilla%2Fshow_bug.cgi%3Fid%3D27434&amp;data=04%7C01%7CNagajyothi.E%40amd.com%7C37c0fb4399464264b01808d8d41bcb9c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637492563147330979%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=AqQRLjgKh9h7YHPIr4wDiqP1rRTXz2kG6IZlAT0SaSQ%3D&amp;reserved=0

This is a little trickier than DW_FORM_addrx[1234] since such DIEs using DW_FORM_strx may be moved to a multifile. You also probably want to make them equal to DW_FORM_strp entries pointing (indirectly) to the same string.

You might want to add a note to the the bugs that you are working on them.

Thanks,

Mark

[-- Attachment #2: 0001-PR27375-PR27434-Recognize-new-DWARF5-sections-.debug.patch --]
[-- Type: application/octet-stream, Size: 21776 bytes --]

From 3a36175125ad01cd00174f51a004fa6c490da14c Mon Sep 17 00:00:00 2001
From: Nagajyothi Eggone <Nagajyothi.E@amd.com>
Date: Sun, 16 May 2021 16:02:25 +0530
Subject: [PATCH 1/2] PR27375, PR27434 - Recognize new DWARF5 sections
 .debug_addr, .debug_str_offsets

This adds support for sections .debug_addr and .debug_str_offsets, and related forms DW_FORM_addrx,
DW_FORM_strx[1|2|3|4], which are generated by clang. DW_FORM_addrx[1|2|3|4] are not handled as they are not produced by clang as yet. DW_FORM_loclistx and DW_FORM_rnglistx are also handled in several places as required.

     Changelog:
   * dwz.c (do_read_24) : New function to read DW_FORM_strx3.
           (buf_read_ule24) : Likewise.
           (buf_read_ube24) : Likewise.
           (read_24) : New macro for 24-bit read.
           (read_size) : Add case for 24-bit read.
           (init_endian): Likewise.
           (enum debug_section_kind): Add DEBUG_STR_OFFSETS and DEBUG_ADDR.
           (debug_sections): Add .debug_str_offsets and .debug_addr entries.
           (struct dw_cu): New member cu_str_offsets_base to hold str_offsets_base.
           (read_abbrev): Add DW_FORM_addrx, DW_FORM_strx[1|2|3|4], DW_FORM_loclistx, DW_FORM_rnglistx.
           (skip_attr_no_dw_form_indirect): Likewise.
           (checksum_die): Likewise.
           (checksum_ref_die): Likewise.
           (die_eq_1): Likewise.
           (mark_refs): Likewise.
           (build_abbrevs_for_die): Likewise.
           (write_unit_die): Likewise.
           (write_die): Likewise.
           (read_debug_info): Add DW_FORM_addrx, DW_FORM_strx[1|2|3|4].
                              record str_offsets_base in dw_cu member cu_str_offsets_base for use in
                              reading strings referenced with DW_FORM_strx[1|2|3|4].
           (partition_dups_1): Add size of str_offsets_base to CU/PU header size estimate.

           (read_debug_line): Add case for DW_LNCT_MD5.
           (get_AT_string): Read string index from .debug_str_offsets sections and read string
                            from .debug_str section using this as offset.
           (read_exprloc): Add DW_OP_addrx.
           (adjust_exprloc): Likewise.

    This patch does not address ODR and multifile support, which will be added through subsequent patches. Due to this,
	make check CC="clang -gdwarf-5" CXX="clang++ -gdwarf-5"
has the following tests failing:
	testsuite/dwz.tests/cycle.sh
	testsuite/dwz.tests/odr-class-ns.sh
	testsuite/dwz.tests/odr-loc.sh
	testsuite/dwz.tests/odr-struct-ns.sh
	testsuite/dwz.tests/odr-class.sh
	testsuite/dwz.tests/odr-union-ns.sh
	testsuite/dwz.tests/odr-struct-multifile.sh
	testsuite/dwz.tests/odr-struct.sh
	testsuite/dwz.tests/odr-union.sh
---
 dwz.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 253 insertions(+), 4 deletions(-)

diff --git a/dwz.c b/dwz.c
index a3b289f..f758ddb 100644
--- a/dwz.c
+++ b/dwz.c
@@ -475,6 +475,7 @@ static unsigned int lowest_line_version = 5;
    given ELF endianity, which might be different from host endianity.
    No specific alignment is expected.  */
 static uint16_t (*do_read_16) (unsigned char *ptr);
+static uint32_t (*do_read_24) (unsigned char *ptr);
 static uint32_t (*do_read_32) (unsigned char *ptr);
 static uint64_t (*do_read_64) (unsigned char *ptr);
 static void (*do_write_16) (unsigned char *ptr, unsigned short val);
@@ -493,6 +494,20 @@ buf_read_ube16 (unsigned char *data)
   return data[1] | (data[0] << 8);
 }
 
+static inline uint32_t
+buf_read_ule24 (unsigned char *data)
+{
+  return (data[0] | (data[1] << 8) | (data[2] << 16)
+          | ((unsigned int)0x0 << 24));
+}
+
+static inline uint32_t
+buf_read_ube24 (unsigned char *data)
+{
+  return ((0x0) | (data[2] << 8) | (data[1] << 16)
+	   | ((unsigned int)data[0] << 24));
+}
+
 static inline uint32_t
 buf_read_ule32 (unsigned char *data)
 {
@@ -529,6 +544,12 @@ buf_read_ube64 (unsigned char *data)
   ret;							\
 })
 
+#define read_24(ptr) ({					\
+  uint32_t ret = do_read_24 (ptr);			\
+  ptr += 3;						\
+  ret;							\
+})
+
 #define read_32(ptr) ({					\
   uint32_t ret = do_read_32 (ptr);			\
   ptr += 4;						\
@@ -577,6 +598,7 @@ read_size (unsigned char *p, int size)
     {
     case 1: return read_8 (p);
     case 2: return read_16 (p);
+    case 3: return read_24 (p);
     case 4: return read_32 (p);
     case 8: return read_64 (p);
     default: abort ();
@@ -720,9 +742,11 @@ enum debug_section_kind
   DEBUG_ABBREV,
   DEBUG_LINE,
   DEBUG_STR,
+  DEBUG_STR_OFFSETS,
   DEBUG_MACRO,
   DEBUG_TYPES,
   DEBUG_ARANGES,
+  DEBUG_ADDR,
   DEBUG_PUBNAMES,
   DEBUG_PUBTYPES,
   DEBUG_GNU_PUBNAMES,
@@ -757,9 +781,11 @@ static struct
     { ".debug_abbrev", NULL, NULL, 0, 0, 0 },
     { ".debug_line", NULL, NULL, 0, 0, 0 },
     { ".debug_str", NULL, NULL, 0, 0, 0 },
+    { ".debug_str_offsets", NULL, NULL, 0, 0, 0 },
     { ".debug_macro", NULL, NULL, 0, 0, 0 },
     { ".debug_types", NULL, NULL, 0, 0, 0 },
     { ".debug_aranges", NULL, NULL, 0, 0, 0 },
+    { ".debug_addr", NULL, NULL, 0, 0, 0 },
     { ".debug_pubnames", NULL, NULL, 0, 0, 0 },
     { ".debug_pubtypes", NULL, NULL, 0, 0, 0 },
     { ".debug_gnu_pubnames", NULL, NULL, 0, 0, 0 },
@@ -942,6 +968,7 @@ struct dw_cu
   /* Intracusize argument to init_new_die_offsets.  Set in compute_abbrevs,
      used in recompute_abbrevs.  */
   unsigned int initial_intracusize;
+  unsigned int cu_str_offsets_base;
   enum dwarf_source_language lang;
 };
 
@@ -1236,6 +1263,14 @@ read_abbrev (DSO *dso, unsigned char *ptr)
 	      || (form > DW_FORM_flag_present
 		  && !(form == DW_FORM_ref_sig8
 		       || form == DW_FORM_data16
+		       || form == DW_FORM_addrx
+		       || form == DW_FORM_loclistx
+		       || form == DW_FORM_rnglistx
+		       || 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)))
 	    {
 	      error (0, 0, "%s: Unknown DWARF %s",
@@ -1316,15 +1351,21 @@ skip_attr_no_dw_form_indirect (unsigned int cu_version, uint32_t form,
     case DW_FORM_implicit_const:
       break;
     case DW_FORM_ref1:
+    case DW_FORM_strx1:
     case DW_FORM_flag:
     case DW_FORM_data1:
       ++ptr;
       break;
     case DW_FORM_ref2:
+    case DW_FORM_strx2:
     case DW_FORM_data2:
       ptr += 2;
       break;
+    case DW_FORM_strx3:
+      ptr += 3;
+      break;
     case DW_FORM_ref4:
+    case DW_FORM_strx4:
     case DW_FORM_data4:
     case DW_FORM_sec_offset:
     case DW_FORM_strp:
@@ -1342,6 +1383,10 @@ skip_attr_no_dw_form_indirect (unsigned int cu_version, uint32_t form,
     case DW_FORM_sdata:
     case DW_FORM_ref_udata:
     case DW_FORM_udata:
+    case DW_FORM_addrx:
+    case DW_FORM_loclistx:
+    case DW_FORM_rnglistx:
+    case DW_FORM_strx:
       skip_leb128 (ptr);
       break;
     case DW_FORM_string:
@@ -1716,6 +1761,9 @@ read_debug_line (DSO *dso, dw_cu_ref cu, uint32_t off)
 		}
 	      break;
 
+            case DW_LNCT_MD5:
+              break;
+
 	    default:
 	      error (0, 0, "%s: .debug_line unhandled file element %s",
 		     dso->filename, get_DW_LNCT_str (lnct));
@@ -2201,6 +2249,39 @@ get_AT_string (dw_die_ref die, enum dwarf_attribute at)
 	  return NULL;
 	return (char *) debug_sections[DEBUG_STR].data + strp;
       }
+    case DW_FORM_strx:
+    case DW_FORM_strx1:
+    case DW_FORM_strx2:
+    case DW_FORM_strx3:
+    case DW_FORM_strx4:
+      {
+	unsigned int str_offsets_base = die_cu(die)->cu_str_offsets_base;
+
+	uint64_t str_idx = 0;
+	if (form == DW_FORM_strx)
+	  str_idx = read_uleb128 (ptr);
+	if (form == DW_FORM_strx1)
+	  str_idx = read_8 (ptr);
+	if (form == DW_FORM_strx2)
+	  str_idx = read_16 (ptr);
+	if (form == DW_FORM_strx3)
+	  str_idx = read_24 (ptr);
+	if (form == DW_FORM_strx4)
+	  str_idx = read_32 (ptr);
+
+        if (str_idx >= debug_sections[DEBUG_STR_OFFSETS].size)
+          return NULL;
+
+	unsigned char *str_offset_ptr = str_offsets_base +
+		debug_sections[DEBUG_STR_OFFSETS].data +
+		(str_idx * 4); /* Each index entry is 4 bytes long*/
+
+        unsigned int str_offset = read_32(str_offset_ptr);
+        if (str_offset >= debug_sections[DEBUG_STR].size)
+          return NULL;
+
+	return (char *) debug_sections[DEBUG_STR].data + str_offset;
+      }
     case DW_FORM_line_strp:
       {
 	unsigned int line_strp = read_32 (ptr);
@@ -2239,6 +2320,10 @@ read_exprloc (DSO *dso, dw_die_ref die, unsigned char *ptr, size_t len,
 	  die->die_no_multifile = 1;
 	  ptr += ptr_size;
 	  break;
+	case DW_OP_addrx:
+	  die->die_no_multifile = 1;
+	  skip_leb128 (ptr);
+	  break;
 	case DW_OP_deref:
 	case DW_OP_dup:
 	case DW_OP_drop:
@@ -3560,6 +3645,10 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
 	  die->die_no_multifile = 1;
 	  ptr += ptr_size;
 	  break;
+	case DW_FORM_addrx:
+	  die->die_no_multifile = 1;
+	  skip_leb128 (ptr);
+	  break;
 	case DW_FORM_flag_present:
 	  break;
 	case DW_FORM_implicit_const:
@@ -3575,13 +3664,19 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
 	  break;
 	case DW_FORM_flag:
 	case DW_FORM_data1:
+	case DW_FORM_strx1:
 	  ++ptr;
 	  break;
 	case DW_FORM_data2:
+	case DW_FORM_strx2:
 	  ptr += 2;
 	  break;
+	case DW_FORM_strx3:
+	  ptr += 3;
+	  break;
 	case DW_FORM_data4:
 	case DW_FORM_sec_offset:
+	case DW_FORM_strx4:
 	  ptr += 4;
 	  break;
 	case DW_FORM_data8:
@@ -3596,6 +3691,9 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
 	  break;
 	case DW_FORM_sdata:
 	case DW_FORM_udata:
+	case DW_FORM_strx:
+	case DW_FORM_loclistx:
+	case DW_FORM_rnglistx:
 	  skip_leb128 (ptr);
 	  break;
 	case DW_FORM_ref_udata:
@@ -4018,15 +4116,21 @@ checksum_ref_die (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die,
 	      break;
 	    case DW_FORM_flag:
 	    case DW_FORM_data1:
+	    case DW_FORM_strx1:
 	      ++ptr;
 	      break;
 	    case DW_FORM_data2:
+	    case DW_FORM_strx2:
 	      ptr += 2;
 	      break;
+	    case DW_FORM_strx3:
+	      ptr += 3;
+	      break;
 	    case DW_FORM_data4:
 	    case DW_FORM_sec_offset:
 	    case DW_FORM_strp:
 	    case DW_FORM_line_strp:
+	    case DW_FORM_strx4:
 	      ptr += 4;
 	      break;
 	    case DW_FORM_data8:
@@ -4038,6 +4142,10 @@ checksum_ref_die (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die,
 	      break;
 	    case DW_FORM_sdata:
 	    case DW_FORM_udata:
+	    case DW_FORM_addrx:
+	    case DW_FORM_loclistx:
+	    case DW_FORM_rnglistx:
+	    case DW_FORM_strx:
 	      skip_leb128 (ptr);
 	      break;
 	    case DW_FORM_ref_udata:
@@ -4877,15 +4985,22 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
 	  break;
 	case DW_FORM_flag:
 	case DW_FORM_data1:
+	case DW_FORM_strx1:
 	  ++ptr1;
 	  ++ptr2;
 	  break;
 	case DW_FORM_data2:
+	case DW_FORM_strx2:
 	  ptr1 += 2;
 	  ptr2 += 2;
 	  break;
+	case DW_FORM_strx3:
+	  ptr1 += 3;
+	  ptr2 += 3;
+	  break;
 	case DW_FORM_data4:
 	case DW_FORM_sec_offset:
+	case DW_FORM_strx4:
 	  ptr1 += 4;
 	  ptr2 += 4;
 	  break;
@@ -4900,6 +5015,10 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
 	  break;
 	case DW_FORM_sdata:
 	case DW_FORM_udata:
+	case DW_FORM_addrx:
+	case DW_FORM_loclistx:
+	case DW_FORM_rnglistx:
+	case DW_FORM_strx:
 	  skip_leb128 (ptr1);
 	  skip_leb128 (ptr2);
 	  break;
@@ -5972,12 +6091,18 @@ mark_refs (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die, int mode)
 	    case DW_FORM_implicit_const:
 	      break;
 	    case DW_FORM_flag:
+            case DW_FORM_strx1:
 	    case DW_FORM_data1:
 	      ++ptr;
 	      break;
+            case DW_FORM_strx2:
 	    case DW_FORM_data2:
 	      ptr += 2;
 	      break;
+	    case DW_FORM_strx3:
+	      ptr += 3;
+	      break;
+	    case DW_FORM_strx4:
 	    case DW_FORM_data4:
 	    case DW_FORM_sec_offset:
 	    case DW_FORM_strp:
@@ -5993,6 +6118,10 @@ mark_refs (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die, int mode)
 	      break;
 	    case DW_FORM_sdata:
 	    case DW_FORM_udata:
+	    case DW_FORM_addrx:
+	    case DW_FORM_loclistx:
+	    case DW_FORM_rnglistx:
+	    case DW_FORM_strx:
 	      skip_leb128 (ptr);
 	      break;
 	    case DW_FORM_ref_udata:
@@ -6967,6 +7096,7 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count)
 		    cu->lang = *ptr;
 		  /* FALLTHRU */
 		case DW_FORM_ref1:
+		case DW_FORM_strx1:
 		case DW_FORM_flag:
 		  ++ptr;
 		  break;
@@ -6978,8 +7108,20 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count)
 		    cu->lang = do_read_16 (ptr);
 		  /* FALLTHRU */
 		case DW_FORM_ref2:
+		case DW_FORM_strx2:
 		  ptr += 2;
 		  break;
+		case DW_FORM_strx3:
+		  ptr += 3;
+		  break;
+		case DW_FORM_sec_offset:
+		  if ((die->die_tag == DW_TAG_compile_unit
+			  || die->die_tag == DW_TAG_partial_unit)
+		      && t->attr[i].attr == DW_AT_str_offsets_base)
+		    cu->cu_str_offsets_base = read_32(ptr);
+		  else
+		    ptr += 4;
+		  break;
 		case DW_FORM_data4:
 		  if (lang_p
 		      && (die->die_tag == DW_TAG_compile_unit
@@ -6988,7 +7130,7 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count)
 		    read_lang (ptr, form, &cu->lang);
 		  /* FALLTHRU */
 		case DW_FORM_ref4:
-		case DW_FORM_sec_offset:
+		case DW_FORM_strx4:
 		  ptr += 4;
 		  break;
 		case DW_FORM_data8:
@@ -7017,6 +7159,10 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count)
 		    }
 		  /* FALLTHRU */
 		case DW_FORM_ref_udata:
+		case DW_FORM_addrx:
+		case DW_FORM_rnglistx:
+		case DW_FORM_loclistx:
+		case DW_FORM_strx:
 		  skip_leb128 (ptr);
 		  break;
 		case DW_FORM_strp:
@@ -8052,6 +8198,7 @@ partition_dups_1 (dw_die_ref *arr, size_t nr_partitions, size_t *partitions,
 	   + ((uni_lang_p || part_lang)
 	      ? nr_bytes_for (die_cu (arr[i])->lang)
 	      : 0)
+	   + (die_cu (arr[i])->cu_str_offsets_base ? 4: 0)
 	   /* CU root DIE children terminator: abbreviation code 0
 					       (unsigned LEB128).
 	      1 byte.  */
@@ -10805,12 +10952,17 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 		case DW_FORM_implicit_const:
 		  break;
 		case DW_FORM_flag:
+		case DW_FORM_strx1:
 		case DW_FORM_data1:
 		  ++ptr;
 		  break;
+		case DW_FORM_strx2:
 		case DW_FORM_data2:
 		  ptr += 2;
 		  break;
+		case DW_FORM_strx3:
+		  ptr += 3;
+		  break;
 		case DW_FORM_data4:
 		  if (reft->attr[i].attr == DW_AT_high_pc)
 		    {
@@ -10827,6 +10979,7 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 		    }
 		  ptr += 4;
 		  break;
+		case DW_FORM_strx4:
 		case DW_FORM_sec_offset:
 		  ptr += 4;
 		  break;
@@ -10864,6 +11017,10 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 		  break;
 		case DW_FORM_sdata:
 		case DW_FORM_udata:
+		case DW_FORM_addrx:
+		case DW_FORM_loclistx:
+		case DW_FORM_rnglistx:
+		case DW_FORM_strx:
 		  skip_leb128 (ptr);
 		  break;
 		case DW_FORM_strp:
@@ -11038,7 +11195,12 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 	    unsigned char *ptr = get_AT (origin, DW_AT_comp_dir, &form);
 	    assert (ptr && (form == DW_FORM_string
 			    || form == DW_FORM_strp
-			    || form == DW_FORM_line_strp));
+			    || form == DW_FORM_line_strp
+                            || form == DW_FORM_strx
+                            || form == DW_FORM_strx1
+                            || form == DW_FORM_strx2
+                            || form == DW_FORM_strx3
+                            || form == DW_FORM_strx4));
 	    if (form == DW_FORM_strp)
 	      {
 		if (unlikely (op_multifile || fi_multifile))
@@ -11047,6 +11209,20 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 	      }
 	    else if (form == DW_FORM_line_strp)
 	      die->die_size += 4;
+	    else if (form == DW_FORM_strx)
+              {
+                uint64_t idx = read_uleb128(ptr);
+                unsigned int len = size_of_uleb128(idx);
+                die->die_size += len;
+              }
+            else if (form == DW_FORM_strx1)
+              die->die_size += 1;
+            else if (form == DW_FORM_strx2)
+              die->die_size += 2;
+            else if (form == DW_FORM_strx3)
+              die->die_size += 3;
+            else if (form == DW_FORM_strx4)
+              die->die_size += 4;
 	    else
 	      die->die_size
 		+= strlen (refcu->cu_comp_dir) + 1;
@@ -11054,6 +11230,16 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 	    t->attr[t->nattr].form = form;
 	    t->nattr++;
 	  }
+	if (refcu->cu_str_offsets_base)
+          {
+            enum dwarf_form form;
+            unsigned char *ptr = get_AT (origin, DW_AT_str_offsets_base, &form);
+            assert (ptr && (form == DW_FORM_sec_offset));
+            die->die_size += 4;
+            t->attr[t->nattr].attr = DW_AT_str_offsets_base;
+            t->attr[t->nattr].form = form;
+            t->nattr++;
+          }
 	break;
       case DW_TAG_namespace:
       case DW_TAG_module:
@@ -11062,7 +11248,12 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 	  unsigned char *ptr = get_AT (origin, DW_AT_name, &form);
 	  assert (ptr && (form == DW_FORM_string
 			  || form == DW_FORM_strp
-			  || form == DW_FORM_line_strp));
+			  || form == DW_FORM_line_strp
+                          || form == DW_FORM_strx
+                          || form == DW_FORM_strx1
+                          || form == DW_FORM_strx2
+                          || form == DW_FORM_strx3
+                          || form == DW_FORM_strx4));
 	  if (form == DW_FORM_strp)
 	    {
 	      if (unlikely (op_multifile || fi_multifile))
@@ -11071,6 +11262,20 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 	    }
 	  else if (form == DW_FORM_line_strp)
 	    die->die_size += 4;
+	  else if (form == DW_FORM_strx)
+            {
+              uint64_t idx = read_uleb128(ptr);
+              unsigned int len = size_of_uleb128(idx);
+              die->die_size = len;
+            }
+	  else if (form == DW_FORM_strx1)
+            die->die_size = 1;
+          else if (form == DW_FORM_strx2)
+            die->die_size = 2;
+          else if (form == DW_FORM_strx3)
+            die->die_size = 3;
+          else if (form == DW_FORM_strx4)
+            die->die_size = 4;
 	  else
 	    die->die_size = strlen ((char *) ptr) + 1;
 	  t->attr[0].attr = DW_AT_name;
@@ -12044,6 +12249,7 @@ adjust_exprloc (dw_cu_ref cu, dw_die_ref die, dw_cu_ref refcu,
 	case DW_OP_constu:
 	case DW_OP_plus_uconst:
 	case DW_OP_regx:
+	case DW_OP_addrx:
 	case DW_OP_piece:
 	case DW_OP_consts:
 	case DW_OP_breg0 ... DW_OP_breg31:
@@ -12171,11 +12377,33 @@ write_unit_die (unsigned char *ptr, dw_die_ref die, dw_die_ref origin)
 		    ptr += 4;
 		  }
 	      }
-	    else if (form == DW_FORM_line_strp)
+	    else if (form == DW_FORM_line_strp || form == DW_FORM_strx4)
 	      {
 		memcpy (ptr, p, 4);
 		ptr += 4;
 	      }
+	    else if (form == DW_FORM_strx)
+	      {
+                uint64_t idx = read_uleb128(p);
+		unsigned int len = size_of_uleb128(idx);
+	        memcpy (ptr, p, len);
+		ptr += len;
+	      }
+	    else if (form == DW_FORM_strx1)
+              {
+                memcpy (ptr, p, 1);
+                ptr += 1;
+              }
+            else if (form == DW_FORM_strx2)
+              {
+                memcpy (ptr, p, 2);
+                ptr += 2;
+              }
+            else if (form == DW_FORM_strx3)
+              {
+                memcpy (ptr, p, 3);
+                ptr += 3;
+              }
 	    else
 	      {
 		size_t len = strlen ((char *) p) + 1;
@@ -12191,6 +12419,15 @@ write_unit_die (unsigned char *ptr, dw_die_ref die, dw_die_ref origin)
 	    write_size (ptr, lang_size, lang);
 	    ptr += lang_size;
 	  }
+          break;
+        case DW_AT_str_offsets_base:
+          {
+            enum dwarf_form form;
+            unsigned char *p = get_AT (origin, DW_AT_str_offsets_base, &form);
+            assert (p && (form == DW_FORM_sec_offset));
+            memcpy(ptr, p, 4);
+            ptr += 4;
+	  }
 	  break;
 	default:
 	  assert (false);
@@ -12400,12 +12637,17 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die,
 	    case DW_FORM_implicit_const:
 	      break;
 	    case DW_FORM_flag:
+	    case DW_FORM_strx1:
 	    case DW_FORM_data1:
 	      ++inptr;
 	      break;
 	    case DW_FORM_data2:
+	    case DW_FORM_strx2:
 	      inptr += 2;
 	      break;
+	    case DW_FORM_strx3:
+	      inptr += 3;
+	      break;
 	    case DW_FORM_data4:
 	      if (reft->attr[i].attr == DW_AT_high_pc
 		  && t->attr[j].form != reft->attr[i].form)
@@ -12425,6 +12667,7 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die,
 	      inptr += 4;
 	      break;
 	    case DW_FORM_sec_offset:
+	    case DW_FORM_strx4:
 	      inptr += 4;
 	      break;
 	    case DW_FORM_data8:
@@ -12456,6 +12699,10 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die,
 	      break;
 	    case DW_FORM_sdata:
 	    case DW_FORM_udata:
+	    case DW_FORM_addrx:
+	    case DW_FORM_loclistx:
+	    case DW_FORM_rnglistx:
+	    case DW_FORM_strx:
 	      skip_leb128 (inptr);
 	      break;
 	    case DW_FORM_strp:
@@ -13508,6 +13755,7 @@ init_endian (int endianity)
   if (endianity == ELFDATA2LSB)
     {
       do_read_16 = buf_read_ule16;
+      do_read_24 = buf_read_ule24;
       do_read_32 = buf_read_ule32;
       do_read_64 = buf_read_ule64;
       do_write_16 = buf_write_le16;
@@ -13517,6 +13765,7 @@ init_endian (int endianity)
   else if (endianity == ELFDATA2MSB)
     {
       do_read_16 = buf_read_ube16;
+      do_read_24 = buf_read_ube24;
       do_read_32 = buf_read_ube32;
       do_read_64 = buf_read_ube64;
       do_write_16 = buf_write_be16;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-05-19 17:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-16 11:29 [PATCH 1/2] Support for clang-generated DWARF5 sections .debug_addr/.debug_str_offsets E, Nagajyothi
2021-05-19 17:22 ` E, Nagajyothi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).