1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
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)));
}
|