[ros-diffs] [dgorbachev] 44335: Update log2lines to version 1.4. Jan Roeloffzen, bug #4342.

dgorbachev at svn.reactos.org dgorbachev at svn.reactos.org
Mon Nov 30 22:49:18 CET 2009


Author: dgorbachev
Date: Mon Nov 30 22:49:18 2009
New Revision: 44335

URL: http://svn.reactos.org/svn/reactos?rev=44335&view=rev
Log:
Update log2lines to version 1.4. Jan Roeloffzen, bug #4342.

Modified:
    trunk/reactos/tools/rsym/log2lines.c

Modified: trunk/reactos/tools/rsym/log2lines.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/log2lines.c?rev=44335&r1=44334&r2=44335&view=diff
==============================================================================
--- trunk/reactos/tools/rsym/log2lines.c [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/log2lines.c [iso-8859-1] Mon Nov 30 22:49:18 2009
@@ -1,14 +1,6 @@
 /*
- * Usage: log2lines [-cd:fFhmrv] [<exefile> <offset>]
- * Try log2lines -h
- *
- * This is a tool and is compiled using the host compiler,
- * i.e. on Linux gcc and not mingw-gcc (cross-compiler).
- * Therefore we can't include SDK headers and we have to
- * duplicate some definitions here.
- * Also note that the internal functions are "old C-style",
- * returning an int, where a return of 0 means success and
- * non-zero is failure.
+ * ReactOS log2lines
+ * Written by Jan Roeloffzen
  */
 
 #include <stdio.h>
@@ -18,7 +10,7 @@
 
 #include "rsym.h"
 
-#define LOG2LINES_VERSION   "1.1"
+#define LOG2LINES_VERSION   "1.4"
 
 #define INVALID_BASE    0xFFFFFFFFL
 
@@ -34,7 +26,7 @@
 #define CP_CMD          "copy /Y "
 #define DIR_FMT         "dir /a:-d /s /b %s > %s"
 
-#else  /* not defined (__DJGPP__) || defined (__WIN32__) */
+#else /* not defined (__DJGPP__) || defined (__WIN32__) */
 
 #include <errno.h>
 #include <limits.h>
@@ -48,16 +40,25 @@
 #define CP_CMD          "cp -f "
 #define DIR_FMT         "find %s -type f > %s"
 
-#endif  /* not defined (__DJGPP__) || defined (__WIN32__) */
+#endif /* not defined (__DJGPP__) || defined (__WIN32__) */
 
 #define CP_FMT          CP_CMD "%s %s > " DEV_NULL
 
 #define CMD_7Z          "7z"
+//#define UNZIP_FMT_7Z    "%s e -y %s -o%s > " DEV_NULL
+#define UNZIP_FMT_7Z    "%s e -y %s -o%s"
 #define UNZIP_FMT       "%s x -y -r %s -o%s > " DEV_NULL
 #define UNZIP_FMT_CAB \
 "%s x -y -r %s" PATH_STR "reactos" PATH_STR "reactos.cab -o%s" PATH_STR "reactos" PATH_STR "reactos > " DEV_NULL
 
 #define LINESIZE        1024
+
+#define log(outFile, fmt, ...)                          \
+    {                                                   \
+        fprintf(outFile, fmt, ##__VA_ARGS__);           \
+        if (logFile)                                    \
+            fprintf(logFile, fmt, ##__VA_ARGS__);       \
+    }
 
 struct entry_struct
 {
@@ -79,20 +80,21 @@
 
 struct summ_struct
 {
-    int     translated;
-    int     undo;
-    int     redo;
-    int     skipped;
-    int     diff;
-    int     offset_errors;
-    int     total;
+    int translated;
+    int undo;
+    int redo;
+    int skipped;
+    int diff;
+    int majordiff;
+    int offset_errors;
+    int total;
 };
 
 typedef struct cache_struct CACHE;
-typedef struct summ_struct  SUMM;
-
-static CACHE    cache;
-static SUMM     summ;
+typedef struct summ_struct SUMM;
+
+static CACHE cache;
+static SUMM summ;
 
 static char *optchars  = "bcd:fFhl:mMrstTuUvz:";
 static int opt_buffered= 0;         // -b
@@ -112,7 +114,7 @@
 static char opt_dir[MAX_PATH];      // -d
 static char opt_logFile[MAX_PATH];  // -l
 static char opt_7z[MAX_PATH];       // -z
-static char opt_scanned[LINESIZE]; // all scanned options
+static char opt_scanned[LINESIZE];  // all scanned options
 static FILE *logFile   = NULL;
 
 static char *cache_name;
@@ -152,11 +154,11 @@
 }
 
 static PROSSYM_ENTRY
-find_offset(void *data, size_t offset, char *toString)
-{
-    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data;
-    PROSSYM_ENTRY Entries = (PROSSYM_ENTRY) ((char *)data + RosSymHeader->SymbolsOffset);
-    size_t symbols = RosSymHeader->SymbolsLength / sizeof (ROSSYM_ENTRY);
+find_offset(void *data, size_t offset)
+{
+    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
+    PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset);
+    size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
     size_t i;
 
     for (i = 0; i < symbols; i++)
@@ -177,80 +179,108 @@
 static int
 print_offset(void *data, size_t offset, char *toString)
 {
-    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data;
+    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
     PROSSYM_ENTRY e = NULL;
     PROSSYM_ENTRY e2 = NULL;
+    int bFileOffsetChanged = 0;
+    char fmt[LINESIZE];
     char *Strings = (char *)data + RosSymHeader->StringsOffset;
 
-    
-    e = find_offset(data, offset, toString);
+    fmt[0] = '\0';
+    e = find_offset(data, offset);
     if (opt_twice)
     {
-        e2 = find_offset(data, offset-1, toString);
-        
-        if (  e == e2 )
+        e2 = find_offset(data, offset - 1);
+
+        if (e == e2)
             e2 = NULL;
-
-        if ( opt_Twice &&  e2 )
+        else
+            summ.diff++;
+
+        if (opt_Twice && e2)
         {
             e = e2;
             e2 = NULL;
-            /* replaced (transparantly), but update stats: */
-            summ.diff ++;
-        }
-    }
-    if ( e || e2 )
-    {
-        if (toString)
-        {  // put in toString if provided
-            if ( e2 )
-            {
-                snprintf(toString, LINESIZE, "%s:%u (%s) [%s:%u (%s)]",
+            /* replaced (transparantly), but updated stats */
+        }
+    }
+    if (e || e2)
+    {
+        if (e2)
+        {
+            bFileOffsetChanged = e->FileOffset != e2->FileOffset;
+            if (e->FileOffset != e2->FileOffset || e->FunctionOffset != e2->FunctionOffset)
+                summ.majordiff++;
+
+            /*
+             * - "%.0s" displays nothing, but processes argument
+             * - bFileOffsetChanged implies always display 2nd SourceLine even if the same
+             * - also for FunctionOffset
+             */
+            strcat(fmt, "%s");
+            if (bFileOffsetChanged)
+                strcat(fmt, "[%s]");
+            else
+                strcat(fmt, "%.0s");
+
+            strcat(fmt, ":%u");
+            if (e->SourceLine != e2->SourceLine || bFileOffsetChanged)
+                strcat(fmt, "[%u]");
+            else
+                strcat(fmt, "%.0u");
+
+            strcat(fmt, " (%s");
+            if (e->FunctionOffset != e2->FunctionOffset || bFileOffsetChanged)
+                strcat(fmt, "[%s])");
+            else
+                strcat(fmt, "%.0s)");
+
+            if (toString)
+            {   // put in toString if provided
+                snprintf(toString, LINESIZE, fmt,
                          &Strings[e->FileOffset],
+                         &Strings[e2->FileOffset],
                          (unsigned int)e->SourceLine,
+                         (unsigned int)e2->SourceLine,
                          &Strings[e->FunctionOffset],
-                         &Strings[e2->FileOffset],
-                         (unsigned int)e2->SourceLine,
                          &Strings[e2->FunctionOffset]);
-                summ.diff ++;
             }
             else
             {
+               strcat(fmt, "\n");
+               printf(fmt,
+                      &Strings[e->FileOffset],
+                      &Strings[e2->FileOffset],
+                      (unsigned int)e->SourceLine,
+                      (unsigned int)e2->SourceLine,
+                      &Strings[e->FunctionOffset],
+                      &Strings[e2->FunctionOffset]);
+            }
+        }
+        else
+        {
+            if (toString)
+            {   // put in toString if provided
                 snprintf(toString, LINESIZE, "%s:%u (%s)",
                          &Strings[e->FileOffset],
                          (unsigned int)e->SourceLine,
                          &Strings[e->FunctionOffset]);
             }
-            return 0;
-        }
-        else
-        {  // to stdout
-            if ( e2 )
-            {
-                printf("%s:%u (%s) [%s:%u (%s)]\n",
+            else
+            {
+                printf("%s:%u (%s)\n",
                        &Strings[e->FileOffset],
                        (unsigned int)e->SourceLine,
-                       &Strings[e->FunctionOffset],
-                       &Strings[e2->FileOffset],
-                       (unsigned int)e2->SourceLine,
-                       &Strings[e2->FunctionOffset]);
-                summ.diff ++;
-            }
-            else
-            {
-                printf("%s:%u (%s)\n",
-                        &Strings[e->FileOffset],
-                       (unsigned int)e->SourceLine,
                        &Strings[e->FunctionOffset]);
             }
-            return 0;
-        }
+        }
+        return 0;
     }
     return 1;
 }
 
 static int
-process_data(const void *FileData, size_t FileSize, size_t offset, char *toString)
+process_data(const void *FileData, size_t offset, char *toString)
 {
     PIMAGE_DOS_HEADER PEDosHeader;
     PIMAGE_FILE_HEADER PEFileHeader;
@@ -261,24 +291,24 @@
     int res;
 
     /* Check if MZ header exists */
-    PEDosHeader = (PIMAGE_DOS_HEADER) FileData;
+    PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
     if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
     {
         fprintf(stderr, "Input file is not a PE image.\n");
-        summ.offset_errors ++;
+        summ.offset_errors++;
         return 1;
     }
 
     /* Locate PE file header */
     /* sizeof(ULONG) = sizeof(MAGIC) */
-    PEFileHeader = (PIMAGE_FILE_HEADER) ((char *)FileData + PEDosHeader->e_lfanew + sizeof (ULONG));
+    PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
 
     /* Locate optional header */
-    PEOptHeader = (PIMAGE_OPTIONAL_HEADER) (PEFileHeader + 1);
+    PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
     ImageBase = PEOptHeader->ImageBase;
 
     /* Locate PE section headers */
-    PESectionHeaders = (PIMAGE_SECTION_HEADER) ((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
+    PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
 
     /* make sure offset is what we want */
     offset = fixup_offset(ImageBase, offset);
@@ -288,7 +318,7 @@
     if (!PERosSymSectionHeader)
     {
         fprintf(stderr, "Couldn't find rossym section in executable\n");
-        summ.offset_errors ++;
+        summ.offset_errors++;
         return 1;
     }
     res = print_offset((char *)FileData + PERosSymSectionHeader->PointerToRawData, offset, toString);
@@ -303,16 +333,15 @@
             printf("??:0\n");
         }
         fprintf(stderr, "Offset not found.\n");
-        summ.offset_errors ++;
+        summ.offset_errors++;
     }
 
     return res;
 }
 
-static long
-my_atoi(const char *a)
-{
-    int i = 0;
+static const char *
+getFmt(const char *a)
+{
     const char *fmt = "%x";
 
     if (*a == '0')
@@ -332,8 +361,24 @@
             break;
         }
     }
-    sscanf(a, fmt, &i);
+    return fmt;
+}
+
+static long
+my_atoi(const char *a)
+{
+    int i = 0;
+    sscanf(a, getFmt(a), &i);
     return i;
+}
+
+static int
+isOffset(const char *a)
+{
+    int i = 0;
+    if (strchr(a, '.'))
+        return 0;
+    return sscanf(a, getFmt(a), &i);
 }
 
 static int
@@ -387,7 +432,7 @@
     }
     else
     {
-        res = process_data(FileData, FileSize, offset, toString);
+        res = process_data(FileData, offset, toString);
         free(FileData);
     }
     return res;
@@ -408,12 +453,12 @@
     fr = fopen(fname, "rb");
     if (!fr)
     {
-        if (opt_verbose)
+        if (opt_verbose > 2)
             fprintf(stderr, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno));
         return 1;
     }
 
-    readLen = fread(&PEDosHeader, sizeof (IMAGE_DOS_HEADER), 1, fr);
+    readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr);
     if (1 != readLen)
     {
         if (opt_verbose)
@@ -432,8 +477,8 @@
     }
 
     /* Locate PE file header */
-    res = fseek(fr, PEDosHeader.e_lfanew + sizeof (ULONG), SEEK_SET);
-    readLen = fread(&PEFileHeader, sizeof (IMAGE_FILE_HEADER), 1, fr);
+    res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET);
+    readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr);
     if (1 != readLen)
     {
         if (opt_verbose)
@@ -443,7 +488,7 @@
     }
 
     /* Locate optional header */
-    readLen = fread(&PEOptHeader, sizeof (IMAGE_OPTIONAL_HEADER), 1, fr);
+    readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr);
     if (1 != readLen)
     {
         if (opt_verbose)
@@ -453,8 +498,8 @@
     }
 
     /* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */
