public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries.
@ 2020-08-10 15:06 nitachra
  2020-08-10 15:06 ` [PATCH v2 2/2] DWARFv5: Fix for the filename complaint when printing macro nitachra
  2020-08-14 20:55 ` [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries Tom Tromey
  0 siblings, 2 replies; 4+ messages in thread
From: nitachra @ 2020-08-10 15:06 UTC (permalink / raw)
  To: gdb-patches, simark, tom; +Cc: JiniSusan.George, nitachra

Hi Tom,

Thanks for the review.

>>> +        const gdb_byte *info_ptr = (str_offsets_section->buffer
>>> +                                    + str_offsets_base
>>> +                                    + offset_index * offset_size);
>>> +
>>> +        const char *macinfo_str = (macinfo_type == DW_MACRO_define_strx ?
>>> +                                   "DW_MACRO_define_strx" : 
>>> + "DW_MACRO_undef_strx");
>>> +
>>> +        if (str_offsets_base + offset_index * offset_size
>>> +            >= str_offsets_section->size)
>>> +          complaint (_("%s pointing outside of .debug_str_offsets section "
>>> +                       "[in module %s]"), macinfo_str, objfile_name 
>>> + (objfile));

>>I think that, in addition to issuing a complaint, this code should probably not try to read the string.  This is going to be an out-of-bounds read.

Done

>>> +        ULONGEST str_offset;
>>> +        if (offset_size == 4)
>>> +          str_offset = bfd_get_32 (abfd, info_ptr);
>>> +        else
>>> +          str_offset = bfd_get_64 (abfd, info_ptr);

>>I think this can use read_offset.
Done

>>>  /* Return the .debug_loc section to use for CU.
>>> diff --git a/gdb/macrotab.c b/gdb/macrotab.c index 
>>> 9ada436eaf..4ffb2d67cb 100644
>>> --- a/gdb/macrotab.c
>>> +++ b/gdb/macrotab.c
>>> @@ -507,7 +507,8 @@ struct macro_source_file *  
>>> macro_lookup_inclusion (struct macro_source_file *source, const char 
>>> *name)  {
>>>    /* Is SOURCE itself named NAME?  */
>>> -  if (filename_cmp (name, source->filename) == 0)
>>> +  if (filename_cmp (name, source->filename) == 0 ||
>>> +      filename_cmp (basename (name), basename (source->filename)) == 
>>> + 0)
>>>      return source;

>>This seems to be an unrelated change.

I have divided the patch in two. Please have a look.

Regards,
Nitika

---
GDB complaints "During symbol reading: unrecognized DW_MACFINO
opcode 0xb" with the testcase given below. Clang is emitting
DW_MACRO_define_strx and DW_MACRO_undef_strx entries in .debug_macro
section which are not supported in GDB. This patch handles them.

DW_MACRO_define_strx and DW_MACRO_undef_strx are added in DWARFv5.
They have two operands. The first operand encodes the line number of
the #define or #undef macro directive. The second operand identifies
a string; it is represented using an unsigned LEB128 encoded value,
which is interpreted as a zero-based index into an array of offsets
in the .debug_str_offsets section. This is as per the section 6.3.2.1
of Dwarf Debugging Information Format Version 5.

Test case used:
 #define MAX_SIZE 10
int main(void)
{
   int size = 0;
   size = size + MAX_SIZE;

   printf("\n The value of size is [%d]\n",size);

   return 0;
}

clang -gdwarf-5 -fdebug-macro  macro.c -o macro.out

Before the patch:

gdb/new_gdb/binutils-gdb/build/bin/gdb -q macro.out -ex "set complaints 1" -ex "start"
Reading symbols from macro.out...
During symbol reading: unrecognized DW_MACFINO opcode 0xb
Temporary breakpoint 1 at 0x4004df: file macro.c, line 7.
Starting program: /home/nitika/workspace/macro.out

Temporary breakpoint 1, main () at macro.c:7
7          int size = 0;
(gdb)

Tested by running the testsuite before and after the patch with
 -gdwarf-5 and there is no increase in the number of test cases
that fails. Used clang 11.0.0.

gdb/ChangeLog:

	* dwarf2/macro.c (dwarf_decode_macro_bytes): Handle DW_MACRO_define_strx
	and DW_MACRO_undef_strx.
	(dwarf_decode_macros): Likewise
	* dwarf2/read.c (dwarf_decode_macros): Pass str_offsets_base in the parameters
	which is the value of DW_AT_str_offsets_base.
	* dwarf2/macro.h (dwarf_decode_macros): Modify the definition to include
	str_offsets_base.
---
 gdb/dwarf2/macro.c | 71 ++++++++++++++++++++++++++++++++++++++++++++--
 gdb/dwarf2/macro.h |  3 ++
 gdb/dwarf2/read.c  | 21 +++++++++++++-
 3 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index d047d806f8..9208614564 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -427,6 +427,9 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 			  const struct dwarf2_section_info *section,
 			  int section_is_gnu, int section_is_dwz,
 			  unsigned int offset_size,
+			  struct dwarf2_section_info *str_section,
+			  struct dwarf2_section_info *str_offsets_section,
+			  ULONGEST str_offsets_base,
 			  htab_t include_hash)
 {
   struct objfile *objfile = per_objfile->objfile;
@@ -561,6 +564,53 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
           }
           break;
 
