1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Support MSVC14 and 15 [Bug #11118]

Search _pioinfo which is not exported after MSVC14.
[Bug #12014] [GH-884]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54737 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2016-04-23 18:46:26 +00:00
parent d4557cf6a6
commit 9afc312b4f
2 changed files with 57 additions and 1 deletions

View file

@ -114,6 +114,7 @@ class Exports::Mswin < Exports
when /OBJECT/, /LIBRARY/
next if /^[[:xdigit:]]+ 0+ UNDEF / =~ l
next unless /External/ =~ l
next if /(?:_local_stdio_printf_options|v(f|sn?)printf_l)\Z/ =~ l
next unless l.sub!(/.*?\s(\(\)\s+)?External\s+\|\s+/, '')
is_data = !$1
if noprefix or /^[@_]/ =~ l

View file

@ -2317,6 +2317,21 @@ typedef struct {
#endif
/* License: Ruby's */
#if RUBY_MSVCRT_VERSION >= 140
typedef struct {
CRITICAL_SECTION lock;
intptr_t osfhnd; // underlying OS file HANDLE
__int64 startpos; // File position that matches buffer start
unsigned char osfile; // Attributes of file (e.g., open in text mode?)
char textmode;
char _pipe_lookahead;
uint8_t unicode : 1; // Was the file opened as unicode?
uint8_t utf8translations : 1; // Buffer contains translations other than CRLF
uint8_t dbcsBufferUsed : 1; // Is the dbcsBuffer in use?
char dbcsBuffer; // Buffer for the lead byte of DBCS when converting from DBCS to Unicode
} ioinfo;
#else
typedef struct {
intptr_t osfhnd; /* underlying OS file HANDLE */
char osfile; /* attributes of file (e.g., open in text mode?) */
@ -2328,16 +2343,22 @@ typedef struct {
char pipech2[2];
#endif
} ioinfo;
#endif
#if !defined _CRTIMP || defined __MINGW32__
#undef _CRTIMP
#define _CRTIMP __declspec(dllimport)
#endif
#if RUBY_MSVCRT_VERSION >= 140
static ioinfo ** __pioinfo = NULL;
#define IOINFO_L2E 6
#else
EXTERN_C _CRTIMP ioinfo * __pioinfo[];
#define IOINFO_L2E 5
#endif
static inline ioinfo* _pioinfo(int);
#define IOINFO_L2E 5
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
#define _osfhnd(i) (_pioinfo(i)->osfhnd)
#define _osfile(i) (_pioinfo(i)->osfile)
@ -2352,6 +2373,39 @@ static size_t pioinfo_extra = 0; /* workaround for VC++8 SP1 */
static void
set_pioinfo_extra(void)
{
#if RUBY_MSVCRT_VERSION >= 140
/* get __pioinfo addr with _isatty */
HMODULE mod = GetModuleHandle("ucrtbase.dll");
char *p = (char*)GetProcAddress(mod, "_isatty");
char *pend = p + 100;
/* _osfile(fh) & FDEV /*0x40*/
#if _WIN64
int32_t rel;
char *rip;
/* lea rdx,[__pioinfo's addr in RIP-relative 32bit addr] */
# define PIOINFO_MARK "\x48\x8d\x15"
#else
/* mov eax,dword ptr [eax*4+100EB430h] */
# define PIOINFO_MARK "\x8B\x04\x85"
#endif
for (p; p < pend; p++) {
if (memcmp(p, PIOINFO_MARK, strlen(PIOINFO_MARK)) == 0) {
goto found;
}
}
fprintf(stderr, "unexpected ucrtbase.dll\n");
_exit(1);
found:
p += strlen(PIOINFO_MARK);
#if _WIN64
rel = *(int32_t*)(p);
rip = p + sizeof(int32_t);
__pioinfo = (ioinfo**)(rip + rel);
#else
__pioinfo = (ioinfo**)(p);
#endif
#else
int fd;
fd = _open("NUL", O_RDONLY);
@ -2366,6 +2420,7 @@ set_pioinfo_extra(void)
/* not found, maybe something wrong... */
pioinfo_extra = 0;
}
#endif
}
#else
#define pioinfo_extra 0