This is an automated email from Gerrit.

"Peter Collingbourne <p...@google.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7513

-- gerrit

commit 65d99b82948c409157972cb22c1e69405430acd0
Author: Peter Collingbourne <p...@google.com>
Date:   Wed Mar 1 20:20:29 2023 -0800

    target/image: zero-initialize ELF segments up to p_memsz
    
    We were previously not zero-initializing ELF segments between p_filesz
    and p_memsz (aka BSS). However, this may be necessary depending on the
    user's application. Therefore, start doing so.
    
    Change-Id: I5a743390069583aca7ee276f53afeccf2cac0855
    Signed-off-by: Peter Collingbourne <p...@google.com>

diff --git a/src/target/image.c b/src/target/image.c
index f8de7a23e3..dae5c06ee7 100644
--- a/src/target/image.c
+++ b/src/target/image.c
@@ -407,12 +407,10 @@ static int image_elf32_read_headers(struct image *image)
                return ERROR_FILEIO_OPERATION_FAILED;
        }
 
-       /* count useful segments (loadable), ignore BSS section */
+       /* count useful segments (loadable) */
        image->num_sections = 0;
        for (i = 0; i < elf->segment_count; i++)
-               if ((field32(elf,
-                       elf->segments32[i].p_type) == PT_LOAD) &&
-                       (field32(elf, elf->segments32[i].p_filesz) != 0))
+               if (field32(elf, elf->segments32[i].p_type) == PT_LOAD)
                        image->num_sections++;
 
        if (image->num_sections == 0) {
@@ -452,7 +450,7 @@ static int image_elf32_read_headers(struct image *image)
                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);
+                       image->sections[j].size = field32(elf, 
elf->segments32[i].p_memsz);
                        if (load_to_vaddr)
                                image->sections[j].base_address = field32(elf,
                                                elf->segments32[i].p_vaddr);
@@ -532,12 +530,10 @@ static int image_elf64_read_headers(struct image *image)
                return ERROR_FILEIO_OPERATION_FAILED;
        }
 
-       /* count useful segments (loadable), ignore BSS section */
+       /* count useful segments (loadable) */
        image->num_sections = 0;
        for (i = 0; i < elf->segment_count; i++)
-               if ((field32(elf,
-                       elf->segments64[i].p_type) == PT_LOAD) &&
-                       (field64(elf, elf->segments64[i].p_filesz) != 0))
+               if (field32(elf, elf->segments64[i].p_type) == PT_LOAD)
                        image->num_sections++;
 
        if (image->num_sections == 0) {
@@ -651,6 +647,8 @@ 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;
 
@@ -659,9 +657,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 < field32(elf, segment->p_filesz)) {
+       if (offset < filesz) {
                /* maximal size present in file for the current segment */
-               read_size = MIN(size, field32(elf, segment->p_filesz) - offset);
+               read_size = MIN(size, 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 */
@@ -675,6 +673,7 @@ static int image_elf32_read_section(struct image *image,
                        LOG_ERROR("cannot read ELF segment content, read 
failed");
                        return retval;
                }
+               offset += read_size;
                size -= read_size;
                *size_read += read_size;
                /* need more data ? */
@@ -682,6 +681,13 @@ 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 + read_size, 0, memset_size);
+               *size_read += memset_size;
+       }
+
        return ERROR_OK;
 }
 
@@ -694,6 +700,8 @@ 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;
 
@@ -702,9 +710,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 < field64(elf, segment->p_filesz)) {
+       if (offset < filesz) {
                /* maximal size present in file for the current segment */
-               read_size = MIN(size, field64(elf, segment->p_filesz) - offset);
+               read_size = MIN(size, 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 */
@@ -718,6 +726,7 @@ static int image_elf64_read_section(struct image *image,
                        LOG_ERROR("cannot read ELF segment content, read 
failed");
                        return retval;
                }
+               offset += read_size;
                size -= read_size;
                *size_read += read_size;
                /* need more data ? */
@@ -725,6 +734,13 @@ 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 + read_size, 0, memset_size);
+               *size_read += memset_size;
+       }
+
        return ERROR_OK;
 }
 

-- 

Reply via email to