-    if ((PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) &&
-        (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC))
+    if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
+        PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
     {
         if (opt_verbose > 1)
             fprintf(stderr, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR<32|64>\n", fname);
@@ -500,7 +545,7 @@
     if (!Line)
         return NULL;
 
-    pentry = malloc(sizeof (CACHE_ENTRY));
+    pentry = malloc(sizeof(CACHE_ENTRY));
     if (!pentry)
         return NULL;
 
@@ -557,7 +602,7 @@
         if (PATHCMP(name, pnext->name) == 0)
         {
             if (pprev)
-            {  // move to head for faster lookup next time
+            {   // move to head for faster lookup next time
                 pprev->pnext = pnext->pnext;
                 pnext->pnext = cache.phead;
                 cache.phead = pnext;
@@ -680,7 +725,7 @@
                 if (*Fname == '\n')
                     *Fname = '\0';
 
-                while ((Fname > Line) && (*Fname != PATH_CHAR))
+                while (Fname > Line && *Fname != PATH_CHAR)
                     Fname--;
                 if (*Fname == PATH_CHAR)
                     Fname++;
@@ -770,9 +815,9 @@
 static char *
 remove_mark(char *Line)
 {
-    if( Line[1] == ' ' && Line[2] == '<' )
-        if ( Line[0] == '*' || Line[0] == '?' )
-            return Line+2;
+    if (Line[1] == ' ' && Line[2] == '<')
+        if (Line[0] == '*' || Line[0] == '?')
+            return Line + 2;
     return Line;
 }
 
@@ -799,33 +844,29 @@
             if (cnt == 3 && ch == ' ')
             {
                 tail = strchr(s, '>');
-                tail = tail ? tail-1 : tail;
-                if (tail && (tail[0] == ')') && (tail[1] == '>') )
+                tail = tail ? tail - 1 : tail;
+                if (tail && tail[0] == ')' && tail[1] == '>')
                 {
                     res = 0;
                     tail += 2;
                     mark = opt_mark ? "* " : "";
                     if (opt_redo && !(res = translate_file(path, offset, LineOut)))
                     {
-                        fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
-                        if (logFile)
-                            fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
-                        summ.redo ++;
+                        log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
+                        summ.redo++;
                     }
                     else
                     {
-                        fprintf(outFile, "%s<%s:%x>%s", mark, path, offset, tail);
-                        if (logFile)
-                            fprintf(logFile, "%s<%s:%x>%s", mark, path, offset, tail);
-                        summ.undo ++;
+                        log(outFile, "%s<%s:%x>%s", mark, path, offset, tail);
+                        summ.undo++;
                     }
                 }
                 else
                 {
                     mark = opt_Mark ? "? " : "";
-                    summ.skipped ++;
+                    summ.skipped++;
                 }
-                summ.total ++;
+                summ.total++;
             }
         }
 
@@ -837,17 +878,15 @@
                 if (!(res = translate_file(path, offset, LineOut)))
                 {
                     mark = opt_mark ? "* " : "";
-                    fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
-                    if (logFile)
-                        fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
-                    summ.translated ++;
+                    log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
+                    summ.translated++;
                 }
                 else
                 {
                     mark = opt_Mark ? "? " : "";
-                    summ.skipped ++;
+                    summ.skipped++;
                 }
-                summ.total ++;
+                summ.total++;
             }
         }
     }
@@ -855,36 +894,35 @@
     {
         if (sep)
             *sep = ':';  // restore because not translated
-        fprintf(outFile, "%s%s", mark, s);  // just copy
-        if (logFile)
-            fprintf(logFile, "%s%s", mark, s);  // just copy
+        log(outFile, "%s%s", mark, s);
     }
     memset(Line, '\0', LINESIZE);  // flushed
 }
 
 static void
