[ATL] Add CString.AllocSysString
[reactos.git] / sdk / lib / rossym / pe.c
1 #define NTOSAPI
2 #include <ntifs.h>
3 #include <ndk/ntndk.h>
4 #include <reactos/rossym.h>
5 #include "rossympriv.h"
6 #include <ntimage.h>
7
8 #define NDEBUG
9 #include <debug.h>
10
11 #include "dwarf.h"
12 #include "pe.h"
13 #include "rossympriv.h"
14
15 PeSect *pesection(Pe *pe, const char *name)
16 {
17 int i;
18 ANSI_STRING WantName;
19 RtlInitAnsiString(&WantName, name);
20 DPRINT("Searching for section %s\n", name);
21 for (i = 0; i < pe->nsections; i++) {
22 PANSI_STRING AnsiString = ANSI_NAME_STRING(&pe->sect[i]);
23 if (WantName.Length == AnsiString->Length &&
24 !memcmp(AnsiString->Buffer, name, WantName.Length)) {
25 DPRINT("Found %s (%d) @ %x (%x)\n", name, i,
26 ((PCHAR)pe->imagebase)+pe->sect[i].VirtualAddress,
27 pe->sect[i].SizeOfRawData);
28 return &pe->sect[i];
29 }
30 }
31 DPRINT("%s not found\n", name);
32 return nil;
33 }
34
35 u16int peget2(const unsigned char *ptr) {
36 return *((u16int*)ptr);
37 }
38
39 u32int peget4(const unsigned char *ptr) {
40 return *((u32int*)ptr);
41 }
42
43 u64int peget8(const unsigned char *ptr) {
44 return *((u64int*)ptr);
45 }
46
47 int readn(void *filectx, char *buffer, ulong size) {
48 return RosSymReadFile(filectx, buffer, size);
49 }
50
51 int seek(void *filectx, ulong position, int origin) {
52 assert(origin == 0);
53 return RosSymSeekFile(filectx, position);
54 }
55
56 static int
57 readblock(void *fd, DwarfBlock *b, ulong off, ulong len)
58 {
59 b->data = malloc(len);
60 if(b->data == nil)
61 return -1;
62 if(!seek(fd, off, 0) || !readn(fd, (char *)b->data, len)){
63 free(b->data);
64 b->data = nil;
65 return -1;
66 }
67 b->len = len;
68 return 0;
69 }
70
71 int
72 loaddisksection(Pe *pe, char *name, DwarfBlock *b)
73 {
74 PeSect *s;
75 if((s = pesection(pe, name)) == nil)
76 return -1;
77 return readblock(pe->fd, b, s->PointerToRawData, s->SizeOfRawData);
78 }
79
80 int
81 loadmemsection(Pe *pe, char *name, DwarfBlock *b)
82 {
83 PeSect *s;
84
85 if((s = pesection(pe, name)) == nil)
86 return -1;
87 DPRINT("Loading section %s (ImageBase %x RVA %x)\n", name, pe->fd, s->VirtualAddress);
88 b->data = RosSymAllocMem(s->SizeOfRawData);
89 b->len = s->SizeOfRawData;
90 PCHAR DataSource = ((char *)pe->fd) + s->VirtualAddress;
91 DPRINT("Copying to %x from %x (%x)\n", DataSource, b->data, b->len);
92 RtlCopyMemory(b->data, DataSource, s->SizeOfRawData);
93
94 return s->SizeOfRawData;
95 }
96
97 void *RosSymAllocMemZero(ulong size, ulong count) {
98 void *res = RosSymAllocMem(size * count);
99 if (res) memset(res, 0, size * count);
100 return res;
101 }
102
103 int GetStrnlen(const char *string, int maxlen) {
104 int i;
105 for (i = 0; i < maxlen && string[i]; i++);
106 return i;
107 }
108
109 void pefree(Pe *pe) {
110 int i;
111 for (i = 0; i < pe->nsections; i++) {
112 RtlFreeAnsiString(ANSI_NAME_STRING(&pe->sect[i]));
113 }
114 for (i = 0; i < pe->nsymbols; i++) {
115 free(pe->symtab[i].name);
116 }
117 free(pe->symtab);
118 free(pe->sect);
119 free(pe);
120 }
121
122 void xfree(void *v) {
123 if (v) RosSymFreeMem(v);
124 }
125
126 ulong pefindrva(struct _IMAGE_SECTION_HEADER *SectionHeaders, int NumberOfSections, ulong TargetPhysical) {
127 int i;
128 DPRINT("Finding RVA for Physical %x\n", TargetPhysical);
129 for (i = 0; i < NumberOfSections; i++) {
130 DPRINT("Section %d name %s Raw %x Virt %x\n",
131 i,
132 ANSI_NAME_STRING(&SectionHeaders[i])->Buffer,
133 SectionHeaders[i].PointerToRawData,
134 SectionHeaders[i].VirtualAddress);
135 if (TargetPhysical >= SectionHeaders[i].PointerToRawData &&
136 TargetPhysical < SectionHeaders[i].PointerToRawData + SectionHeaders[i].SizeOfRawData) {
137 DPRINT("RVA %x\n", TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress);
138 return TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress;
139 }
140 }
141 return nil;
142 }