57
57
//
58
58
// ===----------------------------------------------------------------------===//
59
59
60
+ #ifdef _WIN32
61
+ #define WIN32_LEAN_AND_MEAN
62
+ #define _CRT_SECURE_NO_WARNINGS
63
+ #define strtok_r strtok_s
64
+ #include < windows.h>
65
+ #include < BaseTsd.h>
66
+ typedef SSIZE_T ssize_t ;
67
+ #define PROT_EXEC 4
68
+ #endif
60
69
#include < Python.h>
61
70
#include < algorithm>
62
71
#include < cassert>
69
78
#include < stdint.h>
70
79
#include < stdio.h>
71
80
#include < stdlib.h>
81
+ #ifndef _WIN32
72
82
#include < sys/mman.h>
73
- #include < sys/stat.h>
74
83
#include < sys/wait.h>
75
84
#include < unistd.h>
85
+ #endif
86
+ #include < sys/stat.h>
76
87
#include < vector>
77
88
78
89
// ===----------------------------------------------------------------------===//
@@ -106,6 +117,10 @@ uint64_t TakeU64(unsigned char *&Buf) {
106
117
// Forks, execs Cmd under a shell and returns
107
118
// a file descriptor reading the command's stdout.
108
119
FILE *ForkAndExec (std::string Cmd) {
120
+ #ifdef _WIN32
121
+ Cmd = " cmd.exe /c " + Cmd;
122
+ FILE *Stream = _popen (Cmd.c_str (), " rt" );
123
+ #else
109
124
int P[2 ];
110
125
pipe (P);
111
126
@@ -118,10 +133,43 @@ FILE *ForkAndExec(std::string Cmd) {
118
133
} else {
119
134
close (P[1 ]);
120
135
}
121
-
136
+ # endif
122
137
return Stream;
123
138
}
124
139
140
+ #ifdef _WIN32
141
+ ssize_t getline (char ** lineptr, size_t * n, FILE* stream) {
142
+ if (lineptr == nullptr || stream == nullptr || n == nullptr ) return -1 ;
143
+ int c = fgetc (stream);
144
+ if (c == EOF) return -1 ;
145
+ char * bufptr = *lineptr;
146
+ size_t size = *n;
147
+ if (bufptr == nullptr ) {
148
+ size = 128 ;
149
+ bufptr = (char *)malloc (size);
150
+ if (bufptr == nullptr ) return -1 ;
151
+ *lineptr = bufptr;
152
+ }
153
+ char * p = bufptr;
154
+ while (c != EOF) {
155
+ size_t offset = (size_t )(p - bufptr);
156
+ if ((offset + 2 ) > size)) {
157
+ size = size + 128 ;
158
+ bufptr = (char *)realloc (bufptr, size);
159
+ if (bufptr == nullptr ) return -1 ;
160
+ *lineptr = bufptr;
161
+ p = bufptr + offset;
162
+ }
163
+ *p++ = c;
164
+ if (c == ' \n ' ) break ;
165
+ c = fgetc (stream);
166
+ }
167
+ *p = ' \0 ' ;
168
+ *n = size;
169
+ return p - bufptr;
170
+ }
171
+ #endif
172
+
125
173
void Assert (bool Expr, const char *ExprStr, const char *File, int Line) {
126
174
if (Expr)
127
175
return ;
@@ -228,8 +276,6 @@ struct perf_event_mmap {
228
276
char filename[1 ];
229
277
};
230
278
231
- #define PROT_EXEC 4
232
-
233
279
struct perf_event_mmap2 {
234
280
struct perf_event_header header;
235
281
@@ -348,7 +394,11 @@ class NmOutput : public std::vector<Symbol> {
348
394
D = " " ;
349
395
std::string Cmd = Nm + " " + D + " -S --defined-only " +
350
396
BinaryCacheRoot + std::string (M->Filename ) +
397
+ #ifdef _WIN32
398
+ " 2> NUL" ;
399
+ #else
351
400
" 2>/dev/null" ;
401
+ #endif
352
402
auto Stream = ForkAndExec (Cmd);
353
403
354
404
char *Line = nullptr ;
@@ -394,8 +444,12 @@ class NmOutput : public std::vector<Symbol> {
394
444
if (Line)
395
445
free (Line);
396
446
447
+ #ifdef _WIN32
448
+ _pclose (Stream);
449
+ #else
397
450
fclose (Stream);
398
451
wait (NULL );
452
+ #endif
399
453
}
400
454
401
455
void reset (Map *M) {
@@ -435,8 +489,12 @@ class ObjdumpOutput {
435
489
Line (NULL ), LineLen(0 ) {}
436
490
~ObjdumpOutput () {
437
491
if (Stream) {
492
+ #ifdef _WIN32
493
+ _pclose (Stream);
494
+ #else
438
495
fclose (Stream);
439
496
wait (NULL );
497
+ #endif
440
498
}
441
499
if (Line)
442
500
free (Line);
@@ -446,8 +504,12 @@ class ObjdumpOutput {
446
504
ThisAddress = 0 ;
447
505
ThisText = " " ;
448
506
if (Stream) {
507
+ #ifdef _WIN32
508
+ _pclose (Stream);
509
+ #else
449
510
fclose (Stream);
450
511
wait (NULL );
512
+ #endif
451
513
}
452
514
453
515
char buf1[32 ], buf2[32 ];
@@ -458,7 +520,11 @@ class ObjdumpOutput {
458
520
std::string (buf1) + " --stop-address=" +
459
521
std::string (buf2) + " " +
460
522
BinaryCacheRoot + std::string (M->Filename ) +
523
+ #ifdef _WIN32
524
+ " 2> NUL" ;
525
+ #else
461
526
" 2>/dev/null" ;
527
+ #endif
462
528
Stream = ForkAndExec (Cmd);
463
529
464
530
EndAddress = Stop;
@@ -528,7 +594,12 @@ class PerfReader {
528
594
529
595
private:
530
596
unsigned char *Buffer;
597
+ #ifdef _WIN32
598
+ HANDLE hFile;
599
+ HANDLE hMapFile;
600
+ #else
531
601
size_t BufferLen;
602
+ #endif
532
603
533
604
perf_header *Header;
534
605
std::map<uint64_t , const char *> EventIDs;
@@ -551,6 +622,20 @@ PerfReader::PerfReader(const std::string &Filename,
551
622
: Nm(Nm), Objdump(Objdump), BinaryCacheRoot(BinaryCacheRoot) {
552
623
TopLevelCounters = PyDict_New ();
553
624
Functions = PyDict_New ();
625
+ #ifdef _WIN32
626
+ Buffer = nullptr ;
627
+ hMapFile = nullptr ;
628
+ hFile = ::CreateFileA (Filename.c_str (), GENERIC_READ, FILE_SHARE_READ, NULL ,
629
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
630
+ assert (hFile != INVALID_HANDLE_VALUE);
631
+ LARGE_INTEGER size;
632
+ size.QuadPart = 0 ;
633
+ assert (::GetFileSizeEx (hFile, &size) != FALSE );
634
+ hMapFile = ::CreateFileMapping (hFile, NULL , PAGE_READONLY, size.HighPart , size.LowPart , NULL );
635
+ assert (hMapFile != nullptr );
636
+ Buffer = (unsigned char *)::MapViewOfFile (hMapFile, FILE_MAP_READ, 0 , 0 , 0 );
637
+ assert (Buffer != nullptr );
638
+ #else
554
639
int fd = open (Filename.c_str (), O_RDONLY);
555
640
assert (fd > 0 );
556
641
@@ -560,9 +645,20 @@ PerfReader::PerfReader(const std::string &Filename,
560
645
561
646
Buffer = (unsigned char *)mmap (NULL , BufferLen, PROT_READ, MAP_SHARED, fd, 0 );
562
647
assert (Buffer != MAP_FAILED);
648
+ #endif
563
649
}
564
650
565
- PerfReader::~PerfReader () { munmap (Buffer, BufferLen); }
651
+ PerfReader::~PerfReader () {
652
+ #ifdef _WIN32
653
+ if (hMapFile != NULL ) {
654
+ if (Buffer != NULL ) ::UnmapViewOfFile (Buffer);
655
+ ::CloseHandle (hMapFile);
656
+ }
657
+ if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle (hFile);
658
+ #else
659
+ munmap (Buffer, BufferLen);
660
+ #endif
661
+ }
566
662
567
663
void PerfReader::readHeader () {
568
664
Header = (perf_header *)&Buffer[0 ];
0 commit comments