2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/rossym/frommem.c
5 * PURPOSE: Creating rossym info from an in-memory image
7 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
12 #include <ndk/ntndk.h>
13 #include <reactos/rossym.h>
14 #include "rossympriv.h"
24 RosSymCreateFromMem(PVOID ImageStart
, ULONG_PTR ImageSize
, PROSSYM_INFO
*RosSymInfo
)
26 ANSI_STRING AnsiNameString
= { };
27 PIMAGE_DOS_HEADER DosHeader
;
28 PIMAGE_NT_HEADERS NtHeaders
;
29 PIMAGE_SECTION_HEADER SectionHeaders
;
31 unsigned SymbolTable
, NumSymbols
;
33 /* Check if MZ header is valid */
34 DosHeader
= (PIMAGE_DOS_HEADER
) ImageStart
;
35 if (ImageSize
< sizeof(IMAGE_DOS_HEADER
)
36 || ! ROSSYM_IS_VALID_DOS_HEADER(DosHeader
))
38 DPRINT1("Image doesn't have a valid DOS header\n");
42 /* Locate NT header */
43 NtHeaders
= (PIMAGE_NT_HEADERS
)((char *) ImageStart
+ DosHeader
->e_lfanew
);
44 if (ImageSize
< DosHeader
->e_lfanew
+ sizeof(IMAGE_NT_HEADERS
)
45 || ! ROSSYM_IS_VALID_NT_HEADERS(NtHeaders
))
47 DPRINT1("Image doesn't have a valid PE header\n");
51 SymbolTable
= NtHeaders
->FileHeader
.PointerToSymbolTable
;
52 NumSymbols
= NtHeaders
->FileHeader
.NumberOfSymbols
;
54 /* Search for the section header */
55 ULONG SectionHeaderSize
= NtHeaders
->FileHeader
.NumberOfSections
* sizeof(IMAGE_SECTION_HEADER
);
56 SectionHeaders
= RosSymAllocMem(SectionHeaderSize
);
57 RtlCopyMemory(SectionHeaders
, IMAGE_FIRST_SECTION(NtHeaders
), SectionHeaderSize
);
59 // Convert names to ANSI_STRINGs
60 for (SectionIndex
= 0; SectionIndex
< NtHeaders
->FileHeader
.NumberOfSections
;
63 if (SectionHeaders
[SectionIndex
].Name
[0] != '/') {
64 AnsiNameString
.Buffer
= RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME
);
65 RtlCopyMemory(AnsiNameString
.Buffer
, SectionHeaders
[SectionIndex
].Name
, IMAGE_SIZEOF_SHORT_NAME
);
66 AnsiNameString
.MaximumLength
= IMAGE_SIZEOF_SHORT_NAME
;
67 AnsiNameString
.Length
= GetStrnlen(AnsiNameString
.Buffer
, IMAGE_SIZEOF_SHORT_NAME
);
69 UNICODE_STRING intConv
;
73 if (!RtlCreateUnicodeStringFromAsciiz(&intConv
, (PCSZ
)SectionHeaders
[SectionIndex
].Name
+ 1))
75 Status
= RtlUnicodeStringToInteger(&intConv
, 10, &StringOffset
);
76 RtlFreeUnicodeString(&intConv
);
77 if (!NT_SUCCESS(Status
)) goto freeall
;
78 ULONG VirtualOffset
= pefindrva(SectionHeaders
, NtHeaders
->FileHeader
.NumberOfSections
, SymbolTable
+(NumSymbols
*SYMBOL_SIZE
)+StringOffset
);
79 if (!VirtualOffset
) goto freeall
;
80 AnsiNameString
.Buffer
= RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE
);
81 if (!AnsiNameString
.Buffer
) goto freeall
;
82 PCHAR StringTarget
= ((PCHAR
)ImageStart
)+VirtualOffset
;
83 PCHAR EndOfImage
= ((PCHAR
)ImageStart
) + NtHeaders
->OptionalHeader
.SizeOfImage
;
84 if (StringTarget
>= EndOfImage
) goto freeall
;
85 ULONG PossibleStringLength
= EndOfImage
- StringTarget
;
86 if (PossibleStringLength
> MAXIMUM_DWARF_NAME_SIZE
)
87 PossibleStringLength
= MAXIMUM_DWARF_NAME_SIZE
;
88 RtlCopyMemory(AnsiNameString
.Buffer
, StringTarget
, PossibleStringLength
);
89 AnsiNameString
.Length
= strlen(AnsiNameString
.Buffer
);
90 AnsiNameString
.MaximumLength
= MAXIMUM_DWARF_NAME_SIZE
;
93 (&SectionHeaders
[SectionIndex
],
95 sizeof(AnsiNameString
));
98 Pe
*pe
= RosSymAllocMem(sizeof(*pe
));
103 pe
->loadbase
= (ULONG
)ImageStart
;
104 pe
->imagebase
= NtHeaders
->OptionalHeader
.ImageBase
;
105 pe
->imagesize
= NtHeaders
->OptionalHeader
.SizeOfImage
;
106 pe
->nsections
= NtHeaders
->FileHeader
.NumberOfSections
;
107 pe
->sect
= SectionHeaders
;
108 pe
->nsymbols
= NtHeaders
->FileHeader
.NumberOfSymbols
;
109 pe
->symtab
= malloc(pe
->nsymbols
* sizeof(CoffSymbol
));
110 PSYMENT SymbolData
= (PSYMENT
)
111 (((PCHAR
)ImageStart
) +
115 NtHeaders
->FileHeader
.PointerToSymbolTable
));
117 for (i
= 0, j
= 0; i
< pe
->nsymbols
; i
++) {
118 if ((SymbolData
[i
].e_scnum
< 1) ||
119 (SymbolData
[i
].e_sclass
!= C_EXT
&&
120 SymbolData
[i
].e_sclass
!= C_STAT
))
122 int section
= SymbolData
[i
].e_scnum
- 1;
123 if (SymbolData
[i
].e
.e
.e_zeroes
) {
124 pe
->symtab
[j
].name
= malloc(sizeof(SymbolData
[i
].e
.e_name
)+1);
125 strcpy(pe
->symtab
[j
].name
, SymbolData
[i
].e
.e_name
);
127 PCHAR SymbolName
= ((PCHAR
)ImageStart
) +
131 NtHeaders
->FileHeader
.PointerToSymbolTable
+
132 (NtHeaders
->FileHeader
.NumberOfSymbols
* 18) +
133 SymbolData
[i
].e
.e
.e_offset
);
134 pe
->symtab
[j
].name
= malloc(strlen(SymbolName
)+1);
135 strcpy(pe
->symtab
[j
].name
, SymbolName
);
137 if (pe
->symtab
[j
].name
[0] == '.') {
138 free(pe
->symtab
[j
].name
);
141 pe
->symtab
[j
].address
= pe
->sect
[section
].VirtualAddress
+ SymbolData
[i
].e_value
;
145 pe
->loadsection
= loadmemsection
;
146 *RosSymInfo
= dwarfopen(pe
);
148 return !!*RosSymInfo
;
151 if (AnsiNameString
.Buffer
) RosSymFreeMem(AnsiNameString
.Buffer
);
152 for (SectionIndex
= 0; SectionIndex
< NtHeaders
->FileHeader
.NumberOfSections
;
154 RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders
[SectionIndex
]));
155 RosSymFreeMem(SectionHeaders
);