xref: /reactos/sdk/lib/rossym_new/fromfile.c (revision 845faec4)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS kernel
4  * FILE:            lib/rossym/fromfile.c
5  * PURPOSE:         Creating rossym info from a file
6  *
7  * PROGRAMMERS:     Ge van Geldorp (gvg@reactos.com)
8  */
9 
10 #include <precomp.h>
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define SYMBOL_SIZE 18
16 
17 extern NTSTATUS RosSymStatus;
18 
19 BOOLEAN
20 RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo)
21 {
22     IMAGE_DOS_HEADER DosHeader;
23     IMAGE_NT_HEADERS NtHeaders;
24     PIMAGE_SECTION_HEADER SectionHeaders;
25     unsigned SectionIndex;
26     unsigned SymbolTable, NumSymbols;
27 
28     /* Load DOS header */
29     if (! RosSymSeekFile(FileContext, 0))
30     {
31         werrstr("Could not rewind file\n");
32         return FALSE;
33     }
34     if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER)))
35     {
36         werrstr("Failed to read DOS header %x\n", RosSymStatus);
37         return FALSE;
38     }
39     if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader))
40     {
41         werrstr("Image doesn't have a valid DOS header\n");
42         return FALSE;
43     }
44 
45     /* Load NT headers */
46     if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew))
47     {
48         werrstr("Failed seeking to NT headers\n");
49         return FALSE;
50     }
51     if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS)))
52     {
53         werrstr("Failed to read NT headers\n");
54         return FALSE;
55     }
56     if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders))
57     {
58         werrstr("Image doesn't have a valid PE header\n");
59         return FALSE;
60     }
61 
62     SymbolTable = NtHeaders.FileHeader.PointerToSymbolTable;
63     NumSymbols = NtHeaders.FileHeader.NumberOfSymbols;
64 
65     if (!NumSymbols)
66     {
67         werrstr("Image doesn't have debug symbols\n");
68         return FALSE;
69     }
70 
71     DPRINT("SymbolTable %x NumSymbols %x\n", SymbolTable, NumSymbols);
72 
73     /* Load section headers */
74     if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) -
75                          (char *) &NtHeaders + DosHeader.e_lfanew))
76     {
77         werrstr("Failed seeking to section headers\n");
78         return FALSE;
79     }
80     DPRINT("Alloc section headers\n");
81     SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections
82                                     * sizeof(IMAGE_SECTION_HEADER));
83     if (NULL == SectionHeaders)
84     {
85         werrstr("Failed to allocate memory for %u section headers\n",
86                 NtHeaders.FileHeader.NumberOfSections);
87         return FALSE;
88     }
89     if (! RosSymReadFile(FileContext, SectionHeaders,
90                          NtHeaders.FileHeader.NumberOfSections
91                          * sizeof(IMAGE_SECTION_HEADER)))
92     {
93         RosSymFreeMem(SectionHeaders);
94         werrstr("Failed to read section headers\n");
95         return FALSE;
96     }
97 
98     // Convert names to ANSI_STRINGs
99     for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections;
100          SectionIndex++)
101     {
102         ANSI_STRING astr;
103         if (SectionHeaders[SectionIndex].Name[0] != '/') {
104             DPRINT("Short name string %d, %s\n", SectionIndex, SectionHeaders[SectionIndex].Name);
105             astr.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME);
106             memcpy(astr.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME);
107             astr.MaximumLength = IMAGE_SIZEOF_SHORT_NAME;
108             astr.Length = GetStrnlen(astr.Buffer, IMAGE_SIZEOF_SHORT_NAME);
109         } else {
110             UNICODE_STRING intConv;
111             NTSTATUS Status;
112             ULONG StringOffset;
113 
114             if (!RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1))
115                 goto freeall;
116             Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset);
117             RtlFreeUnicodeString(&intConv);
118             if (!NT_SUCCESS(Status)) goto freeall;
119             if (!RosSymSeekFile(FileContext, SymbolTable + NumSymbols * SYMBOL_SIZE + StringOffset))
120                 goto freeall;
121             astr.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE);
122             if (!RosSymReadFile(FileContext, astr.Buffer, MAXIMUM_DWARF_NAME_SIZE))
123                 goto freeall;
124             astr.Length = GetStrnlen(astr.Buffer, MAXIMUM_DWARF_NAME_SIZE);
125             astr.MaximumLength = MAXIMUM_DWARF_NAME_SIZE;
126             DPRINT("Long name %d, %s\n", SectionIndex, astr.Buffer);
127         }
128         *ANSI_NAME_STRING(&SectionHeaders[SectionIndex]) = astr;
129     }
130 
131     DPRINT("Done with sections\n");
132     Pe *pe = RosSymAllocMem(sizeof(*pe));
133     pe->fd = FileContext;
134     pe->e2 = peget2;
135     pe->e4 = peget4;
136     pe->e8 = peget8;
137     pe->nsections = NtHeaders.FileHeader.NumberOfSections;
138     pe->sect = SectionHeaders;
139     pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase;
140     pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage;
141     pe->codestart = NtHeaders.OptionalHeader.BaseOfCode;
142     pe->datastart = NtHeaders.OptionalHeader.BaseOfData;
143     pe->loadsection = loaddisksection;
144     *RosSymInfo = dwarfopen(pe);
145 
146     return TRUE;
147 
148 freeall:
149     for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections;
150          SectionIndex++)
151         RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex]));
152     RosSymFreeMem(SectionHeaders);
153 
154     return FALSE;
155 }
156 
157 /* EOF */
158