diff options
author | Antonio Borneo <borneo.antonio@gmail.com> | 2023-05-06 11:44:53 +0200 |
---|---|---|
committer | Antonio Borneo <borneo.antonio@gmail.com> | 2023-05-27 06:38:12 +0000 |
commit | 144d940a8b0276d2ecb97ee6615d8a78faf4117d (patch) | |
tree | 6fbe8a4ef408b3ce4bf881d8c6d637d26227d7ce | |
parent | a5d34202c6880bc9b8d0b326628ba1f2e5b061ff (diff) | |
download | riscv-openocd-144d940a8b0276d2ecb97ee6615d8a78faf4117d.zip riscv-openocd-144d940a8b0276d2ecb97ee6615d8a78faf4117d.tar.gz riscv-openocd-144d940a8b0276d2ecb97ee6615d8a78faf4117d.tar.bz2 |
Revert "target/image: zero-initialize ELF segments up to p_memsz"
This reverts commit 047b1a8fc237af480e3bab66a9827a358afd7547.
Commit 047b1a8fc237 ("target/image: zero-initialize ELF segments
up to p_memsz") breaks the backward compatibility introducing some
problem:
- an empty bss segment with paddr in SRAM gets zero filled at load
but does not survive after a reset, causing verify to fail;
- an empty bss segment with paddr in FLASH causes excessive flash
usage, which can exceed flash size (causing error) and makes
flash aging faster.
Revert it while looking for a better implementation.
Change-Id: Iaaf926dafce46a220a5bbe20c8576eb449996d76
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reported-by: Marian Buschsieweke <marian.buschsieweke@ovgu.de>
Reviewed-on: https://review.openocd.org/c/openocd/+/7658
Reviewed-by: Bohdan Tymkiv <bohdan200@gmail.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-by: Nemui Trinomius <nemuisan_kawausogasuki@live.jp>
Reviewed-by: Peter Collingbourne <pcc@google.com>
Tested-by: jenkins
-rw-r--r-- | src/target/image.c | 54 |
1 files changed, 20 insertions, 34 deletions
diff --git a/src/target/image.c b/src/target/image.c index 6aa609d..f8de7a2 100644 --- a/src/target/image.c +++ b/src/target/image.c @@ -407,10 +407,12 @@ static int image_elf32_read_headers(struct image *image) return ERROR_FILEIO_OPERATION_FAILED; } - /* count useful segments (loadable) */ + /* count useful segments (loadable), ignore BSS section */ image->num_sections = 0; for (i = 0; i < elf->segment_count; i++) - if (field32(elf, elf->segments32[i].p_type) == PT_LOAD) + if ((field32(elf, + elf->segments32[i].p_type) == PT_LOAD) && + (field32(elf, elf->segments32[i].p_filesz) != 0)) image->num_sections++; if (image->num_sections == 0) { @@ -447,8 +449,10 @@ static int image_elf32_read_headers(struct image *image) } for (i = 0, j = 0; i < elf->segment_count; i++) { - if (field32(elf, elf->segments32[i].p_type) == PT_LOAD) { - image->sections[j].size = field32(elf, elf->segments32[i].p_memsz); + if ((field32(elf, + elf->segments32[i].p_type) == PT_LOAD) && + (field32(elf, elf->segments32[i].p_filesz) != 0)) { + image->sections[j].size = field32(elf, elf->segments32[i].p_filesz); if (load_to_vaddr) image->sections[j].base_address = field32(elf, elf->segments32[i].p_vaddr); @@ -528,10 +532,12 @@ static int image_elf64_read_headers(struct image *image) return ERROR_FILEIO_OPERATION_FAILED; } - /* count useful segments (loadable) */ + /* count useful segments (loadable), ignore BSS section */ image->num_sections = 0; for (i = 0; i < elf->segment_count; i++) - if (field32(elf, elf->segments64[i].p_type) == PT_LOAD) + if ((field32(elf, + elf->segments64[i].p_type) == PT_LOAD) && + (field64(elf, elf->segments64[i].p_filesz) != 0)) image->num_sections++; if (image->num_sections == 0) { @@ -568,8 +574,10 @@ static int image_elf64_read_headers(struct image *image) } for (i = 0, j = 0; i < elf->segment_count; i++) { - if (field32(elf, elf->segments64[i].p_type) == PT_LOAD) { - image->sections[j].size = field64(elf, elf->segments64[i].p_memsz); + if ((field32(elf, + elf->segments64[i].p_type) == PT_LOAD) && + (field64(elf, elf->segments64[i].p_filesz) != 0)) { + image->sections[j].size = field64(elf, elf->segments64[i].p_filesz); if (load_to_vaddr) image->sections[j].base_address = field64(elf, elf->segments64[i].p_vaddr); @@ -643,8 +651,6 @@ static int image_elf32_read_section(struct image *image, { struct image_elf *elf = image->type_private; Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private; - uint32_t filesz = field32(elf, segment->p_filesz); - uint32_t memsz = field32(elf, segment->p_memsz); size_t read_size, really_read; int retval; @@ -653,9 +659,9 @@ static int image_elf32_read_section(struct image *image, LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size); /* read initialized data in current segment if any */ - if (offset < filesz) { + if (offset < field32(elf, segment->p_filesz)) { /* maximal size present in file for the current segment */ - read_size = MIN(size, filesz - offset); + read_size = MIN(size, field32(elf, segment->p_filesz) - offset); LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size, field32(elf, segment->p_offset) + offset); /* read initialized area of the segment */ @@ -669,8 +675,6 @@ static int image_elf32_read_section(struct image *image, LOG_ERROR("cannot read ELF segment content, read failed"); return retval; } - buffer += read_size; - offset += read_size; size -= read_size; *size_read += read_size; /* need more data ? */ @@ -678,13 +682,6 @@ static int image_elf32_read_section(struct image *image, return ERROR_OK; } - /* clear bss in current segment if any */ - if (offset >= filesz) { - uint32_t memset_size = MIN(size, memsz - filesz); - memset(buffer, 0, memset_size); - *size_read += memset_size; - } - return ERROR_OK; } @@ -697,8 +694,6 @@ static int image_elf64_read_section(struct image *image, { struct image_elf *elf = image->type_private; Elf64_Phdr *segment = (Elf64_Phdr *)image->sections[section].private; - uint64_t filesz = field64(elf, segment->p_filesz); - uint64_t memsz = field64(elf, segment->p_memsz); size_t read_size, really_read; int retval; @@ -707,9 +702,9 @@ static int image_elf64_read_section(struct image *image, LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size); /* read initialized data in current segment if any */ - if (offset < filesz) { + if (offset < field64(elf, segment->p_filesz)) { /* maximal size present in file for the current segment */ - read_size = MIN(size, filesz - offset); + read_size = MIN(size, field64(elf, segment->p_filesz) - offset); LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size, field64(elf, segment->p_offset) + offset); /* read initialized area of the segment */ @@ -723,8 +718,6 @@ static int image_elf64_read_section(struct image *image, LOG_ERROR("cannot read ELF segment content, read failed"); return retval; } - buffer += read_size; - offset += read_size; size -= read_size; *size_read += read_size; /* need more data ? */ @@ -732,13 +725,6 @@ static int image_elf64_read_section(struct image *image, return ERROR_OK; } - /* clear bss in current segment if any */ - if (offset >= filesz) { - uint64_t memset_size = MIN(size, memsz - filesz); - memset(buffer, 0, memset_size); - *size_read += memset_size; - } - return ERROR_OK; } |