Rizin
unix-like reverse engineering framework and cli tools
io_qnx.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2010-2016 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_io.h>
5 #include <rz_lib.h>
6 #include <rz_socket.h>
7 #include <rz_util.h>
8 #define IRAPI static inline
9 #include <libqnxr.h>
10 
11 typedef struct {
13 } RzIOQnx;
14 
15 static libqnxr_t *desc = NULL;
16 static RzIODesc *rioqnx = NULL;
17 
18 static bool __plugin_open(RzIO *io, const char *file, bool many) {
19  return (!strncmp(file, "qnx://", 6));
20 }
21 
22 /* hacky cache to speedup io a bit */
23 /* reading in a different place clears the previous cache */
24 static ut64 c_addr = UT64_MAX;
25 static ut32 c_size = UT32_MAX;
26 static ut8 *c_buff = NULL;
27 #define SILLY_CACHE 0
28 
29 static int debug_qnx_read_at(ut8 *buf, int sz, ut64 addr) {
30  ut32 size_max = 500;
31  ut32 packets = sz / size_max;
32  ut32 last = sz % size_max;
33  ut32 x;
34  if (c_buff && addr != UT64_MAX && addr == c_addr) {
35  memcpy(buf, c_buff, sz);
36  return sz;
37  }
38  if (sz < 1 || addr >= UT64_MAX) {
39  return -1;
40  }
41  for (x = 0; x < packets; x++) {
42  qnxr_read_memory(desc, addr + x * size_max, (buf + x * size_max), size_max);
43  }
44  if (last) {
45  qnxr_read_memory(desc, addr + x * size_max, (buf + x * size_max), last);
46  }
47  c_addr = addr;
48  c_size = sz;
49 #if SILLY_CACHE
50  free(c_buff);
51  c_buff = rz_mem_dup(buf, sz);
52 #endif
53  return sz;
54 }
55 
56 static int debug_qnx_write_at(const ut8 *buf, int sz, ut64 addr) {
57  ut32 x, size_max = 500;
58  ut32 packets = sz / size_max;
59  ut32 last = sz % size_max;
60 
61  if (sz < 1 || addr >= UT64_MAX) {
62  return -1;
63  }
64  if (c_addr != UT64_MAX && addr >= c_addr && c_addr + sz < (c_addr + c_size)) {
65  RZ_FREE(c_buff);
66  c_addr = UT64_MAX;
67  }
68  for (x = 0; x < packets; x++) {
69  qnxr_write_memory(desc, addr + x * size_max,
70  (const uint8_t *)(buf + x * size_max), size_max);
71  }
72  if (last) {
73  qnxr_write_memory(desc, addr + x * size_max,
74  (buf + x * size_max), last);
75  }
76 
77  return sz;
78 }
79 
80 static RzIODesc *__open(RzIO *io, const char *file, int rw, int mode) {
81  RzIOQnx *rioq;
82  char host[128], *port, *p;
83 
84  if (!__plugin_open(io, file, 0)) {
85  return NULL;
86  }
87  if (rioqnx) {
88  // FIX: Don't allocate more than one RzIODesc
89  return rioqnx;
90  }
91  strncpy(host, file + 6, sizeof(host) - 1);
92  host[sizeof(host) - 1] = '\0';
93  port = strchr(host, ':');
94  if (!port) {
95  eprintf("Port not specified. Please use qnx://[host]:[port]\n");
96  return NULL;
97  }
98  *port = '\0';
99  port++;
100  p = strchr(port, '/');
101  if (p) {
102  *p = 0;
103  }
104 
105  rioq = RZ_NEW0(RzIOQnx);
106  qnxr_init(&rioq->desc);
107  int i_port = atoi(port);
108  if (qnxr_connect(&rioq->desc, host, i_port) == 0) {
109  desc = &rioq->desc;
110  rioqnx = rz_io_desc_new(io, &rz_io_plugin_qnx, file, rw, mode, rioq);
111  return rioqnx;
112  }
113  eprintf("qnx.io.open: Cannot connect to host.\n");
114  free(rioq);
115  return NULL;
116 }
117 
118 static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count) {
119  ut64 addr = io->off;
120  if (!desc) {
121  return -1;
122  }
123  return debug_qnx_write_at(buf, count, addr);
124 }
125 
126 static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
127  return offset;
128 }
129 
130 static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count) {
131  memset(buf, 0xff, count);
132  ut64 addr = io->off;
133  if (!desc) {
134  return -1;
135  }
136  return debug_qnx_read_at(buf, count, addr);
137 }
138 
139 static int __close(RzIODesc *fd) {
140  // TODO
141  return -1;
142 }
143 
144 static char *__system(RzIO *io, RzIODesc *fd, const char *cmd) {
145  return NULL;
146 }
147 
149  .name = "qnx",
150  .license = "LGPL3",
151  .desc = "Attach to QNX pdebug instance",
152  .uris = "qnx://",
153  .open = __open,
154  .close = __close,
155  .read = __read,
156  .write = __write,
157  .check = __plugin_open,
158  .lseek = __lseek,
159  .system = __system,
160  .isdbg = true
161 };
162 
163 #ifndef RZ_PLUGIN_INCORE
165  .type = RZ_LIB_TYPE_IO,
166  .data = &rz_io_plugin_qnx,
168 };
169 #endif
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static int debug_qnx_read_at(ut8 *buf, int sz, ut64 addr)
Definition: io_qnx.c:29
static libqnxr_t * desc
Definition: io_qnx.c:15
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: io_qnx.c:130
static ut32 c_size
Definition: io_qnx.c:25
static bool __plugin_open(RzIO *io, const char *file, bool many)
Definition: io_qnx.c:18
RZ_API RzLibStruct rizin_plugin
Definition: io_qnx.c:164
static RzIODesc * __open(RzIO *io, const char *file, int rw, int mode)
Definition: io_qnx.c:80
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: io_qnx.c:118
static ut64 c_addr
Definition: io_qnx.c:24
static int debug_qnx_write_at(const ut8 *buf, int sz, ut64 addr)
Definition: io_qnx.c:56
static RzIODesc * rioqnx
Definition: io_qnx.c:16
static ut8 * c_buff
Definition: io_qnx.c:26
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_qnx.c:126
static int __close(RzIODesc *fd)
Definition: io_qnx.c:139
RzIOPlugin rz_io_plugin_qnx
Definition: io_qnx.c:148
static char * __system(RzIO *io, RzIODesc *fd, const char *cmd)
Definition: io_qnx.c:144
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int qnxr_connect(libqnxr_t *g, const char *server, int port)
Definition: core.c:147
int qnxr_write_memory(libqnxr_t *g, ut64 address, const ut8 *data, ut64 len)
Definition: core.c:395
int qnxr_read_memory(libqnxr_t *g, ut64 address, ut8 *data, ut64 len)
Definition: core.c:365
int qnxr_init(libqnxr_t *g)
Definition: core.c:104
int x
Definition: mipsasm.c:20
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
Definition: io_desc.c:11
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
RZ_API void * rz_mem_dup(const void *s, int l)
Definition: mem.c:319
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
unsigned char uint8_t
Definition: sftypes.h:31
libqnxr_t desc
Definition: debug_qnx.c:30
Definition: gzappend.c:170
const char * name
Definition: rz_io.h:115
const char * version
Definition: rz_io.h:117
Definition: rz_io.h:59
ut64 off
Definition: rz_io.h:61
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997
static int addr
Definition: z80asm.c:58