[nasm:master] debug: feed single-line macro definitions and include hierachy to dfmt

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Tue Aug 25 16:18:07 PDT 2020


Commit-ID:  16ab7aed219916fffafcd8fff71b1e5c111a96f8
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=16ab7aed219916fffafcd8fff71b1e5c111a96f8
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Tue, 25 Aug 2020 15:52:05 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Tue, 25 Aug 2020 15:52:05 -0700

debug: feed single-line macro definitions and include hierachy to dfmt

At least DWARF can encode C-style macros. In doing so, it wants the
file include hierarchy, so give the debug format backend the option of
receiving that information from the preprocessor.

Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>


---
 asm/preproc.c     | 113 ++++++++++++++++++++++++++++++++++++++----------------
 include/nasm.h    |  22 +++++++++++
 output/codeview.c |   2 +
 output/nulldbg.c  |   2 +
 output/outdbg.c   |  24 ++++++++++--
 output/outelf.c   |  12 ++++++
 output/outieee.c  |   2 +
 output/outmacho.c |   4 ++
 output/outobj.c   |   2 +
 9 files changed, 146 insertions(+), 37 deletions(-)

diff --git a/asm/preproc.c b/asm/preproc.c
index b5a500dc..cfa8df15 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -91,7 +91,10 @@ static struct pp_config {
  * Preprocessor debug-related flags
  */
 static enum pp_debug_flags {
-    PDBG_MACROS = 1              /* Collect macro information */
+    PDBG_MMACROS      = 1,      /* Collect mmacro information */
+    PDBG_SMACROS      = 2,      /* Collect smacro information */
+    PDBG_LIST_SMACROS = 4,      /* Smacros to list file (list option 's') */
+    PDBG_INCLUDE      = 8       /* Collect %include information */
 } ppdbg;
 
 /*
@@ -2726,17 +2729,17 @@ smacro_expand_default(const SMacro *s, Token **params, int nparams)
 }
 
 /*
- * Emit a macro defintion or undef to the listing file, if
- * desired. This is similar to detoken(), but it handles the reverse
- * expansion list, does not expand %! or local variable tokens, and
- * does some special handling for macro parameters.
+ * Emit a macro defintion or undef to the listing file or debug format
+ * if desired. This is similar to detoken(), but it handles the
+ * reverse expansion list, does not expand %! or local variable
+ * tokens, and does some special handling for macro parameters.
  */
 static void
 list_smacro_def(enum preproc_token op, const Context *ctx, const SMacro *m)
 {
     Token *t;
     size_t namelen, size;
-    char *def, *p;
+    char *def, *p, *end_spec;
     char *context_prefix = NULL;
     size_t context_len;
 
@@ -2781,6 +2784,7 @@ list_smacro_def(enum preproc_token op, const Context *ctx, const SMacro *m)
     }
 
     *--p = ' ';
+    end_spec = p;               /* Truncate here for macro def only */
 
     if (m->nparam) {
         int i;
@@ -2813,7 +2817,14 @@ list_smacro_def(enum preproc_token op, const Context *ctx, const SMacro *m)
         nasm_free(context_prefix);
     }
 
-    nasm_listmsg("%s %s", pp_directives[op], p);
+    if (ppdbg & PDBG_LIST_SMACROS)
+        nasm_listmsg("%s %s", pp_directives[op], p);
+    if (ppdbg & PDBG_SMACROS) {
+        bool define = !(op == PP_UNDEF || op == PP_UNDEFALIAS);
+        if (!define)
+            *end_spec = '\0';   /* Remove the expansion (for list file only) */
+        dfmt->debug_smacros(define, p);
+    }
     nasm_free(def);
 }
 
@@ -3019,7 +3030,7 @@ static SMacro *define_smacro(const char *mname, bool casesense,
             smac->expandpvt = tmpl->expandpvt;
         }
     }
-    if (list_option('s')) {
+    if (ppdbg & (PDBG_SMACROS|PDBG_LIST_SMACROS)) {
         list_smacro_def((smac->alias ? PP_DEFALIAS : PP_DEFINE)
                         + !casesense, ctx, smac);
     }
@@ -3888,13 +3899,18 @@ static int do_directive(Token *tline, Token **output)
             /* -MG given but file not found, or repeated %require */
             nasm_free(inc);
         } else {
-            inc->where = src_where();
-            inc->lineinc = 1;
-            inc->nolist = istk->nolist;
-            inc->noline = istk->noline;
+            inc->nolist  = istk->nolist;
+            inc->noline  = istk->noline;
+            inc->where   = istk->where;
+            inc->lineinc = 0;
             istk = inc;
-            if (!istk->noline)
+            if (!istk->noline) {
                 src_set(0, found_path ? found_path : p);
+                istk->where = src_where();
+                istk->lineinc = 1;
+                if (ppdbg & PDBG_INCLUDE)
+                    dfmt->debug_include(true, istk->next->where, istk->where);
+            }
             if (!istk->nolist)
                 lfmt->uplevel(LIST_INCLUDE, 0);
         }
