X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fimage.c;h=c0aabecd5838cf47c3628053fbc81292da90a643;hp=454fc6c183baa8ed8e4f1de039c5dbd11989150e;hb=3a550e5b5fe011e526b150a5d234b48e8e2aaad6;hpb=33a17fd35995a7f679f92600055a8f55ae380022 diff --git a/src/target/image.c b/src/target/image.c index 454fc6c183..c0aabecd58 100644 --- a/src/target/image.c +++ b/src/target/image.c @@ -347,7 +347,6 @@ static int image_ihex_buffer_complete_inner(struct image *image, char *lpszLine, } sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &checksum); - bytes_read += 2; if ((uint8_t)checksum != (uint8_t)(~cal_checksum + 1)) { @@ -396,6 +395,7 @@ static int image_elf_read_headers(struct image *image) size_t read_bytes; uint32_t i,j; int retval; + uint32_t nload,load_to_vaddr=0; elf->header = malloc(sizeof(Elf32_Ehdr)); @@ -471,6 +471,28 @@ static int image_elf_read_headers(struct image *image) 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++) @@ -478,7 +500,10 @@ static int image_elf_read_headers(struct image *image) 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++; @@ -520,9 +545,7 @@ static int image_elf_read_section(struct image *image, int section, uint32_t off LOG_ERROR("cannot read ELF segment content, read failed"); return retval; } - buffer += read_size; size -= read_size; - offset += read_size; *size_read += read_size; /* need more data ? */ if (!size) @@ -692,7 +715,6 @@ static int image_mot_buffer_complete_inner(struct image *image, char *lpszLine, /* account for checksum, will always be 0xFF */ sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &checksum); cal_checksum += (uint8_t)checksum; - bytes_read += 2; if (cal_checksum != 0xFF) { @@ -880,7 +902,7 @@ int image_read_section(struct image *image, int section, uint32_t offset, uint32 { 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; + return ERROR_COMMAND_SYNTAX_ERROR; } if (image->type == IMAGE_BINARY) @@ -889,7 +911,7 @@ int image_read_section(struct image *image, int section, uint32_t offset, uint32 /* only one section in a plain binary */ if (section != 0) - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; /* seek to offset */ if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK) @@ -977,7 +999,7 @@ int image_add_section(struct image *image, uint32_t base, uint32_t size, int fla /* only image builder supports adding sections */ if (image->type != IMAGE_BUILDER) - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; /* see if there's a previous section */ if (image->num_sections)