/* 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 */
- ihex->buffer = malloc(fileio_size(fileio) >> 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];
size_t read_bytes;
uint32_t i,j;
int retval;
+ uint32_t nload,load_to_vaddr=0;
elf->header = malloc(sizeof(Elf32_Ehdr));
if ((elf->endianness != ELFDATA2LSB)
&&(elf->endianness != ELFDATA2MSB))
{
- LOG_ERROR("invalid ELF file, unknown endianess setting");
+ LOG_ERROR("invalid ELF file, unknown endianness setting");
return ERROR_IMAGE_FORMAT_ERROR;
}
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++;
+
+ assert(image->num_sections > 0);
+
+ /**
+ * some ELF linkers produce binaries with *all* the program header
+ * p_paddr fields zero (there can be however one loadable segment
+ * that has valid physical address 0x0).
+ * If we have such a binary with more than
+ * one PT_LOAD header, then use p_vaddr instead of p_paddr
+ * (ARM ELF standard demands p_paddr = 0 anyway, and BFD
+ * library uses this approach to workaround zero-initialized p_paddrs
+ * when obtaining lma - look at elf.c of BDF)
+ */
+ for (nload = 0, i = 0; i < elf->segment_count; i++)
+ if (elf->segments[i].p_paddr != 0)
+ break;
+ else if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_memsz) != 0))
+ ++nload;
+
+ if (i >= elf->segment_count && nload > 1)
+ load_to_vaddr = 1;
+
/* alloc and fill sections array with loadable segments */
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))
{
image->sections[j].size = field32(elf,elf->segments[i].p_filesz);
- image->sections[j].base_address = field32(elf,elf->segments[i].p_paddr);
+ if (load_to_vaddr)
+ image->sections[j].base_address = field32(elf,elf->segments[i].p_vaddr);
+ else
+ 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++;
/* 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 */
- mot->buffer = malloc(fileio_size(fileio) >> 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];
{
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(struct imagesection));
image->sections[0].base_address = 0x0;
- image->sections[0].size = fileio_size(&image_binary->fileio);
+ image->sections[0].size = filesize;
image->sections[0].flags = 0;
}
else if (image->type == IMAGE_IHEX)