Rizin
unix-like reverse engineering framework and cli tools
io_srec.c File Reference
#include <rz_io.h>
#include <rz_lib.h>
#include <rz_util.h>

Go to the source code of this file.

Classes

struct  srec_t
 

Macros

#define SREC_SIZE   64
 
#define NMAX   100
 
#define SREC_PATH_PREFIX   "srec://"
 

Typedefs

typedef struct srec_t SRecord
 

Functions

static void write_S3_record (FILE *fd, ut32 address, const ut8 *buffer, ut16 size)
 
static st32 __write (RzIO *io, RzIODesc *fd, const ut8 *buf, st32 count)
 
static st32 __read (RzIO *io, RzIODesc *fd, ut8 *buf, st32 count)
 
static st32 __close (RzIODesc *fd)
 
static ut64 __lseek (struct rz_io_t *io, RzIODesc *fd, ut64 offset, st32 whence)
 
static bool __plugin_open (RzIO *io, const char *pathname, bool many)
 
static bool srecord_parse (RzBuffer *buf, char *str)
 
static RzIODesc__open (RzIO *io, const char *pathname, st32 rw, st32 mode)
 
static bool __resize (RzIO *io, RzIODesc *fd, ut64 size)
 

Variables

RzIOPlugin rz_io_plugin_srec
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ NMAX

#define NMAX   100

Definition at line 20 of file io_srec.c.

◆ SREC_PATH_PREFIX

#define SREC_PATH_PREFIX   "srec://"

Definition at line 21 of file io_srec.c.

◆ SREC_SIZE

#define SREC_SIZE   64

Definition at line 19 of file io_srec.c.

Typedef Documentation

◆ SRecord

typedef struct srec_t SRecord

Function Documentation

◆ __close()

static st32 __close ( RzIODesc fd)
static

Definition at line 116 of file io_srec.c.

