public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] gdb: Fix issue with Clang CLI macros
@ 2022-04-20 17:41 Bruno Larsen
  2022-05-04 12:50 ` [PING] " Bruno Larsen
  2022-05-11 12:59 ` Simon Marchi
  0 siblings, 2 replies; 8+ messages in thread
From: Bruno Larsen @ 2022-04-20 17:41 UTC (permalink / raw)
  To: gdb-patches

Clang up to the current version adds macros that were defined in the
command line or by "other means", according to the Dwarf specification,
after the last DW_MACRO_end_file, instead of before the first
DW_MACRO_start_file, as the specification dictates. This has been
submitted as a bug to Clang developers, but seeing as there is no
expected date for it to be fixed, a workaround was added for all current
versions of Clang.

The workaround detects when the main file would be closed and if the
producer is clang, and turns that operation into a noop, so we keep a
reference to the current_file as those macros are read.

This patch fixes PR macros/29034, and can be tested by running
gdb.base/macscp.exp using clang, the test printing FROM_COMMANDLINE
should be fixed.
---
 gdb/dwarf2/cu.h    |  1 +
 gdb/dwarf2/macro.c | 17 +++++++++++++----
 gdb/dwarf2/macro.h |  2 +-
 gdb/dwarf2/read.c  | 15 ++++++++++++++-
 gdb/dwarf2/read.h  |  2 ++
 gdb/producer.c     | 26 ++++++++++++++++++++++++++
 gdb/producer.h     |  4 ++++
 7 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index 6b72ec234bf..3b7f92be406 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -257,6 +257,7 @@ struct dwarf2_cu
   bool producer_is_icc : 1;
   bool producer_is_icc_lt_14 : 1;
   bool producer_is_codewarrior : 1;
+  bool producer_is_clang_le_14 : 1;
 
   /* When true, the file that we're processing is known to have
      debugging info for C++ namespaces.  GCC 3.3.x did not produce
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index 99c3653a2c3..305af1a7f47 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -431,7 +431,7 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 			  struct dwarf2_section_info *str_section,
 			  struct dwarf2_section_info *str_offsets_section,
 			  gdb::optional<ULONGEST> str_offsets_base,
-			  htab_t include_hash)
+			  htab_t include_hash, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = per_objfile->objfile;
   enum dwarf_macro_record_type macinfo_type;
@@ -658,6 +658,15 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 	  if (! current_file)
 	    complaint (_("macro debug info has an unmatched "
 			 "`close_file' directive"));
+	  else if (current_file->included_by == nullptr
+		   && producer_is_clang_le_14 (cu))
+	    {
+	      /* Clang, until the current version, misplaces macro definitions,
+		 putting them after the last DW_MACRO_end_file instead of
+		 before the first DW_MACRO_start_file.  This condition should be
+		 removed once we can reasonably expect most clang users to have
+		 updated to a fixed version.  */
+	    }
 	  else
 	    {
 	      current_file = current_file->included_by;
@@ -737,7 +746,7 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile,
 					  current_file, lh, section,
 					  section_is_gnu, is_dwz, offset_size,
 					  str_section, str_offsets_section,
-					  str_offsets_base, include_hash);
+					  str_offsets_base, include_hash, cu);
 
 		htab_remove_elt (include_hash, (void *) new_mac_ptr);
 	      }
@@ -781,7 +790,7 @@ dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
 		     unsigned int offset, struct dwarf2_section_info *str_section,
 		     struct dwarf2_section_info *str_offsets_section,
 		     gdb::optional<ULONGEST> str_offsets_base,
-		     int section_is_gnu)
+		     int section_is_gnu, struct dwarf2_cu *cu)
 {
   bfd *abfd;
   const gdb_byte *mac_ptr, *mac_end;
@@ -942,5 +951,5 @@ dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
   dwarf_decode_macro_bytes (per_objfile, builder, abfd, mac_ptr, mac_end,
 			    current_file, lh, section, section_is_gnu, 0,
 			    offset_size, str_section, str_offsets_section,
-			    str_offsets_base, include_hash.get ());
+			    str_offsets_base, include_hash.get (), cu);
 }
