#include "target.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))
+#define field16(elf, field)\
+ ((elf->endianness == ELFDATA2LSB)? \
+ le_to_h_u16((u8*)&field) : be_to_h_u16((u8*)&field))
-#define field32(elf,field)\
- ((elf->endianness==ELFDATA2LSB)? \
- le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
+#define field32(elf, field)\
+ ((elf->endianness == ELFDATA2LSB)? \
+ le_to_h_u32((u8*)&field) : be_to_h_u32((u8*)&field))
static int autodetect_image_type(image_t *image, char *url)
{
DEBUG("ELF image detected.");
image->type = IMAGE_ELF;
}
- else if ((buffer[0]==':') /* record start byte */
+ 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'))
+ &&(buffer[7] == '0') /* record type : 00 -> 05 */
+ &&(buffer[8] >= '0') && (buffer[8] < '6'))
{
DEBUG("IHEX image detected.");
image->type = IMAGE_IHEX;
for (i = 0; i < image->num_sections; i++)
{
image->sections[i].private = section[i].private;
- image->sections[i].base_address = section[i].base_address +
- ((image->base_address_set) ? image->base_address : 0);
+ image->sections[i].base_address = section[i].base_address;
image->sections[i].size = section[i].size;
image->sections[i].flags = section[i].flags;
}
full_address = (full_address & 0xffff) | (upper_address << 4);
}
}
+ else if (record_type == 3) /* Start Segment Address Record */
+ {
+ u32 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;
+ bytes_read += 2;
+ }
+ }
else if (record_type == 4) /* Extended Linear Address Record */
{
u16 upper_address;
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)
{
ERROR("invalid ELF file, bad magic number");
return ERROR_IMAGE_FORMAT_ERROR;
}
- if (elf->header->e_ident[EI_CLASS]!=ELFCLASS32)
+ if (elf->header->e_ident[EI_CLASS] != ELFCLASS32)
{
ERROR("invalid ELF file, only 32bits files are supported");
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))
{
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)
+ elf->segment_count = field16(elf, elf->header->e_phnum);
+ if (elf->segment_count == 0)
{
ERROR("invalid ELF file, no program headers");
return ERROR_IMAGE_FORMAT_ERROR;
}
- elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
+ elf->segments = malloc(elf->segment_count * sizeof(Elf32_Phdr));
- 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), (u8*)elf->segments, &read_bytes)) != ERROR_OK)
{
ERROR("cannot read ELF segment headers, read failed");
return retval;
}
- if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr))
+ if (read_bytes != elf->segment_count * sizeof(Elf32_Phdr))
{
ERROR("cannot read ELF segment headers, only partially read");
return ERROR_FILEIO_OPERATION_FAILED;
/* 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++)
+ 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))
{
- image->sections[j].size = field32(elf,elf->segments[i].p_memsz);
- image->sections[j].base_address = field32(elf,elf->segments[i].p_paddr);
+ image->sections[j].size = field32(elf, elf->segments[i].p_memsz);
+ image->sections[j].base_address = field32(elf, elf->segments[i].p_paddr);
image->sections[j].private = &elf->segments[i];
- image->sections[j].flags = field32(elf,elf->segments[i].p_flags);
+ image->sections[j].flags = field32(elf, elf->segments[i].p_flags);
j++;
}
}
image->start_address_set = 1;
- image->start_address = field32(elf,elf->header->e_entry);
+ image->start_address = field32(elf, elf->header->e_entry);
return ERROR_OK;
}
{
image_elf_t *elf = image->type_private;
Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
- u32 read_size,really_read;
+ u32 read_size, really_read;
int retval;
*size_read = 0;
- DEBUG("load segment %d at 0x%x (sz=0x%x)",section,offset,size);
+ DEBUG("load segment %d at 0x%x (sz = 0x%x)", 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);
- DEBUG("read elf: size = 0x%x at 0x%x",read_size,
- field32(elf,segment->p_offset)+offset);
+ read_size = MIN(size, field32(elf, segment->p_filesz) - offset);
+ DEBUG("read elf: size = 0x%x at 0x%x", 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)
{
ERROR("cannot find ELF segment content, seek failed");
return retval;
if (!size)
return ERROR_OK;
}
- /* if there is remaining zeroed area in current segment */
- if (offset<field32(elf,segment->p_memsz))
- {
- /* fill zeroed part (BSS) of the segment */
- read_size = MIN(size, field32(elf,segment->p_memsz)-offset);
- DEBUG("zero fill: size = 0x%x",read_size);
- memset(buffer,0,read_size);
- *size_read += read_size;
- }
-
+
return ERROR_OK;
}
bytes_read += 8;
count -=4;
break;
-
}
if (full_address != address)
full_address++;
}
}
+ else if (record_type == 5)
+ {
+ /* S5 is the data count record, we ignore it */
+ u32 dummy;
+
+ while (count-- > 0)
+ {
+ sscanf(&lpszLine[bytes_read], "%2x", &dummy);
+ cal_checksum += (u8)dummy;
+ bytes_read += 2;
+ }
+ }
else if (record_type >= 7 && record_type <= 9)
{
/* S7, S8, S9 - ending records for 32, 24 and 16bit */
for (i = 0; i < image->num_sections; i++)
{
image->sections[i].private = section[i].private;
- image->sections[i].base_address = section[i].base_address +
- ((image->base_address_set) ? image->base_address : 0);
+ image->sections[i].base_address = section[i].base_address;
image->sections[i].size = section[i].size;
image->sections[i].flags = section[i].flags;
}
image->sections[0].base_address = 0x0;
image->sections[0].size = image_binary->fileio.size;
image->sections[0].flags = 0;
-
- if (image->base_address_set == 1)
- image->sections[0].base_address = image->base_address;
-
- return ERROR_OK;
}
else if (image->type == IMAGE_IHEX)
{
image->sections = NULL;
image->type_private = NULL;
}
+
+ if (image->base_address_set)
+ {
+ /* relocate */
+ int section;
+ for (section = 0; section < image->num_sections; section++)
+ {
+ 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;
+ }
return retval;
};
IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK)
{
free(image_memory->cache);
+ image_memory->cache = NULL;
return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
}
image_memory->cache_address = address & ~(IMAGE_MEMORY_CACHE_SIZE - 1);
fileio_close(&image_ihex->fileio);
if (image_ihex->buffer)
+ {
free(image_ihex->buffer);
+ image_ihex->buffer = NULL;
+ }
}
else if (image->type == IMAGE_ELF)
{
image_elf_t *image_elf = image->type_private;
fileio_close(&image_elf->fileio);
-
+
if (image_elf->header)
+ {
free(image_elf->header);
+ image_elf->header = NULL;
+ }
if (image_elf->segments)
+ {
free(image_elf->segments);
+ image_elf->segments = NULL;
+ }
}
else if (image->type == IMAGE_MEMORY)
{
image_memory_t *image_memory = image->type_private;
if (image_memory->cache)
+ {
free(image_memory->cache);
+ image_memory->cache = NULL;
+ }
}
else if (image->type == IMAGE_SRECORD)
{
fileio_close(&image_mot->fileio);
if (image_mot->buffer)
+ {
free(image_mot->buffer);
+ image_mot->buffer = NULL;
+ }
}
else if (image->type == IMAGE_BUILDER)
{
for (i = 0; i < image->num_sections; i++)
{
free(image->sections[i].private);
+ image->sections[i].private = NULL;
}
}
if (image->type_private)
+ {
free(image->type_private);
+ image->type_private = NULL;
+ }
if (image->sections)
+ {
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)
+{
+ u32 crc = 0xffffffff;
+
+ if (!crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned int c;
+ for (i = 0; i < 256; i++)
+ {
+ /* as per gdb */
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (nbytes--)
+ {
+ /* as per gdb */
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
+ }
+
+ *checksum = crc;
+ return ERROR_OK;
+}
+
+