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