aboutsummaryrefslogtreecommitdiff
path: root/src/target/image.c
diff options
context:
space:
mode:
authorPeter Collingbourne <pcc@google.com>2023-03-01 20:20:29 -0800
committerAntonio Borneo <borneo.antonio@gmail.com>2023-03-18 21:52:02 +0000
commit047b1a8fc237af480e3bab66a9827a358afd7547 (patch)
tree1258fddc8648948a428b9b6fa2dff4d9aaedd974 /src/target/image.c
parenta7f8a1d7fb8e6628f34340a5777ce600dc27f8d8 (diff)
downloadriscv-openocd-047b1a8fc237af480e3bab66a9827a358afd7547.zip
riscv-openocd-047b1a8fc237af480e3bab66a9827a358afd7547.tar.gz
riscv-openocd-047b1a8fc237af480e3bab66a9827a358afd7547.tar.bz2
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 <pcc@google.com> Reviewed-on: https://review.openocd.org/c/openocd/+/7513 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Diffstat (limited to 'src/target/image.c')
-rw-r--r--src/target/image.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/src/target/image.c b/src/target/image.c
index f8de7a2..6aa609d 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) {
@@ -449,10 +447,8 @@ 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) &&
- (field32(elf, elf->segments32[i].p_filesz) != 0)) {
- image->sections[j].size = field32(elf, elf->segments32[i].p_filesz);
+ if (field32(elf, elf->segments32[i].p_type) == PT_LOAD) {
+ 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 +528,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) {
@@ -574,10 +568,8 @@ 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) &&
- (field64(elf, elf->segments64[i].p_filesz) != 0)) {
- image->sections[j].size = field64(elf, elf->segments64[i].p_filesz);
+ if (field32(elf, elf->segments64[i].p_type) == PT_LOAD) {
+ image->sections[j].size = field64(elf, elf->segments64[i].p_memsz);
if (load_to_vaddr)
image->sections[j].base_address = field64(elf,
elf->segments64[i].p_vaddr);
@@ -651,6 +643,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 +653,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 +669,8 @@ 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 ? */
@@ -682,6 +678,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, 0, memset_size);
+ *size_read += memset_size;
+ }
+
return ERROR_OK;
}
@@ -694,6 +697,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 +707,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 +723,8 @@ 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 ? */
@@ -725,6 +732,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, 0, memset_size);
+ *size_read += memset_size;
+ }
+
return ERROR_OK;
}