Index: trunk/src/emx/src/emxomf/emxomf.c
===================================================================
--- trunk/src/emx/src/emxomf/emxomf.c	(revision 299)
+++ trunk/src/emx/src/emxomf/emxomf.c	(revision 304)
@@ -174,5 +174,12 @@
 int *sst_boundary = NULL;
 int *tt_boundary = NULL;
-
+/** The HLL version of the HLL debuginfo we're generating.
+ * Default level is 4.
+ *
+ * VisualAge 3.65 iLink support HLL v6
+ * VisualAge 3.08 iLink support HLL v4
+ * Link386              support HLL v3 (?)
+ */
+int hll_version = 4;
 
 /* Private variables. */
@@ -575,9 +582,9 @@
 
 
-/* Add a symbol to weak symbol list */
+/* Add a symbol to 0 symbol list */
 
 static struct weaksym *add_weak (const char *symname, const char *modname)
 {
-  struct weaksym *newsym = malloc (sizeof (struct weaksym));
+  struct weaksym *newsym = xmalloc (sizeof (struct weaksym));
   newsym->name = xstrdup (symname);
   newsym->module = xstrdup (modname);
@@ -1648,5 +1655,10 @@
       while (boundary_idx < boundary_count && boundary[boundary_idx] < end)
         ++boundary_idx;
+      #if 1/* kso #456 2003-06-05: This must be wrong cause we're splitting unneedingly.
+            *                      Check if we acutally hit the '< end' check.  */
+      if (boundary_idx > 0 && boundary_idx < boundary_count)
+      #else
       if (boundary_idx > 0)
+      #endif
         {
           tmp = boundary[boundary_idx-1] - off;
@@ -1872,5 +1884,5 @@
   put_8 (0x80);
   put_8 (0xa1);                 /* Debug info style */
-  put_8 (3);                    /* Version 3 */
+  put_8 (hll_version);          /* Version */
   put_mem ("HL", 2);            /* HLL style debug tables */
   write_rec ();
@@ -2691,4 +2703,32 @@
 }
 
+/* Write linenumber fixups for HLL v4 records
+ * We need fixups for segment idx and offset in the special
+ * first entry. */
+static void write_linenumfixup(void)
+{
+  /* ASSUME! flat_thread is defined. */
+  /* ASSUME! base seg idx of linnum rec < 128. */
+  init_rec (FIXUPP|REC32);
+  /* LOC=16-bit sel;I=1;M=1; */
+  put_8 (0xc8);
+  /* offset 6 (segment number). */
+  put_8 (0x06);
+  /* F=1;Frame=flat_thread;T=0;P=1;TARGT=0; */
+  put_8 (0x84 | (flat_thread << 4));
+  /* target seg index? */
+  put_8 (text_index);
+
+  /* LOC=32-offset sel;I=1;M=1; */
+  put_8 (0xe4);
+  /* offset 8 (offset). */
+  put_8 (0x08);
+  /* F=1;Frame=flat_thread;T=0;P=1;TARGT=0; */
+  put_8 (0x84 | (flat_thread << 4));
+  /* target seg index? */
+  put_8 (text_index);
+  write_rec ();
+}
+
 
 /* Write line number information to the output file.  Unfortunately,
@@ -2758,37 +2798,141 @@
     len += 1 + strlen (file_list[i]);
 
-/*
- * This is the VAC way, but link386 doesn't like this.
- * too bad :/
- */
-#if 0
-
-  /* Filename table first  -  a first entry like visual age does it and does hints on */
-
-  init_rec (LINNUM|REC32);
-  started = TRUE;
-  put_idx (0);                  /* Base Group */
-  put_idx (0);                  /* Base Segment */
-
-  put_16 (0);                   /* Line number = 0 (special entry) */
-  put_8 (3);                    /* Entry type: some visual age stuff I believe */
-  put_8 (0);                    /* Reserved */
-  put_16 (1);                   /* Count of line number entries */
-  put_16 (0);                   /* Segment number */
-  put_32 (len);                 /* Size of file names table */
-  /* no linenumber */
-  put_32 (0);                   /* First column */
-  put_32 (0);                   /* Number of columns */
-  put_32 (file_grow.count);     /* Number of source and listing files */
-
-  for (i = 0; i < file_grow.count; ++i)
-    {
-      len = strlen (file_list[i]);
-      if (len > sizeof (buf) - 1)
-        len = sizeof (buf) - 1;
-      memcpy (buf, file_list[i], len);
-      buf[len] = 0;
-      convert_filename (buf);
-      if (started && !fits (1 + len))
+  /*
+   * This is the VAC way, too bad link386 doesn't fancy it.
+   */
+  if (hll_version >= 4)
+    {
+      int first_linnum;
+      /* Filename table first  -  a first entry like visual age does it and does hints on */
+
+      init_rec (LINNUM|REC32);
+      started = TRUE;
+      put_idx (0);                  /* Base Group */
+      put_idx (0);                  /* Base Segment */
+
+      put_16 (0);                   /* Line number = 0 (special entry) */
+      put_8 (3);                    /* Entry type: some visual age stuff I believe */
+      put_8 (0);                    /* Reserved */
+      put_16 (1);                   /* Count of line number entries */
+      put_16 (0);                   /* Segment number */
+      put_32 (len);                 /* Size of file names table */
+      /* no linenumber */
+      put_32 (0);                   /* First column */
+      put_32 (0);                   /* Number of columns */
+      put_32 (file_grow.count);     /* Number of source and listing files */
+
+      for (i = 0; i < file_grow.count; ++i)
+        {
+          len = strlen (file_list[i]);
+          if (len > sizeof (buf) - 1)
+            len = sizeof (buf) - 1;
+          memcpy (buf, file_list[i], len);
+          buf[len] = 0;
+          convert_filename (buf);
+          if (started && !fits (1 + len))
+            {
+              write_rec ();
+              started = FALSE;
+            }
+          if (!started)
+            {
+              init_rec (LINNUM|REC32);
+              put_idx (0);          /* Base Group */
+              put_idx (text_index); /* Base Segment */
+              started = TRUE;
+            }
+          put_8 (len);
+          put_mem (buf, len);
+        }
+
+      if (started)
+        write_rec ();
+
+
+      /* Write the line number table. */
+      first_linnum = 1;
+      init_rec (LINNUM|REC32);
+      started = TRUE;
+      put_idx (0);                  /* Base Group */
+      put_idx (text_index);         /* Base Segment */
+
+      put_16 (0);                   /* Line number = 0 (special entry) */
+      put_8 (0);                    /* Entry type: source and offset */
+      put_8 (0);                    /* Reserved */
+      put_16 (valid_lines);         /* Count of line number entries */
+      put_16 (0);                   /* Segment number - Fixup required */
+      put_32 (0);                   /* Segment offset - Fixup required */
+
+      for (i = 0; i < line_grow.count; ++i)
+        if (line_list[i].line >= 0)
+          {
+            if (started && !fits (8))
+              {
+                write_rec ();
+                started = FALSE;
+                if (first_linnum)
+                  {
+                    first_linnum = 0;
+                    write_linenumfixup();
+                  }
+              }
+            if (!started)
+              {
+                init_rec (LINNUM|REC32);
+                put_idx (0);          /* Base Group */
+                put_idx (text_index); /* Base Segment */
+                started = TRUE;
+              }
+            put_16 (line_list[i].line);
+            put_16(line_list[i].file_index + 1);
+            put_32 (line_list[i].addr);
+          }
+
+      if (started)
+        {
+          write_rec ();
+          if (first_linnum)
+              write_linenumfixup();
+        }
+    }
+  else
+    { /* hll version 3 */
+      /* Write the line number table. */
+
+      init_rec (LINNUM|REC32);
+      started = TRUE;
+      put_idx (0);                  /* Base Group */
+      put_idx (text_index);         /* Base Segment */
+
+      put_16 (0);                   /* Line number = 0 (special entry) */
+      put_8 (0);                    /* Entry type: source and offset */
+      put_8 (0);                    /* Reserved */
+      put_16 (valid_lines);         /* Count of line number entries */
+      put_16 (0);                   /* Segment number */
+      put_32 (len);                 /* Size of file names table */
+
+      for (i = 0; i < line_grow.count; ++i)
+        if (line_list[i].line >= 0)
+          {
+            if (started && !fits (8))
+              {
+                write_rec ();
+                started = FALSE;
+              }
+            if (!started)
+              {
+                init_rec (LINNUM|REC32);
+                put_idx (0);          /* Base Group */
+                put_idx (text_index); /* Base Segment */
+                started = TRUE;
+              }
+            put_16 (line_list[i].line);
+            put_16(line_list[i].file_index + 1);
+            put_32 (line_list[i].addr);
+          }
+
+      /* Now write the file names table. */
+
+      if (started && !fits (12))
         {
           write_rec ();
@@ -2802,130 +2946,35 @@
           started = TRUE;
         }
-      put_8 (len);
-      put_mem (buf, len);
-    }
-
-  if (started)
-    write_rec ();
-
-
-  /* Write the line number table. */
-
-  init_rec (LINNUM|REC32);
-  started = TRUE;
-  put_idx (0);                  /* Base Group */
-  put_idx (text_index);         /* Base Segment */
-
-  put_16 (0);                   /* Line number = 0 (special entry) */
-  put_8 (0);                    /* Entry type: source and offset */
-  put_8 (0);                    /* Reserved */
-  put_16 (valid_lines);         /* Count of line number entries */
-  put_16 (0);                   /* Segment number */
-  put_32 (0);                   /* Size of file names table */
-
-  for (i = 0; i < line_grow.count; ++i)
-    if (line_list[i].line >= 0)
-      {
-        if (started && !fits (8))
-          {
-            write_rec ();
-            started = FALSE;
-          }
-        if (!started)
-          {
-            init_rec (LINNUM|REC32);
-            put_idx (0);          /* Base Group */
-            put_idx (text_index); /* Base Segment */
-            started = TRUE;
-          }
-        put_16 (line_list[i].line);
-        put_16(line_list[i].file_index + 1);
-        put_32 (line_list[i].addr);
-      }
-
-  if (started)
-    write_rec ();
-
-
-#else
-  /* Write the line number table. */
-
-  init_rec (LINNUM|REC32);
-  started = TRUE;
-  put_idx (0);                  /* Base Group */
-  put_idx (text_index);         /* Base Segment */
-
-  put_16 (0);                   /* Line number = 0 (special entry) */
-  put_8 (0);                    /* Entry type: source and offset */
-  put_8 (0);                    /* Reserved */
-  put_16 (valid_lines);         /* Count of line number entries */
-  put_16 (0);                   /* Segment number */
-  put_32 (len);                 /* Size of file names table */
-
-  for (i = 0; i < line_grow.count; ++i)
-    if (line_list[i].line >= 0)
-      {
-        if (started && !fits (8))
-          {
-            write_rec ();
-            started = FALSE;
-          }
-        if (!started)
-          {
-            init_rec (LINNUM|REC32);
-            put_idx (0);          /* Base Group */
-            put_idx (text_index); /* Base Segment */
-            started = TRUE;
-          }
-        put_16 (line_list[i].line);
-        put_16(line_list[i].file_index + 1);
-        put_32 (line_list[i].addr);
-      }
-
-  /* Now write the file names table. */
-
-  if (started && !fits (12))
-    {
-      write_rec ();
-      started = FALSE;
-    }
-  if (!started)
-    {
-      init_rec (LINNUM|REC32);
-      put_idx (0);          /* Base Group */
-      put_idx (text_index); /* Base Segment */
-      started = TRUE;
-    }
-  put_32 (0);                   /* First column */
-  put_32 (0);                   /* Number of columns */
-  put_32 (file_grow.count);     /* Number of source and listing files */
-
-  for (i = 0; i < file_grow.count; ++i)
-    {
-      len = strlen (file_list[i]);
-      if (len > sizeof (buf) - 1)
-        len = sizeof (buf) - 1;
-      memcpy (buf, file_list[i], len);
-      buf[len] = 0;
-      convert_filename (buf);
-      if (started && !fits (1 + len))
+      put_32 (0);                   /* First column */
+      put_32 (0);                   /* Number of columns */
+      put_32 (file_grow.count);     /* Number of source and listing files */
+
+      for (i = 0; i < file_grow.count; ++i)
         {
-          write_rec ();
-          started = FALSE;
+          len = strlen (file_list[i]);
+          if (len > sizeof (buf) - 1)
+            len = sizeof (buf) - 1;
+          memcpy (buf, file_list[i], len);
+          buf[len] = 0;
+          convert_filename (buf);
+          if (started && !fits (1 + len))
+            {
+              write_rec ();
+              started = FALSE;
+            }
+          if (!started)
+            {
+              init_rec (LINNUM|REC32);
+              put_idx (0);          /* Base Group */
+              put_idx (text_index); /* Base Segment */
+              started = TRUE;
+            }
+          put_8 (len);
+          put_mem (buf, len);
         }
-      if (!started)
-        {
-          init_rec (LINNUM|REC32);
-          put_idx (0);          /* Base Group */
-          put_idx (text_index); /* Base Segment */
-          started = TRUE;
-        }
-      put_8 (len);
-      put_mem (buf, len);
-    }
-
-  if (started)
-    write_rec ();
-#endif
+
+      if (started)
+        write_rec ();
+    }
 
   grow_free (&line_grow);
@@ -3661,5 +3710,5 @@
   /* Parse the command line options. */
 
-  while ((c = getopt (argc, argv, "bdD:gi:I:m:l::o:p:qO:r:R:suxwz")) != EOF)
+  while ((c = getopt (argc, argv, "bdD:gh:i:I:m:l::o:p:qO:r:R:suxwz")) != EOF)
     switch (c)
       {
@@ -3675,4 +3724,12 @@
       case 'g':
         do_set_groups = TRUE;
+        break;
+      case 'h':
+        hll_version = optarg ? atoi(optarg) : 4;
+        if (hll_version != 4 && hll_version != 3)
+          {
+            printf ("syntax error: Invalid HLL version specified (%d)\n", hll_version);
+            usage ();
+          }
         break;
       case 'i':
Index: trunk/src/emx/src/emxomf/emxomf.h
===================================================================
--- trunk/src/emx/src/emxomf/emxomf.h	(revision 299)
+++ trunk/src/emx/src/emxomf/emxomf.h	(revision 304)
@@ -46,2 +46,3 @@
 extern int *sst_boundary;
 extern int *tt_boundary;
+extern int hll_version;
Index: trunk/src/emx/src/emxomf/listomf.c
===================================================================
--- trunk/src/emx/src/emxomf/listomf.c	(revision 299)
+++ trunk/src/emx/src/emxomf/listomf.c	(revision 304)
@@ -23,4 +23,5 @@
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #ifdef __EMX__
 #include <io.h>
@@ -102,4 +103,6 @@
 static char list_debug = TRUE;
 static char show_addr = FALSE;
+/** If set we will do a hexdump after every record we process. */
+static char hex_dump = FALSE;
 
 
@@ -377,21 +380,38 @@
 {
   int x;
+  char ascii[17];
 
   x = 0;
   while (rec_idx < rec_len && count > 0)
     {
+      unsigned int ui = rec_buf[rec_idx++];
       --count;
       if (x >= 16)
         {
-          printf ("\n");
+          for (x = 0; x < 16; x++)
+            if (!isprint (ascii[x]))
+              ascii[x] = '.';
+          printf ("  %.16s\n", ascii);
           x = 0;
         }
+      ascii[x] = ui;
       if (x == 0)
         printf ("%*s", indent, "");
-      printf (" %.2x", rec_buf[rec_idx++]);
+      if (x != 8)
+        printf (" %.2x", ui);
+      else
+        printf ("-%.2x", ui);
       ++x;
     }
   if (x != 0)
-    printf ("\n");
+    {
+      int cch = x;
+      printf("%*s", (16 - cch)*3, "");
+      for (x = 0; x < cch; x++)
+        if (!isprint (ascii[x]))
+          ascii[x] = '.';
+      ascii[cch] = '\0';
+       printf ("  %.*s\n", cch, ascii);
+    }
 }
 
@@ -876,13 +896,19 @@
           location = rec_idx - loc_base;
           offset = get_dword ();
-          length = get_dword ();
-          printf ("offset: %#lx [@%#x], length: %#lx",
-                  offset, location, length);
           if (rec_idx < rec_len)
             {
-              get_string (name);
-              printf (" ");
-              show_string (name);
+              length = get_dword ();
+              printf ("offset: %#lx [@%#x], length: %#lx",
+                      offset, location, length);
+              if (rec_idx < rec_len)
+                {
+                  get_string (name);
+                  printf (" ");
+                  show_string (name);
+                }
             }
+          else
+            printf ("offset: %#lx [@%#x], no length",
+                    offset, location);
           break;
         case 0x01:
@@ -2240,4 +2266,5 @@
   do
     {
+      int skip_hexdump = 0;
       if (show_addr)
         rec_pos = ftell (f);
@@ -2316,8 +2343,10 @@
         case LEDATA|REC32:
           list_ledata ();
+          skip_hexdump = 1;
           break;
         case LIDATA:
         case LIDATA|REC32:
           list_lidata ();
+          skip_hexdump = 1;
           break;
         case COMDEF:
@@ -2329,4 +2358,5 @@
           printf ("\n");
           dump_rest ();
+          skip_hexdump = 1;
           break;
         case ALIAS:
@@ -2337,5 +2367,17 @@
                   ftell (f) - (sizeof (rec) + rec_len + 1), rec.rec_type);
           dump_rest ();
-          break;
+          skip_hexdump = 1;
+          break;
+        }
+
+      /* hex dump? */
+      if (hex_dump && !skip_hexdump)
+        {
+          printf (" hexdump: type=0x%02x  len=0x%03x (%d) crc=%02x\n",
+                  rec.rec_type, rec.rec_len, rec.rec_len,
+                  rec_buf[rec.rec_len-1]);
+          rec_len = rec.rec_len - 1; /* skip crc */
+          rec_idx = 0;
+          dump_block (rec_len, 2);
         }
     } while (!done);