diff --git a/gdb/dwarf2/macro.h b/gdb/dwarf2/macro.h
index e8c33a34a8d..02753ef377a 100644
--- a/gdb/dwarf2/macro.h
+++ b/gdb/dwarf2/macro.h
@@ -31,6 +31,6 @@ extern void dwarf_decode_macros (dwarf2_per_objfile *per_objfile,
 				 dwarf2_section_info *str_section,
 				 dwarf2_section_info *str_offsets_section,
 				 gdb::optional<ULONGEST> str_offsets_base,
-				 int section_is_gnu);
+				 int section_is_gnu, struct dwarf2_cu *cu);
 
 #endif /* GDB_DWARF2_MACRO_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 698720276a9..1fc5d5d3dd8 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9454,6 +9454,15 @@ producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
   return cu->producer_is_gcc_lt_4_3;
 }
 
+bool
+producer_is_clang_le_14 (struct dwarf2_cu *cu)
+{
+  if (!cu->checked_producer)
+    check_producer (cu);
+  
+  return cu->producer_is_clang_le_14;
+}
+
 static file_and_directory &
 find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
 {
@@ -13295,6 +13304,10 @@ check_producer (struct dwarf2_cu *cu)
     }
   else if (startswith (cu->producer, "CodeWarrior S12/L-ISA"))
     cu->producer_is_codewarrior = true;
+  else if (producer_is_clang (cu->producer, &major, &minor))
+    {
+      cu->producer_is_clang_le_14 = major <= 14;
+    }
   else
     {
       /* For other non-GCC compilers, expect their behavior is DWARF version
@@ -23218,7 +23231,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
 
   dwarf_decode_macros (per_objfile, builder, section, lh,
 		       offset_size, offset, str_section, str_offsets_section,
-		       str_offsets_base, section_is_gnu);
+		       str_offsets_base, section_is_gnu, cu);
 }
 
 /* Return the .debug_loc section to use for CU.
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index be3b9d19601..23f040a6ca8 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -677,4 +677,6 @@ extern void dwarf2_get_section_info (struct objfile *,
 				     asection **, const gdb_byte **,
 				     bfd_size_type *);
 
+extern bool producer_is_clang_le_14(struct dwarf2_cu *cu);
+
 #endif /* DWARF2READ_H */
diff --git a/gdb/producer.c b/gdb/producer.c
index ef1dd93afbc..a9fb7dd8245 100644
--- a/gdb/producer.c
+++ b/gdb/producer.c
@@ -127,6 +127,32 @@ producer_is_llvm (const char *producer)
 				 || startswith (producer, " F90 Flang ")));
 }
 
+/* see producer.h */
+
+bool
+producer_is_clang (const char* producer, int *major, int* minor)
+{
+  const char *cs;
+
+  if (producer != nullptr && startswith (producer, "clang "))
+    {
+      int maj, min;
+      if (major == nullptr)
+	major = &maj;
+      if (minor == nullptr)
+	minor = &min;
+
+      /* The full producer sting will look something like
+	 "clang version XX.X.X ..."
+	 So we can safely ignore all characters before the first digit.  */
+      cs = producer + strlen("clang version ");
+
+      if (sscanf (cs, "%d.%d", major, minor) == 2)
+	  return true;
+    }
+  return false;
+}
+
 #if defined GDB_SELF_TEST
 namespace selftests {
 namespace producer {
diff --git a/gdb/producer.h b/gdb/producer.h
index f7c19368bc6..b75cfae6569 100644
--- a/gdb/producer.h
+++ b/gdb/producer.h
@@ -41,4 +41,8 @@ extern bool producer_is_icc (const char *producer, int *major, int *minor);
    false otherwise.*/
 extern bool producer_is_llvm (const char *producer);
 
+/* Returns true if the given PRODUCER string is clang, false otherwise.
+   Sets MAJOR and MINOR accordingly, if not NULL.  */
+extern bool producer_is_clang (const char *producer, int *major, int *minor);
+
 #endif
-- 
2.31.1


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

end of thread, other threads:[~2022-05-11 20:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-20 17:41 [PATCH] gdb: Fix issue with Clang CLI macros Bruno Larsen
2022-05-04 12:50 ` [PING] " Bruno Larsen
2022-05-11 11:12   ` Bruno Larsen
2022-05-11 12:59 ` Simon Marchi
2022-05-11 14:53   ` Bruno Larsen
2022-05-11 18:48     ` Simon Marchi
2022-05-11 20:03       ` Bruno Larsen
2022-05-11 20:05         ` Simon Marchi

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