Update log2lines to version 1.4. Jan Roeloffzen, bug #4342.

svn path=/trunk/; revision=44335
This commit is contained in:
Dmitry Gorbachev 2009-11-30 21:49:18 +00:00
parent 4b9396cef9
commit 378568a6d9

View file

@ -1,14 +1,6 @@
/* /*
* Usage: log2lines [-cd:fFhmrv] [<exefile> <offset>] * ReactOS log2lines
* Try log2lines -h * Written by Jan Roeloffzen
*
* 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.
*/ */
#include <stdio.h> #include <stdio.h>
@ -18,7 +10,7 @@
#include "rsym.h" #include "rsym.h"
#define LOG2LINES_VERSION "1.1" #define LOG2LINES_VERSION "1.4"
#define INVALID_BASE 0xFFFFFFFFL #define INVALID_BASE 0xFFFFFFFFL
@ -53,12 +45,21 @@
#define CP_FMT CP_CMD "%s %s > " DEV_NULL #define CP_FMT CP_CMD "%s %s > " DEV_NULL
#define CMD_7Z "7z" #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 "%s x -y -r %s -o%s > " DEV_NULL
#define UNZIP_FMT_CAB \ #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 "%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 LINESIZE 1024
#define log(outFile, fmt, ...) \
{ \
fprintf(outFile, fmt, ##__VA_ARGS__); \
if (logFile) \
fprintf(logFile, fmt, ##__VA_ARGS__); \
}
struct entry_struct struct entry_struct
{ {
char *buf; char *buf;
@ -84,6 +85,7 @@ struct summ_struct
int redo; int redo;
int skipped; int skipped;
int diff; int diff;
int majordiff;
int offset_errors; int offset_errors;
int total; int total;
}; };
@ -152,11 +154,11 @@ find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESec
} }
static PROSSYM_ENTRY static PROSSYM_ENTRY
find_offset(void *data, size_t offset, char *toString) find_offset(void *data, size_t offset)
{ {
PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data; PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
PROSSYM_ENTRY Entries = (PROSSYM_ENTRY) ((char *)data + RosSymHeader->SymbolsOffset); PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset);
size_t symbols = RosSymHeader->SymbolsLength / sizeof (ROSSYM_ENTRY); size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
size_t i; size_t i;
for (i = 0; i < symbols; i++) for (i = 0; i < symbols; i++)
@ -177,65 +179,93 @@ find_offset(void *data, size_t offset, char *toString)
static int static int
print_offset(void *data, size_t offset, char *toString) 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 e = NULL;
PROSSYM_ENTRY e2 = NULL; PROSSYM_ENTRY e2 = NULL;
int bFileOffsetChanged = 0;
char fmt[LINESIZE];
char *Strings = (char *)data + RosSymHeader->StringsOffset; char *Strings = (char *)data + RosSymHeader->StringsOffset;
fmt[0] = '\0';
e = find_offset(data, offset, toString); e = find_offset(data, offset);
if (opt_twice) if (opt_twice)
{ {
e2 = find_offset(data, offset-1, toString); e2 = find_offset(data, offset - 1);
if ( e == e2 ) if (e == e2)
e2 = NULL; e2 = NULL;
else
summ.diff++;
if ( opt_Twice && e2 ) if (opt_Twice && e2)
{ {
e = e2; e = e2;
e2 = NULL; e2 = NULL;
/* replaced (transparantly), but update stats: */ /* replaced (transparantly), but updated stats */
summ.diff ++;
} }
} }
if ( e || e2 ) 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) if (toString)
{ // put in toString if provided { // put in toString if provided
if ( e2 ) snprintf(toString, LINESIZE, fmt,
{
snprintf(toString, LINESIZE, "%s:%u (%s) [%s:%u (%s)]",
&Strings[e->FileOffset], &Strings[e->FileOffset],
(unsigned int)e->SourceLine,
&Strings[e->FunctionOffset],
&Strings[e2->FileOffset], &Strings[e2->FileOffset],
(unsigned int)e->SourceLine,
(unsigned int)e2->SourceLine, (unsigned int)e2->SourceLine,
&Strings[e->FunctionOffset],
&Strings[e2->FunctionOffset]); &Strings[e2->FunctionOffset]);
summ.diff ++;
} }
else 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)", snprintf(toString, LINESIZE, "%s:%u (%s)",
&Strings[e->FileOffset], &Strings[e->FileOffset],
(unsigned int)e->SourceLine, (unsigned int)e->SourceLine,
&Strings[e->FunctionOffset]); &Strings[e->FunctionOffset]);
} }
return 0;
}
else
{ // to stdout
if ( e2 )
{
printf("%s:%u (%s) [%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 else
{ {
printf("%s:%u (%s)\n", printf("%s:%u (%s)\n",
@ -243,14 +273,14 @@ print_offset(void *data, size_t offset, char *toString)
(unsigned int)e->SourceLine, (unsigned int)e->SourceLine,
&Strings[e->FunctionOffset]); &Strings[e->FunctionOffset]);
} }
return 0;
} }
return 0;
} }
return 1; return 1;
} }
static int 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_DOS_HEADER PEDosHeader;
PIMAGE_FILE_HEADER PEFileHeader; PIMAGE_FILE_HEADER PEFileHeader;
@ -261,24 +291,24 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin
int res; int res;
/* Check if MZ header exists */ /* 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) if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
{ {
fprintf(stderr, "Input file is not a PE image.\n"); fprintf(stderr, "Input file is not a PE image.\n");
summ.offset_errors ++; summ.offset_errors++;
return 1; return 1;
} }
/* Locate PE file header */ /* Locate PE file header */
/* sizeof(ULONG) = sizeof(MAGIC) */ /* 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 */ /* Locate optional header */
PEOptHeader = (PIMAGE_OPTIONAL_HEADER) (PEFileHeader + 1); PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
ImageBase = PEOptHeader->ImageBase; ImageBase = PEOptHeader->ImageBase;
/* Locate PE section headers */ /* 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 */ /* make sure offset is what we want */
offset = fixup_offset(ImageBase, offset); offset = fixup_offset(ImageBase, offset);
@ -288,7 +318,7 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin
if (!PERosSymSectionHeader) if (!PERosSymSectionHeader)
{ {
fprintf(stderr, "Couldn't find rossym section in executable\n"); fprintf(stderr, "Couldn't find rossym section in executable\n");
summ.offset_errors ++; summ.offset_errors++;
return 1; return 1;
} }
res = print_offset((char *)FileData + PERosSymSectionHeader->PointerToRawData, offset, toString); res = print_offset((char *)FileData + PERosSymSectionHeader->PointerToRawData, offset, toString);
@ -303,16 +333,15 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin
printf("??:0\n"); printf("??:0\n");
} }
fprintf(stderr, "Offset not found.\n"); fprintf(stderr, "Offset not found.\n");
summ.offset_errors ++; summ.offset_errors++;
} }
return res; return res;
} }
static long static const char *
my_atoi(const char *a) getFmt(const char *a)
{ {
int i = 0;
const char *fmt = "%x"; const char *fmt = "%x";
if (*a == '0') if (*a == '0')
@ -332,10 +361,26 @@ my_atoi(const char *a)
break; break;
} }
} }
sscanf(a, fmt, &i); return fmt;
}
static long
my_atoi(const char *a)
{
int i = 0;
sscanf(a, getFmt(a), &i);
return 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 static int
file_exists(char *name) file_exists(char *name)
{ {
@ -387,7 +432,7 @@ process_file(const char *file_name, size_t offset, char *toString)
} }
else else
{ {
res = process_data(FileData, FileSize, offset, toString); res = process_data(FileData, offset, toString);
free(FileData); free(FileData);
} }
return res; return res;
@ -408,12 +453,12 @@ get_ImageBase(char *fname, size_t *ImageBase)
fr = fopen(fname, "rb"); fr = fopen(fname, "rb");
if (!fr) if (!fr)
{ {
if (opt_verbose) if (opt_verbose > 2)
fprintf(stderr, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno)); fprintf(stderr, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno));
return 1; return 1;
} }
readLen = fread(&PEDosHeader, sizeof (IMAGE_DOS_HEADER), 1, fr); readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr);
if (1 != readLen) if (1 != readLen)
{ {
if (opt_verbose) if (opt_verbose)
@ -432,8 +477,8 @@ get_ImageBase(char *fname, size_t *ImageBase)
} }
/* Locate PE file header */ /* Locate PE file header */
res = fseek(fr, PEDosHeader.e_lfanew + sizeof (ULONG), SEEK_SET); res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET);
readLen = fread(&PEFileHeader, sizeof (IMAGE_FILE_HEADER), 1, fr); readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr);
if (1 != readLen) if (1 != readLen)
{ {
if (opt_verbose) if (opt_verbose)
@ -443,7 +488,7 @@ get_ImageBase(char *fname, size_t *ImageBase)
} }
/* Locate optional header */ /* 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 (1 != readLen)
{ {
if (opt_verbose) if (opt_verbose)
@ -453,8 +498,8 @@ get_ImageBase(char *fname, size_t *ImageBase)
} }
/* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */ /* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */
if ((PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) && if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
(PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)) PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
{ {
if (opt_verbose > 1) if (opt_verbose > 1)
fprintf(stderr, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR<32|64>\n", fname); fprintf(stderr, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR<32|64>\n", fname);
@ -500,7 +545,7 @@ entry_create(char *Line)
if (!Line) if (!Line)
return NULL; return NULL;
pentry = malloc(sizeof (CACHE_ENTRY)); pentry = malloc(sizeof(CACHE_ENTRY));
if (!pentry) if (!pentry)
return NULL; return NULL;
@ -680,7 +725,7 @@ create_cache(int force, int skipImageBase)
if (*Fname == '\n') if (*Fname == '\n')
*Fname = '\0'; *Fname = '\0';
while ((Fname > Line) && (*Fname != PATH_CHAR)) while (Fname > Line && *Fname != PATH_CHAR)
Fname--; Fname--;
if (*Fname == PATH_CHAR) if (*Fname == PATH_CHAR)
Fname++; Fname++;
@ -770,9 +815,9 @@ translate_char(int c, FILE *outFile)
static char * static char *
remove_mark(char *Line) remove_mark(char *Line)
{ {
if( Line[1] == ' ' && Line[2] == '<' ) if (Line[1] == ' ' && Line[2] == '<')
if ( Line[0] == '*' || Line[0] == '?' ) if (Line[0] == '*' || Line[0] == '?')
return Line+2; return Line + 2;
return Line; return Line;
} }
@ -799,33 +844,29 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut)
if (cnt == 3 && ch == ' ') if (cnt == 3 && ch == ' ')
{ {
tail = strchr(s, '>'); tail = strchr(s, '>');
tail = tail ? tail-1 : tail; tail = tail ? tail - 1 : tail;
if (tail && (tail[0] == ')') && (tail[1] == '>') ) if (tail && tail[0] == ')' && tail[1] == '>')
{ {
res = 0; res = 0;
tail += 2; tail += 2;
mark = opt_mark ? "* " : ""; mark = opt_mark ? "* " : "";
if (opt_redo && !(res = translate_file(path, offset, LineOut))) if (opt_redo && !(res = translate_file(path, offset, LineOut)))
{ {
fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
if (logFile) summ.redo++;
fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
summ.redo ++;
} }
else else
{ {
fprintf(outFile, "%s<%s:%x>%s", mark, path, offset, tail); log(outFile, "%s<%s:%x>%s", mark, path, offset, tail);
if (logFile) summ.undo++;
fprintf(logFile, "%s<%s:%x>%s", mark, path, offset, tail);
summ.undo ++;
} }
} }
else else
{ {
mark = opt_Mark ? "? " : ""; mark = opt_Mark ? "? " : "";
summ.skipped ++; summ.skipped++;
} }
summ.total ++; summ.total++;
} }
} }
@ -837,17 +878,15 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut)
if (!(res = translate_file(path, offset, LineOut))) if (!(res = translate_file(path, offset, LineOut)))
{ {
mark = opt_mark ? "* " : ""; mark = opt_mark ? "* " : "";
fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
if (logFile) summ.translated++;
fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
summ.translated ++;
} }
else else
{ {
mark = opt_Mark ? "? " : ""; mark = opt_Mark ? "? " : "";
summ.skipped ++; summ.skipped++;
} }
summ.total ++; summ.total++;
} }
} }
} }
@ -855,15 +894,13 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut)
{ {
if (sep) if (sep)
*sep = ':'; // restore because not translated *sep = ':'; // restore because not translated
fprintf(outFile, "%s%s", mark, s); // just copy log(outFile, "%s%s", mark, s);
if (logFile)
fprintf(logFile, "%s%s", mark, s); // just copy
} }
memset(Line, '\0', LINESIZE); // flushed memset(Line, '\0', LINESIZE); // flushed
} }
static void static void
print_summary(FILE * outFile) print_summary(FILE *outFile)
{ {
if (outFile) if (outFile)
{ {
@ -873,18 +910,19 @@ print_summary(FILE * outFile)
fprintf(outFile, "Retranslated: %d\n", summ.redo); fprintf(outFile, "Retranslated: %d\n", summ.redo);
fprintf(outFile, "Skipped: %d\n", summ.skipped); fprintf(outFile, "Skipped: %d\n", summ.skipped);
fprintf(outFile, "Differ: %d\n", summ.diff); 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, "Offset error: %d\n", summ.offset_errors);
fprintf(outFile, "Total: %d\n", summ.total); fprintf(outFile, "Total: %d\n", summ.total);
fprintf(outFile, "-------------------------------\n"); fprintf(outFile, "-------------------------------\n");
fprintf(outFile, "Log2lines version: " LOG2LINES_VERSION "\n"); fprintf(outFile, "Log2lines version: " LOG2LINES_VERSION "\n");
fprintf(outFile, "Directory: %s\n",opt_dir); fprintf(outFile, "Directory: %s\n", opt_dir);
fprintf(outFile, "Passed options: %s\n",opt_scanned); fprintf(outFile, "Passed options: %s\n", opt_scanned);
fprintf(outFile, "-------------------------------\n"); fprintf(outFile, "-------------------------------\n");
} }
} }
static int static int
translate_files(FILE * inFile, FILE * outFile) translate_files(FILE *inFile, FILE *outFile)
{ {
char *Line = malloc(LINESIZE + 1); char *Line = malloc(LINESIZE + 1);
char *path = malloc(LINESIZE + 1); char *path = malloc(LINESIZE + 1);
@ -927,7 +965,6 @@ translate_files(FILE * inFile, FILE * outFile)
translate_line(outFile, Line, path, LineOut); translate_line(outFile, Line, path, LineOut);
translate_char(c, outFile); translate_char(c, outFile);
} }
i = 0;
} }
else else
{ {
@ -971,9 +1008,7 @@ translate_files(FILE * inFile, FILE * outFile)
} }
else else
{ {
fprintf(outFile, "%s", Line); // just copy log(outFile, "%s", Line);
if (logFile)
fprintf(logFile, "%s", Line); // just copy
} }
} }
} }
@ -993,7 +1028,10 @@ translate_files(FILE * inFile, FILE * outFile)
static char *verboseUsage = static char *verboseUsage =
"\n" "\n"
"Description:\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" " 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" " The result is written to stdout.\n"
@ -1008,7 +1046,9 @@ static char *verboseUsage =
" -d <directory>|<ISO image>\n" " -d <directory>|<ISO image>\n"
" Directory to scan for images. (Do not append a '" PATH_STR "')\n" " Directory to scan for images. (Do not append a '" PATH_STR "')\n"
" This option also takes an ISO image as argument:\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 image will be unpacked to a directory with the same name.\n"
" - The embedded reactos.cab file will also be unpacked.\n" " - The embedded reactos.cab file will also be unpacked.\n"
" - Combined with -f the file will be re-unpacked.\n" " - Combined with -f the file will be re-unpacked.\n"
@ -1031,12 +1071,15 @@ static char *verboseUsage =
" - Retranslated: Lines retranslated. See -U option\n" " - Retranslated: Lines retranslated. See -U option\n"
" - Skipped: Lines not translated.\n" " - Skipped: Lines not translated.\n"
" - Differ: Lines where (addr-1) info differs. See -tT options\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" " - Offset error: Image exists, but error retrieving offset info.\n"
" - Total: Total number of lines attempted to translate.\n" " - Total: Total number of lines attempted to translate.\n"
" Also some version info is displayed.\n\n" " Also some version info is displayed.\n\n"
" -t Translate twice. The address itself and for (address - 1)\n" " -t Translate twice. The address itself and for (address - 1)\n"
" Display extra filename and linenumber between [..] if they differ\n\n" " Show extra filename, func and linenumber between [..] if they differ\n"
" -T As -t, but the original filename+linenumber gets replaced\n\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" " -u Undo translations.\n"
" Lines are translated back (reverted) to the form <IMAGENAME:ADDRESS>\n" " Lines are translated back (reverted) to the form <IMAGENAME:ADDRESS>\n"
" Overrides console mode -c.\n\n" " Overrides console mode -c.\n\n"
@ -1061,14 +1104,22 @@ static char *verboseUsage =
" Use kdbg debugger to send output to logfile:\n" " Use kdbg debugger to send output to logfile:\n"
" log2lines < \\\\.\\pipe\\kdbg > dbg.log\n\n" " log2lines < \\\\.\\pipe\\kdbg > dbg.log\n\n"
" Re-translate a debug log:\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"; "\n";
static void static void
usage(int verbose) usage(int verbose)
{ {
fprintf(stderr, "log2lines " LOG2LINES_VERSION "\n\n"); 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) if (verbose)
{ {
fprintf(stderr, "%s", verboseUsage); fprintf(stderr, "%s", verboseUsage);
@ -1094,8 +1145,8 @@ unpack_iso(char *dir, char *iso)
if (opt_verbose) if (opt_verbose)
fprintf(stderr, "Open of %s failed (locked for writing?), trying to copy first\n", iso); fprintf(stderr, "Open of %s failed (locked for writing?), trying to copy first\n", iso);
strcat(iso_tmp,"~"); strcat(iso_tmp, "~");
if (copy_file(iso,iso_tmp)) if (copy_file(iso, iso_tmp))
return 3; return 3;
iso_copied = 1; iso_copied = 1;
} }
@ -1135,10 +1186,51 @@ unpack_iso(char *dir, char *iso)
static int static int
check_directory(int force) check_directory(int force)
{ {
char Line[LINESIZE];
char freeldr_path[MAX_PATH]; char freeldr_path[MAX_PATH];
char iso_path[MAX_PATH]; char iso_path[MAX_PATH];
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);
}
}
char *check_iso = strrchr(opt_dir, '.');
if (check_iso && PATHCMP(check_iso, ".iso") == 0) if (check_iso && PATHCMP(check_iso, ".iso") == 0)
{ {
if (opt_verbose) if (opt_verbose)
@ -1187,7 +1279,7 @@ main(int argc, const char **argv)
int i; int i;
strcpy(opt_scanned, ""); strcpy(opt_scanned, "");
for (i=1; i<argc; i++) for (i = 1; i < argc; i++)
{ {
strcat(opt_scanned, argv[i]); strcat(opt_scanned, argv[i]);
strcat(opt_scanned, " "); strcat(opt_scanned, " ");
@ -1218,7 +1310,7 @@ main(int argc, const char **argv)
case 'h': case 'h':
opt_help++; opt_help++;
usage(1); usage(1);
exit(0); return 0;
break; break;
case 'F': case 'F':
opt_exit++; opt_exit++;
@ -1263,7 +1355,7 @@ main(int argc, const char **argv)
break; break;
default: default:
usage(0); usage(0);
exit(2); return 2;
break; break;
} }
optCount++; optCount++;
@ -1272,18 +1364,12 @@ main(int argc, const char **argv)
opt_console = 0; opt_console = 0;
argc -= optCount; argc -= optCount;
if (argc != 1 && argc != 3)
{
usage(0);
exit(1);
}
if (check_directory(opt_force)) if (check_directory(opt_force))
exit(3); return 3;
create_cache(opt_force, 0); create_cache(opt_force, 0);
if (opt_exit) if (opt_exit)
exit(0); return 0;
read_cache(); read_cache();
@ -1297,7 +1383,7 @@ main(int argc, const char **argv)
{ {
if (opt_verbose) if (opt_verbose)
fprintf(stderr, "Disabling log buffering on %s\n", opt_logFile); fprintf(stderr, "Disabling log buffering on %s\n", opt_logFile);
setbuf(logFile,NULL); setbuf(logFile, NULL);
} }
else else
{ {
@ -1308,13 +1394,39 @@ main(int argc, const char **argv)
else else
{ {
fprintf(stderr, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno)); fprintf(stderr, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno));
exit(2); 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;
} }
} }
if (argc == 3)
{ // translate <exefile> <offset>
translate_file(argv[optCount + 1], my_atoi(argv[optCount + 2]), NULL);
} }
else else
{ // translate logging from stdin { // translate logging from stdin
@ -1323,5 +1435,6 @@ main(int argc, const char **argv)
if (logFile) if (logFile)
fclose(logFile); fclose(logFile);
return res; return res;
} }