diff --git a/doc/cc65.sgml b/doc/cc65.sgml
index df58a0a95..67323931c 100644
--- a/doc/cc65.sgml
+++ b/doc/cc65.sgml
@@ -198,6 +198,189 @@ Here is a description of all the command line options:
   Enables debug mode, for debugging the behavior of cc65.
 
 
+  <tag><tt>--debug-tables name</tt></tag>
+
+  Writes symbol table information to a file, which includes details on structs, unions
+  functions, and global variables. For example, given the following code:
+
+  <tscreen><verb>
+  struct l {
+      unsigned char m;
+      unsigned char n;
+  };
+
+  struct hello {
+      unsigned char j;
+      unsigned char k;
+      struct l l;
+  };
+
+  struct sub {
+      unsigned char x;
+      unsigned char y;
+  };
+
+  union xy {
+      struct sub xy;
+      unsigned int mem;
+  };
+
+  typedef struct hello thingy;
+
+  unsigned char single;
+
+  unsigned char test_local_vars_main(void) {
+      static unsigned char wahoo;
+      static unsigned char bonanza = 0x42;
+      unsigned char i;
+      unsigned int j;
+      unsigned int *random;
+      unsigned char *lol;
+      signed char whoa;
+      struct hello wow;
+      thingy *cool;
+      union xy xy;
+
+      return 0;
+  }
+  </verb></tscreen>
+
+  The following output would be produced:
+
+  <tscreen><verb>
+  SC_FUNC: _test_local_vars_main: Symbol table
+  ============================================
+  __fixargs__:
+      Flags: SC_CONST SC_DEF
+      Type:  unsigned int
+  __argsize__:
+      Flags: SC_CONST SC_DEF
+      Type:  unsigned char
+  wahoo:
+      AsmName: M0001
+      Flags: SC_STATIC SC_DEF SC_REF
+      Type:  unsigned char
+  bonanza:
+      AsmName: M0002
+      Flags: SC_STATIC SC_DEF SC_REF
+      Type:  unsigned char
+  i:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  unsigned char
+  j:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  unsigned int
+  random:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  unsigned int *
+  lol:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  unsigned char *
+  whoa:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  signed char
+  wow:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  struct hello
+  cool:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  struct hello *
+  xy:
+      Flags: SC_AUTO SC_DEF SC_REF
+      Type:  union xy
+
+
+
+
+  Global symbol table
+  ===================
+  thingy:
+      AsmName: _thingy
+      Flags: SC_TYPEDEF 0x100000
+      Type:  struct hello
+  single:
+      AsmName: _single
+      Flags: SC_STATIC SC_EXTERN SC_STORAGE SC_DEF SC_REF 0x100000
+      Type:  unsigned char
+  test_local_vars_main:
+      AsmName: _test_local_vars_main
+      Flags: SC_FUNC SC_STATIC SC_EXTERN SC_DEF 0x100000
+      Type:  unsigned char (void)
+
+
+
+
+  Global tag table
+  ================
+  l:
+      Flags: SC_STRUCT SC_DEF
+      Type:  (none)
+  hello:
+      Flags: SC_STRUCT SC_DEF
+      Type:  (none)
+  sub:
+      Flags: SC_STRUCT SC_DEF
+      Type:  (none)
+  xy:
+      Flags: SC_UNION SC_DEF
+      Type:  (none)
+
+
+
+
+  Global struct and union definitions
+  =========================
+
+  SC_STRUCT: l
+  ============
+  m:
+      Flags: SC_STRUCTFIELD
+      Type:  unsigned char
+  n:
+      Flags: SC_STRUCTFIELD
+      Type:  unsigned char
+
+
+
+
+  SC_STRUCT: hello
+  ================
+  j:
+      Flags: SC_STRUCTFIELD
+      Type:  unsigned char
+  k:
+      Flags: SC_STRUCTFIELD
+      Type:  unsigned char
+  l:
+      Flags: SC_STRUCTFIELD
+      Type:  struct l
+
+
+
+
+  SC_STRUCT: sub
+  ==============
+  x:
+      Flags: SC_STRUCTFIELD
+      Type:  unsigned char
+  y:
+      Flags: SC_STRUCTFIELD
+      Type:  unsigned char
+
+
+
+
+  SC_UNION: xy
+  ============
+  xy:
+      Flags: SC_STRUCTFIELD
+      Type:  struct sub
+  mem:
+      Flags: SC_STRUCTFIELD
+      Type:  unsigned int
+  </verb></tscreen>
+
+
   <tag><tt>--debug-opt name</tt></tag>
 
   The named file contains a list of specific optimization steps to enable or disable.
