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…
==============================================================================
--- 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;
}