[CRT]
[reactos.git] / reactos / lib / sdk / crt / startup / pesect.c
1 /**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7 #include <windows.h>
8 #include <string.h>
9
10 #if defined (_WIN64) && defined (__ia64__)
11 #error FIXME: Unsupported __ImageBase implementation.
12 #else
13 /* Hack, for bug in ld. Will be removed soon. */
14 #ifndef _MSC_VER
15 #define __ImageBase __MINGW_LSYMBOL(_image_base__)
16 #endif
17 /* This symbol is defined by the linker. */
18 extern IMAGE_DOS_HEADER __ImageBase;
19 #endif
20
21 WINBOOL _ValidateImageBase (PBYTE);
22
23 WINBOOL
24 _ValidateImageBase (PBYTE pImageBase)
25 {
26 PIMAGE_DOS_HEADER pDOSHeader;
27 PIMAGE_NT_HEADERS pNTHeader;
28 PIMAGE_OPTIONAL_HEADER pOptHeader;
29
30 pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase;
31 if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
32 return FALSE;
33 pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew);
34 if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
35 return FALSE;
36 pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader;
37 if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
38 return FALSE;
39 return TRUE;
40 }
41
42 PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR);
43
44 PIMAGE_SECTION_HEADER
45 _FindPESection (PBYTE pImageBase, DWORD_PTR rva)
46 {
47 PIMAGE_NT_HEADERS pNTHeader;
48 PIMAGE_SECTION_HEADER pSection;
49 unsigned int iSection;
50
51 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
52
53 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
54 iSection < pNTHeader->FileHeader.NumberOfSections;
55 ++iSection,++pSection)
56 {
57 if (rva >= pSection->VirtualAddress
58 && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize)
59 return pSection;
60 }
61 return NULL;
62 }
63
64 PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
65
66 PIMAGE_SECTION_HEADER
67 _FindPESectionByName (const char *pName)
68 {
69 PBYTE pImageBase;
70 PIMAGE_NT_HEADERS pNTHeader;
71 PIMAGE_SECTION_HEADER pSection;
72 unsigned int iSection;
73
74 /* Long names aren't supported. */
75 if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME)
76 return NULL;
77
78 pImageBase = (PBYTE) &__ImageBase;
79 if (! _ValidateImageBase (pImageBase))
80 return NULL;
81
82 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
83
84 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
85 iSection < pNTHeader->FileHeader.NumberOfSections;
86 ++iSection,++pSection)
87 {
88 if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME))
89 return pSection;
90 }
91 return NULL;
92 }
93
94 int __mingw_GetSectionCount (void);
95 PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p);
96
97 PIMAGE_SECTION_HEADER
98 __mingw_GetSectionForAddress (LPVOID p)
99 {
100 PBYTE pImageBase;
101 DWORD_PTR rva;
102
103 pImageBase = (PBYTE) &__ImageBase;
104 if (! _ValidateImageBase (pImageBase))
105 return NULL;
106
107 rva = (DWORD_PTR) (((PBYTE) p) - pImageBase);
108 return _FindPESection (pImageBase, rva);
109 }
110
111 int
112 __mingw_GetSectionCount (void)
113 {
114 PBYTE pImageBase;
115 PIMAGE_NT_HEADERS pNTHeader;
116
117 pImageBase = (PBYTE) &__ImageBase;
118 if (! _ValidateImageBase (pImageBase))
119 return 0;
120
121 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
122
123 return (int) pNTHeader->FileHeader.NumberOfSections;
124 }
125
126
127 PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
128
129 PIMAGE_SECTION_HEADER
130 _FindPESectionExec (size_t eNo)
131 {
132 PBYTE pImageBase;
133 PIMAGE_NT_HEADERS pNTHeader;
134 PIMAGE_SECTION_HEADER pSection;
135 unsigned int iSection;
136
137 pImageBase = (PBYTE) &__ImageBase;
138 if (! _ValidateImageBase (pImageBase))
139 return NULL;
140
141 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
142
143 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
144 iSection < pNTHeader->FileHeader.NumberOfSections;
145 ++iSection,++pSection)
146 {
147 if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
148 {
149 if (!eNo)
150 return pSection;
151 --eNo;
152 }
153 }
154 return NULL;
155 }
156
157 PBYTE _GetPEImageBase (void);
158
159 PBYTE
160 _GetPEImageBase (void)
161 {
162 PBYTE pImageBase;
163 pImageBase = (PBYTE) &__ImageBase;
164 if (! _ValidateImageBase (pImageBase))
165 return NULL;
166 return pImageBase;
167 }
168
169 WINBOOL _IsNonwritableInCurrentImage (PBYTE);
170
171 WINBOOL
172 _IsNonwritableInCurrentImage (PBYTE pTarget)
173 {
174 PBYTE pImageBase;
175 DWORD_PTR rvaTarget;
176 PIMAGE_SECTION_HEADER pSection;
177
178 pImageBase = (PBYTE) &__ImageBase;
179 if (! _ValidateImageBase (pImageBase))
180 return FALSE;
181 rvaTarget = pTarget - pImageBase;
182 pSection = _FindPESection (pImageBase, rvaTarget);
183 if (pSection == NULL)
184 return FALSE;
185 return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
186 }