+	case DW_MACRO_define_strx:
+	case DW_MACRO_undef_strx:
+	  {
+	    unsigned int bytes_read;
+
+	    int line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	    int offset_index = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+
+	    str_offsets_section->read (objfile);
+	    const gdb_byte *info_ptr = (str_offsets_section->buffer
+					+ str_offsets_base
+					+ offset_index * offset_size);
+
+	    const char *macinfo_str = (macinfo_type == DW_MACRO_define_strx ?
+				       "DW_MACRO_define_strx" : "DW_MACRO_undef_strx");
+
+	    if (str_offsets_base + offset_index * offset_size
+		>= str_offsets_section->size)
+	      {
+		complaint (_("%s pointing outside of .debug_str_offsets section "
+			     "[in module %s]"), macinfo_str, objfile_name (objfile));
+		break;
+	      }
+
+	    ULONGEST str_offset = read_offset (abfd, info_ptr, offset_size);
+
+	    const char *body = str_section->read_string (objfile, str_offset,
+							 macinfo_str);
+	    if (current_file == nullptr)
+	      {
+		/* DWARF violation as no main source is present.  */
+		complaint (_("debug info with no main source gives macro %s "
+			     "on line %d: %s"),
+			     macinfo_type == DW_MACRO_define_strx ? _("definition")
+			     : _("undefinition"), line, body);
+		break;
+	      }
+
+	    if (macinfo_type == DW_MACRO_define_strx)
+	      parse_macro_definition (current_file, line, body);
+	    else
+	      macro_undef (current_file, line, body);
+	   }
+	   break;
+
         case DW_MACRO_start_file:
           {
             unsigned int bytes_read;
@@ -671,7 +721,8 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 					  new_mac_ptr, include_mac_end,
 					  current_file, lh, section,
 					  section_is_gnu, is_dwz, offset_size,
-					  include_hash);
+					  str_section, str_offsets_section,
+					  str_offsets_base, include_hash);
 
 		htab_remove_elt (include_hash, (void *) new_mac_ptr);
 	      }
@@ -712,7 +763,9 @@ dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
 		     buildsym_compunit *builder,
 		     const dwarf2_section_info *section,
 		     const struct line_header *lh, unsigned int offset_size,
-		     unsigned int offset, int section_is_gnu)
+		     unsigned int offset, struct dwarf2_section_info *str_section,
+		     struct dwarf2_section_info *str_offsets_section,
+		     ULONGEST str_offsets_base, int section_is_gnu)
 {
   bfd *abfd;
   const gdb_byte *mac_ptr, *mac_end;
@@ -814,6 +867,17 @@ dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
 	    mac_ptr += offset_size;
 	  }
 	  break;
+	case DW_MACRO_define_strx:
+	case DW_MACRO_undef_strx:
+	  {
+	    unsigned int bytes_read;
+
+	    read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	    read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	  }
+	  break;
 
 	case DW_MACRO_import:
 	case DW_MACRO_import_sup:
@@ -861,5 +925,6 @@ dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
   *slot = (void *) mac_ptr;
   dwarf_decode_macro_bytes (per_objfile, builder, abfd, mac_ptr, mac_end,
 			    current_file, lh, section, section_is_gnu, 0,
-			    offset_size, include_hash.get ());
+			    offset_size, str_section, str_offsets_section,
+			    str_offsets_base, include_hash.get ());
 }
diff --git a/gdb/dwarf2/macro.h b/gdb/dwarf2/macro.h
index d874068947..0a7ac55fc0 100644
--- a/gdb/dwarf2/macro.h
+++ b/gdb/dwarf2/macro.h
@@ -28,6 +28,9 @@ extern void dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
 				 const struct line_header *lh,
 				 unsigned int offset_size,
 				 unsigned int offset,
+				 dwarf2_section_info *str_section,
+				 dwarf2_section_info *str_offsets_section,
+				 ULONGEST str_offsets_base,
 				 int section_is_gnu);
 
 #endif /* GDB_DWARF2_MACRO_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 558fad74f8..845adb0325 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23350,8 +23350,27 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
 
   buildsym_compunit *builder = cu->get_builder ();
 
+  struct dwarf2_section_info *str_offsets_section;
+  struct dwarf2_section_info *str_section;
+  ULONGEST str_offsets_base;
+
+  if (cu->dwo_unit != nullptr)
+    {
+      str_offsets_section = &cu->dwo_unit->dwo_file
+			       ->sections.str_offsets;
+      str_section = &cu->dwo_unit->dwo_file->sections.str;
+      str_offsets_base = cu->header.addr_size;
+    }
+  else
+    {
+      str_offsets_section = &per_objfile->per_bfd->str_offsets;
+      str_section = &per_objfile->per_bfd->str;
+      str_offsets_base = *cu->str_offsets_base;
+    }
+
   dwarf_decode_macros (per_objfile, builder, section, lh,
-		       offset_size, offset, section_is_gnu);
+		       offset_size, offset, str_section, str_offsets_section,
+		       str_offsets_base, section_is_gnu);
 }
 
 /* Return the .debug_loc section to use for CU.
-- 
2.17.1


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

* [PATCH v2 2/2] DWARFv5: Fix for the filename complaint when printing macro
  2020-08-10 15:06 [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries nitachra
@ 2020-08-10 15:06 ` nitachra
  2020-10-04  2:32   ` Simon Marchi
  2020-08-14 20:55 ` [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries Tom Tromey
  1 sibling, 1 reply; 4+ messages in thread
From: nitachra @ 2020-08-10 15:06 UTC (permalink / raw)
  To: gdb-patches, simark, tom; +Cc: JiniSusan.George, nitachra

GDB complaints "During symbol reading: symtab found for 'macro.c',
but that file is not covered in the compilation unit's macro information.
No symbol "MAX_SIZE" in the current context" when printing the macro with
the testcase file macro.c given below. This patch fixes this and prints
the correct value.

When gdb reads file number from DW_MACRO_start_file data in .debug_macro
section, it will do name lookup in file_names and include_directories
index table of .debug_line section. Prior to DWARFv5 include_directories[0]
has no info, so a lookup at that index will return NULL and we have file name
"macro.c". But in dwarfv5 current directory is explicitly represented at index 0
(as shown in the snippet below), hence after lookup you get "PATH/macro.c".
A snippet of .debug_line is as follows-

include_directories[  0] = "/home/nitika/workspace"
include_directories[  1] = "/usr/include"
include_directories[  2] = "/usr/include/x86_64-linux-gnu/bits"
include_directories[  3] = "/usr/include/x86_64-linux-gnu/sys"
include_directories[  4] = "/usr/include/x86_64-linux-gnu/gnu"
include_directories[  5] = "up_llvm/llvm-project/build/lib/clang/11.0.0/include"
include_directories[  6] = "/usr/include/x86_64-linux-gnu/bits/types"

file_names[  0]:
           name: "macro.c"
      dir_index: 0
   md5_checksum: 0ee310711170f2dd9844b522e844207d

Test case used (macro.c):

 #define MAX_SIZE 10
int main(void)
{
   int size = 0;
   size = size + MAX_SIZE;

   printf("\n The value of size is [%d]\n",size);

   return 0;
}

clang -gdwarf-5 -fdebug-macro  macro.c -o macro.out

Before the patch:

gdb -q  macro.out -ex "start" -ex "set complaints 1"  -ex "p MAX_SIZE"
Reading symbols from macro.out...
Temporary breakpoint 1 at 0x4004df: file macro.c, line 7.
Starting program: /home/nitika/workspace/macro.out

Temporary breakpoint 1, main () at macro.c:7
7          int size = 0;
During symbol reading: symtab found for 'macro.c',
but that file is not covered in the compilation unit's macro information
No symbol "MAX_SIZE" in current context.

After the patch:

gdb -q  macro.out -ex "start" -ex "p MAX_SIZE"
Reading symbols from macro.out...
Temporary breakpoint 1 at 0x4004df: file macro.c, line 7.
Starting program: /home/nitika/workspace/macro.out

Temporary breakpoint 1, main () at macro.c:7
7          int size = 0;
$1 = 10

Tested by running the testsuite before and after the patch with
 -gdwarf-5 and there is no increase in the number of test cases
that fails. Used clang 11.0.0.

gdb/ChangeLog:

	* macrotab.c (macro_lookup_inclusion): In DWARF version 5 filename includes
	the full directory path.
---
 gdb/macrotab.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gdb/macrotab.c b/gdb/macrotab.c
index 9ada436eaf..4ffb2d67cb 100644
--- a/gdb/macrotab.c
+++ b/gdb/macrotab.c
@@ -507,7 +507,8 @@ struct macro_source_file *
 macro_lookup_inclusion (struct macro_source_file *source, const char *name)
 {
   /* Is SOURCE itself named NAME?  */
