mirror of
https://github.com/reactos/reactos.git
synced 2025-04-29 18:48:53 +00:00
Update log2lines to version 1.4. Jan Roeloffzen, bug #4342.
svn path=/trunk/; revision=44335
This commit is contained in:
parent
4b9396cef9
commit
378568a6d9
1 changed files with 277 additions and 164 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue