openocd: src/helper: replace the GPL-2.0-or-later license tag
[fw/openocd] / src / helper / replacements.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2006 by Dominic Rath                                    *
5  *   Dominic.Rath@gmx.de                                                   *
6  *                                                                         *
7  *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *
8  *   oyvind.harboe@zylin.com                                               *
9  *                                                                         *
10  *   Copyright (C) 2008 by Spencer Oliver                                  *
11  *   spen@spen-soft.co.uk                                                  *
12  ***************************************************************************/
13 /* DANGER!!!! These must be defined *BEFORE* replacements.h and the malloc() macro!!!! */
14
15 #include <stdlib.h>
16 #include <string.h>
17 /*
18  * clear_malloc
19  *
20  * will alloc memory and clear it
21  */
22 void *clear_malloc(size_t size)
23 {
24         void *t = malloc(size);
25         if (t)
26                 memset(t, 0x00, size);
27         return t;
28 }
29
30 void *fill_malloc(size_t size)
31 {
32         void *t = malloc(size);
33         if (t) {
34                 /* We want to initialize memory to some known bad state.
35                  * 0 and 0xff yields 0 and -1 as integers, which often
36                  * have meaningful values. 0x5555... is not often a valid
37                  * integer and is quite easily spotted in the debugger
38                  * also it is almost certainly an invalid address */
39                 memset(t, 0x55, size);
40         }
41         return t;
42 }
43
44 #define IN_REPLACEMENTS_C
45 #ifdef HAVE_CONFIG_H
46 #include "config.h"
47 #endif
48 #ifdef HAVE_STRINGS_H
49 #include <strings.h>
50 #endif
51
52 #ifdef _WIN32
53 #include <io.h>
54 #include <winsock2.h>
55 #endif
56
57 /* replacements for gettimeofday */
58 #ifndef HAVE_GETTIMEOFDAY
59
60 /* Windows */
61 #ifdef _WIN32
62
63 #ifndef __GNUC__
64 #define EPOCHFILETIME (116444736000000000i64)
65 #else
66 #define EPOCHFILETIME (116444736000000000LL)
67 #endif
68
69 int gettimeofday(struct timeval *tv, struct timezone *tz)
70 {
71         FILETIME ft;
72         LARGE_INTEGER li;
73         __int64 t;
74         static int tzflag;
75
76         if (tv) {
77                 GetSystemTimeAsFileTime(&ft);
78                 li.LowPart  = ft.dwLowDateTime;
79                 li.HighPart = ft.dwHighDateTime;
80                 t  = li.QuadPart;                                       /* In 100-nanosecond intervals */
81                 t -= EPOCHFILETIME;                                     /* Offset to the Epoch time */
82                 t /= 10;                                                        /* In microseconds */
83                 tv->tv_sec  = (long)(t / 1000000);
84                 tv->tv_usec = (long)(t % 1000000);
85         }
86
87         if (tz) {
88                 if (!tzflag) {
89                         _tzset();
90                         tzflag++;
91                 }
92                 tz->tz_minuteswest = _timezone / 60;
93                 tz->tz_dsttime = _daylight;
94         }
95
96         return 0;
97 }
98 #endif  /* _WIN32 */
99
100 #endif  /* HAVE_GETTIMEOFDAY */
101
102 #ifndef HAVE_STRNLEN
103 size_t strnlen(const char *s, size_t maxlen)
104 {
105         const char *end = (const char *)memchr(s, '\0', maxlen);
106         return end ? (size_t) (end - s) : maxlen;
107 }
108 #endif
109
110 #ifndef HAVE_STRNDUP
111 char *strndup(const char *s, size_t n)
112 {
113         size_t len = strnlen(s, n);
114         char *new = malloc(len + 1);
115
116         if (!new)
117                 return NULL;
118
119         new[len] = '\0';
120         return (char *) memcpy(new, s, len);
121 }
122 #endif
123
124 #ifdef _WIN32
125 int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
126 {
127         DWORD ms_total, limit;
128         HANDLE handles[MAXIMUM_WAIT_OBJECTS];
129         int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];
130         int n_handles = 0, i;
131         fd_set sock_read, sock_write, sock_except;
132         fd_set aread, awrite, aexcept;
133         int sock_max_fd = -1;
134         struct timeval tvslice;
135         int retcode;
136
137 #define SAFE_FD_ISSET(fd, set)  (set && FD_ISSET(fd, set))
138
139         /* calculate how long we need to wait in milliseconds */
140         if (!tv)
141                 ms_total = INFINITE;
142         else {
143                 ms_total = tv->tv_sec * 1000;
144                 ms_total += tv->tv_usec / 1000;
145         }
146
147         FD_ZERO(&sock_read);
148         FD_ZERO(&sock_write);
149         FD_ZERO(&sock_except);
150
151         /* build an array of handles for non-sockets */
152         for (i = 0; i < max_fd; i++) {
153                 if (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) {
154                         intptr_t handle = (intptr_t) _get_osfhandle(i);
155                         handles[n_handles] = (HANDLE)handle;
156                         if (handles[n_handles] == INVALID_HANDLE_VALUE) {
157                                 /* socket */
158                                 if (SAFE_FD_ISSET(i, rfds))
159                                         FD_SET(i, &sock_read);
160                                 if (SAFE_FD_ISSET(i, wfds))
161                                         FD_SET(i, &sock_write);
162                                 if (SAFE_FD_ISSET(i, efds))
163                                         FD_SET(i, &sock_except);
164                                 if (i > sock_max_fd)
165                                         sock_max_fd = i;
166                         } else {
167                                 handle_slot_to_fd[n_handles] = i;
168                                 n_handles++;
169                         }
170                 }
171         }
172
173         if (n_handles == 0) {
174                 /* plain sockets only - let winsock handle the whole thing */
175                 return select(max_fd, rfds, wfds, efds, tv);
176         }
177
178         /* mixture of handles and sockets; lets multiplex between
179          * winsock and waiting on the handles */
180
181         FD_ZERO(&aread);
182         FD_ZERO(&awrite);
183         FD_ZERO(&aexcept);
184
185         limit = GetTickCount() + ms_total;
186         do {
187                 retcode = 0;
188
189                 if (sock_max_fd >= 0) {
190                         /* overwrite the zero'd sets here; the select call
191                          * will clear those that are not active */
192                         aread = sock_read;
193                         awrite = sock_write;
194                         aexcept = sock_except;
195
196                         tvslice.tv_sec = 0;
197                         tvslice.tv_usec = 1000;
198
199                         retcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept, &tvslice);
200                 }
201
202                 if (n_handles > 0) {
203                         /* check handles */
204                         DWORD wret;
205
206                         wret = MsgWaitForMultipleObjects(n_handles,
207                                         handles,
208                                         FALSE,
209                                         retcode > 0 ? 0 : 1,
210                                         QS_ALLEVENTS);
211
212                         if (wret == WAIT_TIMEOUT) {
213                                 /* set retcode to 0; this is the default.
214                                  * select() may have set it to something else,
215                                  * in which case we leave it alone, so this branch
216                                  * does nothing */
217                                 ;
218                         } else if (wret == WAIT_FAILED) {
219                                 if (retcode == 0)
220                                         retcode = -1;
221                         } else {
222                                 if (retcode < 0)
223                                         retcode = 0;
224                                 for (i = 0; i < n_handles; i++) {
225                                         if (WaitForSingleObject(handles[i], 0) == WAIT_OBJECT_0) {
226                                                 if (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) {
227                                                         DWORD bytes;
228                                                         intptr_t handle = (intptr_t) _get_osfhandle(
229                                                                         handle_slot_to_fd[i]);
230
231                                                         if (PeekNamedPipe((HANDLE)handle, NULL, 0,
232                                                                     NULL, &bytes, NULL)) {
233                                                                 /* check to see if gdb pipe has data available */
234                                                                 if (bytes) {
235                                                                         FD_SET(handle_slot_to_fd[i], &aread);
236                                                                         retcode++;
237                                                                 }
238                                                         } else {
239                                                                 FD_SET(handle_slot_to_fd[i], &aread);
240                                                                 retcode++;
241                                                         }
242                                                 }
243                                                 if (SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) {
244                                                         FD_SET(handle_slot_to_fd[i], &awrite);
245                                                         retcode++;
246                                                 }
247                                                 if (SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) {
248                                                         FD_SET(handle_slot_to_fd[i], &aexcept);
249                                                         retcode++;
250                                                 }
251                                         }
252                                 }
253                         }
254                 }
255         } while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));
256
257         if (rfds)
258                 *rfds = aread;
259         if (wfds)
260                 *wfds = awrite;
261         if (efds)
262                 *efds = aexcept;
263
264         return retcode;
265 }
266 #endif