-print_summary(FILE * outFile)
+print_summary(FILE *outFile)
 {
     if (outFile)
     {
         fprintf(outFile, "\n*** LOG2LINES SUMMARY ***\n");
-        fprintf(outFile, "Translated:   %d\n", summ.translated);
-        fprintf(outFile, "Reverted:     %d\n", summ.undo);
-        fprintf(outFile, "Retranslated: %d\n", summ.redo);
-        fprintf(outFile, "Skipped:      %d\n", summ.skipped);
-        fprintf(outFile, "Differ:       %d\n", summ.diff);
-        fprintf(outFile, "Offset error: %d\n", summ.offset_errors);
-        fprintf(outFile, "Total:        %d\n", summ.total);
+        fprintf(outFile, "Translated:               %d\n", summ.translated);
+        fprintf(outFile, "Reverted:                 %d\n", summ.undo);
+        fprintf(outFile, "Retranslated:             %d\n", summ.redo);
+        fprintf(outFile, "Skipped:                  %d\n", summ.skipped);
+        fprintf(outFile, "Differ:                   %d\n", summ.diff);
+        fprintf(outFile, "Differ (function/source): %d\n", summ.majordiff);
+        fprintf(outFile, "Offset error:             %d\n", summ.offset_errors);
+        fprintf(outFile, "Total:                    %d\n", summ.total);
         fprintf(outFile, "-------------------------------\n");
         fprintf(outFile, "Log2lines version: " LOG2LINES_VERSION "\n");
-        fprintf(outFile, "Directory:         %s\n",opt_dir);
-        fprintf(outFile, "Passed options:    %s\n",opt_scanned);
+        fprintf(outFile, "Directory:         %s\n", opt_dir);
+        fprintf(outFile, "Passed options:    %s\n", opt_scanned);
         fprintf(outFile, "-------------------------------\n");
     }
 }
 
 static int
