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 <stdint.h>
30 #include <sys/fcntl.h>
31 #include <sys/stat.h>
32 #include <sys/unistd.h>
33 #include <sys/time.h>
34 #include <stdio.h>
35 
41 #pragma pack(push, 4)
42 
43 // When compiling under Linux, these get #defined and mess things up
44 #undef st_atime
45 #undef st_mtime
46 #undef st_ctime
47 
51 struct gdb_stat_t {
52  uint32_t st_dev; // device
53  uint32_t st_ino; // inode
54  mode_t st_mode; // protection
55  uint32_t st_nlink; // number of hard links
56  uint32_t st_uid; // user ID of owner
57  uint32_t st_gid; // group ID of owner
58  uint32_t st_rdev; // device type (if inode device)
59  uint64_t st_size; // total size, in bytes
60  uint64_t st_blksize; // blocksize for filesystem I/O
61  uint64_t st_blocks; // number of blocks allocated
62  time_t st_atime; // time of last access
63  time_t st_mtime; // time of last modification
64  time_t st_ctime; // time of last change
65 };
66 
70 struct gdb_timeval_t {
71  time_t tv_sec; // second
72  uint64_t tv_usec; // microsecond
73 };
74 
75 #pragma pack(pop)
76 
77 /* GDB Syscall interface */
78 
95 };
96 
97 struct GdbSyscallInfo;
98 
103 using gdb_syscall_callback_t = void (*)(const GdbSyscallInfo& info);
104 
111  void* param;
112  int result;
113  // Command parameters
114  union {
115  struct {
116  const char* filename;
117  int flags;
118  int mode;
119  } open;
120  struct {
121  int fd;
122  } close;
123  struct {
124  int fd;
125  void* buffer;
126  size_t bufSize;
127  } read;
128  struct {
129  int fd;
130  const void* buffer;
131  size_t count;
132  } write;
133  struct {
134  int fd;
135  long offset;
136  int whence;
137  } lseek;
138  struct {
139  const char* oldpath;
140  const char* newpath;
142  struct {
143  const char* pathname;
145  struct {
146  const char* pathname;
148  } stat;
149  struct {
150  int fd;
151  struct gdb_stat_t* buf;
152  } fstat;
153  struct {
155  void* tz;
157  struct {
158  int fd;
160  struct {
161  const char* command;
163  };
164 };
165 
180 int gdb_syscall(const GdbSyscallInfo& info);
181 
192 static inline int gdb_syscall_open(const char* filename, int flags, int mode, gdb_syscall_callback_t callback = nullptr,
193  void* param = nullptr)
194 {
195  GdbSyscallInfo info = {eGDBSYS_open, callback, param};
196  info.open.filename = filename;
197  info.open.flags = flags;
198  info.open.mode = mode;
199  return gdb_syscall(info);
200 }
201 
210 static inline int gdb_syscall_close(int fd, gdb_syscall_callback_t callback = nullptr, void* param = nullptr)
211 {
212  GdbSyscallInfo info = {eGDBSYS_close, callback, param};
213  info.close.fd = fd;
214  return gdb_syscall(info);
215 }
216 
227 static inline int gdb_syscall_read(int fd, void* buffer, size_t bufSize, gdb_syscall_callback_t callback = nullptr,
228  void* param = nullptr)
229 {
230  GdbSyscallInfo info = {eGDBSYS_read, callback, param};
231  info.read.fd = fd;
232  info.read.buffer = buffer;
233  info.read.bufSize = bufSize;
234  return gdb_syscall(info);
235 }
236 
247 static inline int gdb_syscall_write(int fd, const void* buffer, size_t count, gdb_syscall_callback_t callback = nullptr,
248  void* param = nullptr)
249 {
250  GdbSyscallInfo info = {eGDBSYS_write, callback, param};
251  info.write.fd = fd;
252  info.write.buffer = buffer;
253  info.write.count = count;
254  return gdb_syscall(info);
255 }
256 
267 static inline int gdb_syscall_lseek(int fd, long offset, int whence, gdb_syscall_callback_t callback = nullptr,
268  void* param = nullptr)
269 {
270  GdbSyscallInfo info = {eGDBSYS_lseek, callback, param};
271  info.lseek.fd = fd;
272  info.lseek.offset = offset;
273  info.lseek.whence = whence;
274  return gdb_syscall(info);
275 }
276 
286 static inline int gdb_syscall_rename(const char* oldpath, const char* newpath,
287  gdb_syscall_callback_t callback = nullptr, void* param = nullptr)
288 {
289  GdbSyscallInfo info = {eGDBSYS_rename, callback, param};
290  info.rename.oldpath = oldpath;
291  info.rename.newpath = newpath;
292  return gdb_syscall(info);
293 }
294 
303 static inline int gdb_syscall_unlink(const char* pathname, gdb_syscall_callback_t callback = nullptr,
304  void* param = nullptr)
305 {
306  GdbSyscallInfo info = {eGDBSYS_unlink, callback, param};
307  info.unlink.pathname = pathname;
308  return gdb_syscall(info);
309 }
310 
320 static inline int gdb_syscall_stat(const char* pathname, gdb_stat_t* buf, gdb_syscall_callback_t callback = nullptr,
321  void* param = nullptr)
322 {
323  GdbSyscallInfo info = {eGDBSYS_stat, callback, param};
324  info.stat.pathname = pathname;
325  info.stat.buf = buf;
326  return gdb_syscall(info);
327 }
328 
338 static inline int gdb_syscall_fstat(int fd, struct gdb_stat_t* buf, gdb_syscall_callback_t callback = nullptr,
339  void* param = nullptr)
340 {
341  GdbSyscallInfo info = {eGDBSYS_fstat, callback, param};
342  info.fstat.fd = fd;
343  info.fstat.buf = buf;
344  return gdb_syscall(info);
345 }
346 
356 static inline int gdb_syscall_gettimeofday(gdb_timeval_t* tv, void* tz, gdb_syscall_callback_t callback = nullptr,
357  void* param = nullptr)
358 {
359  GdbSyscallInfo info = {eGDBSYS_gettimeofday, callback, param};
360  info.gettimeofday.tv = tv;
361  info.gettimeofday.tz = tz;
362  return gdb_syscall(info);
363 }
364 
373 static inline int gdb_syscall_isatty(int fd, gdb_syscall_callback_t callback = nullptr, void* param = nullptr)
374 {
375  GdbSyscallInfo info = {eGDBSYS_isatty, callback, param};
376  info.isatty.fd = fd;
377  return gdb_syscall(info);
378 }
379 
389 static inline int gdb_syscall_system(const char* command, gdb_syscall_callback_t callback = nullptr,
390  void* param = nullptr)
391 {
392  GdbSyscallInfo info = {eGDBSYS_system, callback, param};
393  info.system.command = command;
394  return gdb_syscall(info);
395 }
396 
407 static inline int gdb_console_read(void* buffer, size_t bufSize, gdb_syscall_callback_t callback = nullptr,
408  void* param = nullptr)
409 {
410  return gdb_syscall_read(STDIN_FILENO, buffer, bufSize, callback, param);
411 }
412 
421 static inline int gdb_console_write(const void* buffer, size_t count, gdb_syscall_callback_t callback = nullptr,
422  void* param = nullptr)
423 {
424  return gdb_syscall_write(STDOUT_FILENO, buffer, count, callback, param);
425 }
426 
int gdb_syscall(const GdbSyscallInfo &info)
Stub function to perform a syscall. Implemented by GDB stub.
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:286
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:421
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:320
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:373
GdbSyscallCommand
Enumeration defining available commands.
Definition: gdb_syscall.h:82
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:267
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:192
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:407
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:247
static int gdb_syscall_close(int fd, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Close a host file.
Definition: gdb_syscall.h:210
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:303
static int gdb_syscall_system(const char *command, gdb_syscall_callback_t callback=nullptr, void *param=nullptr)
Invoke the 'system' command on the host.
Definition: gdb_syscall.h:389
void(*)(const GdbSyscallInfo &info) gdb_syscall_callback_t
GDB Syscall completion callback function.
Definition: gdb_syscall.h:103
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:356
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:338
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:227
@ eGDBSYS_isatty
Definition: gdb_syscall.h:93
@ eGDBSYS_close
Definition: gdb_syscall.h:84
@ eGDBSYS_fstat
Definition: gdb_syscall.h:91
@ eGDBSYS_unlink
Definition: gdb_syscall.h:89
@ eGDBSYS_system
Definition: gdb_syscall.h:94
@ eGDBSYS_write
Definition: gdb_syscall.h:86
@ eGDBSYS_gettimeofday
Definition: gdb_syscall.h:92
@ eGDBSYS_rename
Definition: gdb_syscall.h:88
@ eGDBSYS_read
Definition: gdb_syscall.h:85
@ eGDBSYS_lseek
Definition: gdb_syscall.h:87
@ eGDBSYS_stat
Definition: gdb_syscall.h:90
@ eGDBSYS_open
Definition: gdb_syscall.h:83
GDB Syscall request information.
Definition: gdb_syscall.h:108
struct GdbSyscallInfo::@4::@9 write
int result
Final result of syscall.
Definition: gdb_syscall.h:112
int flags
Definition: gdb_syscall.h:117
const char * pathname
Definition: gdb_syscall.h:143
struct GdbSyscallInfo::@4::@12 unlink
struct GdbSyscallInfo::@4::@8 read
size_t bufSize
Definition: gdb_syscall.h:126
struct GdbSyscallInfo::@4::@11 rename
struct GdbSyscallInfo::@4::@13 stat
void * buffer
Definition: gdb_syscall.h:125
struct GdbSyscallInfo::@4::@6 open
gdb_syscall_callback_t callback
User-supplied callback (if any)
Definition: gdb_syscall.h:110
struct GdbSyscallInfo::@4::@7 close
const void * buffer
Definition: gdb_syscall.h:130
struct GdbSyscallInfo::@4::@16 isatty
struct gdb_stat_t * buf
Definition: gdb_syscall.h:151
void * param
User-supplied parameter for callback.
Definition: gdb_syscall.h:111
void * tz
Definition: gdb_syscall.h:155
gdb_timeval_t * tv
Definition: gdb_syscall.h:154
const char * command
Definition: gdb_syscall.h:161
const char * filename
Definition: gdb_syscall.h:116
struct GdbSyscallInfo::@4::@17 system
int mode
Definition: gdb_syscall.h:118
int fd
Definition: gdb_syscall.h:121
struct GdbSyscallInfo::@4::@14 fstat
struct GdbSyscallInfo::@4::@10 lseek
GdbSyscallCommand command
The syscall command.
Definition: gdb_syscall.h:109
gdb_stat_t * buf
Definition: gdb_syscall.h:147
const char * oldpath
Definition: gdb_syscall.h:139
struct GdbSyscallInfo::@4::@15 gettimeofday
long offset
Definition: gdb_syscall.h:135
const char * newpath
Definition: gdb_syscall.h:140
size_t count
Definition: gdb_syscall.h:131
int whence
Definition: gdb_syscall.h:136
GDB uses a specific version of the stat structure, 64 bytes in size.
Definition: gdb_syscall.h:51
uint32_t st_ino
Definition: gdb_syscall.h:53
uint32_t st_rdev
Definition: gdb_syscall.h:58
uint64_t st_blocks
Definition: gdb_syscall.h:61
uint64_t st_size
Definition: gdb_syscall.h:59
uint64_t st_blksize
Definition: gdb_syscall.h:60
uint32_t st_gid
Definition: gdb_syscall.h:57
mode_t st_mode
Definition: gdb_syscall.h:54
time_t st_ctime
Definition: gdb_syscall.h:64
uint32_t st_dev
Definition: gdb_syscall.h:52
time_t st_mtime
Definition: gdb_syscall.h:63
uint32_t st_uid
Definition: gdb_syscall.h:56
time_t st_atime
Definition: gdb_syscall.h:62
uint32_t st_nlink
Definition: gdb_syscall.h:55
GDB uses a specific version of the timeval structure, 12 bytes in size (manual says 8,...
Definition: gdb_syscall.h:70
time_t tv_sec
Definition: gdb_syscall.h:71
uint64_t tv_usec
Definition: gdb_syscall.h:72