@@ -2361,5 +2403,7 @@
          "Options:\n"
          "  -a    Show addresses of records\n"
-         "  -d    Don't interpret $$TYPES and $$SYMBOLS segments\n", stderr);
+         "  -d    Don't interpret $$TYPES and $$SYMBOLS segments\n"
+         "  -x    Do hex dump of it after the intepretation.\n",
+         stderr);
   exit (1);
 }
@@ -2371,5 +2415,5 @@
 
   opterr = 0;
-  while ((c = getopt (argc, argv, "ad")) != EOF)
+  while ((c = getopt (argc, argv, "adx")) != EOF)
     switch (c)
       {
@@ -2380,4 +2424,7 @@
         list_debug = FALSE;
         break;
+      case 'x':
+        hex_dump = TRUE;
+        break;
       default:
         usage ();
Index: trunk/src/emx/src/emxomf/stabshll.c
===================================================================
--- trunk/src/emx/src/emxomf/stabshll.c	(revision 299)
+++ trunk/src/emx/src/emxomf/stabshll.c	(revision 304)
@@ -734,4 +734,10 @@
   /* Put the type into the table. */
 
+#ifdef HLL_DEBUG
+  printf ("  type: stabs %d => HLL 0x%x\n", number, hll->index);
+  if (stype_list[number-1] != NULL && stype_list[number-1] != hll)
+    warning ("Type stabs %d allready mapped to HLL 0x%x, new HLL 0x%x!!\n", number, stype_list[number-1]->index, hll->index);
+#endif
+
   stype_list[number-1] = hll;
 }
