FLASH/NOR: Remove useless file stellaris.h
[openocd.git] / src / target / image.c
index 793a811f6724ba901a63aa6618b4663c5c960c2e..b0d957f8ab62164f7d9a1d63be442655ef2393f0 100644 (file)
@@ -2,12 +2,15 @@
  *   Copyright (C) 2007 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
- *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
+ *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   Copyright (C) 2008 by Spencer Oliver                                  *
  *   spen@spen-soft.co.uk                                                  *
  *                                                                         *
+ *   Copyright (C) 2009 by Franck Hereson                                  *
+ *   franck.hereson@secad.fr                                               *
+ *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
 #include "config.h"
 #endif
 
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_ELF_H
-#include <elf.h>
-#endif
-
 #include "image.h"
-
-#include "types.h"
-#include "replacements.h"
-#include "log.h"
-
-#include "fileio.h"
 #include "target.h"
+#include <helper/log.h>
+
 
 /* convert ELF header field to host endianness */
 #define field16(elf,field)\
-       ((elf->endianness==ELFDATA2LSB)? \
-               le_to_h_u16((u8*)&field):be_to_h_u16((u8*)&field))
+       ((elf->endianness == ELFDATA2LSB)? \
+               le_to_h_u16((uint8_t*)&field):be_to_h_u16((uint8_t*)&field))
 
 #define field32(elf,field)\
