summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2025-04-02 13:35:31 +0200
committerMark Wielaard <[email protected]>2025-04-08 23:18:13 +0200
commit4d50c9e68808cbdd22dd70c26482ec010aefcbbf (patch)
treee7db17ba5c0d3fb059cecc1424e1aeda1c68d4f2
parentf33f4c85581045ae493e7f12c6ba1bf5829d8192 (diff)
libdw: Add Nim language and dwarf_srclang tests
DW_LANG_Nim and DW_LNAME_Nim were added to the DWARF languages. While adding them, and the default lower bounds, I noticed DW_LANG_V and DW_LANG_Algol68 where missing in srclang_to_language an internal helper function. Testing through the public api is not that easy since you need a Dwarf_Die with the right attributes. So this patch adds a way to compile an individual source file with an optional main function that can directly access the internal/static functions. Note that it is almost generic. But even though using .SECONDEXPANSION I couldn't figure out how to create the equivalent of a rule starting with %_check$(EXEEXT) target. So for now the rule has to repeated for every new _check TEST. And there needs to be a line to tell make dist to not expect the fake source: nodist_src_check_SOURCES = src_check.c The new test pointed out that there were a few more bugs with DW_LANG_Dylan and DW_LNAME_Mojo. Also fix those. * libdw/dwarf.h: Add DW_LANG_Nim and DW_LNAME_Nim. * libdw/Makefile.am: Add check_PROGRAMS and TESTS for dwarf_srclang_check. * libdw/dwarf_default_lower_bound.c (dwarf_default_lower_bound): Add DW_LANG_Nim. (dwarf_language_lower_bound): Add DW_LNAME_Nim. * libdw/dwarf_srclang.c (srclang_to_language): Handle DW_LANG_Dylan, DW_LANG_V, DW_LANG_Algol68 and DW_LANG_Nim. (language_to_srclang): Fix DW_LNAME_Mojo. Add DW_LNAME_Nim. (test_lang): New function guarded by MAIN_CHECK. (main): Likewise. Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--libdw/Makefile.am11
-rw-r--r--libdw/dwarf.h2
-rw-r--r--libdw/dwarf_default_lower_bound.c2
-rw-r--r--libdw/dwarf_srclang.c87
4 files changed, 101 insertions, 1 deletions
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 8cbe0f32..9dadc19b 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -160,3 +160,14 @@ libdw.manifest: $(libdw_a_OBJECTS)
MOSTLYCLEANFILES = $(am_libdw_a_OBJECTS) $(am_libdw_pic_a_OBJECTS) libdw.so.$(VERSION)
CLEANFILES = libdw.so $(EXTRA_libdw_a_DEPENDENCIES)
MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h
+
+# Internal checks
+check_PROGRAMS = dwarf_srclang_check
+TESTS = $(check_PROGRAMS)
+
+CHECK_DEF_FLAGS = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DMAIN_CHECK=1
+
+.SECONDEXPANSION:
+dwarf_srclang_check$(EXEEXT): $$(filter-out $$(subst _check,,$$@).o,$(libdw_a_OBJECTS)) $$(subst _check,,$$@).c
+ $(AM_V_CC)$(CC) $(CHECK_DEF_FLAGS) -o $@ $^ $(filter-out libdw_pic.a,$(libdw_so_LIBS)) $(libdw_so_LDLIBS)
+nodist_dwarf_srclang_check_SOURCES = dwarf_srclang_check.c
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 5c856312..e1808096 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -777,6 +777,7 @@ enum
DW_LANG_Hylo = 0x0042, /* Hylo */
DW_LANG_V = 0x0043, /* V Programming Language */
DW_LANG_Algol68 = 0x0044, /* Algol68 */
+ DW_LANG_Nim = 0x0045, /* Nim */
DW_LANG_lo_user = 0x8000,
DW_LANG_Mips_Assembler = 0x8001, /* Assembler */
@@ -835,6 +836,7 @@ enum
DW_LNAME_Metal = 0x002c,
DW_LNAME_V = 0x002d,
DW_LNAME_Algol68 = 0x002e,
+ DW_LNAME_Nim = 0x002f,
DW_LNAME_lo_user = 0x8000,
DW_LNAME_hi_user = 0xffff
diff --git a/libdw/dwarf_default_lower_bound.c b/libdw/dwarf_default_lower_bound.c
index 7cc808b2..71a313fe 100644
--- a/libdw/dwarf_default_lower_bound.c
+++ b/libdw/dwarf_default_lower_bound.c
@@ -89,6 +89,7 @@ dwarf_default_lower_bound (int lang, Dwarf_Sword *result)
case DW_LANG_Move:
case DW_LANG_Hylo:
case DW_LANG_V:
+ case DW_LANG_Nim:
*result = 0;
return 0;
@@ -170,6 +171,7 @@ dwarf_language_lower_bound (Dwarf_Word lang, Dwarf_Sword *result)
case DW_LNAME_P4:
case DW_LNAME_Metal:
case DW_LNAME_V:
+ case DW_LNAME_Nim:
*result = 0;
return 0;
diff --git a/libdw/dwarf_srclang.c b/libdw/dwarf_srclang.c
index 948f44cb..10dfce8b 100644
--- a/libdw/dwarf_srclang.c
+++ b/libdw/dwarf_srclang.c
@@ -118,6 +118,10 @@ static int srclang_to_language (Dwarf_Word srclang,
*lname = DW_LNAME_D;
*lversion = 0;
return 0;
+ case DW_LANG_Dylan:
+ *lname = DW_LNAME_Dylan;
+ *lversion = 0;
+ return 0;
case DW_LANG_Python:
*lname = DW_LNAME_Python;
*lversion = 0;
@@ -299,6 +303,18 @@ static int srclang_to_language (Dwarf_Word srclang,
*lname = DW_LNAME_Hylo;
*lversion = 0;
return 0;
+ case DW_LANG_V:
+ *lname = DW_LNAME_V;
+ *lversion = 0;
+ return 0;
+ case DW_LANG_Algol68:
+ *lname = DW_LNAME_Algol68;
+ *lversion = 0;
+ return 0;
+ case DW_LANG_Nim:
+ *lname = DW_LNAME_Nim;
+ *lversion = 0;
+ return 0;
default:
__libdw_seterrno (DWARF_E_UNKNOWN_LANGUAGE);
return -1;
@@ -447,7 +463,7 @@ language_to_srclang (Dwarf_Word lname, Dwarf_Word lversion, Dwarf_Word *value)
*value = DW_LANG_C_sharp;
return 0;
case DW_LNAME_Mojo:
- *value = DW_LANG_Move;
+ *value = DW_LANG_Mojo;
return 0;
case DW_LNAME_GLSL:
*value = DW_LANG_GLSL;
@@ -494,6 +510,9 @@ language_to_srclang (Dwarf_Word lname, Dwarf_Word lversion, Dwarf_Word *value)
case DW_LNAME_Algol68:
*value = DW_LANG_Algol68;
return 0;
+ case DW_LNAME_Nim:
+ *value = DW_LANG_Nim;
+ return 0;
default:
__libdw_seterrno (DWARF_E_UNKNOWN_LANGUAGE);
return -1;
@@ -574,3 +593,69 @@ dwarf_language (Dwarf_Die *cudie, Dwarf_Word *lname, Dwarf_Word *lversion)
return res;
}
INTDEF (dwarf_language)
+
+#ifdef MAIN_CHECK
+#include "known-dwarf.h"
+#include <inttypes.h>
+#include <stdio.h>
+
+void
+test_lang (const char *name, Dwarf_Word lang)
+{
+ printf ("Testing %s: 0x%" PRIx64 "\n", name, lang);
+
+ Dwarf_Word lname;
+ Dwarf_Word lversion;
+ int res = srclang_to_language (lang, &lname, &lversion);
+ if (res != 0)
+ {
+ printf ("srclang_to_language failed (%d) for %s\n", res, name);
+ exit (-1);
+ }
+
+ Dwarf_Word rlang;
+ res = language_to_srclang (lname, lversion, &rlang);
+ if (res != 0)
+ {
+ printf ("language_to_srclang (%" PRId64 ", %" PRId64 ") failed (%d)\n",
+ lname, lversion, res);
+ exit (-1);
+ }
+
+ /* Most langs should roundtrip, but there are some exceptions. */
+ switch (lang)
+ {
+ case DW_LANG_Assembly:
+ if (rlang != DW_LANG_Mips_Assembler)
+ {
+ printf ("For compatibility Assembly should go to Mips_Assembler\n");
+ exit (-1);
+ }
+ break;
+ case DW_LANG_C_plus_plus_03:
+ if (rlang != DW_LANG_C_plus_plus)
+ {
+ printf ("For c++03 doesn't exist it is just c++\n");
+ exit (-1);
+ }
+ break;
+ default:
+ if (lang != rlang)
+ {
+ printf ("going from srclang to lang and back gives different name "
+ "for %s (%" PRId64 " != %" PRId64 ")\n", name, lang, rlang);
+ exit (-1);
+ }
+ }
+}
+
+int
+main (void)
+{
+ /* Test all known language codes. */
+#define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) test_lang (#NAME, CODE);
+ DWARF_ALL_KNOWN_DW_LANG
+#undef DWARF_ONE_KNOWN_DW_LANG
+ return 0;
+}
+#endif