- add missing image handling files
[openocd.git] / src / target / image.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "image.h"
28
29 #include "types.h"
30 #include "replacements.h"
31 #include "log.h"
32
33 #include "fileio.h"
34 #include "target.h"
35
36 int image_ihex_buffer_complete(image_t *image)
37 {
38 image_ihex_t *ihex = image->type_private;
39 fileio_t *fileio = &ihex->fileio;
40 u32 raw_bytes_read, raw_bytes;
41 int retval;
42 u32 full_address = image->base_address;
43 char *buffer = malloc(ihex->raw_size);
44 u32 cooked_bytes = 0x0;
45
46 ihex->raw_size = fileio->size;
47 ihex->buffer = malloc(ihex->raw_size >> 1);
48
49 if ((retval = fileio_read(fileio, ihex->raw_size, (u8*)buffer, &raw_bytes_read)) != ERROR_OK)
50 {
51 free(buffer);
52 ERROR("failed buffering IHEX file, read failed");
53 return ERROR_FILEIO_OPERATION_FAILED;
54 }
55
56 if (raw_bytes_read != ihex->raw_size)
57 {
58 free(buffer);
59 ERROR("failed buffering complete IHEX file, only partially read");
60 return ERROR_FILEIO_OPERATION_FAILED;
61 }
62
63 image->size = 0x0;
64 raw_bytes = 0x0;
65 while (raw_bytes < raw_bytes_read)
66 {
67 u32 count;
68 u32 address;
69 u32 record_type;
70 u32 checksum;
71
72 if (sscanf(&buffer[raw_bytes], ":%2x%4x%2x", &count, &address, &record_type) != 3)
73 {
74 return ERROR_IMAGE_FORMAT_ERROR;
75 }
76 raw_bytes += 9;
77
78 if (record_type == 0)
79 {
80 if ((full_address & 0xffff) != address)
81 {
82 free(buffer);
83 ERROR("can't handle non-linear IHEX file");
84 return ERROR_IMAGE_FORMAT_ERROR;
85 }
86
87 while (count-- > 0)
88 {
89 sscanf(&buffer[raw_bytes], "%2hhx", &ihex->buffer[cooked_bytes]);
90 raw_bytes += 2;
91 cooked_bytes += 1;
92 full_address++;
93 }
94 }
95 else if (record_type == 1)
96 {
97 free(buffer);
98 image->size = cooked_bytes;
99 return ERROR_OK;
100 }
101 else if (record_type == 4)
102 {
103 u16 upper_address;
104
105 sscanf(&buffer[raw_bytes], "%4hx", &upper_address);
106 raw_bytes += 4;
107
108 if ((full_address >> 16) != upper_address)
109 {
110 free(buffer);
111 ERROR("can't handle non-linear IHEX file");
112 return ERROR_IMAGE_FORMAT_ERROR;
113 }
114 }
115 else if (record_type == 5)
116 {
117 u32 start_address;
118
119 sscanf(&buffer[raw_bytes], "%8x", &start_address);
120 raw_bytes += 8;
121
122 image->start_address_set = 1;
123 image->start_address = be_to_h_u32((u8*)&start_address);
124 }
125 else
126 {
127 free(buffer);
128 ERROR("unhandled IHEX record type: %i", record_type);
129 return ERROR_IMAGE_FORMAT_ERROR;
130 }
131
132 sscanf(&buffer[raw_bytes], "%2x", &checksum);
133 raw_bytes += 2;
134
135 /* consume new-line character(s) */
136 if ((buffer[raw_bytes] == '\n') || (buffer[raw_bytes] == '\r'))
137 raw_bytes++;
138
139 if ((buffer[raw_bytes] == '\n') || (buffer[raw_bytes] == '\r'))
140 raw_bytes++;
141 }
142
143 free(buffer);
144 ERROR("premature end of IHEX file, no end-of-file record found");
145 return ERROR_IMAGE_FORMAT_ERROR;
146 }
147
148 int image_open(image_t *image, void *source, enum fileio_access access)
149 {
150 int retval = ERROR_OK;
151
152 if (image->type == IMAGE_BINARY)
153 {
154 image_binary_t *image_binary;
155 char *url = source;
156
157 image_binary = image->type_private = malloc(sizeof(image_binary_t));
158
159 if ((retval = fileio_open(&image_binary->fileio, url, access, FILEIO_BINARY)) != ERROR_OK)
160 {
161 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
162 ERROR(image->error_str);
163 return retval;
164 }
165
166 if (access == FILEIO_WRITE)
167 image->size = 0;
168 else
169 image->size = image_binary->fileio.size;
170
171 return ERROR_OK;
172 }
173 else if (image->type == IMAGE_IHEX)
174 {
175 image_ihex_t *image_ihex;
176 char *url = source;
177
178 if (access != FILEIO_READ)
179 {
180 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
181 "can't open IHEX file for writing");
182 ERROR(image->error_str);
183 return ERROR_FILEIO_ACCESS_NOT_SUPPORTED;
184 }
185
186 image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
187
188 if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
189 {
190 strncpy(image->error_str, image_ihex->fileio.error_str, IMAGE_MAX_ERROR_STRING);
191 ERROR(image->error_str);
192 return retval;
193 }
194
195 image_ihex->position = 0;
196 image_ihex->raw_size = image_ihex->fileio.size;
197
198 if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
199 {
200 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
201 "failed buffering IHEX image, check daemon output for additional information");
202 ERROR(image->error_str);
203 fileio_close(&image_ihex->fileio);
204 return retval;
205 }
206 }
207 else if (image->type == IMAGE_MEMORY)
208 {
209 image_memory_t *image_memory;
210 target_t *target = source;
211
212 image_memory = image->type_private = malloc(sizeof(image_memory_t));
213
214 image_memory->target = target;
215 }
216
217 return retval;
218 };
219
220 int image_read(image_t *image, u32 size, u8 *buffer, u32 *size_read)
221 {
222 int retval;
223
224 if (image->type == IMAGE_BINARY)
225 {
226 image_binary_t *image_binary = image->type_private;
227
228 if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
229 {
230 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
231 return retval;
232 }
233 }
234 else if (image->type == IMAGE_IHEX)
235 {
236 image_ihex_t *image_ihex = image->type_private;
237
238 if ((image_ihex->position + size) > image->size)
239 {
240 /* don't read past the end of the file */
241 size = (image->size - image_ihex->position);
242 }
243
244 memcpy(buffer, image_ihex->buffer + image_ihex->position, size);
245 image_ihex->position += size;
246 *size_read = size;
247 image->error_str[0] = '\0';
248
249 return ERROR_OK;
250 }
251 else if (image->type == IMAGE_MEMORY)
252 {
253 /* TODO: handle target memory pseudo image */
254 }
255
256 return ERROR_OK;
257 }
258
259 int image_write(image_t *image, u32 size, u8 *buffer, u32 *size_written)
260 {
261 int retval = ERROR_FILEIO_OPERATION_NOT_SUPPORTED;
262
263 if (image->type == IMAGE_BINARY)
264 {
265 image_binary_t *image_binary = image->type_private;
266
267 if ((retval = fileio_write(&image_binary->fileio, size, buffer, size_written)) != ERROR_OK)
268 {
269 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
270 return retval;
271 }
272 }
273 else if (image->type == IMAGE_IHEX)
274 {
275 return ERROR_FILEIO_OPERATION_NOT_SUPPORTED;
276 }
277 else if (image->type == IMAGE_MEMORY)
278 {
279 /* TODO: handle target memory pseudo image */
280 }
281
282 if (retval != ERROR_OK)
283 return retval;
284
285 image->size += size;
286
287 return ERROR_OK;
288 }
289
290 int image_close(image_t *image)
291 {
292 if (image->type == IMAGE_BINARY)
293 {
294 image_binary_t *image_binary = image->type_private;
295
296 fileio_close(&image_binary->fileio);
297 }
298 else if (image->type == IMAGE_IHEX)
299 {
300 image_ihex_t *image_ihex = image->type_private;
301
302 fileio_close(&image_ihex->fileio);
303
304 if (image_ihex->buffer)
305 free(image_ihex->buffer);
306 }
307 else if (image->type == IMAGE_MEMORY)
308 {
309 /* do nothing for now */
310 }
311
312 free(image->type_private);
313
314 return ERROR_OK;
315 }
316
317 int identify_image_type(image_type_t *type, char *type_string)
318 {
319 if (type_string)
320 {
321 if (!strcmp(type_string, "bin"))
322 {
323 *type = IMAGE_BINARY;
324 }
325 else if (!strcmp(type_string, "ihex"))
326 {
327 *type = IMAGE_IHEX;
328 }
329 else
330 {
331 return ERROR_IMAGE_TYPE_UNKNOWN;
332 }
333 }
334 else
335 {
336 *type = IMAGE_BINARY;
337 }
338
339 return ERROR_OK;
340 }

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)