diff --git a/src/cc65/global.c b/src/cc65/global.c
index a337549fe..8b9838dc5 100644
--- a/src/cc65/global.c
+++ b/src/cc65/global.c
@@ -66,6 +66,7 @@ IntStack CodeSizeFactor     = INTSTACK(100);/* Size factor for generated code */
 IntStack DataAlignment      = INTSTACK(1);  /* Alignment for data */
 
 /* File names */
-StrBuf DepName     = STATIC_STRBUF_INITIALIZER; /* Name of dependencies file */
-StrBuf FullDepName = STATIC_STRBUF_INITIALIZER; /* Name of full dependencies file */
-StrBuf DepTarget   = STATIC_STRBUF_INITIALIZER; /* Name of dependency target */
+StrBuf DepName        = STATIC_STRBUF_INITIALIZER; /* Name of dependencies file */
+StrBuf FullDepName    = STATIC_STRBUF_INITIALIZER; /* Name of full dependencies file */
+StrBuf DepTarget      = STATIC_STRBUF_INITIALIZER; /* Name of dependency target */
+StrBuf DebugTableName = STATIC_STRBUF_INITIALIZER; /* Name of debug table dump file */
diff --git a/src/cc65/global.h b/src/cc65/global.h
index b9bcf5550..266035346 100644
--- a/src/cc65/global.h
+++ b/src/cc65/global.h
@@ -77,6 +77,7 @@ extern IntStack         DataAlignment;          /* Alignment for data */
 extern StrBuf           DepName;                /* Name of dependencies file */
 extern StrBuf           FullDepName;            /* Name of full dependencies file */
 extern StrBuf           DepTarget;              /* Name of dependency target */
+extern StrBuf           DebugTableName;         /* Name of debug table dump file */
 
 
 
diff --git a/src/cc65/main.c b/src/cc65/main.c
index 0ed5af986..74d4fd146 100644
--- a/src/cc65/main.c
+++ b/src/cc65/main.c
@@ -114,6 +114,7 @@ static void Usage (void)
             "  --create-full-dep name\tCreate a full make dependency file\n"
             "  --data-name seg\t\tSet the name of the DATA segment\n"
             "  --debug\t\t\tDebug mode\n"
+            "  --debug-tables name\t\tWrite symbol table debug info to a file\n"
             "  --debug-info\t\t\tAdd debug info to object file\n"
             "  --debug-opt name\t\tDebug optimization steps\n"
             "  --debug-opt-output\t\tDebug output of each optimization step\n"
@@ -494,7 +495,11 @@ static void OptDebug (const char* Opt attribute ((unused)),
     ++Debug;
 }
 
-
+static void OptDebugTables (const char* Opt, const char* Arg)
+/* Dump tables to file */
+{
+    FileNameOption (Opt, Arg, &DebugTableName);
+}
 
 static void OptDebugInfo (const char* Opt attribute ((unused)),
                           const char* Arg attribute ((unused)))
@@ -865,6 +870,7 @@ int main (int argc, char* argv[])
         { "--create-full-dep",      1,      OptCreateFullDep        },
         { "--data-name",            1,      OptDataName             },
         { "--debug",                0,      OptDebug                },
+        { "--debug-tables",         1,      OptDebugTables          },
         { "--debug-info",           0,      OptDebugInfo            },
         { "--debug-opt",            1,      OptDebugOpt             },
         { "--debug-opt-output",     0,      OptDebugOptOutput       },
diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c
index c1c5c4696..b4c97e962 100644
--- a/src/cc65/symtab.c
+++ b/src/cc65/symtab.c
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <errno.h>
 
 /* common */
 #include "check.h"
@@ -68,8 +69,6 @@
 /*                                   Data                                    */
 /*****************************************************************************/
 