@@ -4824,14 +4840,17 @@ static bool paste_tokens(Token **head, const struct concat_mask *m,
             if (!handle_explicit)
                 break;
 
-            /* Left pasting token is start of line, just drop %+ */
+            did_paste = true;
+
             if (!prev_nonspace) {
-                tok = delete_Token(tok);
+                /*
+                 * Left pasting token is start of line, just drop %+
+                 * and any whitespace leading up to it.
+                 */
+                *head = next = delete_Token(tok);
                 break;
             }
 
-            did_paste = true;
-
             prev_next = prev_nonspace;
             t = *prev_nonspace;
 
@@ -4856,7 +4875,7 @@ static bool paste_tokens(Token **head, const struct concat_mask *m,
              * Nothing after? Just leave the existing token.
              */
             if (!next) {
-                t->next = tok = NULL; /* End of line */
+                t->next = next = NULL; /* End of line */
                 break;
             }
 
@@ -4873,10 +4892,10 @@ static bool paste_tokens(Token **head, const struct concat_mask *m,
                  * No output at all? Replace with a single whitespace.
                  * This should never happen.
                  */
-                t = new_White(NULL);
+                tok = t = new_White(NULL);
+            } else {
+                *prev_nonspace = tok = t;
             }
-
-            *prev_nonspace = tok = t;
             while (t->next)
                 t = t->next;    /* Find the last token produced */
 
@@ -4923,7 +4942,7 @@ static bool paste_tokens(Token **head, const struct concat_mask *m,
             while (t->next)
                 t = t->next;
             t->next = next;
-            prev_next = prev_nonspace = &t->next;
+            tok = t;
             did_paste = true;
             break;
         }
@@ -4932,10 +4951,10 @@ static bool paste_tokens(Token **head, const struct concat_mask *m,
             pasted = true;
         } else {
             prev_next = &tok->next;
-            if (next && next->type != TOKEN_WHITESPACE && next->type != TOKEN_PASTE)
+            if (next && next->type != TOKEN_WHITESPACE &&
+                next->type != TOKEN_PASTE)
                 prev_nonspace = prev_next;
         }
-
         tok = next;
     }
 
@@ -6544,7 +6563,7 @@ static int expand_mmacro(Token * tline)
 
         lfmt->uplevel(LIST_MACRO, 0);
 
-        if (ppdbg & PDBG_MACROS)
+        if (ppdbg & PDBG_MMACROS)
             debug_macro_start(m, src_where());
     }
 
@@ -6701,13 +6720,17 @@ static void pp_reset_stdmac(enum preproc_mode mode)
     nasm_new(inc);
     inc->next = istk;
     inc->nolist = inc->noline = !list_option('b');
+    inc->where = istk->where;
     istk = inc;
-    if (!istk->nolist)
+    if (!istk->nolist) {
         lfmt->uplevel(LIST_INCLUDE, 0);
-    if (!istk->noline)
+    }
+    if (!istk->noline) {
         src_set(0, NULL);
-
-    istk->where = src_where();
+        istk->where = src_where();
+        if (ppdbg & PDBG_INCLUDE)
+            dfmt->debug_include(true, istk->next->where, istk->where);
+    }
 
     pp_add_magic_stdmac();
 
