gdb_syscall.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * gdb_syscall.h - Support for GDB file I/O
8  *
9  * @author: 2019 - Mikee47 <mike@sillyhouse.net>
10  *
11  * An API is defined for communicating with GDB using the 'file-I/O protocol', but the name is misleading
12  * as it can also perform functions not related to file (or console) I/O. The functions are generally
13  * POSIX compatible so for further details consult the appropriate reference for your operating system.
14  *
15  * This is a synchronous protocol, so only one request may be in progress at a time.
16  * While a request is in progress GDB will not respond to any notifications from the target - including debug output.
17  *
18  * All functions are implemented with an optional callback routine, which is essential when reading the
19  * console as it can take a considerable time to execute.
20  *
21  * To use in your application, build with GDBSTUB_ENABLE_SYSCALL=1 and #include this header.
22  *
23  * @see https://sourceware.org/gdb/current/onlinedocs/gdb/File_002dI_002fO-Remote-Protocol-Extension.html
24  *
25  ****/
26 
27 #pragma once
28 
29 #include <user_config.h>
30 #include <sys/fcntl.h>
31 #include <sys/stat.h>
32 #include <sys/unistd.h>
33 #include <sys/time.h>
34 
40 #pragma pack(push, 4)
41 
42 // When compiling under Linux, these get #defined and mess things up
43 #undef st_atime
44 #undef st_mtime
45 #undef st_ctime
46 
50 struct gdb_stat_t {
51  uint32_t st_dev; // device
52  uint32_t st_ino; // inode
53  mode_t st_mode; // protection
54  uint32_t st_nlink; // number of hard links
55  uint32_t st_uid; // user ID of owner
56  uint32_t st_gid; // group ID of owner
57  uint32_t st_rdev; // device type (if inode device)
58  uint64_t st_size; // total size, in bytes
59  uint64_t st_blksize; // blocksize for filesystem I/O
60  uint64_t st_blocks; // number of blocks allocated
61  time_t st_atime; // time of last access
62  time_t st_mtime; // time of last modification
63  time_t st_ctime; // time of last change
64 };
65 
69 struct gdb_timeval_t {
70  time_t tv_sec; // second
71  uint64_t tv_usec; // microsecond
72 };
73 
74 #pragma pack(pop)
75 
76 /* GDB Syscall interface */
77 
94 };
95 
96 struct GdbSyscallInfo;
97 
102 typedef void (*gdb_syscall_callback_t)(const GdbSyscallInfo& info);
103 
110  void* param;
111  int result;
112  // Command parameters
113  union {
114  struct {
115  const char* filename;
116  int flags;
117  int mode;
118  } open;
119  struct {
120  int fd;
121  } close;
122  struct {
123  int fd;
124  void* buffer;
125  size_t bufSize;
126  } read;
127  struct {
128  int fd;
129  const void* buffer;
130  size_t count;
131  } write;
132  struct {
133  int fd;
134  long offset;
135  int whence;
136  } lseek;
137  struct {
138  const char* oldpath;
139  const char* newpath;
140  } rename;
141  struct {
142  const char* pathname;
143  } unlink;
144  struct {
145  const char* pathname;
147  } stat;
148  struct {
149  int fd;
150  struct gdb_stat_t* buf;
151  } fstat;
152  struct {
154  void* tz;
155  } gettimeofday;
156  struct {
157  int fd;
158  } isatty;
159  struct {
160  const char* command;
161  } system;
162  };
163 };
164 
179 int gdb_syscall(const GdbSyscallInfo& info);
180 
191 static inline int gdb_syscall_open(const char* filename, int flags, int mode, gdb_syscall_callback_t callback = nullptr,
192  void* param = nullptr)
193 {
194  GdbSyscallInfo info = {eGDBSYS_open, callback, param};
195  info.open.filename = filename;
196  info.open.flags = flags;
197  info.open.mode = mode;
198  return gdb_syscall(info);
199 }
200 
209 static inline int gdb_syscall_close(int fd, gdb_syscall_callback_t callback = nullptr, void* param = nullptr)
210 {
211  GdbSyscallInfo info = {eGDBSYS_close, callback, param};
212  info.close.fd = fd;
213  return gdb_syscall(info);
214 }
215 
226 static inline int gdb_syscall_read(int fd, void* buffer, size_t bufSize, gdb_syscall_callback_t callback = nullptr,
227  void* param = nullptr)
228 {
229  GdbSyscallInfo info = {eGDBSYS_read, callback, param};
230  info.read.fd = fd;
231  info.read.buffer = buffer;
232  info.read.bufSize = bufSize;
233  return gdb_syscall(info);
234 }
235 
246 static inline int gdb_syscall_write(int fd, const void* buffer, size_t count, gdb_syscall_callback_t callback = nullptr,
247  void* param = nullptr)
248 {
249  GdbSyscallInfo info = {eGDBSYS_write, callback, param};
250  info.write.fd = fd;
251  info.write.buffer = buffer;
252  info.write.count = count;
253  return gdb_syscall(info);
254 }
255 
266 static inline int gdb_syscall_lseek(int fd, long offset, int whence, gdb_syscall_callback_t callback = nullptr,
267  void* param = nullptr)
268 {
269  GdbSyscallInfo info = {eGDBSYS_lseek, callback, param};
270  info.lseek.fd = fd;
271  info.lseek.offset = offset;
272  info.lseek.whence = whence;
273  return gdb_syscall(info);
274 }
275 
285 static inline int gdb_syscall_rename(const char* oldpath, const char* newpath,
286  gdb_syscall_callback_t callback = nullptr, void* param = nullptr)
287 {
288  GdbSyscallInfo info = {eGDBSYS_rename, callback, param};
289  info.rename.oldpath = oldpath;
290  info.rename.newpath = newpath;
291  return gdb_syscall(info);
292 }
293 
302 static inline int gdb_syscall_unlink(const char* pathname, gdb_syscall_callback_t callback = nullptr,
303  void* param = nullptr)
304 {
305  GdbSyscallInfo info = {eGDBSYS_unlink, callback, param};
306  info.unlink.pathname = pathname;
307  return gdb_syscall(info);
308 }
309 
319 static inline int gdb_syscall_stat(const char* pathname, gdb_stat_t* buf, gdb_syscall_callback_t callback = nullptr,
320  void* param = nullptr)
321 {
322  GdbSyscallInfo info = {eGDBSYS_stat, callback, param};
323  info.stat.pathname = pathname;
324  info.stat.buf = buf;
325  return gdb_syscall(info);
326 }
327 
337 static inline int gdb_syscall_fstat(int fd, struct gdb_stat_t* buf, gdb_syscall_callback_t callback = nullptr,
338  void* param = nullptr)
339 {
340  GdbSyscallInfo info = {eGDBSYS_fstat, callback, param};
341  info.fstat.fd = fd;
342  info.fstat.buf = buf;
343  return gdb_syscall(info);
344 }
345 
355 static inline int gdb_syscall_gettimeofday(gdb_timeval_t* tv, void* tz, gdb_syscall_callback_t callback = nullptr,
356  void* param = nullptr)
357 {
358  GdbSyscallInfo info = {eGDBSYS_gettimeofday, callback, param};
359  info.gettimeofday.tv = tv;
360  info.gettimeofday.tz = tz;
361  return gdb_syscall(info);
362 }
363 
372 static inline int gdb_syscall_isatty(int fd, gdb_syscall_callback_t callback = nullptr, void* param = nullptr)
373 {
374  GdbSyscallInfo info = {eGDBSYS_isatty, callback, param};
375  info.isatty.fd = fd;
376  return gdb_syscall(info);
377 }
378 
388 static inline int gdb_syscall_system(const char* command, gdb_syscall_callback_t callback = nullptr,
389  void* param = nullptr)
390 {
391  GdbSyscallInfo info = {eGDBSYS_system, callback, param};
392  info.system.command = command;
393  return gdb_syscall(info);
394 }
395 
406 static inline int gdb_console_read(void* buffer, size_t bufSize, gdb_syscall_callback_t callback = nullptr,
407  void* param = nullptr)
408 {
409  return gdb_syscall_read(STDIN_FILENO, buffer, bufSize, callback, param);
410 }
411 
420 static inline int gdb_console_write(const void* buffer, size_t count, gdb_syscall_callback_t callback = nullptr,
421  void* param = nullptr)
422 {
423  return gdb_syscall_write(STDOUT_FILENO, buffer, count, callback, param);
424 }
425 
size_t bufSize
Definition: gdb_syscall.h:125
const char * newpath
Definition: gdb_syscall.h:139
GDB uses a specific version of the timeval structure, 12 bytes in size (manual says 8...
Definition: gdb_syscall.h:69
struct GdbSyscallInfo::@3::@10 rename
GdbSyscallCommand command
The syscall command.
Definition: gdb_syscall.h:108
int result
Final result of syscall.
Definition: gdb_syscall.h:111
time_t st_mtime
Definition: gdb_syscall.h:62
int mode
Definition: gdb_syscall.h:117
static int gdb_syscall_unlink(const char *pathname, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Unlink/remove/delete a host file.
Definition: gdb_syscall.h:302
static int gdb_syscall_write(int fd, const void *buffer, size_t count, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Write data from a host file.
Definition: gdb_syscall.h:246
struct gdb_stat_t * buf
Definition: gdb_syscall.h:150
uint64_t st_blksize
Definition: gdb_syscall.h:59
time_t st_ctime
Definition: gdb_syscall.h:63
int whence
Definition: gdb_syscall.h:135
static int gdb_syscall_close(int fd, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Close a host file.
Definition: gdb_syscall.h:209
uint32_t st_gid
Definition: gdb_syscall.h:56
Definition: gdb_syscall.h:85
Definition: gdb_syscall.h:93
Definition: gdb_syscall.h:84
Definition: gdb_syscall.h:89
uint64_t st_blocks
Definition: gdb_syscall.h:60
int fd
Definition: gdb_syscall.h:120
static int gdb_syscall_fstat(int fd, struct gdb_stat_t *buf, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Obtain information about a host file given its file handle.
Definition: gdb_syscall.h:337
const char * oldpath
Definition: gdb_syscall.h:138
struct GdbSyscallInfo::@3::@13 fstat
const char * pathname
Definition: gdb_syscall.h:142
struct GdbSyscallInfo::@3::@16 system
static int gdb_syscall_rename(const char *oldpath, const char *newpath, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Rename a host file.
Definition: gdb_syscall.h:285
const char * command
Definition: gdb_syscall.h:160
void * buffer
Definition: gdb_syscall.h:124
static int gdb_syscall_system(const char *command, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Invoke the &#39;system&#39; command on the host.
Definition: gdb_syscall.h:388
time_t tv_sec
Definition: gdb_syscall.h:70
struct GdbSyscallInfo::@3::@12 stat
time_t st_atime
Definition: gdb_syscall.h:61
struct GdbSyscallInfo::@3::@15 isatty
mode_t st_mode
Definition: gdb_syscall.h:53
Definition: gdb_syscall.h:90
struct GdbSyscallInfo::@3::@14 gettimeofday
Definition: gdb_syscall.h:83
uint32_t st_dev
Definition: gdb_syscall.h:51
uint32_t st_uid
Definition: gdb_syscall.h:55
uint64_t tv_usec
Definition: gdb_syscall.h:71
void * param
User-supplied parameter for callback.
Definition: gdb_syscall.h:110
const void * buffer
Definition: gdb_syscall.h:129
int gdb_syscall(const GdbSyscallInfo &info)
Stub function to perform a syscall. Implemented by GDB stub.
gdb_timeval_t * tv
Definition: gdb_syscall.h:153
void(* gdb_syscall_callback_t)(const GdbSyscallInfo &info)
GDB Syscall completion callback function.
Definition: gdb_syscall.h:102
Definition: gdb_syscall.h:91
gdb_stat_t * buf
Definition: gdb_syscall.h:146
uint32_t st_nlink
Definition: gdb_syscall.h:54
struct GdbSyscallInfo::@3::@5 open
static int gdb_syscall_open(const char *filename, int flags, int mode, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Open a file on the host.
Definition: gdb_syscall.h:191
uint32_t st_ino
Definition: gdb_syscall.h:52
struct GdbSyscallInfo::@3::@9 lseek
static int gdb_syscall_isatty(int fd, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Determine if the given file handle refers to a console/tty.
Definition: gdb_syscall.h:372
GDB uses a specific version of the stat structure, 64 bytes in size.
Definition: gdb_syscall.h:50
static int gdb_syscall_read(int fd, void *buffer, size_t bufSize, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Read data from a host file.
Definition: gdb_syscall.h:226
struct GdbSyscallInfo::@3::@8 write
static int gdb_console_write(const void *buffer, size_t count, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Write text to the GDB console.
Definition: gdb_syscall.h:420
Definition: gdb_syscall.h:92
uint32_t st_rdev
Definition: gdb_syscall.h:57
struct GdbSyscallInfo::@3::@6 close
int flags
Definition: gdb_syscall.h:116
GDB Syscall request information.
Definition: gdb_syscall.h:107
struct GdbSyscallInfo::@3::@11 unlink
struct GdbSyscallInfo::@3::@7 read
static int gdb_console_read(void *buffer, size_t bufSize, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Read a line of text from the GDB console.
Definition: gdb_syscall.h:406
void * tz
Definition: gdb_syscall.h:154
GdbSyscallCommand
Enumeration defining available commands.
Definition: gdb_syscall.h:81
size_t count
Definition: gdb_syscall.h:130
Definition: gdb_syscall.h:82
gdb_syscall_callback_t callback
User-supplied callback (if any)
Definition: gdb_syscall.h:109
Definition: gdb_syscall.h:87
static int gdb_syscall_stat(const char *pathname, gdb_stat_t *buf, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Obtain information about a host file given its name/path.
Definition: gdb_syscall.h:319
long offset
Definition: gdb_syscall.h:134
uint64_t st_size
Definition: gdb_syscall.h:58
Definition: gdb_syscall.h:86
static int gdb_syscall_gettimeofday(gdb_timeval_t *tv, void *tz, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Get current time of day from host, in UTC.
Definition: gdb_syscall.h:355
Definition: gdb_syscall.h:88
static int gdb_syscall_lseek(int fd, long offset, int whence, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Get/set current file pointer position in a host file.
Definition: gdb_syscall.h:266
const char * filename
Definition: gdb_syscall.h:115