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