|
12 | 12 |
|
13 | 13 | module rt.sections_win64;
|
14 | 14 |
|
15 |
| -version (LDC) { /* implemented in rt.sections_elf_shared */ } else: |
16 |
| - |
17 | 15 | version (CRuntime_Microsoft):
|
18 | 16 |
|
19 | 17 | // debug = PRINTF;
|
20 | 18 | debug(PRINTF) import core.stdc.stdio;
|
21 | 19 | import core.stdc.stdlib : malloc, free;
|
22 | 20 | import rt.deh, rt.minfo;
|
23 | 21 |
|
| 22 | +version (LDC) { /* implemented in rt.sections_elf_shared, we just need some helpers */ } else |
| 23 | +{ |
| 24 | + |
24 | 25 | struct SectionGroup
|
25 | 26 | {
|
26 | 27 | static int opApply(scope int delegate(ref SectionGroup) dg)
|
@@ -66,10 +67,12 @@ shared(bool) conservative;
|
66 | 67 |
|
67 | 68 | void initSections() nothrow @nogc
|
68 | 69 | {
|
69 |
| - _sections._moduleGroup = ModuleGroup(getModuleInfos()); |
| 70 | + auto doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase; |
| 71 | + |
| 72 | + _sections._moduleGroup = ModuleGroup(getModuleInfos(doshdr)); |
70 | 73 |
|
71 | 74 | // the ".data" image section includes both object file sections ".data" and ".bss"
|
72 |
| - void[] dataSection = findImageSection(".data"); |
| 75 | + void[] dataSection = findImageSection(doshdr, ".data"); |
73 | 76 | debug(PRINTF) printf("found .data section: [%p,+%llx]\n", dataSection.ptr,
|
74 | 77 | cast(ulong)dataSection.length);
|
75 | 78 |
|
@@ -194,65 +197,33 @@ void scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothr
|
194 | 197 | }
|
195 | 198 | }
|
196 | 199 |
|
| 200 | +} // !LDC |
| 201 | + |
197 | 202 | private:
|
198 |
| -__gshared SectionGroup _sections; |
199 | 203 |
|
200 |
| -version (LDC) |
| 204 | +version (LDC) {} else |
201 | 205 | {
|
202 |
| - version (MinGW) |
203 |
| - { |
204 |
| - // This linked list is created by a compiler generated function inserted |
205 |
| - // into the .ctor list by the compiler. |
206 |
| - struct ModuleReference |
207 |
| - { |
208 |
| - ModuleReference* next; |
209 |
| - immutable(ModuleInfo)* mod; |
210 |
| - } |
| 206 | + __gshared SectionGroup _sections; |
211 | 207 |
|
212 |
| - extern(C) __gshared ModuleReference* _Dmodule_ref; // start of linked list |
213 |
| - } |
214 |
| -} |
215 |
| -else |
216 |
| -{ |
217 | 208 | extern(C)
|
218 | 209 | {
|
219 | 210 | extern __gshared void* _minfo_beg;
|
220 | 211 | extern __gshared void* _minfo_end;
|
221 | 212 | }
|
222 | 213 | }
|
223 | 214 |
|
224 |
| -immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc |
| 215 | +package immutable(ModuleInfo*)[] getModuleInfos(IMAGE_DOS_HEADER* doshdr) nothrow @nogc |
225 | 216 | out (result)
|
226 | 217 | {
|
227 | 218 | foreach (m; result)
|
228 | 219 | assert(m !is null);
|
229 | 220 | }
|
230 | 221 | do
|
231 | 222 | {
|
232 |
| - version (MinGW) // LDC |
233 |
| - { |
234 |
| - import core.stdc.stdlib : malloc; |
235 |
| - |
236 |
| - size_t len = 0; |
237 |
| - for (auto mr = _Dmodule_ref; mr; mr = mr.next) |
238 |
| - len++; |
239 |
| - |
240 |
| - auto result = (cast(immutable(ModuleInfo)**)malloc(len * size_t.sizeof))[0 .. len]; |
241 |
| - |
242 |
| - auto tip = _Dmodule_ref; |
243 |
| - foreach (ref r; result) |
244 |
| - { |
245 |
| - r = tip.mod; |
246 |
| - tip = tip.next; |
247 |
| - } |
248 |
| - |
249 |
| - return cast(immutable)result; |
250 |
| - } |
251 |
| - else |
252 |
| - { |
253 | 223 | version (LDC)
|
254 | 224 | {
|
255 |
| - void[] minfoSection = findImageSection(".minfo"); |
| 225 | + // the ".minfo" section consists of pointers to all ModuleInfos defined in object files linked into the image |
| 226 | + void[] minfoSection = findImageSection(doshdr, ".minfo"); |
256 | 227 | auto m = (cast(immutable(ModuleInfo*)*)minfoSection.ptr)[0 .. minfoSection.length / size_t.sizeof];
|
257 | 228 | }
|
258 | 229 | else
|
|
263 | 234 | /* Because of alignment inserted by the linker, various null pointers
|
264 | 235 | * are there. We need to filter them out.
|
265 | 236 | */
|
266 |
| - auto p = m.ptr; |
267 |
| - auto pend = m.ptr + m.length; |
268 | 237 |
|
269 | 238 | // count non-null pointers
|
270 |
| - size_t cnt; |
271 |
| - for (; p < pend; ++p) |
272 |
| - { |
273 |
| - if (*p !is null) ++cnt; |
274 |
| - } |
| 239 | + size_t count; |
| 240 | + foreach (mi; m) |
| 241 | + if (mi !is null) ++count; |
| 242 | + |
| 243 | + if (count == m.length) |
| 244 | + return m; |
275 | 245 |
|
276 |
| - auto result = (cast(immutable(ModuleInfo)**).malloc(cnt * size_t.sizeof))[0 .. cnt]; |
| 246 | + auto result = (cast(immutable(ModuleInfo)**) malloc(count * size_t.sizeof))[0 .. count]; |
277 | 247 |
|
278 |
| - p = m.ptr; |
279 |
| - cnt = 0; |
280 |
| - for (; p < pend; ++p) |
281 |
| - if (*p !is null) result[cnt++] = *p; |
| 248 | + count = 0; |
| 249 | + foreach (mi; m) |
| 250 | + if (mi !is null) result[count++] = mi; |
282 | 251 |
|
283 |
| - return cast(immutable)result; |
284 |
| - } |
| 252 | + return cast(immutable) result; |
285 | 253 | }
|
286 | 254 |
|
287 | 255 | extern(C)
|
@@ -310,7 +278,7 @@ extern(C)
|
310 | 278 |
|
311 | 279 | enum IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ
|
312 | 280 |
|
313 |
| -struct IMAGE_DOS_HEADER // DOS .EXE header |
| 281 | +package struct IMAGE_DOS_HEADER // DOS .EXE header |
314 | 282 | {
|
315 | 283 | ushort e_magic; // Magic number
|
316 | 284 | ushort[29] e_res2; // Reserved ushorts
|
@@ -359,19 +327,18 @@ bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @
|
359 | 327 | return name.length == 8 || section.Name[name.length] == 0;
|
360 | 328 | }
|
361 | 329 |
|
362 |
| -void[] findImageSection(string name) nothrow @nogc |
| 330 | +package void[] findImageSection(IMAGE_DOS_HEADER* doshdr, string name) nothrow @nogc |
363 | 331 | {
|
364 | 332 | if (name.length > 8) // section name from string table not supported
|
365 | 333 | return null;
|
366 |
| - IMAGE_DOS_HEADER* doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase; |
367 | 334 | if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
|
368 | 335 | return null;
|
369 | 336 |
|
370 |
| - auto nthdr = cast(IMAGE_NT_HEADERS*)(cast(void*)doshdr + doshdr.e_lfanew); |
371 |
| - auto sections = cast(IMAGE_SECTION_HEADER*)(cast(void*)nthdr + IMAGE_NT_HEADERS.sizeof + nthdr.FileHeader.SizeOfOptionalHeader); |
| 337 | + auto nthdr = cast(IMAGE_NT_HEADERS*) (cast(void*)doshdr + doshdr.e_lfanew); |
| 338 | + auto sections = cast(IMAGE_SECTION_HEADER*) (cast(void*)nthdr + IMAGE_NT_HEADERS.sizeof + nthdr.FileHeader.SizeOfOptionalHeader); |
372 | 339 | for (ushort i = 0; i < nthdr.FileHeader.NumberOfSections; i++)
|
373 |
| - if (compareSectionName (sections[i], name)) |
374 |
| - return (cast(void*)&__ImageBase + sections[i].VirtualAddress)[0 .. sections[i].VirtualSize]; |
| 340 | + if (compareSectionName(sections[i], name)) |
| 341 | + return (cast(void*)doshdr + sections[i].VirtualAddress)[0 .. sections[i].VirtualSize]; |
375 | 342 |
|
376 | 343 | return null;
|
377 | 344 | }
|
0 commit comments