116  {
117  rz_return_val_if_fail(fd && fd->data, -1);
118 
119  SRecord *srec = (SRecord *)fd->data;
120  rz_buf_free(srec->buf);
121  free(srec);
122  fd->data = NULL;
123  return 0;
124 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
Definition: io_srec.c:23
RzBuffer * buf
Definition: io_srec.c:25
static const z80_opcode fd[]
Definition: z80_tab.h:997

References srec_t::buf, fd, free(), NULL, rz_buf_free(), and rz_return_val_if_fail.

◆ __lseek()

static ut64 __lseek ( struct rz_io_t io,
RzIODesc fd,
ut64  offset,
st32  whence 
)
static

Definition at line 126 of file io_srec.c.

126  {
127  rz_return_val_if_fail(fd && fd->data, 0);
128  SRecord *srec = (SRecord *)fd->data;
129  io->off = rz_buf_seek(srec->buf, offset, whence);
130  return io->off;
131 }
voidpf uLong offset
Definition: ioapi.h:144
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
Definition: buf.c:1166
ut64 off
Definition: rz_io.h:61

References srec_t::buf, fd, rz_io_t::off, rz_buf_seek(), and rz_return_val_if_fail.

◆ __open()

static RzIODesc* __open ( RzIO io,
const char *  pathname,
st32  rw,
st32  mode 
)
static

Definition at line 505 of file io_srec.c.

505  {
507 
508  SRecord *mal = NULL;
509  char *str = NULL;
510  if (__plugin_open(io, pathname, 0)) {
511  str = rz_file_slurp(pathname + 7, NULL);
512  if (!str) {
513  return NULL;
514  }
515  mal = RZ_NEW0(SRecord);
516  if (!mal) {
517  free(str);
518  return NULL;
519  }
520  mal->buf = rz_buf_new_sparse(io->Oxff);
521  if (!mal->buf) {
522  free(str);
523  free(mal);
524  return NULL;
525  }
526  if (!srecord_parse(mal->buf, str)) {
527  RZ_LOG_ERROR("srec: failed to parse file\n");
528  free(str);
529  rz_buf_free(mal->buf);
530  free(mal);
531  return NULL;
532  }
533  free(str);
534  return rz_io_desc_new(io, &rz_io_plugin_srec, pathname, rw, mode, mal);
535  }
536  return NULL;
537 }
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
Definition: io_srec.c:133
RzIOPlugin rz_io_plugin_srec
Definition: io_srec.c:549
static bool srecord_parse(RzBuffer *buf, char *str)
Definition: io_srec.c:137
const char int mode
Definition: ioapi.h:137
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char pathname
Definition: sflib.h:66
RZ_API RZ_OWN RzBuffer * rz_buf_new_sparse(ut8 Oxff)
Creates a sparse buffer.
Definition: buf.c:408
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
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
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_NEW0(x)
Definition: rz_types.h:284
int Oxff
Definition: rz_io.h:65
static struct @626 mal

References __plugin_open(), free(), mal, NULL, rz_io_t::Oxff, pathname, rz_buf_free(), rz_buf_new_sparse(), rz_file_slurp(), rz_io_desc_new(), rz_io_plugin_srec, RZ_LOG_ERROR, RZ_NEW0, rz_return_val_if_fail, srecord_parse(), and cmd_descs_generate::str.

◆ __plugin_open()

static bool __plugin_open ( RzIO io,
const char *  pathname,
bool  many 
)
static

Definition at line 133 of file io_srec.c.

133  {
134  return (!strncmp(pathname, SREC_PATH_PREFIX, strlen(SREC_PATH_PREFIX)));
135 }
#define SREC_PATH_PREFIX
Definition: io_srec.c:21

References pathname, and SREC_PATH_PREFIX.

Referenced by __open().

◆ __read()

static st32 __read ( RzIO io,
RzIODesc fd,
ut8 buf,
st32  count 
)
static

Definition at line 102 of file io_srec.c.

102  {
103  rz_return_val_if_fail(io && fd && fd->data && buf && count > 0, -1);
104 
105  SRecord *srec = (SRecord *)fd->data;
106  memset(buf, io->Oxff, count);
107  st32 r = rz_buf_read_at(srec->buf, io->off, buf, count);
108  if (r >= 0) {
109  rz_buf_seek(srec->buf, r, RZ_BUF_CUR);
110  }
111  // sparse read return >= 0 but < count still means everything was read successfully,
112  // just maybe not entirely populated by chunks:
113  return r < 0 ? -1 : count;
114 }
#define r
Definition: crypto_rc6.c:12
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
voidpf void * buf
Definition: ioapi.h:138
return memset(p, 0, total)
#define RZ_BUF_CUR
Definition: rz_buf.h:15
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
#define st32
Definition: rz_types_base.h:12

References srec_t::buf, count, fd, memset(), rz_io_t::off, rz_io_t::Oxff, r, RZ_BUF_CUR, rz_buf_read_at(), rz_buf_seek(), rz_return_val_if_fail, and st32.

◆ __resize()

static bool __resize ( RzIO io,
RzIODesc fd,
ut64  size 
)
static

Definition at line 539 of file io_srec.c.

539  {
540  rz_return_val_if_fail(fd && fd->data, false);
541 
542  SRecord *srec = (SRecord *)fd->data;
543  if (srec) {
544  return rz_buf_resize(srec->buf, size);
545  }
546  return false;
547 }
voidpf void uLong size
Definition: ioapi.h:138
RZ_API bool rz_buf_resize(RZ_NONNULL RzBuffer *b, ut64 newsize)
Resize the buffer size.
Definition: buf.c:890
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References srec_t::buf, fd, if(), rz_buf_resize(), and rz_return_val_if_fail.

◆ __write()

static st32 __write ( RzIO io,
RzIODesc fd,
const ut8 buf,
st32  count 
)
static

Definition at line 48 of file io_srec.c.

48  {
49  rz_return_val_if_fail(fd && fd->data && fd->perm & RZ_PERM_W && count > 0, -1);
50 
51  const char *pathname = NULL;
52  FILE *out = NULL;
53  SRecord *srec = NULL;
54  ut32 address = 0, size = 0;
55  ut8 n_bytes = 0;
56  size_t chunks_count = 0;
57  const RzBufferSparseChunk *chunks = NULL;
58  const RzBufferSparseChunk *sparse = NULL;
59 
60  srec = (SRecord *)fd->data;
61  pathname = fd->name + strlen(SREC_PATH_PREFIX);
62  out = rz_sys_fopen(pathname, "w");
63 
64  if (!out) {
65  RZ_LOG_ERROR("srec:write(): cannot open '%s' for writing\n", pathname);
66  return -1;
67  }
68 
69  // starting record, contains "rizin-srec\0"
70  fprintf(out, "S00E000072697A696E2D7372656300EB\n");
71 
72  /* mem write */
73  if (rz_buf_write_at(srec->buf, io->off, buf, count) != count) {
74  RZ_LOG_ERROR("srec:write(): cannot write into buffer\n");
75  fclose(out);
76  return -1;
77  }
78 
80  chunks = rz_buf_sparse_get_chunks(srec->buf, &chunks_count);
81 
82  for (size_t i = 0; i < chunks_count; i++) {
83  sparse = &chunks[i];
84  size = sparse->to - sparse->from;
85  for (ut32 offset = 0; offset < size; offset += SREC_SIZE) {
86  address = sparse->from + offset;
87  n_bytes = SREC_SIZE;
88  if (offset + SREC_SIZE > size) {
89  n_bytes = size - offset;
90  }
91  write_S3_record(out, address, sparse->data + offset, n_bytes);
92  }
93  }
94 
95  // termination
96  fprintf(out, "S70500000000FA\n");
97  fclose(out);
98  out = NULL;
99  return 0;
100 }
lzma_index ** i
Definition: index.h:629
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
uint32_t ut32
#define SREC_SIZE
Definition: io_srec.c:19
static void write_S3_record(FILE *fd, ut32 address, const ut8 *buffer, ut16 size)
Definition: io_srec.c:28
uint8_t ut8
Definition: lh5801.h:11
string FILE
Definition: benchmark.py:21
RZ_API st64 rz_buf_write_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the specified address.
Definition: buf.c:1197
RZ_API const RzBufferSparseChunk * rz_buf_sparse_get_chunks(RzBuffer *b, RZ_NONNULL size_t *count)
Only for sparse RzBuffers, get all sparse data chunks currently populated.
Definition: buf_sparse.c:313
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
#define RZ_PERM_W
Definition: rz_types.h:94
ut8 * data
size == to - from + 1
Definition: rz_buf.h:56
ut64 from
inclusive
Definition: rz_buf.h:54
ut64 to
inclusive, there can't be chunks with size == 0
Definition: rz_buf.h:55
char * name
Definition: z80_tab.h:24

References srec_t::buf, count, rz_buf_sparse_chunk_t::data, fd, benchmark::FILE, rz_buf_sparse_chunk_t::from, i, z80_opcode::name, NULL, rz_io_t::off, out, pathname, RZ_BUF_CUR, rz_buf_seek(), rz_buf_sparse_get_chunks(), rz_buf_write_at(), RZ_LOG_ERROR, RZ_PERM_W, rz_return_val_if_fail, rz_sys_fopen(), SREC_PATH_PREFIX, SREC_SIZE, rz_buf_sparse_chunk_t::to, and write_S3_record().

◆ srecord_parse()

static bool srecord_parse ( RzBuffer buf,
char *  str 
)
static

Definition at line 137 of file io_srec.c.

137  {
138  if (!str || *str != 'S') {
139  return false;
140  }
141  ut8 *record_data = NULL;
142  ut32 record_size = 0;
143  ut32 record_begin = 0;
144  ut32 record_addr = 0;
145  ut32 record_next = 0;
146  char record_type = 0;
147  char *eol = NULL;
148  ut8 cksum = 0;
149  st32 byte_count = 0;
150  st32 byte = 0, i = 0, counter = 0;
151  int line = 0;
152 
153  record_data = malloc(UT16_MAX);
154  if (!record_data) {
155  goto fail;
156  }
157 
158  do {
159  line++;
160  if (sscanf(str, "S%c%02x", &record_type, &byte_count) != 2) {
161  RZ_LOG_ERROR("srec:parse(): invalid data in motorola srecord file at line %d\n", line);
162  goto fail;
163  }
164 
165  byte_count &= 0xff;
166 
167  switch (record_type) {
168  case '0': // Header with 16-bit address
169  counter = byte_count - 3;
170  if (sscanf(str + 4, "%04x", &record_addr) != 1) {
171  RZ_LOG_ERROR("srec:parse(): invalid header hexadecimal address 16-bit at line %d\n", line);
172  goto fail;
173  }
174  record_addr &= 0xffff;
175 
176  cksum = byte_count;
177  cksum += record_addr & 0xff;
178  cksum += record_addr >> 8;
179 
180  for (i = 0; i < counter; i++) {
181  if (sscanf(str + 8 + (i * 2), "%02x", &byte) != 1) {
182  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value! at line %d\n", line);
183  goto fail;
184  }
185  cksum += byte;
186  }
187  cksum = ~cksum;
188 
189  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
190  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value! at line %d\n", line);
191  goto fail;
192  } else if (cksum != byte) {
193  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
194  goto fail;
195  }
196 
197  str = strchr(str + 1, 'S');
198  break;
199 
200  case '1': // Data with 16-bit address
201  counter = byte_count - 3;
202  if (sscanf(str + 4, "%04x", &record_addr) != 1) {
203  RZ_LOG_ERROR("srec:parse(): invalid data hexadecimal address 16-bit at line %d\n", line);
204  goto fail;
205  }
206  record_addr &= 0xffff;
207 
208  cksum = byte_count;
209  cksum += record_addr & 0xff;
210  cksum += record_addr >> 8;
211 
212  if ((record_next != record_addr) || ((record_size + counter) > UT16_MAX)) {
213  if (record_size && record_size < UT16_MAX) {
214  if (rz_buf_write_at(buf, record_begin, record_data, (st32)record_size) != record_size) {
215  RZ_LOG_ERROR("srec:parse(): cannot write buffer at 0x%x\n", record_begin);
216  goto fail;
217  }
218  }
219  record_begin = record_addr;
220  record_next = record_addr;
221  record_size = 0;
222  }
223 
224  for (i = 0; i < byte_count - 3; i++) {
225  if (sscanf(str + 8 + (i * 2), "%02x", &byte) != 1) {
226  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
227  goto fail;
228  }
229  if (record_size + i < UT16_MAX) {
230  record_data[record_size + i] = (ut8)byte & 0xff;
231  }
232  cksum += byte;
233  }
234  cksum = ~cksum;
235  record_size += counter;
236  record_next += counter;
237 
238  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
239  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
240  goto fail;
241  } else if (cksum != byte) {
242  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
243  goto fail;
244  }
245 
246  str = strchr(str + 1, 'S');
247  break;
248 
249  case '5': // Count with 16-bit address
250  if (sscanf(str + 4, "%04x", &record_addr) != 1) {
251  RZ_LOG_ERROR("srec:parse(): invalid count hexadecimal address 16-bit at line %d\n", line);
252  goto fail;
253  }
254  record_addr &= 0xffff;
255 
256  cksum = byte_count;
257  cksum += record_addr & 0xff;
258  cksum += record_addr >> 8;
259  cksum = ~cksum;
260 
261  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
262  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
263  goto fail;
264  } else if (cksum != byte) {
265  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
266  goto fail;
267  }
268 
269  str = strchr(str + 1, 'S');
270  break;
271 
272  case '9': // Terminator with 16-bit address
273  if (sscanf(str + 4, "%04x", &record_addr) != 1) {
274  RZ_LOG_ERROR("srec:parse(): invalid terminator hexadecimal address 16-bit at line %d\n", line);
275  goto fail;
276  }
277  record_addr &= 0xffff;
278 
279  cksum = byte_count;
280  cksum += record_addr & 0xff;
281  cksum += record_addr >> 8;
282  cksum = ~cksum;
283 
284  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
285  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
286  goto fail;
287  } else if (cksum != byte) {
288  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
289  goto fail;
290  }
291 
292  str = strchr(str + 1, 'S');
293  break;
294  case '2': // Data with 24-bit address
295  counter = byte_count - 4;
296  if (sscanf(str + 4, "%06x", &record_addr) != 1) {
297  RZ_LOG_ERROR("srec:parse(): invalid data hexadecimal address 24-bit at line %d\n", line);
298  goto fail;
299  }
300  record_addr &= 0xffffff;
301 
302  cksum = byte_count;
303  cksum += record_addr & 0xff;
304  cksum += (record_addr >> 8) & 0xff;
305  cksum += record_addr >> 16;
306 
307  if ((record_next != record_addr) || ((record_size + counter) > UT16_MAX)) {
308  if (record_size && record_size < UT16_MAX) {
309  if (rz_buf_write_at(buf, record_begin, record_data, (st32)record_size) != record_size) {
310  RZ_LOG_ERROR("srec:parse(): cannot write buffer at 0x%x\n", record_begin);
311  goto fail;
312  }
313  }
314  record_begin = record_addr;
315  record_next = record_addr;
316  record_size = 0;
317  }
318 
319  for (i = 0; i < byte_count - 4; i++) {
320  if (sscanf(str + 10 + (i * 2), "%02x", &byte) != 1) {
321  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
322  goto fail;
323  }
324  if (record_size + i < UT16_MAX) {
325  record_data[record_size + i] = (ut8)byte & 0xff;
326  }
327  cksum += byte;
328  }
329  cksum = ~cksum;
330  record_size += counter;
331  record_next += counter;
332 
333  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
334  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
335  goto fail;
336  } else if (cksum != byte) {
337  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
338  goto fail;
339  }
340 
341  str = strchr(str + 1, 'S');
342  break;
343 
344  case '6': // Count with 24-bit address
345  if (sscanf(str + 4, "%06x", &record_addr) != 1) {
346  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal address 24-bit at line %d\n", line);
347  goto fail;
348  }
349  record_addr &= 0xffffff;
350 
351  cksum = byte_count;
352  cksum += record_addr & 0xff;
353  cksum += (record_addr >> 8) & 0xff;
354  cksum += record_addr >> 16;
355  cksum = ~cksum;
356 
357  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
358  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
359  goto fail;
360  } else if (cksum != byte) {
361  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
362  goto fail;
363  }
364 
365  str = strchr(str + 1, 'S');
366  break;
367 
368  case '8': // Terminator with 24-bit address
369  if (sscanf(str + 4, "%06x", &record_addr) != 1) {
370  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal address 24-bit at line %d\n", line);
371  goto fail;
372  }
373  record_addr &= 0xffffff;
374 
375  eol = strchr(str + 1, 'S');
376  if (eol) {
377  *eol = 0;
378  }
379 
380  cksum = byte_count;
381  cksum += record_addr & 0xff;
382  cksum += (record_addr >> 8) & 0xff;
383  cksum += record_addr >> 16;
384  cksum = ~cksum;
385 
386  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
387  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
388  goto fail;
389  } else if (cksum != byte) {
390  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
391  goto fail;
392  }
393 
394  str = strchr(str + 1, 'S');
395  break;
396 
397  case '3': // Data with 32-bit address
398  counter = byte_count - 5;
399  if (sscanf(str + 4, "%08x", &record_addr) != 1) {
400  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal address 32-bit at line %d\n", line);
401  goto fail;
402  }
403  record_addr &= 0xffffffff;
404 
405  eol = strchr(str + 1, 'S');
406  if (eol) {
407  *eol = 0;
408  }
409 
410  cksum = byte_count;
411  cksum += record_addr & 0xff;
412  cksum += (record_addr >> 8) & 0xff;
413  cksum += (record_addr >> 16) & 0xff;
414  cksum += record_addr >> 24;
415 
416  if ((record_next != record_addr) || ((record_size + counter) > UT16_MAX)) {
417  if (record_size && record_size < UT16_MAX) {
418  if (rz_buf_write_at(buf, record_begin, record_data, (st32)record_size) != record_size) {
419  RZ_LOG_ERROR("srec:parse(): cannot write buffer at 0x%x\n", record_begin);
420  goto fail;
421  }
422  }
423  record_begin = record_addr;
424  record_next = record_addr;
425  record_size = 0;
426  }
427 
428  for (i = 0; i < byte_count - 5; i++) {
429  if (sscanf(str + 12 + (i * 2), "%02x", &byte) != 1) {
430  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
431  goto fail;
432  }
433  if (record_size + i < UT16_MAX) {
434  record_data[record_size + i] = (ut8)byte & 0xff;
435  }
436  cksum += byte;
437  }
438  cksum = ~cksum;
439  record_size += counter;
440  record_next += counter;
441 
442  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
443  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
444  goto fail;
445  } else if (cksum != byte) {
446  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
447  goto fail;
448  }
449 
450  str = strchr(str + 1, 'S');
451  break;
452 
453  case '7': // Terminator with 32-bit address
454  if (sscanf(str + 4, "%08x", &record_addr) != 1) {
455  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal address 32-bit at line %d\n", line);
456  goto fail;
457  }
458  record_addr &= 0xffffffff;
459 
460  eol = strchr(str + 1, 'S');
461  if (eol) {
462  *eol = 0;
463  }
464 
465  cksum = byte_count;
466  cksum += record_addr & 0xff;
467  cksum += (record_addr >> 8) & 0xff;
468  cksum += (record_addr >> 16) & 0xff;
469  cksum += record_addr >> 24;
470  cksum = ~cksum;
471 
472  if (sscanf(str + 2 + (byte_count * 2), "%02x", &byte) != 1) {
473  RZ_LOG_ERROR("srec:parse(): invalid hexadecimal value at line %d\n", line);
474  goto fail;
475  } else if (cksum != byte) {
476  RZ_LOG_ERROR("srec:parse(): checksum check failed (got %02x expected %02x) at line %d\n", byte, cksum, line);
477  goto fail;
478  }
479 
480  str = strchr(str + 1, 'S');
481  break;
482 
483  case '4':
484  break;
485  default:
486  RZ_LOG_ERROR("srec:parse(): invalid motorola srecord type '%c' at line %d\n", record_type, line);
487  goto fail;
488  }
489  } while (str);
490 
491  if (record_size && record_size < UT16_MAX) {
492  if (rz_buf_write_at(buf, record_begin, record_data, (st32)record_size) != record_size) {
493  RZ_LOG_ERROR("srec:parse(): cannot write buffer at 0x%x\n", record_begin);
494  goto fail;
495  }
496  }
497 
498  free(record_data);
499  return true;
500 fail:
501  free(record_data);
502  return false;
503 }
#define ut8
Definition: dcpu16.h:8
void * malloc(size_t size)
Definition: malloc.c:123
line
Definition: setup.py:34
#define UT16_MAX
int64_t counter
Definition: main.c:4
#define fail(test)
Definition: tests.h:29