-translate_files(FILE * inFile, FILE * outFile)
+translate_files(FILE *inFile, FILE *outFile)
 {
     char *Line = malloc(LINESIZE + 1);
     char *path = malloc(LINESIZE + 1);
@@ -927,7 +965,6 @@
                                 translate_line(outFile, Line, path, LineOut);
                                 translate_char(c, outFile);
                             }
-                            i = 0;
                         }
                         else
                         {
@@ -962,7 +999,7 @@
             }
         }
         else
-        {  // Line by line, slightly faster but less interactive
+        {   // Line by line, slightly faster but less interactive
             while (fgets(Line, LINESIZE, inFile) != NULL)
             {
                 if (!opt_raw)
@@ -971,9 +1008,7 @@
                 }
                 else
                 {
-                    fprintf(outFile, "%s", Line);  // just copy
-                    if (logFile)
-                        fprintf(logFile, "%s", Line);  // just copy
+                    log(outFile, "%s", Line);
                 }
             }
         }
@@ -993,9 +1028,12 @@
 static char *verboseUsage =
 "\n"
 "Description:\n"
-"  When <exefile> <offset> are given, log2lines works just like raddr2line\n"
+"  When <exefile> <offset> are given, log2lines works like raddr2line:\n"
+"      - The <exefile> <offset> combination can be repeated\n"
+"      - Also, <offset> can be repeated for each <exefile>\n"
+"      - NOTE: some of the options below will have no effect in this form.\n"
 "  Otherwise it reads stdin and tries to translate lines of the form:\n"
