From c80a3e56e9f943844478fb34351a8c3decba413e Mon Sep 17 00:00:00 2001
From: Sourabh Singh Tomar <SourabhSingh.Tomar@amd.com>
Date: Wed, 24 Mar 2021 16:23:33 +0530
Subject: [PATCH] Fix macro info lookup for binaries containing DWARFv5 line
 table

Consider following C test case:
```
cat test.c
int main() {
        int a = OUT;
}
```
Compiled as:
`clang -gdwarf-5 -fdebug-macro test.c`

Loading this bin into GDB and trying to access macro info,
GDB is unable to extract and display macro info correctly.
```
$gdb a.out
(gdb) start
(gdb) info macro OUT
Temporary breakpoint 1 at 0x2016a8: file test.c, line 3.
Starting program: /home/a.out
(gdb) info macro OUT
The symbol `OUT' has no definition as a C/C++ preprocessor macro
at /home/test.c:-1
```

The problems starts when processing file and dir indexes from DWARFv5
line table.  DWARFv5 specifies:
  - The current directory is explicitly present in the
    directories field.
  - The current compilation filename is explicitly present and
    has index 0.
dir entry 0 contains the absoute path(Not including source
filename).
file entry 0 contains the source file name and refers dir 0.

As one may notice that dir index `0` will always contain
absoulte path(Not including the file name as), this causes
GDB to append the path + filename to construt macro info
`main_file->filename`. This leads to overriding of the macro filename
which will cause macro info lookup failure due to mismatch in
`main_file->filename` and `sal.symtab->filename`.

This problem does not pops up with GCC compiled binaries, since
GCC does not emits DWARFv5 compliant line tables.

Testing:
- NO regressing observed in `gdb.base` and associated macro based
tests.

2021-03-26  Sourabh Singh Tomar  <SourabhSingh.Tomar@amd.com>

       * dwarf2/line-header.c: Updated the comment and extended
       check in function `line_header::file_file_name` for
       DWARFv5 line tables.
---
 gdb/ChangeLog            |  6 ++++++
 gdb/dwarf2/line-header.c | 30 +++++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 173b08bf04b..1580690a2d7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2021-03-26  Sourabh Singh Tomar  <SourabhSingh.Tomar@amd.com>
+
+	* dwarf2/line-header.c: Updated the comment and extended
+	check in function `line_header::file_file_name` for
+	DWARFv5 line tables.
+
 2021-03-25  Pedro Alves  <pedro@palves.net>
 
 	* gdb.server/bkpt-other-inferior.exp: Only enable remote output
diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c
index 7575297f966..dad44550531 100644
--- a/gdb/dwarf2/line-header.c
+++ b/gdb/dwarf2/line-header.c
@@ -64,7 +64,8 @@ gdb::unique_xmalloc_ptr<char>
 line_header::file_file_name (int file) const
 {
   /* Is the file number a valid index into the line header's file name
-     table?  Remember that file numbers start with one, not zero.  */
+	table?  Remember that file numbers start with zero for DWARFv5 and one
+	for DWARFv4 .  */
   if (is_valid_file_index (file))
     {
       const file_entry *fe = file_name_at (file);
@@ -72,7 +73,29 @@ line_header::file_file_name (int file) const
       if (!IS_ABSOLUTE_PATH (fe->name))
 	{
 	  const char *dir = fe->include_dir (this);
-	  if (dir != NULL)
+     /* clang  compiler emits DWARFv5 compliant line tables i.e
+	 For any C file compiled as:
+	clang -gdwarf-5 -fdebug-macro test.c
+
+	```
+	line table:
+	include_directories[  0] = "/home/"
+	file_names[  0]:
+	name: = "test.c"
+	dir_index: 0
+
+	macro table:
+	Referring to file index 0.
+	```
+	Now the 0 dir index will never be NULL for DWARFv5.
+	Do Not append the path to file name since this will override
+	the macro filename which will cause macro info lookup failure
+	due to mismatch in `main_file->filename` and
+	`sal.symtab->filename`.
+	Note that previously this check will always be `true` for
+	DWARFv5, since index 0 will never be NULL*/
+
+	  if (dir != NULL && file)
 	    return gdb::unique_xmalloc_ptr<char> (concat (dir, SLASH_STRING,
 							  fe->name,
 							  (char *) NULL));
@@ -100,7 +123,8 @@ gdb::unique_xmalloc_ptr<char>
 line_header::file_full_name (int file, const char *comp_dir) const
 {
   /* Is the file number a valid index into the line header's file name
-     table?  Remember that file numbers start with one, not zero.  */
+	table?  Remember that file numbers start with zero for DWARFv5 and one
+	for DWARFv4 .  */
   if (is_valid_file_index (file))
     {
       gdb::unique_xmalloc_ptr<char> relative = file_file_name (file);
-- 
2.17.1

