1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
30 #include "replacements.h"
36 int image_ihex_buffer_complete(image_t
*image
)
38 image_ihex_t
*ihex
= image
->type_private
;
39 fileio_t
*fileio
= &ihex
->fileio
;
40 u32 raw_bytes_read
, raw_bytes
;
42 u32 full_address
= 0x0;
43 char *buffer
= malloc(fileio
->size
);
47 /* we can't determine the number of sections that we'll have to create ahead of time,
48 * so we locally hold them until parsing is finished */
49 image_section_t section
[IMAGE_MAX_SECTIONS
];
50 u8
*section_pointer
[IMAGE_MAX_SECTIONS
];
52 if ((retval
= fileio_read(fileio
, fileio
->size
, (u8
*)buffer
, &raw_bytes_read
)) != ERROR_OK
)
55 ERROR("failed buffering IHEX file, read failed");
56 return ERROR_FILEIO_OPERATION_FAILED
;
59 if (raw_bytes_read
!= fileio
->size
)
62 ERROR("failed buffering complete IHEX file, only partially read");
63 return ERROR_FILEIO_OPERATION_FAILED
;
66 ihex
->buffer
= malloc(fileio
->size
>> 1);
69 image
->num_sections
= 0;
70 section_pointer
[image
->num_sections
] = &ihex
->buffer
[cooked_bytes
];
71 section
[image
->num_sections
].base_address
= 0x0;
72 section
[image
->num_sections
].size
= 0x0;
73 section
[image
->num_sections
].flags
= 0;
74 while (raw_bytes
< raw_bytes_read
)
81 if (sscanf(&buffer
[raw_bytes
], ":%2x%4x%2x", &count
, &address
, &record_type
) != 3)
83 return ERROR_IMAGE_FORMAT_ERROR
;
87 if (record_type
== 0) /* Data Record */
89 if ((full_address
& 0xffff) != address
)
91 /* we encountered a nonconsecutive location, create a new section,
92 * unless the current section has zero size, in which case this specifies
93 * the current section's base address
95 if (section
[image
->num_sections
].size
!= 0)
97 image
->num_sections
++;
98 section
[image
->num_sections
].size
= 0x0;
99 section
[image
->num_sections
].flags
= 0;
100 section_pointer
[image
->num_sections
] = &ihex
->buffer
[cooked_bytes
];
102 section
[image
->num_sections
].base_address
=
103 (full_address
& 0xffff0000) | address
;
104 full_address
= (full_address
& 0xffff0000) | address
;
109 sscanf(&buffer
[raw_bytes
], "%2hhx", &ihex
->buffer
[cooked_bytes
]);
112 section
[image
->num_sections
].size
+= 1;
116 else if (record_type
== 1) /* End of File Record */
118 /* finish the current section */
119 image
->num_sections
++;
121 /* copy section information */
122 ihex
->section_pointer
= malloc(sizeof(u8
*) * image
->num_sections
);
123 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
124 for (i
= 0; i
< image
->num_sections
; i
++)
126 ihex
->section_pointer
[i
] = section_pointer
[i
];
127 image
->sections
[i
].base_address
= section
[i
].base_address
+
128 ((image
->base_address_set
) ? image
->base_address
: 0);
129 image
->sections
[i
].size
= section
[i
].size
;
130 image
->sections
[i
].flags
= section
[i
].flags
;
136 else if (record_type
== 4) /* Extended Linear Address Record */
140 sscanf(&buffer
[raw_bytes
], "%4hx", &upper_address
);
143 if ((full_address
>> 16) != upper_address
)
145 /* we encountered a nonconsecutive location, create a new section,
146 * unless the current section has zero size, in which case this specifies
147 * the current section's base address
149 if (section
[image
->num_sections
].size
!= 0)
151 image
->num_sections
++;
152 section
[image
->num_sections
].size
= 0x0;
153 section
[image
->num_sections
].flags
= 0;
154 section_pointer
[image
->num_sections
] = &ihex
->buffer
[cooked_bytes
];
156 section
[image
->num_sections
].base_address
=
157 (full_address
& 0xffff) | (upper_address
<< 16);
158 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
161 else if (record_type
== 5) /* Start Linear Address Record */
165 sscanf(&buffer
[raw_bytes
], "%8x", &start_address
);
168 image
->start_address_set
= 1;
169 image
->start_address
= be_to_h_u32((u8
*)&start_address
);
174 ERROR("unhandled IHEX record type: %i", record_type
);
175 return ERROR_IMAGE_FORMAT_ERROR
;
178 sscanf(&buffer
[raw_bytes
], "%2x", &checksum
);
181 /* consume new-line character(s) */
182 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
185 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
190 ERROR("premature end of IHEX file, no end-of-file record found");
191 return ERROR_IMAGE_FORMAT_ERROR
;
194 int image_open(image_t
*image
, void *source
, enum fileio_access access
)
196 int retval
= ERROR_OK
;
198 if (image
->type
== IMAGE_BINARY
)
200 image_binary_t
*image_binary
;
203 image_binary
= image
->type_private
= malloc(sizeof(image_binary_t
));
205 if ((retval
= fileio_open(&image_binary
->fileio
, url
, access
, FILEIO_BINARY
)) != ERROR_OK
)
207 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
208 ERROR(image
->error_str
);
212 image
->num_sections
= 1;
213 image
->sections
= malloc(sizeof(image_section_t
));
214 image
->sections
[0].base_address
= 0x0;
215 image
->sections
[0].size
= image_binary
->fileio
.size
;
216 image
->sections
[0].flags
= 0;
218 if (image
->base_address_set
== 1)
219 image
->sections
[0].base_address
= image
->base_address
;
223 else if (image
->type
== IMAGE_IHEX
)
225 image_ihex_t
*image_ihex
;
228 if (access
!= FILEIO_READ
)
230 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
231 "can't open IHEX file for writing");
232 ERROR(image
->error_str
);
233 return ERROR_FILEIO_ACCESS_NOT_SUPPORTED
;
236 image_ihex
= image
->type_private
= malloc(sizeof(image_ihex_t
));
238 if ((retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
240 strncpy(image
->error_str
, image_ihex
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
241 ERROR(image
->error_str
);
245 if ((retval
= image_ihex_buffer_complete(image
)) != ERROR_OK
)
247 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
248 "failed buffering IHEX image, check daemon output for additional information");
249 ERROR(image
->error_str
);
250 fileio_close(&image_ihex
->fileio
);
254 else if (image
->type
== IMAGE_MEMORY
)
256 image_memory_t
*image_memory
;
257 target_t
*target
= source
;
259 image_memory
= image
->type_private
= malloc(sizeof(image_memory_t
));
261 image_memory
->target
= target
;
267 int image_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
271 if (image
->type
== IMAGE_BINARY
)
273 image_binary_t
*image_binary
= image
->type_private
;
275 /* only one section in a plain binary */
277 return ERROR_INVALID_ARGUMENTS
;
279 if ((offset
> image
->sections
[0].size
) || (offset
+ size
> image
->sections
[0].size
))
280 return ERROR_INVALID_ARGUMENTS
;
283 if ((retval
= fileio_seek(&image_binary
->fileio
, offset
)) != ERROR_OK
)
285 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
289 /* return requested bytes */
290 if ((retval
= fileio_read(&image_binary
->fileio
, size
, buffer
, size_read
)) != ERROR_OK
)
292 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
296 else if (image
->type
== IMAGE_IHEX
)
298 image_ihex_t
*image_ihex
= image
->type_private
;
300 memcpy(buffer
, image_ihex
->section_pointer
[section
] + offset
, size
);
302 image
->error_str
[0] = '\0';
306 else if (image
->type
== IMAGE_MEMORY
)
308 /* TODO: handle target memory pseudo image */
314 int image_close(image_t
*image
)
316 if (image
->type
== IMAGE_BINARY
)
318 image_binary_t
*image_binary
= image
->type_private
;
320 fileio_close(&image_binary
->fileio
);
322 else if (image
->type
== IMAGE_IHEX
)
324 image_ihex_t
*image_ihex
= image
->type_private
;
326 fileio_close(&image_ihex
->fileio
);
328 if (image_ihex
->section_pointer
)
329 free(image_ihex
->section_pointer
);
331 if (image_ihex
->buffer
)
332 free(image_ihex
->buffer
);
334 else if (image
->type
== IMAGE_MEMORY
)
336 /* do nothing for now */
339 if (image
->type_private
)
340 free(image
->type_private
);
343 free(image
->sections
);
348 int identify_image_type(image_type_t
*type
, char *type_string
)
352 if (!strcmp(type_string
, "bin"))
354 *type
= IMAGE_BINARY
;
356 else if (!strcmp(type_string
, "ihex"))
362 return ERROR_IMAGE_TYPE_UNKNOWN
;
367 *type
= IMAGE_BINARY
;
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)