@@ -6773,8 +6796,15 @@ void pp_reset(const char *file, enum preproc_mode mode,
     if (!(ppopt & PP_TRIVIAL)) {
         if (pass_final()) {
             if (dfmt->debug_mmacros)
-                ppdbg |= PDBG_MACROS;
+                ppdbg |= PDBG_MMACROS;
+            if (dfmt->debug_smacros)
+                ppdbg |= PDBG_SMACROS;
+            if (dfmt->debug_include)
+                ppdbg |= PDBG_INCLUDE;
         }
+
+        if (list_option('s'))
+            ppdbg |= PDBG_LIST_SMACROS;
     }
 
     memset(use_loaded, 0, use_package_count * sizeof(bool));
@@ -6790,6 +6820,11 @@ void pp_reset(const char *file, enum preproc_mode mode,
     istk->where = src_where();
     istk->lineinc = 1;
 
+    if (ppdbg & PDBG_INCLUDE) {
+        /* Let the debug format know the main file */
+        dfmt->debug_include(true, src_nowhere(), istk->where);
+    }
+
     strlist_add(deplist, file);
 
     do_predef = false;
@@ -6919,7 +6954,7 @@ static Token *pp_tokline(void)
                     istk->nolist--;
                 } else if (!istk->nolist) {
                     lfmt->downlevel(LIST_MACRO);
-                    if ((ppdbg & PDBG_MACROS) && fm->name)
+                    if ((ppdbg & PDBG_MMACROS) && fm->name)
                         debug_macro_end(fm);
                 }
 
@@ -6981,8 +7016,14 @@ static Token *pp_tokline(void)
 
                 if (!i->nolist)
                     lfmt->downlevel(LIST_INCLUDE);
-                if (!i->noline && istk)
-                    src_update(istk->where);
+                if (!i->noline) {
+                    struct src_location whereto
+                        = istk ? istk->where : src_nowhere();
+                    if (ppdbg & PDBG_INCLUDE)
+                        dfmt->debug_include(false, whereto, i->where);
+                    if (istk)
+                        src_update(istk->where);
+                }
 
                 nasm_free(i);
                 return &tok_pop;
@@ -7120,13 +7161,17 @@ void pp_cleanup_pass(void)
         Include *i = istk;
         istk = istk->next;
         fclose(i->fp);
+        if (!istk && (ppdbg & PDBG_INCLUDE)) {
+            /* Signal closing the top-level input file */
+            dfmt->debug_include(false, src_nowhere(), i->where);
+        }
         nasm_free(i);
     }
     while (cstk)
         ctx_pop();
     src_set_fname(NULL);
 
-    if (ppdbg & PDBG_MACROS)
+    if (ppdbg & PDBG_MMACROS)
         debug_macro_output();
 }
 