References counter, fail, free(), i, setup::line, malloc(), NULL, rz_buf_write_at(), RZ_LOG_ERROR, st32, cmd_descs_generate::str, UT16_MAX, and ut8.

Referenced by __open().

◆ write_S3_record()

static void write_S3_record ( FILE *  fd,
ut32  address,
const ut8 buffer,
ut16  size 
)
static

Definition at line 28 of file io_srec.c.

28  {
30 
31  ut8 record_size = 4 + size + 1;
32  ut8 checksum = record_size;
33  checksum += address & 0xff;
34  checksum += (address >> 8) & 0xff;
35  checksum += (address >> 16) & 0xff;
36  checksum += address >> 24;
37 
38  fprintf(fd, "S3%02x%08x", record_size, address);
39 
40  for (ut16 j = 0; j < size; j++) {
41  checksum += buffer[j];
42  fprintf(fd, "%02x", buffer[j]);
43  }
44 
45  fprintf(fd, "%02x\n", checksum);
46 }
uint16_t ut16
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
Definition: buffer.h:15

References fd, and rz_return_if_fail.

Referenced by __write().

Variable Documentation

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_IO,
}
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_io.h:117

Definition at line 564 of file io_srec.c.

◆ rz_io_plugin_srec

RzIOPlugin rz_io_plugin_srec
Initial value:
= {
.name = "srec",
.desc = "Motorola S-record file format",
.license = "LGPL-3",
.open = __open,
.close = __close,
.read = __read,
.check = __plugin_open,
.lseek = __lseek,
.write = __write,
.resize = __resize
}
static st32 __write(RzIO *io, RzIODesc *fd, const ut8 *buf, st32 count)
Definition: io_srec.c:48
static st32 __close(RzIODesc *fd)
Definition: io_srec.c:116
static bool __resize(RzIO *io, RzIODesc *fd, ut64 size)
Definition: io_srec.c:539
static RzIODesc * __open(RzIO *io, const char *pathname, st32 rw, st32 mode)
Definition: io_srec.c:505
static ut64 __lseek(struct rz_io_t *io, RzIODesc *fd, ut64 offset, st32 whence)
Definition: io_srec.c:126
static st32 __read(RzIO *io, RzIODesc *fd, ut8 *buf, st32 count)
Definition: io_srec.c:102

Definition at line 549 of file io_srec.c.

Referenced by __open().