@@ -2555,5 +2561,5 @@
   buffer_dword (&sst, addr);    /* Segment offset */
   buffer_dword (&sst, 0);       /* Length of block -- patched later */
-#if 0
+#if 1
   buffer_nstr (&sst, "");       /* Name of block (optional) */
 #endif
@@ -2688,4 +2694,23 @@
 
 
+/**
+ * Checks if the given name is likely to be a C++ method.
+ *
+ * @returns 1 if C++ method.
+ * @returns 0 if not method.
+ * @param   pszName     Pointer to the name.
+ * @remark  Can also, if need, look around for symbols, types and stuff, but
+ *          will no alter any parser state.
+ */
+static int isCxxMethod(const char* pszName)
+{
+    /* not perfect, but probably close enought */
+    return cplusplus_flag
+        && pszName[0] == '_'
+        && pszName[1] == 'Z'
+        && pszName[2] == 'N';
+}
+
+
 /* Define a function.  SYMBOL points to the sym_ptr entry.  The
    function arguments are taken from the args_list array.  Several
@@ -2729,19 +2754,41 @@
   t2 = type_add (&last_fun_type);
   make_type (t2, &ti);
-  sst_start (cplusplus_flag ? SST_CPPproc : SST_proc);
-  r.r_address = sst.size;
-  buffer_dword (&sst, symbol->n_value); /* Segment offset */
-  buffer_word (&sst, ti);       /* Type index */
-  proc_patch_base = sst.size;
-  buffer_dword (&sst, 0);       /* Length of proc */
-  buffer_word (&sst, 0);        /* Length of prologue */
-  buffer_dword (&sst, 0);       /* Length of prologue and body */
-  buffer_word (&sst, 0);        /* Class type (for member functions) */
-  buffer_byte (&sst, 8);        /* 32-bit near */
-  if (cplusplus_flag)
-    buffer_enc (&sst, name);    /* Proc name */
+  if (isCxxMethod(name))
+    {
+      /* kso #456 2003-06-05: TODO - check for methods somehow */
+      sst_start (cplusplus_flag ? SST_CPPproc : SST_proc);
+      r.r_address = sst.size;
+      buffer_dword (&sst, symbol->n_value); /* Segment offset */
+      buffer_word (&sst, ti);       /* Type index */
+      proc_patch_base = sst.size;
+      buffer_dword (&sst, 0);       /* Length of proc */
+      buffer_word (&sst, 0);        /* Length of prologue */
+      buffer_dword (&sst, 0);       /* Length of prologue and body */
+      buffer_word (&sst, 0);        /* Class type (for member functions) */
+      buffer_byte (&sst, 8);        /* 32-bit near */
+      if (cplusplus_flag)
+        buffer_enc (&sst, name);    /* Proc name */
+      else
+        buffer_nstr (&sst, name);   /* Proc name */
+      sst_end ();
+    }
   else