-       ((elf->endianness==ELFDATA2LSB)? \
-               le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
+       ((elf->endianness == ELFDATA2LSB)? \
+               le_to_h_u32((uint8_t*)&field):be_to_h_u32((uint8_t*)&field))
 
-static int autodetect_image_type(image_t *image, char *url)
+static int autodetect_image_type(struct image *image, const char *url)
 {
        int retval;
-       fileio_t fileio;
-       u32 read_bytes;
-       u8 buffer[9];
+       struct fileio fileio;
+       size_t read_bytes;
+       uint8_t buffer[9];
 
        /* read the first 4 bytes of image */
        if ((retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
@@ -65,33 +58,33 @@ static int autodetect_image_type(image_t *image, char *url)
        }
        retval = fileio_read(&fileio, 9, buffer, &read_bytes);
 
-       if (retval==ERROR_OK)
+       if (retval == ERROR_OK)
        {
                if (read_bytes != 9)
                {
-                       retval=ERROR_FILEIO_OPERATION_FAILED;
+                       retval = ERROR_FILEIO_OPERATION_FAILED;
                }
        }
        fileio_close(&fileio);
 
-       if (retval!=ERROR_OK)
+       if (retval != ERROR_OK)
                return retval;
 
        /* check header against known signatures */
-       if (strncmp((char*)buffer,ELFMAG,SELFMAG)==0)
+       if (strncmp((char*)buffer,ELFMAG,SELFMAG) == 0)
        {
                LOG_DEBUG("ELF image detected.");
                image->type = IMAGE_ELF;
        }
-       else if  ((buffer[0]==':') /* record start byte */
-               &&(isxdigit(buffer[1]))
-               &&(isxdigit(buffer[2]))
-               &&(isxdigit(buffer[3]))
-               &&(isxdigit(buffer[4]))
-               &&(isxdigit(buffer[5]))
-               &&(isxdigit(buffer[6]))
-               &&(buffer[7]=='0') /* record type : 00 -> 05 */
-               &&(buffer[8]>='0')&&(buffer[8]<'6'))
+       else if ((buffer[0]==':') /* record start byte */
+               &&(isxdigit(buffer[1]))
+               &&(isxdigit(buffer[2]))
+               &&(isxdigit(buffer[3]))
+               &&(isxdigit(buffer[4]))
+               &&(isxdigit(buffer[5]))
+               &&(isxdigit(buffer[6]))
+               &&(buffer[7]=='0') /* record type : 00 -> 05 */
+               &&(buffer[8]>='0') && (buffer[8]<'6'))
        {
                LOG_DEBUG("IHEX image detected.");
                image->type = IMAGE_IHEX;
@@ -113,7 +106,7 @@ static int autodetect_image_type(image_t *image, char *url)
        return ERROR_OK;
 }
 
-int identify_image_type(image_t *image, char *type_string, char *url)
+static int identify_image_type(struct image *image, const char *type_string, const char *url)
 {
        if (type_string)
        {
@@ -154,20 +147,24 @@ int identify_image_type(image_t *image, char *type_string, char *url)
        return ERROR_OK;
 }
 
-int image_ihex_buffer_complete(image_t *image)
+static int image_ihex_buffer_complete_inner(struct image *image, char *lpszLine, struct imagesection *section)
 {
-       image_ihex_t *ihex = image->type_private;
-       fileio_t *fileio = &ihex->fileio;
-       u32 full_address = 0x0;
-       u32 cooked_bytes;
+       struct image_ihex *ihex = image->type_private;
+       struct fileio *fileio = &ihex->fileio;
+       uint32_t full_address = 0x0;
+       uint32_t cooked_bytes;
        int i;
-       char lpszLine[1023];
 
        /* we can't determine the number of sections that we'll have to create ahead of time,
         * so we locally hold them until parsing is finished */
-       image_section_t section[IMAGE_MAX_SECTIONS];
 
-       ihex->buffer = malloc(fileio->size >> 1);
+       int filesize;
+       int retval;
+       retval = fileio_size(fileio, &filesize);
+       if (retval != ERROR_OK)
+               return retval;
+
+       ihex->buffer = malloc(filesize >> 1);
        cooked_bytes = 0x0;
        image->num_sections = 0;
        section[image->num_sections].private = &ihex->buffer[cooked_bytes];
@@ -177,23 +174,23 @@ int image_ihex_buffer_complete(image_t *image)
 
        while (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK)
        {
-               u32 count;
-               u32 address;
-               u32 record_type;
-               u32 checksum;
-               u8 cal_checksum = 0;
-               u32 bytes_read = 0;
-
-               if (sscanf(&lpszLine[bytes_read], ":%2x%4x%2x", &count, &address, &record_type) != 3)
+               uint32_t count;
+               uint32_t address;
+               uint32_t record_type;
+               uint32_t checksum;
+               uint8_t cal_checksum = 0;
+               size_t bytes_read = 0;
+
+               if (sscanf(&lpszLine[bytes_read], ":%2" SCNx32 "%4" SCNx32 "%2" SCNx32 , &count, &address, &record_type) != 3)
                {
                        return ERROR_IMAGE_FORMAT_ERROR;
                }
                bytes_read += 9;
 
-               cal_checksum += (u8)count;
-               cal_checksum += (u8)(address >> 8);
-               cal_checksum += (u8)address;
-               cal_checksum += (u8)record_type;
+               cal_checksum += (uint8_t)count;
+               cal_checksum += (uint8_t)(address >> 8);
+               cal_checksum += (uint8_t)address;
+               cal_checksum += (uint8_t)record_type;
 
                if (record_type == 0) /* Data Record */
                {
@@ -206,6 +203,12 @@ int image_ihex_buffer_complete(image_t *image)
                                if (section[image->num_sections].size != 0)
                                {
                                        image->num_sections++;
+                                       if (image->num_sections >= IMAGE_MAX_SECTIONS)
+                                       {
+                                               /* too many sections */
+                                               LOG_ERROR("Too many sections found in IHEX file");
+                                               return ERROR_IMAGE_FORMAT_ERROR;
+                                       }
                                        section[image->num_sections].size = 0x0;
                                        section[image->num_sections].flags = 0;
                                        section[image->num_sections].private = &ihex->buffer[cooked_bytes];
@@ -217,8 +220,10 @@ int image_ihex_buffer_complete(image_t *image)
 
                        while (count-- > 0)
                        {
-                               sscanf(&lpszLine[bytes_read], "%2x", (u32*)&ihex->buffer[cooked_bytes]);
-                               cal_checksum += (u8)ihex->buffer[cooked_bytes];
+                               unsigned value;
+                               sscanf(&lpszLine[bytes_read], "%2x", &value);
+                               ihex->buffer[cooked_bytes] = (uint8_t)value;
+                               cal_checksum += (uint8_t)ihex->buffer[cooked_bytes];
                                bytes_read += 2;
                                cooked_bytes += 1;
                                section[image->num_sections].size += 1;
@@ -231,7 +236,7 @@ int image_ihex_buffer_complete(image_t *image)
                        image->num_sections++;
 
                        /* copy section information */
-                       image->sections = malloc(sizeof(image_section_t) * image->num_sections);
+                       image->sections = malloc(sizeof(struct imagesection) * image->num_sections);
                        for (i = 0; i < image->num_sections; i++)
                        {
                                image->sections[i].private = section[i].private;
@@ -244,11 +249,11 @@ int image_ihex_buffer_complete(image_t *image)
                }
                else if (record_type == 2) /* Linear Address Record */
                {
-                       u16 upper_address;
+                       uint16_t upper_address;
 
                        sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
-                       cal_checksum += (u8)(upper_address >> 8);
-                       cal_checksum += (u8)upper_address;
+                       cal_checksum += (uint8_t)(upper_address >> 8);
+                       cal_checksum += (uint8_t)upper_address;
                        bytes_read += 4;
 
                        if ((full_address >> 4) != upper_address)
@@ -260,6 +265,12 @@ int image_ihex_buffer_complete(image_t *image)
                                if (section[image->num_sections].size != 0)
                                {
                                        image->num_sections++;
+                                       if (image->num_sections >= IMAGE_MAX_SECTIONS)
+                                       {
+                                               /* too many sections */
+                                               LOG_ERROR("Too many sections found in IHEX file");
+                                               return ERROR_IMAGE_FORMAT_ERROR;
+                                       }
                                        section[image->num_sections].size = 0x0;
                                        section[image->num_sections].flags = 0;
                                        section[image->num_sections].private = &ihex->buffer[cooked_bytes];
@@ -271,24 +282,24 @@ int image_ihex_buffer_complete(image_t *image)
                }
                else if (record_type == 3) /* Start Segment Address Record */
                {
-                       u32 dummy;
+                       uint32_t dummy;
 
                        /* "Start Segment Address Record" will not be supported */
                        /* but we must consume it, and do not create an error.  */
                        while (count-- > 0)
                        {
-                               sscanf(&lpszLine[bytes_read], "%2x", &dummy);
-                               cal_checksum += (u8)dummy;
+                               sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &dummy);
+                               cal_checksum += (uint8_t)dummy;
                                bytes_read += 2;
                        }
                }
                else if (record_type == 4) /* Extended Linear Address Record */
                {
-                       u16 upper_address;
+                       uint16_t upper_address;
 
                        sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
-                       cal_checksum += (u8)(upper_address >> 8);
-                       cal_checksum += (u8)upper_address;
+                       cal_checksum += (uint8_t)(upper_address >> 8);
+                       cal_checksum += (uint8_t)upper_address;
                        bytes_read += 4;
 
                        if ((full_address >> 16) != upper_address)
@@ -300,6 +311,12 @@ int image_ihex_buffer_complete(image_t *image)
                                if (section[image->num_sections].size != 0)
                                {
                                        image->num_sections++;
+                                       if (image->num_sections >= IMAGE_MAX_SECTIONS)
+                                       {
+                                               /* too many sections */
+                                               LOG_ERROR("Too many sections found in IHEX file");
+                                               return ERROR_IMAGE_FORMAT_ERROR;
+                                       }
                                        section[image->num_sections].size = 0x0;
                                        section[image->num_sections].flags = 0;
                                        section[image->num_sections].private = &ihex->buffer[cooked_bytes];
@@ -311,28 +328,28 @@ int image_ihex_buffer_complete(image_t *image)
                }
                else if (record_type == 5) /* Start Linear Address Record */
                {
-                       u32 start_address;
+                       uint32_t start_address;
 
-                       sscanf(&lpszLine[bytes_read], "%8x", &start_address);
-                       cal_checksum += (u8)(start_address >> 24);
-                       cal_checksum += (u8)(start_address >> 16);
-                       cal_checksum += (u8)(start_address >> 8);
-                       cal_checksum += (u8)start_address;
+                       sscanf(&lpszLine[bytes_read], "%8" SCNx32, &start_address);
+                       cal_checksum += (uint8_t)(start_address >> 24);
+                       cal_checksum += (uint8_t)(start_address >> 16);
+                       cal_checksum += (uint8_t)(start_address >> 8);
+                       cal_checksum += (uint8_t)start_address;
                        bytes_read += 8;
 
                        image->start_address_set = 1;
-                       image->start_address = be_to_h_u32((u8*)&start_address);
+                       image->start_address = be_to_h_u32((uint8_t*)&start_address);
                }
                else
                {
-                       LOG_ERROR("unhandled IHEX record type: %i", record_type);
+                 LOG_ERROR("unhandled IHEX record type: %i", (int)record_type);
                        return ERROR_IMAGE_FORMAT_ERROR;
                }
 
-               sscanf(&lpszLine[bytes_read], "%2x", &checksum);
+               sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &checksum);
                bytes_read += 2;
 
-               if ((u8)checksum != (u8)(~cal_checksum + 1))
+               if ((uint8_t)checksum != (uint8_t)(~cal_checksum + 1))
                {
                        /* checksum failed */
                        LOG_ERROR("incorrect record checksum found in IHEX file");
@@ -344,22 +361,51 @@ int image_ihex_buffer_complete(image_t *image)
        return ERROR_IMAGE_FORMAT_ERROR;
 }
 
-int image_elf_read_headers(image_t *image)
+/**
+ * Allocate memory dynamically instead of on the stack. This
+ * is important w/embedded hosts.
+ */
+static int image_ihex_buffer_complete(struct image *image)
+{
+       char *lpszLine = malloc(1023);
+       if (lpszLine == NULL)
+       {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       struct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS);
+       if (section == NULL)
+       {
+               free(lpszLine);
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       int retval;
+
+       retval = image_ihex_buffer_complete_inner(image, lpszLine, section);
+
+       free(section);
+       free(lpszLine);
+
+       return retval;
+}
+
+static int image_elf_read_headers(struct image *image)
 {
-       image_elf_t *elf = image->type_private;
-       u32 read_bytes;
-       u32 i,j;
+       struct image_elf *elf = image->type_private;
+       size_t read_bytes;
+       uint32_t i,j;
        int retval;
 
        elf->header = malloc(sizeof(Elf32_Ehdr));
 
-       if(elf->header == NULL)
+       if (elf->header == NULL)
        {
                LOG_ERROR("insufficient memory to perform operation ");
                return ERROR_FILEIO_OPERATION_FAILED;
        }
 
-       if ((retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (u8*)elf->header, &read_bytes)) != ERROR_OK)
+       if ((retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (uint8_t*)elf->header, &read_bytes)) != ERROR_OK)
        {
                LOG_ERROR("cannot read ELF file header, read failed");
                return ERROR_FILEIO_OPERATION_FAILED;
@@ -370,7 +416,7 @@ int image_elf_read_headers(image_t *image)
                return ERROR_FILEIO_OPERATION_FAILED;
        }
 
-       if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG)!=0)
+       if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG) != 0)
        {
                LOG_ERROR("invalid ELF file, bad magic number");
                return ERROR_IMAGE_FORMAT_ERROR;
@@ -381,17 +427,16 @@ int image_elf_read_headers(image_t *image)
                return ERROR_IMAGE_FORMAT_ERROR;
        }
 
-
        elf->endianness = elf->header->e_ident[EI_DATA];
-       if ((elf->endianness!=ELFDATA2LSB)
-                &&(elf->endianness!=ELFDATA2MSB))
+       if ((elf->endianness != ELFDATA2LSB)
+                &&(elf->endianness != ELFDATA2MSB))
        {
                LOG_ERROR("invalid ELF file, unknown endianess setting");
                return ERROR_IMAGE_FORMAT_ERROR;
        }
 
        elf->segment_count = field16(elf,elf->header->e_phnum);
-       if (elf->segment_count==0)
+       if (elf->segment_count == 0)
        {
                LOG_ERROR("invalid ELF file, no program headers");
                return ERROR_IMAGE_FORMAT_ERROR;
@@ -404,13 +449,13 @@ int image_elf_read_headers(image_t *image)
        }
 
        elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
-       if(elf->segments == NULL)
+       if (elf->segments == NULL)
        {
                LOG_ERROR("insufficient memory to perform operation ");
                return ERROR_FILEIO_OPERATION_FAILED;
        }
 
-       if ((retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), (u8*)elf->segments, &read_bytes)) != ERROR_OK)
+       if ((retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), (uint8_t*)elf->segments, &read_bytes)) != ERROR_OK)
        {
                LOG_ERROR("cannot read ELF segment headers, read failed");
                return retval;
@@ -423,12 +468,12 @@ int image_elf_read_headers(image_t *image)
 
        /* count useful segments (loadable), ignore BSS section */
        image->num_sections = 0;
-       for (i=0;i<elf->segment_count;i++)
+       for (i = 0;i < elf->segment_count;i++)
                if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
                        image->num_sections++;
        /* alloc and fill sections array with loadable segments */
-       image->sections = malloc(image->num_sections * sizeof(image_section_t));
-       for (i=0,j=0;i<elf->segment_count;i++)
+       image->sections = malloc(image->num_sections * sizeof(struct imagesection));
+       for (i = 0,j = 0;i < elf->segment_count;i++)
        {
                if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
                {
@@ -446,26 +491,26 @@ int image_elf_read_headers(image_t *image)
        return ERROR_OK;
 }
 
-int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
+static int image_elf_read_section(struct image *image, int section, uint32_t offset, uint32_t size, uint8_t *buffer, size_t *size_read)
 {
-       image_elf_t *elf = image->type_private;
+       struct image_elf *elf = image->type_private;
        Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
-       u32 read_size,really_read;
+       size_t read_size,really_read;
        int retval;
 
        *size_read = 0;
 
-       LOG_DEBUG("load segment %d at 0x%x (sz=0x%x)",section,offset,size);
+       LOG_DEBUG("load segment %d at 0x%" PRIx32 " (sz = 0x%" PRIx32 ")",section,offset,size);
 
        /* read initialized data in current segment if any */
-       if (offset<field32(elf,segment->p_filesz))
+       if (offset < field32(elf,segment->p_filesz))
        {
                /* maximal size present in file for the current segment */
                read_size = MIN(size, field32(elf,segment->p_filesz)-offset);
-               LOG_DEBUG("read elf: size = 0x%x at 0x%x",read_size,
-                       field32(elf,segment->p_offset)+offset);
+               LOG_DEBUG("read elf: size = 0x%zu at 0x%" PRIx32 "", read_size,
+                       field32(elf,segment->p_offset) + offset);
                /* read initialized area of the segment */
-               if ((retval = fileio_seek(&elf->fileio, field32(elf,segment->p_offset)+offset)) != ERROR_OK)
+               if ((retval = fileio_seek(&elf->fileio, field32(elf,segment->p_offset) + offset)) != ERROR_OK)
                {
                        LOG_ERROR("cannot find ELF segment content, seek failed");
                        return retval;
@@ -487,20 +532,24 @@ int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8
        return ERROR_OK;
 }
 
-int image_mot_buffer_complete(image_t *image)
+static int image_mot_buffer_complete_inner(struct image *image, char *lpszLine, struct imagesection *section)
 {
-       image_mot_t *mot = image->type_private;
-       fileio_t *fileio = &mot->fileio;
-       u32 full_address = 0x0;
-       u32 cooked_bytes;
+       struct image_mot *mot = image->type_private;
+       struct fileio *fileio = &mot->fileio;
+       uint32_t full_address = 0x0;
+       uint32_t cooked_bytes;
        int i;
-       char lpszLine[1023];
 
        /* we can't determine the number of sections that we'll have to create ahead of time,
         * so we locally hold them until parsing is finished */
-       image_section_t section[IMAGE_MAX_SECTIONS];
 
-       mot->buffer = malloc(fileio->size >> 1);
+       int retval;
+       int filesize;
+       retval = fileio_size(fileio, &filesize);
+       if (retval != ERROR_OK)
+               return retval;
+
+       mot->buffer = malloc(filesize >> 1);
        cooked_bytes = 0x0;
        image->num_sections = 0;
        section[image->num_sections].private = &mot->buffer[cooked_bytes];
@@ -510,21 +559,21 @@ int image_mot_buffer_complete(image_t *image)
 
        while (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK)
        {
-               u32 count;
-               u32 address;
-               u32 record_type;
-               u32 checksum;
-               u8 cal_checksum = 0;
-               u32 bytes_read = 0;
+               uint32_t count;
+               uint32_t address;
+               uint32_t record_type;
+               uint32_t checksum;
+               uint8_t cal_checksum = 0;
+               uint32_t bytes_read = 0;
 
                /* get record type and record length */
-               if (sscanf(&lpszLine[bytes_read], "S%1x%2x", &record_type, &count) != 2)
+               if (sscanf(&lpszLine[bytes_read], "S%1" SCNx32 "%2" SCNx32 , &record_type, &count) != 2)
                {
                        return ERROR_IMAGE_FORMAT_ERROR;
                }
 
                bytes_read += 4;
-               cal_checksum += (u8)count;
+               cal_checksum += (uint8_t)count;
 
                /* skip checksum byte */
                count -=1;
@@ -536,40 +585,40 @@ int image_mot_buffer_complete(image_t *image)
 
                        while (count-- > 0) {
                                sscanf(&lpszLine[bytes_read], "%2x", &iValue);
-                               cal_checksum += (u8)iValue;
+                               cal_checksum += (uint8_t)iValue;
                                bytes_read += 2;
                        }
                }
                else if (record_type >= 1 && record_type <= 3)
                {
-                       switch( record_type )
+                       switch (record_type)
                        {
                                case 1:
                                        /* S1 - 16 bit address data record */
-                                       sscanf(&lpszLine[bytes_read], "%4x", &address);
-                                       cal_checksum += (u8)(address >> 8);
-                                       cal_checksum += (u8)address;
+                                       sscanf(&lpszLine[bytes_read], "%4" SCNx32, &address);
+                                       cal_checksum += (uint8_t)(address >> 8);
+                                       cal_checksum += (uint8_t)address;
                                        bytes_read += 4;
                                        count -=2;
                                        break;
 
                                case 2:
                                        /* S2 - 24 bit address data record */
-                                       sscanf(&lpszLine[bytes_read], "%6x", &address);
-                                       cal_checksum += (u8)(address >> 16);
-                                       cal_checksum += (u8)(address >> 8);
-                                       cal_checksum += (u8)address;
+                                       sscanf(&lpszLine[bytes_read], "%6" SCNx32 , &address);
+                                       cal_checksum += (uint8_t)(address >> 16);
+                                       cal_checksum += (uint8_t)(address >> 8);
+                                       cal_checksum += (uint8_t)address;
                                        bytes_read += 6;
                                        count -=3;
                                        break;
 
                                case 3:
                                        /* S3 - 32 bit address data record */
-                                       sscanf(&lpszLine[bytes_read], "%8x", &address);
-                                       cal_checksum += (u8)(address >> 24);
-                                       cal_checksum += (u8)(address >> 16);
-                                       cal_checksum += (u8)(address >> 8);
-                                       cal_checksum += (u8)address;
+                                       sscanf(&lpszLine[bytes_read], "%8" SCNx32 , &address);
+                                       cal_checksum += (uint8_t)(address >> 24);
+                                       cal_checksum += (uint8_t)(address >> 16);
+                                       cal_checksum += (uint8_t)(address >> 8);
+                                       cal_checksum += (uint8_t)address;
                                        bytes_read += 8;
                                        count -=4;
                                        break;
@@ -595,8 +644,10 @@ int image_mot_buffer_complete(image_t *image)
 
                        while (count-- > 0)
                        {
-                               sscanf(&lpszLine[bytes_read], "%2x", (u32*)&mot->buffer[cooked_bytes]);
-                               cal_checksum += (u8)mot->buffer[cooked_bytes];
+                               unsigned value;
+                               sscanf(&lpszLine[bytes_read], "%2x", &value);
+                               mot->buffer[cooked_bytes] = (uint8_t)value;
+                               cal_checksum += (uint8_t)mot->buffer[cooked_bytes];
                                bytes_read += 2;
                                cooked_bytes += 1;
                                section[image->num_sections].size += 1;
@@ -606,12 +657,12 @@ int image_mot_buffer_complete(image_t *image)
                else if (record_type == 5)
                {
                        /* S5 is the data count record, we ignore it */
-                       u32 dummy;
+                       uint32_t dummy;
 
                        while (count-- > 0)
                        {
-                               sscanf(&lpszLine[bytes_read], "%2x", &dummy);
-                               cal_checksum += (u8)dummy;
+                               sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &dummy);
+                               cal_checksum += (uint8_t)dummy;
                                bytes_read += 2;
                        }
                }
@@ -621,7 +672,7 @@ int image_mot_buffer_complete(image_t *image)
                        image->num_sections++;
 
                        /* copy section information */
-                       image->sections = malloc(sizeof(image_section_t) * image->num_sections);
+                       image->sections = malloc(sizeof(struct imagesection) * image->num_sections);
                        for (i = 0; i < image->num_sections; i++)
                        {
                                image->sections[i].private = section[i].private;
@@ -634,16 +685,16 @@ int image_mot_buffer_complete(image_t *image)
                }
                else
                {
-                       LOG_ERROR("unhandled S19 record type: %i", record_type);
+                 LOG_ERROR("unhandled S19 record type: %i", (int)(record_type));
                        return ERROR_IMAGE_FORMAT_ERROR;
                }
 
                /* account for checksum, will always be 0xFF */
-               sscanf(&lpszLine[bytes_read], "%2x", &checksum);
-               cal_checksum += (u8)checksum;
+               sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &checksum);
+               cal_checksum += (uint8_t)checksum;
                bytes_read += 2;
 
-               if( cal_checksum != 0xFF )
+               if (cal_checksum != 0xFF)
                {
                        /* checksum failed */
                        LOG_ERROR("incorrect record checksum found in S19 file");
@@ -655,7 +706,37 @@ int image_mot_buffer_complete(image_t *image)
        return ERROR_IMAGE_FORMAT_ERROR;
 }
 
-int image_open(image_t *image, char *url, char *type_string)
+/**
+ * Allocate memory dynamically instead of on the stack. This
+ * is important w/embedded hosts.
+ */
+static int image_mot_buffer_complete(struct image *image)
+{
+       char *lpszLine = malloc(1023);
+       if (lpszLine == NULL)
+       {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       struct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS);
+       if (section == NULL)
+       {
+               free(lpszLine);
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       int retval;
+
+       retval = image_mot_buffer_complete_inner(image, lpszLine, section);
+
+       free(section);
+       free(lpszLine);
+
+       return retval;
+}
+
+
+int image_open(struct image *image, const char *url, const char *type_string)
 {
        int retval = ERROR_OK;
 
@@ -666,26 +747,33 @@ int image_open(image_t *image, char *url, char *type_string)
 
        if (image->type == IMAGE_BINARY)
        {
-               image_binary_t *image_binary;
+               struct image_binary *image_binary;
 
-               image_binary = image->type_private = malloc(sizeof(image_binary_t));
+               image_binary = image->type_private = malloc(sizeof(struct image_binary));
 
                if ((retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
                {
                        return retval;
                }
+               int filesize;
+               retval = fileio_size(&image_binary->fileio, &filesize);
+               if (retval != ERROR_OK)
+               {
+                       fileio_close(&image_binary->fileio);
+                       return retval;
+               }
 
                image->num_sections = 1;
-               image->sections = malloc(sizeof(image_section_t));
+               image->sections = malloc(sizeof(struct imagesection));
                image->sections[0].base_address = 0x0;
-               image->sections[0].size = image_binary->fileio.size;
+               image->sections[0].size = filesize;
                image->sections[0].flags = 0;
        }
        else if (image->type == IMAGE_IHEX)
        {
-               image_ihex_t *image_ihex;
+               struct image_ihex *image_ihex;
 
-               image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
+               image_ihex = image->type_private = malloc(sizeof(struct image_ihex));
 
                if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
                {
@@ -701,9 +789,9 @@ int image_open(image_t *image, char *url, char *type_string)
        }
        else if (image->type == IMAGE_ELF)
        {
-               image_elf_t *image_elf;
+               struct image_elf *image_elf;
 
-               image_elf = image->type_private = malloc(sizeof(image_elf_t));
+               image_elf = image->type_private = malloc(sizeof(struct image_elf));
 
                if ((retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
                {
@@ -718,25 +806,33 @@ int image_open(image_t *image, char *url, char *type_string)
        }
        else if (image->type == IMAGE_MEMORY)
        {
-               image_memory_t *image_memory;
+               struct target *target = get_target(url);
+
+               if (target == NULL)
+               {
+                       LOG_ERROR("target '%s' not defined", url);
+                       return ERROR_FAIL;
+               }
+
+               struct image_memory *image_memory;
 
                image->num_sections = 1;
-               image->sections = malloc(sizeof(image_section_t));
+               image->sections = malloc(sizeof(struct imagesection));
                image->sections[0].base_address = 0x0;
                image->sections[0].size = 0xffffffff;
                image->sections[0].flags = 0;
 
-               image_memory = image->type_private = malloc(sizeof(image_memory_t));
+               image_memory = image->type_private = malloc(sizeof(struct image_memory));
 
-               image_memory->target = get_target_by_num(strtoul(url, NULL, 0));;
+               image_memory->target = target;
                image_memory->cache = NULL;
                image_memory->cache_address = 0x0;
        }
        else if (image->type == IMAGE_SRECORD)
        {
-               image_mot_t *image_mot;
+               struct image_mot *image_mot;
 
-               image_mot = image->type_private = malloc(sizeof(image_mot_t));
+               image_mot = image->type_private = malloc(sizeof(struct image_mot));
 
                if ((retval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
                {
@@ -761,35 +857,35 @@ int image_open(image_t *image, char *url, char *type_string)
        {
                /* relocate */
                int section;
-               for (section=0; section < image->num_sections; section++)
+               for (section = 0; section < image->num_sections; section++)
                {
-                       image->sections[section].base_address+=image->base_address;
+                       image->sections[section].base_address += image->base_address;
                }
                /* we're done relocating. The two statements below are mainly
                 * for documenation purposes: stop anyone from empirically
                 * thinking they should use these values henceforth. */
-               image->base_address=0;
-               image->base_address_set=0;
+               image->base_address = 0;
+               image->base_address_set = 0;
        }
 
        return retval;
 };
 
-int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
+int image_read_section(struct image *image, int section, uint32_t offset, uint32_t size, uint8_t *buffer, size_t *size_read)
 {
        int retval;
 
        /* don't read past the end of a section */
        if (offset + size > image->sections[section].size)
        {
-               LOG_DEBUG("read past end of section: 0x%8.8x + 0x%8.8x > 0x%8.8x",
+               LOG_DEBUG("read past end of section: 0x%8.8" PRIx32 " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "",
                                offset, size, image->sections[section].size);
                return ERROR_INVALID_ARGUMENTS;
        }
 
        if (image->type == IMAGE_BINARY)
        {
-               image_binary_t *image_binary = image->type_private;
+               struct image_binary *image_binary = image->type_private;
 
                /* only one section in a plain binary */
                if (section != 0)
@@ -809,7 +905,7 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
        }
        else if (image->type == IMAGE_IHEX)
        {
-               memcpy(buffer, (u8*)image->sections[section].private + offset, size);
+               memcpy(buffer, (uint8_t*)image->sections[section].private + offset, size);
                *size_read = size;
 
                return ERROR_OK;
@@ -820,14 +916,14 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
        }
        else if (image->type == IMAGE_MEMORY)
        {
-               image_memory_t *image_memory = image->type_private;
-               u32 address = image->sections[section].base_address + offset;
+               struct image_memory *image_memory = image->type_private;
+               uint32_t address = image->sections[section].base_address + offset;
 
                *size_read = 0;
 
                while ((size - *size_read) > 0)
                {
-                       u32 size_in_cache;
+                       uint32_t size_in_cache;
 
                        if (!image_memory->cache
                                || (address < image_memory->cache_address)
@@ -851,7 +947,7 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
                        memcpy(buffer + *size_read,
                                image_memory->cache + (address - image_memory->cache_address),
                                (size_in_cache > size) ? size : size_in_cache
-                               );
+);
 
                        *size_read += (size_in_cache > size) ? size : size_in_cache;
                        address += (size_in_cache > size) ? size : size_in_cache;
@@ -859,14 +955,14 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
        }
        else if (image->type == IMAGE_SRECORD)
        {
-               memcpy(buffer, (u8*)image->sections[section].private + offset, size);
+               memcpy(buffer, (uint8_t*)image->sections[section].private + offset, size);
                *size_read = size;
 
                return ERROR_OK;
        }
        else if (image->type == IMAGE_BUILDER)
        {
-               memcpy(buffer, (u8*)image->sections[section].private + offset, size);
+               memcpy(buffer, (uint8_t*)image->sections[section].private + offset, size);
                *size_read = size;
 
                return ERROR_OK;
@@ -875,9 +971,9 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
        return ERROR_OK;
 }
 
-int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data)
+int image_add_section(struct image *image, uint32_t base, uint32_t size, int flags, uint8_t *data)
 {
-       image_section_t *section;
+       struct imagesection *section;
 
        /* only image builder supports adding sections */
        if (image->type != IMAGE_BUILDER)
@@ -893,7 +989,7 @@ int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data)
                if (((section->base_address + section->size) == base) && (section->flags == flags))
                {
                        section->private = realloc(section->private, section->size + size);
-                       memcpy((u8*)section->private + section->size, data, size);
+                       memcpy((uint8_t*)section->private + section->size, data, size);
                        section->size += size;
                        return ERROR_OK;
                }
@@ -901,28 +997,28 @@ int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data)
 
        /* allocate new section */
        image->num_sections++;
-       image->sections = realloc(image->sections, sizeof(image_section_t) * image->num_sections);
+       image->sections = realloc(image->sections, sizeof(struct imagesection) * image->num_sections);
        section = &image->sections[image->num_sections - 1];
        section->base_address = base;
        section->size = size;
        section->flags = flags;
-       section->private = malloc(sizeof(u8) * size);
-       memcpy((u8*)section->private, data, size);
+       section->private = malloc(sizeof(uint8_t) * size);
+       memcpy((uint8_t*)section->private, data, size);
 
        return ERROR_OK;
 }
 
-int image_close(image_t *image)
+void image_close(struct image *image)
 {
        if (image->type == IMAGE_BINARY)
        {
-               image_binary_t *image_binary = image->type_private;
+               struct image_binary *image_binary = image->type_private;
 
                fileio_close(&image_binary->fileio);
        }
        else if (image->type == IMAGE_IHEX)
        {
-               image_ihex_t *image_ihex = image->type_private;
+               struct image_ihex *image_ihex = image->type_private;
 
                fileio_close(&image_ihex->fileio);
 
@@ -934,7 +1030,7 @@ int image_close(image_t *image)
        }
        else if (image->type == IMAGE_ELF)
        {
-               image_elf_t *image_elf = image->type_private;
+               struct image_elf *image_elf = image->type_private;
 
                fileio_close(&image_elf->fileio);
 
@@ -952,7 +1048,7 @@ int image_close(image_t *image)
        }
        else if (image->type == IMAGE_MEMORY)
        {
-               image_memory_t *image_memory = image->type_private;
+               struct image_memory *image_memory = image->type_private;
 
                if (image_memory->cache)
                {
@@ -962,7 +1058,7 @@ int image_close(image_t *image)
        }
        else if (image->type == IMAGE_SRECORD)
        {
-               image_mot_t *image_mot = image->type_private;
+               struct image_mot *image_mot = image->type_private;
 
                fileio_close(&image_mot->fileio);
 
@@ -994,17 +1090,17 @@ int image_close(image_t *image)
                free(image->sections);
                image->sections = NULL;
        }
-
-       return ERROR_OK;
 }
 
-static u32 crc32_table[256] = {0, 0};
-
-int image_calculate_checksum(u8* buffer, u32 nbytes, u32* checksum)
+int image_calculate_checksum(uint8_t* buffer, uint32_t nbytes, uint32_t* checksum)
 {
-       u32 crc = 0xffffffff;
+       uint32_t crc = 0xffffffff;
+       LOG_DEBUG("Calculating checksum");
+
+       static uint32_t crc32_table[256];
 
-       if (!crc32_table[1])
+       static bool first_init = false;
+       if (!first_init)
        {
                /* Initialize the CRC table and the decoding table.  */
                int i, j;
@@ -1016,20 +1112,28 @@ int image_calculate_checksum(u8* buffer, u32 nbytes, u32* checksum)
                                c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
                        crc32_table[i] = c;
                }
+
+               first_init = true;
        }
 
-       while (nbytes--)
+       while (nbytes > 0)
        {
-               /* as per gdb */
-               crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
-               if ((nbytes%16384)==0)
+               int run = nbytes;
+               if (run > 32768)
+               {
+                       run = 32768;
+               }
+               nbytes -= run;
+               while (run--)
                {
-                       keep_alive();
+                       /* as per gdb */
+                       crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
                }
+               keep_alive();
        }
 
+       LOG_DEBUG("Calculating checksum done");
+
        *checksum = crc;
        return ERROR_OK;
 }
-
-

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)