-"  <IMAGENAME:ADDRESS>\n\n"
+"      <IMAGENAME:ADDRESS>\n\n"
 "  The result is written to stdout.\n"
 "  log2lines uses a cache in order to avoid a directory scan at each\n"
 "  image lookup, greatly increasing performance. Only image path and its\n"
@@ -1008,7 +1046,9 @@
 "  -d <directory>|<ISO image>\n"
 "       Directory to scan for images. (Do not append a '" PATH_STR "')\n"
 "       This option also takes an ISO image as argument:\n"
-"       - The image is recognized by the '.iso' extension.\n"
+"       - The image is recognized by the '.iso' or '.7z' extension.\n"
+"       - NOTE: The '.7z' and extracted '.iso' basenames must be identical,\n"
+"         which is normally true for Reactos trunk builds.\n"
 "       - The image will be unpacked to a directory with the same name.\n"
 "       - The embedded reactos.cab file will also be unpacked.\n"
 "       - Combined with -f the file will be re-unpacked.\n"
@@ -1026,17 +1066,20 @@
 "  -r   Raw output without translation.\n\n"
 "  -s   Statistics. A summary with the following info is printed after EOF:\n"
 "       *** LOG2LINES SUMMARY ***\n"
-"       - Translated:   Translated lines.\n"
-"       - Reverted:     Lines translated back. See -u option\n"
-"       - Retranslated: Lines retranslated. See -U option\n"
-"       - Skipped:      Lines not translated.\n"
-"       - Differ:       Lines where (addr-1) info differs. See -tT options\n"
-"       - Offset error: Image exists, but error retrieving offset info.\n"
-"       - Total:        Total number of lines attempted to translate.\n"
+"       - Translated:      Translated lines.\n"
+"       - Reverted:        Lines translated back. See -u option\n"
+"       - Retranslated:    Lines retranslated. See -U option\n"
+"       - Skipped:         Lines not translated.\n"
+"       - Differ:          Lines where (addr-1) info differs. See -tT options\n"
+"       - Differ(func/src):Lines where also function or source info differ.\n"
+"       - Offset error:    Image exists, but error retrieving offset info.\n"
+"       - Total:           Total number of lines attempted to translate.\n"
 "       Also some version info is displayed.\n\n"
 "  -t   Translate twice. The address itself and for (address - 1)\n"
