Showing with 86 additions and 12 deletions.
  1. +10 −5 src/rt/sections_win32.d
  2. +76 −7 src/rt/sections_win64.d
15 changes: 10 additions & 5 deletions src/rt/sections_win32.d
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,21 @@ struct SectionGroup

private:
ModuleGroup _moduleGroup;
void[][1] _gcRanges;
void[][2] _gcRanges;
}

void initSections()
{
_sections._moduleGroup = ModuleGroup(getModuleInfos());

auto pbeg = cast(void*)&_xi_a;
auto pend = cast(void*)&_end;
_sections._gcRanges[0] = pbeg[0 .. pend - pbeg];
auto databeg = cast(void*)&_xi_a;
auto dataend = cast(void*)_moduleinfo_array.ptr;
_sections._gcRanges[0] = databeg[0 .. dataend - databeg];

// skip module info and CONST segment
auto bssbeg = cast(void*)&_edata;
auto bssend = cast(void*)&_end;
_sections._gcRanges[1] = bssbeg[0 .. bssend - bssbeg];
}

void finiSections()
Expand Down Expand Up @@ -105,7 +110,7 @@ extern(C)
extern __gshared
{
int _xi_a; // &_xi_a just happens to be start of data segment
//int _edata; // &_edata is start of BSS segment
int _edata; // &_edata is start of BSS segment
int _end; // &_end is past end of BSS
}

Expand Down
83 changes: 76 additions & 7 deletions src/rt/sections_win64.d
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ void initSections()
{
_sections._moduleGroup = ModuleGroup(getModuleInfos());

auto pbeg = cast(void*)&__xc_a;
auto pend = cast(void*)&_deh_beg;
_sections._gcRanges[0] = pbeg[0 .. pend - pbeg];
// the ".data" image section includes both object file sections ".data" and ".bss"
_sections._gcRanges[0] = findImageSection(".data");
debug(PRINTF) printf("found .data section: [%p,+%llx]\n", _sections._gcRanges[0].ptr,
cast(ulong)_sections._gcRanges[0].length);
}

void finiSections()
Expand Down Expand Up @@ -137,12 +138,10 @@ extern(C)
*/
extern __gshared
{
void* __ImageBase;

void* _deh_beg;
void* _deh_end;

int __xc_a; // &__xc_a just happens to be start of data segment
//int _edata; // &_edata is start of BSS segment
//void* _deh_beg; // &_deh_beg is past end of BSS
}

extern
Expand All @@ -151,3 +150,73 @@ extern(C)
int _tls_end;
}
}

/////////////////////////////////////////////////////////////////////

enum IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ

struct IMAGE_DOS_HEADER // DOS .EXE header
{
ushort e_magic; // Magic number
ushort[29] e_res2; // Reserved ushorts
int e_lfanew; // File address of new exe header
}

struct IMAGE_FILE_HEADER
{
ushort Machine;
ushort NumberOfSections;
uint TimeDateStamp;
uint PointerToSymbolTable;
uint NumberOfSymbols;
ushort SizeOfOptionalHeader;
ushort Characteristics;
}

struct IMAGE_NT_HEADERS
{
uint Signature;
IMAGE_FILE_HEADER FileHeader;
// optional header follows
}

struct IMAGE_SECTION_HEADER
{
char[8] Name;
union {
uint PhysicalAddress;
uint VirtualSize;
}
uint VirtualAddress;
uint SizeOfRawData;
uint PointerToRawData;
uint PointerToRelocations;
uint PointerToLinenumbers;
ushort NumberOfRelocations;
ushort NumberOfLinenumbers;
uint Characteristics;
}

bool compareSectionName(ref IMAGE_SECTION_HEADER section, string name) nothrow
{
if (name[] != section.Name[0 .. name.length])
return false;
return name.length == 8 || section.Name[name.length] == 0;
}

void[] findImageSection(string name) nothrow
{
if (name.length > 8) // section name from string table not supported
return null;
IMAGE_DOS_HEADER* doshdr = cast(IMAGE_DOS_HEADER*) &__ImageBase;
if (doshdr.e_magic != IMAGE_DOS_SIGNATURE)
return null;

auto nthdr = cast(IMAGE_NT_HEADERS*)(cast(void*)doshdr + doshdr.e_lfanew);
auto sections = cast(IMAGE_SECTION_HEADER*)(cast(void*)nthdr + IMAGE_NT_HEADERS.sizeof + nthdr.FileHeader.SizeOfOptionalHeader);
for(ushort i = 0; i < nthdr.FileHeader.NumberOfSections; i++)
if (compareSectionName (sections[i], name))
return (cast(void*)&__ImageBase + sections[i].VirtualAddress)[0 .. sections[i].VirtualSize];

return null;
}