summaryrefslogtreecommitdiffstats
path: root/common/elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/elf.c')
-rw-r--r--common/elf.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/common/elf.c b/common/elf.c
index f10fb77953..62f793010f 100644
--- a/common/elf.c
+++ b/common/elf.c
@@ -10,6 +10,7 @@
#include <libfile.h>
#include <memory.h>
#include <unistd.h>
+#include <zero_page.h>
#include <linux/fs.h>
#include <linux/list_sort.h>
@@ -59,14 +60,13 @@ static int request_elf_segment(struct elf_image *elf, void *phdr)
{
void *dst = (void *) (phys_addr_t) elf_phdr_p_paddr(elf, phdr);
int ret;
- u64 p_filesz = elf_phdr_p_filesz(elf, phdr);
u64 p_memsz = elf_phdr_p_memsz(elf, phdr);
/* we care only about PT_LOAD segments */
if (elf_phdr_p_type(elf, phdr) != PT_LOAD)
return 0;
- if (!p_filesz)
+ if (!p_memsz)
return 0;
if (dst < elf->low_addr)
@@ -74,9 +74,9 @@ static int request_elf_segment(struct elf_image *elf, void *phdr)
if (dst + p_memsz > elf->high_addr)
elf->high_addr = dst + p_memsz;
- pr_debug("Requesting segment 0x%p (%llu bytes)\n", dst, p_filesz);
+ pr_debug("Requesting segment 0x%p (%llu bytes)\n", dst, p_memsz);
- ret = elf_request_region(elf, (resource_size_t)dst, p_filesz, phdr);
+ ret = elf_request_region(elf, (resource_size_t)dst, p_memsz, phdr);
if (ret)
return ret;
@@ -101,7 +101,7 @@ static int elf_section_cmp(void *priv, struct list_head *a, struct list_head *b)
static int load_elf_to_memory(struct elf_image *elf)
{
void *dst;
- int ret, fd = -1;
+ int ret = 0, fd = -1;
u64 p_filesz, p_memsz, p_offset;
struct elf_section *r;
struct list_head *list = &elf->list;
@@ -109,11 +109,13 @@ static int load_elf_to_memory(struct elf_image *elf)
if (elf->filename) {
fd = open(elf->filename, O_RDONLY);
if (fd < 0) {
- pr_err("could not open: %s\n", errno_str());
+ pr_err("could not open: %m\n");
return -errno;
}
}
+ zero_page_access();
+
list_for_each_entry(r, list, list) {
p_offset = elf_phdr_p_offset(elf, r->phdr);
p_filesz = elf_phdr_p_filesz(elf, r->phdr);
@@ -128,15 +130,13 @@ static int load_elf_to_memory(struct elf_image *elf)
if (ret == -1) {
pr_err("lseek at offset 0x%llx failed\n",
p_offset);
- close(fd);
- return ret;
+ goto out;
}
if (read_full(fd, dst, p_filesz) < 0) {
- pr_err("could not read elf segment: %s\n",
- errno_str());
- close(fd);
- return -errno;
+ pr_err("could not read elf segment: %m\n");
+ ret = -errno;
+ goto out;
}
} else {
memcpy(dst, elf->hdr_buf + p_offset, p_filesz);
@@ -146,9 +146,12 @@ static int load_elf_to_memory(struct elf_image *elf)
memset(dst + p_filesz, 0x00, p_memsz - p_filesz);
}
+out:
+ zero_page_faulting();
+
close(fd);
- return 0;
+ return ret >= 0 ? 0 : ret;
}
static int load_elf_image_segments(struct elf_image *elf)
@@ -256,13 +259,13 @@ static struct elf_image *elf_check_init(const char *filename)
/* First pass is to read elf header only */
fd = open(filename, O_RDONLY);
if (fd < 0) {
- pr_err("could not open: %s\n", errno_str());
+ pr_err("could not open: %m\n");
ret = -errno;
goto err_free_elf;
}
if (read_full(fd, &hdr, sizeof(hdr)) < 0) {
- pr_err("could not read elf header: %s\n", errno_str());
+ pr_err("could not read elf header: %m\n");
close(fd);
ret = -errno;
goto err_free_elf;
@@ -290,13 +293,13 @@ static struct elf_image *elf_check_init(const char *filename)
*/
fd = open(filename, O_RDONLY);
if (fd < 0) {
- pr_err("could not open: %s\n", errno_str());
+ pr_err("could not open: %m\n");
ret = -errno;
goto err_free_hdr_buf;
}
if (read_full(fd, elf->hdr_buf, hdr_size) < 0) {
- pr_err("could not read elf program headers: %s\n", errno_str());
+ pr_err("could not read elf program headers: %m\n");
ret = -errno;
close(fd);
goto err_free_hdr_buf;