36 #include <sys/types.h>
53 eprintf(
"ihex:write(): sparse write failed\n");
65 ut8 cks = 0 - (6 + (eaddr >> 8) + (eaddr & 0xff));
66 return fprintf(
fd,
":02000004%04X%02X\n", eaddr, cks);
82 for (
i = 0; (
i + 0x10) <
size;
i += 0x10) {
84 cks += (
i + start_addr) >> 8;
85 cks += (
i + start_addr);
86 for (j = 0; j < 0x10; j++) {
90 if (fprintf(
fd,
":10%04x00%02x%02x%02x%02x%02x%02x%02x"
91 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
92 (
i + start_addr) & 0xffff,
b[0],
b[1],
b[2],
b[3],
b[4],
b[5],
b[6],
93 b[7],
b[8],
b[9],
b[10],
b[11],
b[12],
b[13],
94 b[14],
b[15], cks) < 0) {
98 if (((
i + start_addr) & 0xffff) < 0x10) {
100 if (
fw04b(
fd, (
i + start_addr) >> 16) < 0) {
109 last_addr =
i + start_addr;
111 cks -= last_addr >> 8;
112 for (j = 0;
i <
size;
i++, j++) {
114 sprintf(linebuf + (2 * j),
"%02X",
b[j]);
118 if (fprintf(
fd,
":%02X%04X00%.*s%02X\n", j, last_addr, 2 * j, linebuf, cks) < 0) {
136 return r < 0 ? -1 :
count;
140 if (!
fd || !
fd->data) {
152 if (!
fd || !
fd->data) {
161 return (!strncmp(
pathname,
"ihex://", 7));
176 int bc = 0,
type, byte,
i, l;
178 #define SEC_MAX (sec_size < INT_MAX) ? sec_size : INT_MAX
181 sec_tmp =
calloc(1, sec_count);
186 l = sscanf(
str,
":%02x%04x%02x", &bc, &addr_tmp, &
type);
188 eprintf(
"Invalid data in ihex file (%.*s)\n", 80,
str);
197 eol = strchr(
str + 1,
':');
202 cksum += addr_tmp >> 8;
206 if ((next_addr != addr_tmp) || ((sec_size + bc) >
SEC_MAX)) {
209 if (sec_size && sec_size <
UT16_MAX) {
210 if (
rz_buf_write_at(rbuf, sec_start, sec_tmp, (
int)sec_size) != sec_size) {
211 eprintf(
"sparse buffer problem, giving up\n");
216 sec_start = segreg + addr_tmp;
217 next_addr = addr_tmp;
221 for (
i = 0;
i < bc;
i++) {
222 if (sscanf(
str + 9 + (
i * 2),
"%02x", &
byte) != 1) {
223 eprintf(
"unparsable data !\n");
226 if (sec_size +
i < sec_count) {
227 sec_tmp[sec_size +
i] = (
ut8)
byte & 0xff;
235 if (sscanf(
str + 9 + (
i * 2),
"%02x", &
byte) != 1) {
236 eprintf(
"unparsable data !\n");
241 ut8 fixedcksum = 0 - (cksum - byte);
242 eprintf(
"Checksum failed %02x (got %02x expected %02x)\n",
243 cksum,
byte, fixedcksum);
253 eprintf(
"sparse buffer problem, giving up. ssiz=%X, sstart=%X\n", sec_size, sec_start);
266 eprintf(
"sparse buffer problem, giving up\n");
272 eol = strchr(
str + 1,
':');
277 cksum += addr_tmp >> 8;
280 if ((bc != 2) || (addr_tmp != 0)) {
281 eprintf(
"invalid type 02/04 record!\n");
284 if ((sscanf(
str + 9 + 0,
"%02x", &extH) != 1) ||
285 (sscanf(
str + 9 + 2,
"%02x", &extL) != 1)) {
286 eprintf(
"unparsable data !\n");
291 cksum += extH + extL;
293 segreg = extH << 8 | extL;
296 segreg = segreg << ((
type == 2) ? 4 : 16);
303 if (sscanf(
str + 9 + 4,
"%02x", &
byte) != 1) {
308 ut8 fixedcksum = 0 - (cksum - byte);
309 eprintf(
"Checksum failed %02x (got %02x expected %02x)\n",
310 cksum,
byte, fixedcksum);
319 str = strchr(
str + 1,
':');
341 for (
size_t i = 0;
i < chunks_count;
i++) {
344 while (
from >> 16 != rbs->
to >> 16) {
348 if (addh != addh_cur) {
352 eprintf(
"ihex:write: file error\n");
360 eprintf(
"ihex:fwblock error\n");
367 if (addh != addh_cur) {
371 eprintf(
"ihex:write: file error\n");
378 eprintf(
"ihex:fwblock error 2\n");
384 fprintf(
out,
":00000001FF\n");
409 eprintf(
"ihex: failed to parse file\n");
438 .desc =
"Open intel HEX file",
450 #ifndef RZ_PLUGIN_INCORE
const lzma_allocator const uint8_t size_t uint8_t * out
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
RZ_API void Ht_() free(HtName_(Ht) *ht)
static ut64 __lseek(struct rz_io_t *io, RzIODesc *fd, ut64 offset, int whence)
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
RzIOPlugin rz_io_plugin_ihex
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
static RzIODesc * __open(RzIO *io, const char *pathname, int rw, int mode)
static int fw04b(FILE *fd, ut16 eaddr)
static bool __resize(RzIO *io, RzIODesc *fd, ut64 size)
RZ_API RzLibStruct rizin_plugin
static int fwblock(FILE *fd, ut8 *b, ut32 start_addr, ut32 size)
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
static bool ihex_parse(RzBuffer *rbuf, char *str)
static bool ihex_write(RzIODesc *desc, Rihex *rih)
static int __close(RzIODesc *fd)
return memset(p, 0, total)
void * calloc(size_t number, size_t size)
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
RZ_API bool rz_buf_resize(RZ_NONNULL RzBuffer *b, ut64 newsize)
Resize the buffer size.
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
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.
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.
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.
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
RZ_API RZ_OWN RzBuffer * rz_buf_new_sparse(ut8 Oxff)
Creates a sparse buffer.
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
ut8 * data
size == to - from + 1
ut64 to
inclusive, there can't be chunks with size == 0
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]