summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2006-09-21 14:51:05 -0400
committerSimon Horman <horms@verge.net.au>2006-10-06 12:46:16 +0900
commitdd3f52d4668938b9b3ad91607d7df3cf337b0863 (patch)
tree7b3b51e254421e8b08d48f68b87685c706946498
parent46ecc6c6c77b1fab20b08286209631a00eb1049e (diff)
kexec-tools: Add a new parameter to generic elf parsing functions
o Adding a new parameter to elf functions. This flag can be used to alter the function behaviour. Currently only one bit is being used for skipping the elf file len check while builing the elf info. Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--kexec/kexec-elf-exec.c9
-rw-r--r--kexec/kexec-elf-rel.c9
-rw-r--r--kexec/kexec-elf.c24
-rw-r--r--kexec/kexec-elf.h15
4 files changed, 35 insertions, 22 deletions
diff --git a/kexec/kexec-elf-exec.c b/kexec/kexec-elf-exec.c
index ec00a05..f65a625 100644
--- a/kexec/kexec-elf-exec.c
+++ b/kexec/kexec-elf-exec.c
@@ -11,11 +11,12 @@
static const int probe_debug = 0;
-int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr)
+int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+ uint32_t flags)
{
struct mem_phdr *phdr, *end_phdr;
int result;
- result = build_elf_info(buf, len, ehdr);
+ result = build_elf_info(buf, len, ehdr, flags);
if (result < 0) {
return result;
}
@@ -136,11 +137,11 @@ int elf_exec_load(struct mem_ehdr *ehdr, struct kexec_info *info)
}
void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr *ehdr,
- const char *buf, off_t len)
+ const char *buf, off_t len, uint32_t flags)
{
int result;
/* Parse the Elf file */
- result = build_elf_exec_info(buf, len, ehdr);
+ result = build_elf_exec_info(buf, len, ehdr, flags);
if (result < 0) {
die("ELF exec parse failed\n");
}
diff --git a/kexec/kexec-elf-rel.c b/kexec/kexec-elf-rel.c
index ae78a09..4419937 100644
--- a/kexec/kexec-elf-rel.c
+++ b/kexec/kexec-elf-rel.c
@@ -135,10 +135,11 @@ static struct mem_rela elf_rela(struct mem_ehdr *ehdr, const unsigned char *ptr)
return rela;
}
-int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr)
+int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+ uint32_t flags)
{
int result;
- result = build_elf_info(buf, len, ehdr);
+ result = build_elf_info(buf, len, ehdr, flags);
if (result < 0) {
return result;
}
@@ -419,12 +420,12 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info,
void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr,
const char *buf, off_t len, unsigned long min, unsigned long max,
- int end)
+ int end, uint32_t flags)
{
int result;
/* Parse the Elf file */
- result = build_elf_rel_info(buf, len, ehdr);
+ result = build_elf_rel_info(buf, len, ehdr, flags);
if (result < 0) {
die("ELF rel parse failed\n");
}
diff --git a/kexec/kexec-elf.c b/kexec/kexec-elf.c
index da2c788..929c79c 100644
--- a/kexec/kexec-elf.c
+++ b/kexec/kexec-elf.c
@@ -368,7 +368,8 @@ static int build_mem_elf64_phdr(const char *buf, off_t len,
return 0;
}
-static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr)
+static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr,
+ uint32_t flags)
{
size_t phdr_size, mem_phdr_size;
int i;
@@ -418,9 +419,11 @@ static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr)
/* Check the program headers to be certain
* they are safe to use.
+ * Skip the check if ELF_SKIP_FILESZ_CHECK is set.
*/
phdr = &ehdr->e_phdr[i];
- if ((phdr->p_offset + phdr->p_filesz) > len) {
+ if (!(flags & ELF_SKIP_FILESZ_CHECK)
+ && (phdr->p_offset + phdr->p_filesz) > len) {
/* The segment does not fit in the buffer */
if (probe_debug) {
fprintf(stderr, "ELF segment not in file\n");
@@ -580,7 +583,8 @@ static int build_mem_elf64_shdr(const char *buf, off_t len,
return 0;
}
-static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr)
+static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr,
+ uint32_t flags)
{
size_t shdr_size, mem_shdr_size;
int i;
@@ -628,11 +632,12 @@ static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr)
}
/* Check the section headers to be certain
* they are safe to use.
+ * Skip the check if ELF_SKIP_FILESZ_CHECK is set.
*/
shdr = &ehdr->e_shdr[i];
- if ((shdr->sh_type != SHT_NOBITS) &&
- ((shdr->sh_offset + shdr->sh_size) > len))
- {
+ if (!(flags & ELF_SKIP_FILESZ_CHECK)
+ && (shdr->sh_type != SHT_NOBITS)
+ && (shdr->sh_offset + shdr->sh_size) > len) {
/* The section does not fit in the buffer */
if (probe_debug) {
fprintf(stderr, "ELF section %d not in file\n",
@@ -729,7 +734,8 @@ void free_elf_info(struct mem_ehdr *ehdr)
memset(ehdr, 0, sizeof(*ehdr));
}
-int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr)
+int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+ uint32_t flags)
{
int result;
result = build_mem_ehdr(buf, len, ehdr);
@@ -737,14 +743,14 @@ int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr)
return result;
}
if ((ehdr->e_phoff > 0) && (ehdr->e_phnum > 0)) {
- result = build_mem_phdrs(buf, len, ehdr);
+ result = build_mem_phdrs(buf, len, ehdr, flags);
if (result < 0) {
free_elf_info(ehdr);
return result;
}
}
if ((ehdr->e_shoff > 0) && (ehdr->e_shnum > 0)) {
- result = build_mem_shdrs(buf, len, ehdr);
+ result = build_mem_shdrs(buf, len, ehdr, flags);
if (result < 0) {
free_elf_info(ehdr);
return result;
diff --git a/kexec/kexec-elf.h b/kexec/kexec-elf.h
index b7332de..0f09285 100644
--- a/kexec/kexec-elf.h
+++ b/kexec/kexec-elf.h
@@ -82,22 +82,27 @@ typedef struct
uint32_t n_type; /* Type of the note. */
} ElfNN_Nhdr;
+/* Misc flags */
+#define ELF_SKIP_FILESZ_CHECK 0x00000001
extern void free_elf_info(struct mem_ehdr *ehdr);
-extern int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr);
-extern int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr);
-extern int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr);
+extern int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+ uint32_t flags);
+extern int build_elf_exec_info(const char *buf, off_t len,
+ struct mem_ehdr *ehdr, uint32_t flags);
+extern int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+ uint32_t flags);
extern int elf_exec_load(struct mem_ehdr *ehdr, struct kexec_info *info);
extern int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info,
unsigned long min, unsigned long max, int end);
extern void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr *ehdr,
- const char *buf, off_t len);
+ const char *buf, off_t len, uint32_t flags);
extern void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr,
const char *buf, off_t len, unsigned long min, unsigned long max,
- int end);
+ int end, uint32_t flags);
extern int elf_rel_find_symbol(struct mem_ehdr *ehdr,
const char *name, struct mem_sym *ret_sym);