-"       Display extra filename and linenumber between [..] if they differ\n\n"
-"  -T   As -t, but the original filename+linenumber gets replaced\n\n"
+"       Show extra filename, func and linenumber between [..] if they differ\n"
+"       So if only the linenumbers differ, then only show the extra\n"
+"       linenumber.\n\n"
+"  -T   As -t, but the original filename+func+linenumber gets replaced\n\n"
 "  -u   Undo translations.\n"
 "       Lines are translated back (reverted) to the form <IMAGENAME:ADDRESS>\n"
 "       Overrides console mode -c.\n\n"
@@ -1053,7 +1096,7 @@
 "Examples:\n"
 "  Setup is a VMware machine with its serial port set to: '\\\\.\\pipe\\kdbg'.\n\n"
 "  Just recreate cache after a svn update or a new module has been added:\n"
-"       log2lines -F\n\n" 
+"       log2lines -F\n\n"
 "  Use kdbg debugger via console (interactive):\n"
 "       log2lines -c < \\\\.\\pipe\\kdbg\n\n"
 "  Use kdbg debugger via console, and append copy to logFile:\n"
@@ -1061,14 +1104,22 @@
 "  Use kdbg debugger to send output to logfile:\n"
 "       log2lines < \\\\.\\pipe\\kdbg > dbg.log\n\n"
 "  Re-translate a debug log:\n"
