+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+ struct imageection *section = malloc(sizeof(struct imageection) * 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)
+{
+ 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)
+ {
+ LOG_ERROR("insufficient memory to perform operation ");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ 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;
+ }
+ if (read_bytes != sizeof(Elf32_Ehdr))
+ {
+ LOG_ERROR("cannot read ELF file header, only partially read");
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+
+ if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG) != 0)
+ {
+ LOG_ERROR("invalid ELF file, bad magic number");
+ return ERROR_IMAGE_FORMAT_ERROR;
+ }
+ if (elf->header->e_ident[EI_CLASS]!=ELFCLASS32)
+ {
+ LOG_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))
+ {
+ 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)
+ {
+ LOG_ERROR("invalid ELF file, no program headers");
+ return ERROR_IMAGE_FORMAT_ERROR;
+ }
+
+ if ((retval = fileio_seek(&elf->fileio, field32(elf,elf->header->e_phoff))) != ERROR_OK)
+ {
+ LOG_ERROR("cannot seek to ELF program header table, read failed");
+ return retval;
+ }
+
+ elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
+ 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), (uint8_t*)elf->segments, &read_bytes)) != ERROR_OK)
+ {
+ LOG_ERROR("cannot read ELF segment headers, read failed");
+ return retval;
+ }
+ if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr))
+ {
+ LOG_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++)
+ 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(struct imageection));
+ 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_filesz);
+ 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);
+ j++;
+ }
+ }
+
+ image->start_address_set = 1;
+ image->start_address = field32(elf,elf->header->e_entry);
+
+ return ERROR_OK;
+}
+
+static int image_elf_read_section(struct image *image, int section, uint32_t offset, uint32_t size, uint8_t *buffer, size_t *size_read)
+{
+ struct image_elf *elf = image->type_private;
+ Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
+ size_t read_size,really_read;
+ int retval;
+
+ *size_read = 0;
+
+ 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))
+ {
+ /* 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%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)