diff --git a/include/nasm.h b/include/nasm.h
index 92bc60c2..a06c71d5 100644
--- a/include/nasm.h
+++ b/include/nasm.h
@@ -1103,6 +1103,28 @@ struct dfmt {
     void (*debug_deflabel)(char *name, int32_t segment, int64_t offset,
                            int is_global, char *special);
 
+    /*
+     * debug_smacros - called when an smacro is defined or undefined
+     * during the code-generation pass. The definition string contains
+     * the macro name, any arguments, a single space, and the macro
+     * definition; this is what is expected by e.g. DWARF.
+     *
+     * The definition is provided even for an undef.
+     */
+    void (*debug_smacros)(bool define, const char *def);
+
+    /*
+     * debug_include - called when a file is included or the include
+     * is finished during the code-generation pass.  The filename is
+     * kept by the srcfile system and so can be compared for pointer
+     * equality.
+     *
+     * A filename of NULL means builtin (initial or %use) or command
+     * line statements.
+     */
+    void (*debug_include)(bool start, struct src_location outer,
+                          struct src_location inner);
+
     /*
      * debug_mmacros - called once at the end with a definition for each
      * non-.nolist macro that has been invoked at least once in the program,
diff --git a/output/codeview.c b/output/codeview.c
index 9b12c136..0875dc41 100644
--- a/output/codeview.c
+++ b/output/codeview.c
@@ -64,6 +64,8 @@ const struct dfmt df_cv8 = {
     cv8_init,                   /* .init */
     cv8_linenum,                /* .linenum */
     cv8_deflabel,               /* .debug_deflabel */
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,       /* .debug_directive */
     cv8_typevalue,              /* .debug_typevalue */
diff --git a/output/nulldbg.c b/output/nulldbg.c
index a8a9dcd9..93ec3a7f 100644
--- a/output/nulldbg.c
+++ b/output/nulldbg.c
@@ -83,6 +83,8 @@ const struct dfmt null_debug_form = {
     null_debug_init,
     null_debug_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     null_debug_typevalue,
diff --git a/output/outdbg.c b/output/outdbg.c
index 7c4065b1..e7a9a4e5 100644
--- a/output/outdbg.c
+++ b/output/outdbg.c
@@ -435,10 +435,19 @@ static void dbgdbg_deflabel(char *name, int32_t segment,
             is_global, special ? ": " : "", special);
 }
 
-static void dbgdbg_define(const char *type, const char *params)
+static void dbgdbg_debug_smacros(bool define, const char *def)
 {
-    fprintf(ofile, "dbg directive: [%s] value [%s]\n", type, params);
+    fprintf(ofile, "dbg define: %s [%s]\n",
+            define ? "define " : "undef ", def);
 }
+static void dbgdbg_debug_include(bool start, struct src_location outer,
+                                 struct src_location inner)
+{
+    fprintf(ofile, "dbg include: %s include: %s:%"PRId32" %s %s:%"PRId32"\n",
+            start ? "start" : "end", outer.filename, outer.lineno,
+            start ? "->" : "<-", inner.filename, inner.lineno);
+}
+
 static void dbgdbg_output(int output_type, void *param)
 {
     (void)output_type;
@@ -505,6 +514,13 @@ static void dbgdbg_debug_mmacros(const struct debug_macro_info *dmi)
     fprintf(ofile, "  end macro debug information\n");
 }
 
+static void dbgdbg_debug_directive(const char *id, const char *value)
+{
+    fprintf(ofile, "dbg directive: id [%s] value [%s] pass %"PRId64" (%s)\n",
+            id, value, pass_count(), pass_type_name());
+}
+
+
 static const struct pragma_facility dbgdbg_pragma_list[] = {
     { "dbgdbg", dbg_pragma },
     { NULL, dbg_pragma }        /* Won't trigger, "debug" is a reserved ns */
@@ -516,8 +532,10 @@ static const struct dfmt debug_debug_form = {
     dbgdbg_init,
     dbgdbg_linnum,
     dbgdbg_deflabel,
+    dbgdbg_debug_smacros,
+    dbgdbg_debug_include,
     dbgdbg_debug_mmacros,
-    dbgdbg_define,
+    dbgdbg_debug_directive,
     dbgdbg_typevalue,
     dbgdbg_output,
     dbgdbg_cleanup,
diff --git a/output/outelf.c b/output/outelf.c
index c87a6f18..bb2acbb4 100644
--- a/output/outelf.c
+++ b/output/outelf.c
@@ -2435,6 +2435,8 @@ static const struct dfmt elf32_df_dwarf = {
     dwarf32_init,
     dwarf_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     debug_typevalue,
@@ -2449,6 +2451,8 @@ static const struct dfmt elf32_df_stabs = {
     null_debug_init,
     stabs_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     debug_typevalue,
@@ -2489,6 +2493,8 @@ static const struct dfmt elf64_df_dwarf = {
     dwarf64_init,
     dwarf_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     debug_typevalue,
@@ -2503,6 +2509,8 @@ static const struct dfmt elf64_df_stabs = {
     null_debug_init,
     stabs_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     debug_typevalue,
@@ -2543,6 +2551,8 @@ static const struct dfmt elfx32_df_dwarf = {
     dwarfx32_init,
     dwarf_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     debug_typevalue,
@@ -2557,6 +2567,8 @@ static const struct dfmt elfx32_df_stabs = {
     null_debug_init,
     stabs_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     debug_typevalue,
diff --git a/output/outieee.c b/output/outieee.c
index 3c89a00f..f03f5732 100644
--- a/output/outieee.c
+++ b/output/outieee.c
@@ -1464,6 +1464,8 @@ static const struct dfmt ladsoft_debug_form = {
     dbgls_init,
     dbgls_linnum,
     dbgls_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     dbgls_typevalue,
diff --git a/output/outmacho.c b/output/outmacho.c
index b7fe1c36..7ec3e752 100644
--- a/output/outmacho.c
+++ b/output/outmacho.c
@@ -2289,6 +2289,8 @@ static const struct dfmt macho32_df_dwarf = {
     macho_dbg_init,
     macho_dbg_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     null_debug_typevalue,
@@ -2357,6 +2359,8 @@ static const struct dfmt macho64_df_dwarf = {
     macho_dbg_init,
     macho_dbg_linenum,
     null_debug_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     null_debug_typevalue,
diff --git a/output/outobj.c b/output/outobj.c
index ce557744..4f57b69f 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -2650,6 +2650,8 @@ static const struct dfmt borland_debug_form = {
     dbgbi_init,
     dbgbi_linnum,
     dbgbi_deflabel,
+    NULL,                       /* .debug_smacros */
+    NULL,                       /* .debug_include */
     NULL,                       /* .debug_mmacros */
     null_debug_directive,
     dbgbi_typevalue,


More information about the Nasm-commits mailing list