From 144d940a8b0276d2ecb97ee6615d8a78faf4117d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 6 May 2023 11:44:53 +0200 Subject: 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 Reported-by: Marian Buschsieweke Reviewed-on: https://review.openocd.org/c/openocd/+/7658 Reviewed-by: Bohdan Tymkiv Reviewed-by: Tomas Vanek Reviewed-by: Nemui Trinomius Reviewed-by: Peter Collingbourne Tested-by: jenkins --- src/target/image.c | 54 ++++++++++++++++++++---------------------------------- 1 file 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; } -- cgit v1.1