Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.

Commit 87e6bad

Browse files
committed
LDC: Reduce code duplication by reusing slightly generalized rt.sections_win64 helpers
1 parent 56aa99b commit 87e6bad

File tree

3 files changed

+37
-169
lines changed

3 files changed

+37
-169
lines changed

src/rt/dso_windows.d

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ version (Windows):
1414

1515
pragma(LDC_no_moduleinfo); // not needed; avoid collision for druntime.dll and other binaries
1616

17-
import rt.sections_elf_shared : CompilerDSOData, IMAGE_DOS_HEADER, _d_dso_registry;
17+
import rt.sections_elf_shared : CompilerDSOData, _d_dso_registry;
1818

1919
private:
2020

@@ -28,7 +28,7 @@ void register_dso()
2828
{
2929
dsoData._version = 1;
3030
dsoData._slot = &dsoSlot;
31-
dsoData._imageBase = cast(IMAGE_DOS_HEADER*) &__ImageBase;
31+
dsoData._imageBase = cast(typeof(dsoData._imageBase)) &__ImageBase;
3232
dsoData._getTLSRange = &getTLSRange;
3333

3434
_d_dso_registry(&dsoData);

src/rt/sections_elf_shared.d

+4-103
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ else version (Windows)
8888
{
8989
import core.sys.windows.winbase;
9090
import core.sys.windows.windef;
91+
import rt.sections_win64 : IMAGE_DOS_HEADER, findImageSection, getModuleInfos;
9192
}
9293
else
9394
{
@@ -541,7 +542,7 @@ package extern(C) void _d_dso_registry(void* arg)
541542
{
542543
ImageHeader header = data._imageBase;
543544
pdso._getTLSRange = data._getTLSRange;
544-
// pdso._moduleGroup set in scanSegments()
545+
pdso._moduleGroup = ModuleGroup(getModuleInfos(header));
545546
}
546547
else
547548
{
@@ -971,42 +972,14 @@ version (Shared)
971972
*/
972973
version (Windows)
973974
{
974-
void scanSegments(IMAGE_DOS_HEADER* image, DSO* pdso)
975+
void scanSegments(IMAGE_DOS_HEADER* image, DSO* pdso) nothrow @nogc
975976
{
976-
// the ".minfo" section consists of pointers to all ModuleInfos defined in object files linked into the image
977-
void[] minfoSection = image.findImageSection(".minfo");
978-
auto moduleInfos = filterModuleInfos(
979-
(cast(immutable(ModuleInfo*)*) minfoSection.ptr)[0 .. minfoSection.length / size_t.sizeof]
980-
);
981-
pdso._moduleGroup = ModuleGroup(moduleInfos);
982-
983977
version (Shared)
984978
pdso._codeSegments.insertBack(image.findImageSection(".text"));
985979

986980
// the ".data" image section includes both object file sections ".data" and ".bss"
987981
pdso._gcRanges.insertBack(image.findImageSection(".data"));
988982
}
989-
990-
// Because of alignment inserted by the linker, various null pointers
991-
// may be found in the .minfo section, and need to be filtered out.
992-
immutable(ModuleInfo*)[] filterModuleInfos(immutable(ModuleInfo*)[] m)
993-
{
994-
// count non-null pointers
995-
size_t count;
996-
foreach (mi; m)
997-
if (mi !is null) ++count;
998-
999-
if (count == m.length)
1000-
return m;
1001-
1002-
auto result = (cast(immutable(ModuleInfo)**) malloc(count * size_t.sizeof))[0 .. count];
1003-
1004-
count = 0;
1005-
foreach (mi; m)
1006-
if (mi !is null) result[count++] = mi;
1007-
1008-
return cast(immutable) result;
1009-
}
1010983
}
1011984
else
1012985
{
@@ -1108,83 +1081,11 @@ version (Shared) void* handleForAddr(void* addr) nothrow @nogc
11081081
}
11091082
}
11101083

1111-
version (Windows)
1112-
{
1113-
// This code is required to parse section ranges from the image header.
1114-
1115-
enum IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ
1116-
1117-
package struct IMAGE_DOS_HEADER // DOS .EXE header
1118-
{
1119-
ushort e_magic; // Magic number
1120-
ushort[29] e_res2; // Reserved ushorts
1121-
int e_lfanew; // File address of new exe header
1122-
}
1123-
1124-
struct IMAGE_FILE_HEADER
1125-
{
1126-
ushort Machine;
1127-
ushort NumberOfSections;
1128-
uint TimeDateStamp;
1129-
uint PointerToSymbolTable;
1130-
uint NumberOfSymbols;
1131-
ushort SizeOfOptionalHeader;
1132-
ushort Characteristics;
1133-
}
1134-
1135-
struct IMAGE_NT_HEADERS
1136-
{
1137-
uint Signature;
1138-
IMAGE_FILE_HEADER FileHeader;
1139-
// optional header follows
1140-
}
1141-
1142-
struct IMAGE_SECTION_HEADER
1143-
{
1144-
char[8] Name = 0;
1145-
union {
1146-
uint PhysicalAddress;
1147-
uint VirtualSize;
1148-
}
1149-
uint VirtualAddress;
1150-
uint SizeOfRawData;
1151-
uint PointerToRawData;
1152-
uint PointerToRelocations;
1153-
uint PointerToLinenumbers;
1154-
ushort NumberOfRelocations;
1155-
ushort NumberOfLinenumbers;
1156-
uint Characteristics;
1157-
}
1158-
1159-
bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @nogc
1160-
{
1161-
if (name[] != section.Name[0 .. name.length])
1162-
return false;
1163-
return name.length == 8 || section.Name[name.length] == 0;
1164-
}
1165-
1166-
void[] findImageSection(IMAGE_DOS_HEADER* doshdr, string name) nothrow @nogc
1167-
{
1168-
if (name.length > 8) // section name from string table not supported
1169-
return null;
1170-
if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
1171-
return null;
1172-
1173-
auto nthdr = cast(IMAGE_NT_HEADERS*) (cast(void*)doshdr + doshdr.e_lfanew);
1174-
auto sections = cast(IMAGE_SECTION_HEADER*) (cast(void*)nthdr + IMAGE_NT_HEADERS.sizeof + nthdr.FileHeader.SizeOfOptionalHeader);
1175-
for (ushort i = 0; i < nthdr.FileHeader.NumberOfSections; i++)
1176-
if (compareSectionName(sections[i], name))
1177-
return (cast(void*)doshdr + sections[i].VirtualAddress)[0 .. sections[i].VirtualSize];
1178-
1179-
return null;
1180-
}
1181-
}
1182-
else: // !Windows
1183-
11841084
///////////////////////////////////////////////////////////////////////////////
11851085
// TLS module helper
11861086
///////////////////////////////////////////////////////////////////////////////
11871087

1088+
version (Windows) {} else:
11881089

11891090
/*
11901091
* Returns: the TLS memory range for a given module and the calling

src/rt/sections_win64.d

+31-64
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@
1212

1313
module rt.sections_win64;
1414

15-
version (LDC) { /* implemented in rt.sections_elf_shared */ } else:
16-
1715
version (CRuntime_Microsoft):
1816

1917
// debug = PRINTF;
2018
debug(PRINTF) import core.stdc.stdio;
2119
import core.stdc.stdlib : malloc, free;
2220
import rt.deh, rt.minfo;
2321

22+
version (LDC) { /* implemented in rt.sections_elf_shared, we just need some helpers */ } else
23+
{
24+
2425
struct SectionGroup
2526
{
2627
static int opApply(scope int delegate(ref SectionGroup) dg)
@@ -66,10 +67,12 @@ shared(bool) conservative;
6667

6768
void initSections() nothrow @nogc
6869
{
69-
_sections._moduleGroup = ModuleGroup(getModuleInfos());
70+
auto doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase;
71+
72+
_sections._moduleGroup = ModuleGroup(getModuleInfos(doshdr));
7073

7174
// the ".data" image section includes both object file sections ".data" and ".bss"
72-
void[] dataSection = findImageSection(".data");
75+
void[] dataSection = findImageSection(doshdr, ".data");
7376
debug(PRINTF) printf("found .data section: [%p,+%llx]\n", dataSection.ptr,
7477
cast(ulong)dataSection.length);
7578

@@ -194,65 +197,33 @@ void scanTLSRanges(void[] rng, scope void delegate(void* pbeg, void* pend) nothr
194197
}
195198
}
196199

200+
} // !LDC
201+
197202
private:
198-
__gshared SectionGroup _sections;
199203

200-
version (LDC)
204+
version (LDC) {} else
201205
{
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;
211207

212-
extern(C) __gshared ModuleReference* _Dmodule_ref; // start of linked list
213-
}
214-
}
215-
else
216-
{
217208
extern(C)
218209
{
219210
extern __gshared void* _minfo_beg;
220211
extern __gshared void* _minfo_end;
221212
}
222213
}
223214

224-
immutable(ModuleInfo*)[] getModuleInfos() nothrow @nogc
215+
package immutable(ModuleInfo*)[] getModuleInfos(IMAGE_DOS_HEADER* doshdr) nothrow @nogc
225216
out (result)
226217
{
227218
foreach (m; result)
228219
assert(m !is null);
229220
}
230221
do
231222
{
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-
{
253223
version (LDC)
254224
{
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");
256227
auto m = (cast(immutable(ModuleInfo*)*)minfoSection.ptr)[0 .. minfoSection.length / size_t.sizeof];
257228
}
258229
else
@@ -263,25 +234,22 @@ do
263234
/* Because of alignment inserted by the linker, various null pointers
264235
* are there. We need to filter them out.
265236
*/
266-
auto p = m.ptr;
267-
auto pend = m.ptr + m.length;
268237

269238
// 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;
275245

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];
277247

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;
282251

283-
return cast(immutable)result;
284-
}
252+
return cast(immutable) result;
285253
}
286254

287255
extern(C)
@@ -310,7 +278,7 @@ extern(C)
310278

311279
enum IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ
312280

313-
struct IMAGE_DOS_HEADER // DOS .EXE header
281+
package struct IMAGE_DOS_HEADER // DOS .EXE header
314282
{
315283
ushort e_magic; // Magic number
316284
ushort[29] e_res2; // Reserved ushorts
@@ -359,19 +327,18 @@ bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow @
359327
return name.length == 8 || section.Name[name.length] == 0;
360328
}
361329

362-
void[] findImageSection(string name) nothrow @nogc
330+
package void[] findImageSection(IMAGE_DOS_HEADER* doshdr, string name) nothrow @nogc
363331
{
364332
if (name.length > 8) // section name from string table not supported
365333
return null;
366-
IMAGE_DOS_HEADER* doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase;
367334
if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
368335
return null;
369336

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);
372339
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];
375342

376343
return null;
377344
}

0 commit comments

Comments
 (0)