-  if (filename_cmp (name, source->filename) == 0)
+  if (filename_cmp (name, source->filename) == 0 ||
+      filename_cmp (basename (name), basename (source->filename)) == 0)
     return source;
 
   /* It's not us.  Try all our children, and return the lowest.  */
-- 
2.17.1


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

* Re: [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries.
  2020-08-10 15:06 [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries nitachra
  2020-08-10 15:06 ` [PATCH v2 2/2] DWARFv5: Fix for the filename complaint when printing macro nitachra
@ 2020-08-14 20:55 ` Tom Tromey
  1 sibling, 0 replies; 4+ messages in thread
From: Tom Tromey @ 2020-08-14 20:55 UTC (permalink / raw)
  To: nitachra; +Cc: gdb-patches, simark, tom, JiniSusan.George

> gdb/ChangeLog:

> 	* dwarf2/macro.c (dwarf_decode_macro_bytes): Handle DW_MACRO_define_strx
> 	and DW_MACRO_undef_strx.
> 	(dwarf_decode_macros): Likewise
> 	* dwarf2/read.c (dwarf_decode_macros): Pass str_offsets_base in the parameters
> 	which is the value of DW_AT_str_offsets_base.
> 	* dwarf2/macro.h (dwarf_decode_macros): Modify the definition to include
> 	str_offsets_base.

Thank you.  This is ok.

Tom

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

* Re: [PATCH v2 2/2] DWARFv5: Fix for the filename complaint when printing macro
  2020-08-10 15:06 ` [PATCH v2 2/2] DWARFv5: Fix for the filename complaint when printing macro nitachra
@ 2020-10-04  2:32   ` Simon Marchi
  0 siblings, 0 replies; 4+ messages in thread
From: Simon Marchi @ 2020-10-04  2:32 UTC (permalink / raw)
  To: nitachra, gdb-patches, tom; +Cc: JiniSusan.George

On 2020-08-10 11:06 a.m., nitachra wrote:
> GDB complaints "During symbol reading: symtab found for 'macro.c',
> but that file is not covered in the compilation unit's macro information.
> No symbol "MAX_SIZE" in the current context" when printing the macro with
> the testcase file macro.c given below. This patch fixes this and prints
> the correct value.
>
> When gdb reads file number from DW_MACRO_start_file data in .debug_macro
> section, it will do name lookup in file_names and include_directories
> index table of .debug_line section. Prior to DWARFv5 include_directories[0]
> has no info, so a lookup at that index will return NULL and we have file name
> "macro.c". But in dwarfv5 current directory is explicitly represented at index 0
> (as shown in the snippet below), hence after lookup you get "PATH/macro.c".
> A snippet of .debug_line is as follows-
>
> include_directories[  0] = "/home/nitika/workspace"
> include_directories[  1] = "/usr/include"
> include_directories[  2] = "/usr/include/x86_64-linux-gnu/bits"
> include_directories[  3] = "/usr/include/x86_64-linux-gnu/sys"
> include_directories[  4] = "/usr/include/x86_64-linux-gnu/gnu"
> include_directories[  5] = "up_llvm/llvm-project/build/lib/clang/11.0.0/include"
> include_directories[  6] = "/usr/include/x86_64-linux-gnu/bits/types"
>
> file_names[  0]:
>            name: "macro.c"
>       dir_index: 0
>    md5_checksum: 0ee310711170f2dd9844b522e844207d
>
> Test case used (macro.c):
>
>  #define MAX_SIZE 10
> int main(void)
> {
>    int size = 0;
>    size = size + MAX_SIZE;
>
>    printf("\n The value of size is [%d]\n",size);
>
>    return 0;
> }
>
> clang -gdwarf-5 -fdebug-macro  macro.c -o macro.out
>
> Before the patch:
>
> gdb -q  macro.out -ex "start" -ex "set complaints 1"  -ex "p MAX_SIZE"
> Reading symbols from macro.out...
> Temporary breakpoint 1 at 0x4004df: file macro.c, line 7.
> Starting program: /home/nitika/workspace/macro.out
>
> Temporary breakpoint 1, main () at macro.c:7
> 7          int size = 0;
> During symbol reading: symtab found for 'macro.c',
> but that file is not covered in the compilation unit's macro information
> No symbol "MAX_SIZE" in current context.
>
> After the patch:
>
> gdb -q  macro.out -ex "start" -ex "p MAX_SIZE"
> Reading symbols from macro.out...
> Temporary breakpoint 1 at 0x4004df: file macro.c, line 7.
> Starting program: /home/nitika/workspace/macro.out
>
> Temporary breakpoint 1, main () at macro.c:7
> 7          int size = 0;
> $1 = 10
>
> Tested by running the testsuite before and after the patch with
>  -gdwarf-5 and there is no increase in the number of test cases
> that fails. Used clang 11.0.0.

But... is there an increase in number of test that pass?  Shouldn't some
macro-related test catch this somehow?  If not, it would be really good
to add a test for this.


>
> gdb/ChangeLog:
>
> 	* macrotab.c (macro_lookup_inclusion): In DWARF version 5 filename includes
> 	the full directory path.
> ---
>  gdb/macrotab.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/gdb/macrotab.c b/gdb/macrotab.c
> index 9ada436eaf..4ffb2d67cb 100644
> --- a/gdb/macrotab.c
> +++ b/gdb/macrotab.c
> @@ -507,7 +507,8 @@ struct macro_source_file *
>  macro_lookup_inclusion (struct macro_source_file *source, const char *name)
>  {
>    /* Is SOURCE itself named NAME?  */
> -  if (filename_cmp (name, source->filename) == 0)
> +  if (filename_cmp (name, source->filename) == 0 ||
> +      filename_cmp (basename (name), basename (source->filename)) == 0)
>      return source;

I'm not sure what the best solution is, since I don't really know this
code, but comparing just the basename sounds dangerous.  Let's say I
debug a file "foo.c" that includes a file "generated/foo.c", won't there
be confusion between the two files?

Simon


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

end of thread, other threads:[~2020-10-04  2:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-10 15:06 [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries nitachra
2020-08-10 15:06 ` [PATCH v2 2/2] DWARFv5: Fix for the filename complaint when printing macro nitachra
2020-10-04  2:32   ` Simon Marchi
2020-08-14 20:55 ` [PATCH v2 1/2] DWARFv5: Handle DW_MACRO_define_strx and DW_MACRO_undef_strx macro entries Tom Tromey

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).