4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-18 23:12:15 +08:00

Cygwin: testsuite: Add x86_64 code to "dynamically load cygwin" test

This still needs some more voudou to actually work.

Also update how-cygtls-works.txt a bit
This commit is contained in:
Jon Turney 2020-11-26 16:50:43 +00:00
parent 6e843f7750
commit b4561c2363
No known key found for this signature in database
GPG Key ID: C7C86F0370285C81
3 changed files with 32 additions and 23 deletions

View File

@ -4,8 +4,8 @@ All cygwin threads have separate context in an object of class _cygtls. The
storage for this object is kept on the stack in the bottom __CYGTLS_PADSIZE__
bytes. Each thread references the storage via the Thread Environment Block
(aka Thread Information Block), which Windows maintains for each user thread
in the system, with the address in the FS segment register. The memory
is laid out as in the NT_TIB structure from <w32api/winnt.h>:
in the system, with the address in a segment register (FS on x86, GS on x86_64).
The memory is laid out as in the NT_TIB structure from <w32api/winnt.h>:
typedef struct _NT_TIB {
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
@ -20,16 +20,10 @@ typedef struct _NT_TIB {
struct _NT_TIB *Self;
} NT_TIB,*PNT_TIB;
Cygwin sees it like this:
extern exception_list *_except_list asm ("%fs:0"); // exceptions.cc
extern char *_tlsbase __asm__ ("%fs:4"); // cygtls.h
extern char *_tlstop __asm__ ("%fs:8"); // cygtls.h
And accesses cygtls like this:
#define _my_tls (((_cygtls *) _tlsbase)[-1]) // cygtls.h
Cygwin accesses cygtls like this (see cygtls.h):
#define _my_tls (*((_cygtls *) ((PBYTE) NtCurrentTeb()->Tib.StackBase \
- __CYGTLS_PADSIZE__)))
Initialization always goes through _cygtls::init_thread(). It works
in the following ways:
@ -65,11 +59,4 @@ __CYGTLS_PADSIZE__ bytes down from there are overwritten.
Debugging
You can examine the segment registers in gdb via "info w32 selector $fs"
(which is using GetThreadSelectorEntry()) to get results like this:
Selector $fs
0x03b: base=0x7ffdd000 limit=0x00000fff 32-bit Data (Read/Write, Exp-up)
Priviledge level = 3. Byte granular.
"x/3x 0x7ffdd000" will give you _except_list, _tlsbase, and _tlstop.
You can examine the TIB in gdb via "info w32 tib"

View File

@ -43,7 +43,10 @@ using std::string;
cygwin::padding *cygwin::padding::_main = NULL;
DWORD cygwin::padding::_mainTID = 0;
// A few cygwin constants.
// Cygwin signal constants
#undef SIGINT
#undef SIGTERM
static const int SIGHUP = 1;
static const int SIGINT = 2;
static const int SIGTERM = 15; // Cygwin won't deliver this one to us;
@ -68,17 +71,30 @@ cygwin::padding::padding ()
_end = _padding + sizeof (_padding);
char *stackbase;
#ifdef __GNUC__
#ifdef __GNUC__ /* GCC */
# ifdef __x86_64__
__asm__ (
"mov %%gs:8, %0"
:"=r"(stackbase)
);
# elif __X86__
__asm__ (
"movl %%fs:4, %0"
:"=r"(stackbase)
);
#else
# else
# error Unknown architecture
# endif
#else /* !GCC assumed to be MSVC */
# ifdef __X86__
__asm
{
mov eax, fs:[4];
mov stackbase, eax;
}
#else
# error Unknown architecture
# endif
#endif
_stackbase = stackbase;

View File

@ -14,7 +14,13 @@ proc ws_spawn {cmd args} {
verbose send "catchCode = $rv\n"
}
ws_spawn "$MINGW_CXX $srcdir/$subdir/cygload.cc -o mingw-cygload.exe -lstdc++ -Wl,-e,_cygloadCRTStartup@0"
if { [string match "i686" $target_alias] } {
set entrypoint "_cygloadCRTStartup@0"
} else {
set entrypoint "cygloadCRTStartup"
}
ws_spawn "$MINGW_CXX $srcdir/$subdir/cygload.cc -o mingw-cygload.exe -static -Wl,-e,$entrypoint"
if { $rv != {0 {}} } {
verbose -log "$rv"