Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / sdk / tools / log2lines / image.c
1 /*
2 * ReactOS log2lines
3 * Written by Jan Roeloffzen
4 *
5 * - Image functions for symbol info
6 */
7
8 #include <errno.h>
9 #include <string.h>
10 #include <rsym.h>
11
12 #include "compat.h"
13 #include "util.h"
14 #include "options.h"
15 #include "log2lines.h"
16
17 static PIMAGE_SECTION_HEADER
18 find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders)
19 {
20 size_t i;
21 for (i = 0; i < PEFileHeader->NumberOfSections; i++)
22 {
23 if (0 == strcmp((char *)PESectionHeaders[i].Name, ".rossym"))
24 return &PESectionHeaders[i];
25 }
26 return NULL;
27 }
28
29 size_t
30 fixup_offset(size_t ImageBase, size_t offset)
31 {
32 if (offset > ABS_TRESHOLD)
33 offset -= ImageBase;
34 return offset;
35 }
36
37 PROSSYM_ENTRY
38 find_offset(void *data, size_t offset)
39 {
40 PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
41 PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset);
42 size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
43 size_t i;
44
45 for (i = 0; i < symbols; i++)
46 {
47 if (Entries[i].Address > offset)
48 {
49 if (!i--)
50 return NULL;
51 else
52 return &Entries[i];
53 }
54 }
55 return NULL;
56 }
57
58 PIMAGE_SECTION_HEADER
59 get_sectionheader(const void *FileData)
60 {
61 PIMAGE_DOS_HEADER PEDosHeader;
62 PIMAGE_FILE_HEADER PEFileHeader;
63 PIMAGE_OPTIONAL_HEADER PEOptHeader;
64 PIMAGE_SECTION_HEADER PESectionHeaders;
65 PIMAGE_SECTION_HEADER PERosSymSectionHeader;
66 size_t ImageBase;
67
68 /* Check if MZ header exists */
69 PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
70 if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
71 {
72 l2l_dbg(0, "Input file is not a PE image.\n");
73 summ.offset_errors++;
74 return NULL;
75 }
76
77 /* Locate PE file header */
78 /* sizeof(ULONG) = sizeof(MAGIC) */
79 PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
80
81 /* Locate optional header */
82 PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
83 ImageBase = PEOptHeader->ImageBase;
84
85 /* Locate PE section headers */
86 PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
87
88 /* find rossym section */
89 PERosSymSectionHeader = find_rossym_section(PEFileHeader, PESectionHeaders);
90 if (!PERosSymSectionHeader)
91 {
92 l2l_dbg(0, "Couldn't find rossym section in executable\n");
93 summ.offset_errors++;
94 return NULL;
95 }
96
97 return PERosSymSectionHeader;
98 }
99
100 int
101 get_ImageBase(char *fname, size_t *ImageBase)
102 {
103 IMAGE_DOS_HEADER PEDosHeader;
104 IMAGE_FILE_HEADER PEFileHeader;
105 IMAGE_OPTIONAL_HEADER PEOptHeader;
106
107 FILE *fr;
108 off_t readLen;
109 int res;
110
111 *ImageBase = INVALID_BASE;
112 fr = fopen(fname, "rb");
113 if (!fr)
114 {
115 l2l_dbg(3, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno));
116 return 1;
117 }
118
119 readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr);
120 if (1 != readLen)
121 {
122 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_DOS_HEADER (%s)\n", fname, strerror(errno));
123 fclose(fr);
124 return 2;
125 }
126
127 /* Check if MZ header exists */
128 if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC || PEDosHeader.e_lfanew == 0L)
129 {
130 l2l_dbg(2, "get_ImageBase %s, MZ header missing\n", fname);
131 fclose(fr);
132 return 3;
133 }
134
135 /* Locate PE file header */
136 res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET);
137 readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr);
138 if (1 != readLen)
139 {
140 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_FILE_HEADER (%s)\n", fname, strerror(errno));
141 fclose(fr);
142 return 4;
143 }
144
145 /* Locate optional header */
146 readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr);
147 if (1 != readLen)
148 {
149 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_OPTIONAL_HEADER (%s)\n", fname, strerror(errno));
150 fclose(fr);
151 return 5;
152 }
153
154 /* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */
155 if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
156 PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
157 {
158 l2l_dbg(2, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR 32/64 bit\n", fname);
159 fclose(fr);
160 return 6;
161 }
162
163 *ImageBase = PEOptHeader.ImageBase;
164 fclose(fr);
165 return 0;
166 }
167
168 /* EOF */