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
7 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
12 #include <ndk/ntndk.h>
13 #include <reactos/rossym.h>
14 #include "rossympriv.h"
23 extern NTSTATUS RosSymStatus
;
26 RosSymCreateFromFile(PVOID FileContext
, PROSSYM_INFO
*RosSymInfo
)
28 IMAGE_DOS_HEADER DosHeader
;
29 IMAGE_NT_HEADERS NtHeaders
;
30 PIMAGE_SECTION_HEADER SectionHeaders
;
31 unsigned SectionIndex
;
32 unsigned SymbolTable
, NumSymbols
;
35 if (! RosSymSeekFile(FileContext
, 0))
37 DPRINT1("Could not rewind file\n");
40 if (! RosSymReadFile(FileContext
, &DosHeader
, sizeof(IMAGE_DOS_HEADER
)))
42 DPRINT1("Failed to read DOS header %x\n", RosSymStatus
);
45 if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader
))
47 DPRINT1("Image doesn't have a valid DOS header\n");
52 if (! RosSymSeekFile(FileContext
, DosHeader
.e_lfanew
))
54 DPRINT1("Failed seeking to NT headers\n");
57 if (! RosSymReadFile(FileContext
, &NtHeaders
, sizeof(IMAGE_NT_HEADERS
)))
59 DPRINT1("Failed to read NT headers\n");
62 if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders
))
64 DPRINT1("Image doesn't have a valid PE header\n");
68 SymbolTable
= NtHeaders
.FileHeader
.PointerToSymbolTable
;
69 NumSymbols
= NtHeaders
.FileHeader
.NumberOfSymbols
;
73 DPRINT1("Image doesn't have debug symbols\n");
77 DPRINT("SymbolTable %x NumSymbols %x\n", SymbolTable
, NumSymbols
);
79 /* Load section headers */
80 if (! RosSymSeekFile(FileContext
, (char *) IMAGE_FIRST_SECTION(&NtHeaders
) -
81 (char *) &NtHeaders
+ DosHeader
.e_lfanew
))
83 DPRINT1("Failed seeking to section headers\n");
86 DPRINT("Alloc section headers\n");
87 SectionHeaders
= RosSymAllocMem(NtHeaders
.FileHeader
.NumberOfSections
88 * sizeof(IMAGE_SECTION_HEADER
));
89 if (NULL
== SectionHeaders
)
91 DPRINT1("Failed to allocate memory for %u section headers\n",
92 NtHeaders
.FileHeader
.NumberOfSections
);
95 if (! RosSymReadFile(FileContext
, SectionHeaders
,
96 NtHeaders
.FileHeader
.NumberOfSections
97 * sizeof(IMAGE_SECTION_HEADER
)))
99 RosSymFreeMem(SectionHeaders
);
100 DPRINT1("Failed to read section headers\n");
104 // Convert names to ANSI_STRINGs
105 for (SectionIndex
= 0; SectionIndex
< NtHeaders
.FileHeader
.NumberOfSections
;
109 if (SectionHeaders
[SectionIndex
].Name
[0] != '/') {
110 DPRINT("Short name string %d, %s\n", SectionIndex
, SectionHeaders
[SectionIndex
].Name
);
111 astr
.Buffer
= RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME
);
112 memcpy(astr
.Buffer
, SectionHeaders
[SectionIndex
].Name
, IMAGE_SIZEOF_SHORT_NAME
);
113 astr
.MaximumLength
= IMAGE_SIZEOF_SHORT_NAME
;
114 astr
.Length
= GetStrnlen(astr
.Buffer
, IMAGE_SIZEOF_SHORT_NAME
);
116 UNICODE_STRING intConv
;
120 Status
= RtlCreateUnicodeStringFromAsciiz(&intConv
, (PCSZ
)SectionHeaders
[SectionIndex
].Name
+ 1);
121 if (!NT_SUCCESS(Status
)) goto freeall
;
122 Status
= RtlUnicodeStringToInteger(&intConv
, 10, &StringOffset
);
123 RtlFreeUnicodeString(&intConv
);
124 if (!NT_SUCCESS(Status
)) goto freeall
;
125 if (!RosSymSeekFile(FileContext
, SymbolTable
+ NumSymbols
* SYMBOL_SIZE
+ StringOffset
))
127 astr
.Buffer
= RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE
);
128 if (!RosSymReadFile(FileContext
, astr
.Buffer
, MAXIMUM_DWARF_NAME_SIZE
))
130 astr
.Length
= GetStrnlen(astr
.Buffer
, MAXIMUM_DWARF_NAME_SIZE
);
131 astr
.MaximumLength
= MAXIMUM_DWARF_NAME_SIZE
;
132 DPRINT("Long name %d, %s\n", SectionIndex
, astr
.Buffer
);
134 *ANSI_NAME_STRING(&SectionHeaders
[SectionIndex
]) = astr
;
137 DPRINT("Done with sections\n");
138 Pe
*pe
= RosSymAllocMem(sizeof(*pe
));
139 pe
->fd
= FileContext
;
143 pe
->nsections
= NtHeaders
.FileHeader
.NumberOfSections
;
144 pe
->sect
= SectionHeaders
;
145 pe
->nsymbols
= NtHeaders
.FileHeader
.NumberOfSymbols
;
146 pe
->symtab
= malloc(pe
->nsymbols
* sizeof(CoffSymbol
));
149 DPRINT("Getting symbol data\n");
150 ASSERT(sizeof(SymbolData
) == 18);
151 for (i
= 0, j
= 0; i
< pe
->nsymbols
; i
++) {
154 NtHeaders
.FileHeader
.PointerToSymbolTable
+ i
* sizeof(SymbolData
)))
156 if (!RosSymReadFile(FileContext
, &SymbolData
, sizeof(SymbolData
)))
158 if ((SymbolData
.e_scnum
< 1) ||
159 (SymbolData
.e_sclass
!= C_EXT
&&
160 SymbolData
.e_sclass
!= C_STAT
))
162 int section
= SymbolData
.e_scnum
- 1;
163 if (SymbolData
.e
.e
.e_zeroes
) {
164 pe
->symtab
[j
].name
= malloc(sizeof(SymbolData
.e
.e_name
)+1);
165 memcpy(pe
->symtab
[j
].name
, SymbolData
.e
.e_name
, sizeof(SymbolData
.e
.e_name
));
166 pe
->symtab
[j
].name
[sizeof(SymbolData
.e
.e_name
)] = 0;
170 NtHeaders
.FileHeader
.PointerToSymbolTable
+
171 (NtHeaders
.FileHeader
.NumberOfSymbols
* 18) +
172 SymbolData
.e
.e
.e_offset
))
174 pe
->symtab
[j
].name
= malloc(MAXIMUM_COFF_SYMBOL_LENGTH
+1);
175 pe
->symtab
[j
].name
[MAXIMUM_COFF_SYMBOL_LENGTH
] = 0;
176 // It's possible that we've got a string just at the end of the file
177 // we'll skip that symbol if needed
178 if (!RosSymReadFile(FileContext
, pe
->symtab
[j
].name
, MAXIMUM_COFF_SYMBOL_LENGTH
)) {
179 free(pe
->symtab
[j
].name
);
183 if (pe
->symtab
[j
].name
[0] == '.') {
184 free(pe
->symtab
[j
].name
);
187 pe
->symtab
[j
].address
= pe
->sect
[section
].VirtualAddress
+ SymbolData
.e_value
;
190 DPRINT("%d symbols\n", j
);
192 pe
->imagebase
= pe
->loadbase
= NtHeaders
.OptionalHeader
.ImageBase
;
193 pe
->imagesize
= NtHeaders
.OptionalHeader
.SizeOfImage
;
194 pe
->loadsection
= loaddisksection
;
195 DPRINT("do dwarfopen\n");
196 *RosSymInfo
= dwarfopen(pe
);
197 DPRINT("done %x\n", *RosSymInfo
);
202 for (SectionIndex
= 0; SectionIndex
< NtHeaders
.FileHeader
.NumberOfSections
;
204 RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders
[SectionIndex
]));
205 RosSymFreeMem(SectionHeaders
);