mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
184 lines
4.6 KiB
D
184 lines
4.6 KiB
D
|
|
version(CRuntime_Microsoft)
|
|
{
|
|
extern(C)
|
|
{
|
|
extern __gshared void* __ImageBase;
|
|
extern __gshared uint _DP_beg;
|
|
extern __gshared uint _DP_end;
|
|
extern __gshared uint _TP_beg;
|
|
extern __gshared uint _TP_end;
|
|
}
|
|
alias _DPbegin = _DP_beg;
|
|
alias _DPend = _DP_end;
|
|
alias _TPbegin = _TP_beg;
|
|
alias _TPend = _TP_end;
|
|
|
|
__gshared void[] dataSection;
|
|
shared static this()
|
|
{
|
|
import core.internal.traits : externDFunc;
|
|
alias findImageSection = externDFunc!("rt.sections_win64.findImageSection",
|
|
void[] function(void* handle, string name) nothrow @nogc);
|
|
dataSection = findImageSection(&__ImageBase, ".data");
|
|
}
|
|
|
|
void[] tlsRange;
|
|
static this()
|
|
{
|
|
import core.internal.traits : externDFunc;
|
|
alias initTLSRanges = externDFunc!("rt.sections_win64.initTLSRanges",
|
|
void[] function() nothrow @nogc);
|
|
tlsRange = initTLSRanges();
|
|
}
|
|
|
|
version = ptrref_supported;
|
|
}
|
|
else version(Win32)
|
|
{
|
|
extern(C)
|
|
{
|
|
extern __gshared void* _DPbegin;
|
|
extern __gshared void* _DPend;
|
|
extern __gshared uint _TPbegin;
|
|
extern __gshared uint _TPend;
|
|
extern int _tlsstart;
|
|
extern int _tlsend;
|
|
}
|
|
|
|
void[] tlsRange;
|
|
static this()
|
|
{
|
|
tlsRange = (cast(void*)&_tlsstart)[0.. cast(void*)&_tlsend - cast(void*)&_tlsstart];
|
|
}
|
|
|
|
version = ptrref_supported;
|
|
}
|
|
|
|
struct Struct
|
|
{
|
|
int x;
|
|
Struct* next;
|
|
}
|
|
|
|
class Class
|
|
{
|
|
void* ptr;
|
|
}
|
|
|
|
struct Struc(T)
|
|
{
|
|
static T vtls;
|
|
static __gshared T vgshared;
|
|
}
|
|
|
|
__gshared Struct* gsharedStrctPtr2 = new Struct(7, new Struct(8, null));
|
|
|
|
int tlsInt;
|
|
void* tlsVar;
|
|
|
|
shared int sharedInt;
|
|
shared void* sharedVar;
|
|
__gshared void* gsharedVar;
|
|
__gshared void* gsharedVar2;
|
|
immutable int[] arr = [1, 2, 3];
|
|
string tlsStr;
|
|
|
|
__gshared Struct gsharedStrct;
|
|
Struct[3] tlsStrcArr;
|
|
Class tlsClss;
|
|
|
|
// expression initializers
|
|
string[] strArr = [ "a", "b" ];
|
|
__gshared Class gsharedClss = new Class;
|
|
__gshared Struct* gsharedStrctPtr = new Struct(7, new Struct(8, null));
|
|
|
|
debug(PRINT) import core.stdc.stdio;
|
|
|
|
void main()
|
|
{
|
|
version(ptrref_supported)
|
|
testRefPtr();
|
|
}
|
|
|
|
version(ptrref_supported):
|
|
|
|
bool findTlsPtr(const(void)* ptr)
|
|
{
|
|
debug(PRINT) printf("findTlsPtr %p\n", ptr);
|
|
for (uint* p = &_TPbegin; p < &_TPend; p++)
|
|
{
|
|
void* addr = tlsRange.ptr + *p;
|
|
debug(PRINT) printf(" try %p\n", addr);
|
|
assert(*p < tlsRange.length);
|
|
if (addr == ptr)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool findDataPtr(const(void)* ptr)
|
|
{
|
|
debug(PRINT) printf("findDataPtr %p\n", ptr);
|
|
for (auto p = &_DPbegin; p < &_DPend; p++)
|
|
{
|
|
debug(PRINT) printf(" try %p\n", cast(void*) cast(size_t) *p);
|
|
version(CRuntime_Microsoft)
|
|
void* addr = dataSection.ptr + *p;
|
|
else
|
|
void* addr = *p;
|
|
|
|
if (addr == ptr)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void testRefPtr()
|
|
{
|
|
debug(PRINT) printf("&_DPbegin %p\n", &_DPbegin);
|
|
debug(PRINT) printf("&_DPend %p\n", &_DPend);
|
|
|
|
debug(PRINT) printf("&_TPbegin %p\n", &_TPbegin);
|
|
debug(PRINT) printf("&_TPend %p\n", &_TPend);
|
|
|
|
assert(!findDataPtr(cast(void*)&sharedInt));
|
|
assert(!findTlsPtr(&tlsInt));
|
|
|
|
assert(findDataPtr(cast(void*)&sharedVar));
|
|
assert(findDataPtr(&gsharedVar));
|
|
assert(findDataPtr(&gsharedStrct.next));
|
|
assert(findDataPtr(&(gsharedClss)));
|
|
assert(findDataPtr(&(gsharedClss.ptr)));
|
|
|
|
assert(findTlsPtr(&tlsVar));
|
|
assert(findTlsPtr(&tlsClss));
|
|
assert(findTlsPtr(&tlsStrcArr[0].next));
|
|
assert(findTlsPtr(&tlsStrcArr[1].next));
|
|
assert(findTlsPtr(&tlsStrcArr[2].next));
|
|
|
|
assert(!findTlsPtr(cast(size_t*)&tlsStr)); // length
|
|
assert(findTlsPtr(cast(size_t*)&tlsStr + 1)); // ptr
|
|
|
|
// monitor is manually managed
|
|
assert(!findDataPtr(cast(size_t*)cast(void*)Class.classinfo + 1));
|
|
assert(!findDataPtr(cast(size_t*)cast(void*)Class.classinfo + 1));
|
|
|
|
assert(!findDataPtr(&arr));
|
|
assert(!findTlsPtr(&arr));
|
|
assert(!findDataPtr(cast(size_t*)&arr + 1));
|
|
assert(!findTlsPtr(cast(size_t*)&arr + 1));
|
|
|
|
assert(findDataPtr(cast(size_t*)&strArr[0] + 1)); // ptr in _DATA!
|
|
assert(findDataPtr(cast(size_t*)&strArr[1] + 1)); // ptr in _DATA!
|
|
strArr[1] = "c";
|
|
|
|
assert(findDataPtr(&gsharedStrctPtr));
|
|
assert(findDataPtr(&gsharedStrctPtr.next));
|
|
assert(findDataPtr(&gsharedStrctPtr.next.next));
|
|
|
|
assert(findDataPtr(&(Struc!(int*).vgshared)));
|
|
assert(!findDataPtr(&(Struc!(int).vgshared)));
|
|
assert(findTlsPtr(&(Struc!(int*).vtls)));
|
|
assert(!findTlsPtr(&(Struc!(int).vtls)));
|
|
}
|