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