-    buffer_nstr (&sst, name);   /* Proc name */
-  sst_end ();
+    {
+      sst_start (cplusplus_flag ? SST_CPPproc : SST_proc);
+      r.r_address = sst.size;
+      buffer_dword (&sst, symbol->n_value); /* Segment offset */
+      buffer_word (&sst, ti);       /* Type index */
+      proc_patch_base = sst.size;
+      buffer_dword (&sst, 0);       /* Length of proc */
+      buffer_word (&sst, 0);        /* Length of prologue */
+      buffer_dword (&sst, 0);       /* Length of prologue and body */
+      buffer_word (&sst, 0);        /* Class type (for member functions) */
+      buffer_byte (&sst, 8);        /* 32-bit near */
+      if (cplusplus_flag)
+        buffer_enc (&sst, name);    /* Proc name */
+      else
+        buffer_nstr (&sst, name);   /* Proc name */
+      sst_end ();
+    }
   r.r_extern = 0;
   r.r_length = 2;
@@ -3013,4 +3060,12 @@
                 prologue_length = sym_ptr[lbrac_index].n_value - last_fun_addr;
             }
+          else
+            {/* kso #456 2003-06-05: We need a begin to catch the parameters. */
+              //block_begin (proc_start_addr);
+              sst_start (SST_begin);
+              buffer_dword (&sst, proc_start_addr); /* Segment offset */
+              buffer_dword (&sst, 10); /* Length */
+              sst_end ();
+            }
 
           /* Parameters */
@@ -3025,5 +3080,10 @@
 
           if (lbrac_index == -1)
-            fun_end (*index+1);
+            {/* kso #456 2003-06-05: We need a begin to catch the parameters. */
+              //block_end (proc_start_addr);
+              sst_start (SST_end);
+              sst_end ();
+              fun_end (*index+1);
+            }
           break;
         }
@@ -3215,4 +3275,16 @@
         }
 
+#ifdef HLL_DEBUG
+  printf ("Stabs to HLL type mappings: %d/%d\n", stype_grow.count, stype_grow.alloc);
+  for (i = 0; i < stype_grow.alloc; i++)
+    if (stype_list[i])
+      {
+        printf ("  %3d => 0x%03x/%-3d  ", i + 1, stype_list[i]->index, stype_list[i]->index);
+        show_type (stype_list[i]);
+        printf("\n");
+      }
+#endif
+
+
   /* Deallocate memory. */
 