-
-
 /* An empty symbol table */
 SymTable        EmptySymTab = {
     0,          /* PrevTab */
@@ -99,6 +98,7 @@ static SymTable*        LabelTab        = 0;
 static SymTable*        SPAdjustTab     = 0;
 static SymTable*        FailSafeTab     = 0;    /* For errors */
 
+static FILE* DebugTableFile = 0;
 
 /*****************************************************************************/
 /*                              struct SymTable                              */
@@ -256,11 +256,25 @@ void PopLexicalLevel (void)
     --LexLevelDepth;
 }
 
-
-
 void EnterGlobalLevel (void)
 /* Enter the program global lexical level */
 {
+    const char* OutName = NULL;
+    if (!SB_IsEmpty (&DebugTableName)) {
+        OutName = SB_GetConstBuf (&DebugTableName);
+    }
+
+    if (OutName) {
+        /* Open the table file */
+        DebugTableFile = fopen (OutName, "w");
+        if (DebugTableFile == 0) {
+            Error ("Cannot create table dump file '%s': %s", OutName, strerror (errno));
+        }
+    }
+    else if (Debug) {
+        DebugTableFile = stdout;
+    }
+
     /* Safety */
     PRECONDITION (GetLexicalLevel () == LEX_LEVEL_NONE);
 
@@ -280,8 +294,6 @@ void EnterGlobalLevel (void)
     FailSafeTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
 }
 
-
-
 void LeaveGlobalLevel (void)
 /* Leave the program global lexical level */
 {
@@ -292,9 +304,41 @@ void LeaveGlobalLevel (void)
     CheckSymTable (SymTab0);
 
     /* Dump the tables if requested */
-    if (Debug) {
-        PrintSymTable (SymTab0, stdout, "Global symbol table");
-        PrintSymTable (TagTab0, stdout, "Global tag table");
+    if (DebugTableFile) {
+        SymEntry* Entry;
+        StrBuf* Header;
+
+        PrintSymTable (SymTab0, DebugTableFile, "Global symbol table");
+        PrintSymTable (TagTab0, DebugTableFile, "Global tag table");
+
+        Entry = TagTab0->SymHead;
+        if (Entry) {
+            fputs ("\nGlobal struct and union definitions", DebugTableFile);
+            fputs ("\n=========================\n", DebugTableFile);
+
+            do {
+                if (!((Entry->Flags & SC_STRUCT) || (Entry->Flags & SC_UNION)) || !Entry->V.S.SymTab) {
+                    continue;
+                }
+
+                Header = NewStrBuf();
+                if(Entry->Flags & SC_STRUCT) {
+                    SB_AppendStr (Header, "SC_STRUCT: ");
+                }
+                else {
+                    SB_AppendStr (Header, "SC_UNION: ");
+                }
+                SB_AppendStr (Header, Entry->Name);
+                SB_Terminate (Header);
+
+                PrintSymTable (Entry->V.S.SymTab, DebugTableFile, SB_GetConstBuf (Header));
+            } while ((Entry = Entry->NextSym));
+        }
+
+        /* Close the file */
+        if (DebugTableFile != stdout && fclose (DebugTableFile) != 0) {
+            Error ("Error closing table dump file '%s': %s", SB_GetConstBuf(&DebugTableName), strerror (errno));
+        }
     }
 
     /* Don't delete the symbol and struct tables! */
@@ -386,6 +430,18 @@ void LeaveFunctionLevel (void)
     CheckSymTable (SymTab);
     CheckSymTable (LabelTab);
 
+    /* Dump the tables if requested */
+    if (DebugTableFile) {
+        StrBuf* SymbolHeader = NewStrBuf();
+
+        SB_AppendStr (SymbolHeader, "SC_FUNC: ");
+        SB_AppendStr (SymbolHeader, CurrentFunc->FuncEntry->AsmName);
+        SB_AppendStr (SymbolHeader, ": Symbol table");
+        SB_Terminate (SymbolHeader);
+
+        PrintSymTable (SymTab, DebugTableFile, SB_GetConstBuf(SymbolHeader));
+    }
+
     /* Drop the label table if it is empty */
     if (LabelTab->SymCount == 0) {
         FreeSymTable (LabelTab);