-"       log2lines -d bootcd-38701-dbg.iso < bugxxxx.log\n\n"
+"       log2lines -U -d bootcd-38701-dbg.iso < bugxxxx.log\n\n"
+"  Re-translate a debug log. Specify a 7z file, which wil be decompressed.\n"
+"  Also check for (address) - (address - 1) differences:\n"
+"       log2lines -U -t -d bootcd-38701-dbg.7z < bugxxxx.log\n"
+"  This would generate loglines like:\n"
+"       '<ntdll.dll:60f1 (dll/ntdll/ldr/utils.c:337[331] (LdrPEStartup))>'\n\n"
+"  The following command line invocations are equivalent:\n"
+"       log2lines msi.dll 2e35d msi.dll 2235 msiexec.exe 30a8 msiexec.exe 2e89\n"
+"       log2lines msi.dll 2e35d 2235 msiexec.exe 30a8 2e89\n\n"
 "\n";
 
 static void
 usage(int verbose)
 {
     fprintf(stderr, "log2lines " LOG2LINES_VERSION "\n\n");
-    fprintf(stderr, "Usage: log2lines [-%s] [<exefile> <offset>]\n", optchars);
+    fprintf(stderr, "Usage: log2lines -%s {<exefile> <offset> {<offset>}}\n", optchars);
     if (verbose)
     {
         fprintf(stderr, "%s", verboseUsage);
@@ -1085,7 +1136,7 @@
     char Line[LINESIZE];
     int res = 0;
     char iso_tmp[MAX_PATH];
-    int  iso_copied = 0;
+    int iso_copied = 0;
     FILE *fiso;
 
     strcpy(iso_tmp, iso);
@@ -1094,8 +1145,8 @@
         if (opt_verbose)
             fprintf(stderr, "Open of %s failed (locked for writing?), trying to copy first\n", iso);
 
-        strcat(iso_tmp,"~");
-        if (copy_file(iso,iso_tmp))
+        strcat(iso_tmp, "~");
+        if (copy_file(iso, iso_tmp))
             return 3;
         iso_copied = 1;
     }
@@ -1135,10 +1186,51 @@
 static int
 check_directory(int force)
 {
+    char Line[LINESIZE];
     char freeldr_path[MAX_PATH];
     char iso_path[MAX_PATH];
-
-    char *check_iso = strrchr(opt_dir, '.');
+    char compressed_7z_path[MAX_PATH];
+    char *check_iso;
+    char *check_dir;
+
+    check_iso = strrchr(opt_dir, '.');
+    if (check_iso && PATHCMP(check_iso, ".7z") == 0)
+    {
+        if (opt_verbose)
+            fprintf(stderr, "Uncompressing 7z image: %s\n", opt_dir);
+
+        // First attempt to decompress to a .iso image
+        strcpy(compressed_7z_path, opt_dir);
+        if ((check_dir = strrchr(compressed_7z_path, PATH_CHAR)))
+        {
+            *check_dir = '\0';
+        }
+        else
+            strcpy(compressed_7z_path, "."); // default to current dir
+
+        sprintf(Line, UNZIP_FMT_7Z, opt_7z, opt_dir, compressed_7z_path);
+
+        /* This of course only works if the .7z and .iso basenames are identical
+         * which is normally true for our trunk builds:
+         */
+        strcpy(check_iso, ".iso");
+        if (!file_exists(opt_dir) || force)
+        {
+            if (system(Line) < 0)
+            {
+                fprintf(stderr, "\nCannot decompress to iso image %s\n", opt_dir);
+                if (opt_verbose)
+                    fprintf(stderr, "Failed to execute: '%s'\n", Line);
+                return 2;
+            }
+        }
+        else
+        {
+            if (opt_verbose > 1)
+                fprintf(stderr, "%s already decompressed\n", opt_dir);
+        }
+    }
+
     if (check_iso && PATHCMP(check_iso, ".iso") == 0)
     {
         if (opt_verbose)
@@ -1187,7 +1279,7 @@
     int i;
 
     strcpy(opt_scanned, "");
-    for (i=1; i<argc; i++)
+    for (i = 1; i < argc; i++)
     {
         strcat(opt_scanned, argv[i]);
         strcat(opt_scanned, " ");
@@ -1218,7 +1310,7 @@
         case 'h':
             opt_help++;
             usage(1);
-            exit(0);
+            return 0;
             break;
         case 'F':
             opt_exit++;
@@ -1263,7 +1355,7 @@
             break;
         default:
             usage(0);
-            exit(2);
+            return 2;
             break;
         }
         optCount++;
@@ -1272,18 +1364,12 @@
         opt_console = 0;
 
     argc -= optCount;
-    if (argc != 1 && argc != 3)
-    {
-        usage(0);
-        exit(1);
-    }
-
     if (check_directory(opt_force))
-        exit(3);
+        return 3;
 
     create_cache(opt_force, 0);
     if (opt_exit)
-        exit(0);
+        return 0;
 
     read_cache();
 
@@ -1297,7 +1383,7 @@
             {
                 if (opt_verbose)
                     fprintf(stderr, "Disabling log buffering on %s\n", opt_logFile);
-                setbuf(logFile,NULL);
+                setbuf(logFile, NULL);
             }
             else
             {
@@ -1308,20 +1394,47 @@
         else
         {
             fprintf(stderr, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno));
-            exit(2);
-
-        }
-    }
-    if (argc == 3)
-    {  // translate <exefile> <offset>
-        translate_file(argv[optCount + 1], my_atoi(argv[optCount + 2]), NULL);
+            return 2;
+        }
+    }
+
+    if (argc > 1)
+    {   // translate {<exefile> <offset>}
+        int i = 1;
+        const char *base = NULL;
+        const char *offset = NULL;
+        while (i < argc)
+        {
+            offset = argv[optCount + i++];
+            if (isOffset(offset))
+            {
+                if (base)
+                {
+                    if (opt_verbose > 1)
+                        fprintf(stderr, "translating %s %s\n", base, offset);
+                    translate_file(base, my_atoi(offset), NULL);
+                }
+                else
+                {
+                    fprintf(stderr, "<exefile> expected\n");
+                    res = 3;
+                    break;
+                }
+            }
+            else
+            {
+                // Must be exefile
+                base = offset;
+            }
+        }
     }
     else
-    {  // translate logging from stdin
+    {   // translate logging from stdin
         translate_files(stdin, stdout);
     }
 
     if (logFile)
         fclose(logFile);
+
     return res;
 }




More information about the Ros-diffs mailing list