File crash-compressed-booted-kernel of Package crash
---
defs.h | 2 ++
filesys.c | 45 +++++++++++++++++++++++++++++++++++----------
symbols.c | 27 +++++++++++++++++++++++++++
3 files changed, 64 insertions(+), 10 deletions(-)
--- a/filesys.c
+++ b/filesys.c
@@ -523,6 +512,8 @@ static int
find_booted_kernel(void)
{
char kernel[BUFSIZE];
+ char kernel_unpacked[PATH_MAX];
+ char *realkernel;
char buffer[BUFSIZE];
char **searchdirs;
int i, preferred, wrapped;
@@ -552,7 +543,8 @@ find_booted_kernel(void)
searchdirs = build_searchdirs(CREATE, &preferred);
- for (i = preferred, wrapped = found = FALSE; !found; i++) {
+ kernel_unpacked[0] = '\0';
+ for (i = preferred, wrapped = found = FALSE; !found; i++) {
if (!searchdirs[i]) {
if (preferred && !wrapped) {
wrapped = TRUE;
@@ -572,18 +564,37 @@ find_booted_kernel(void)
sprintf(kernel, "%s%s", searchdirs[i], dp->d_name);
if (mount_point(kernel) ||
- !file_readable(kernel) ||
- !is_elf_file(kernel))
+ !file_readable(kernel))
continue;
+ kernel_unpacked[0] = '\0';
+ if (is_gzipped_elf_file(kernel)) {
+ realkernel = kernel_unpacked;
+ if (!uncompress_file(kernel, realkernel)) {
+ error(INFO,
+ "Uncompression failed for %s\n",
+ kernel);
+ }
+ } else
+ realkernel = kernel;
+
+ if (!is_elf_file(realkernel)) {
+ if (kernel_unpacked[0])
+ remove(kernel_unpacked);
+ continue;
+ }
+
if (CRASHDEBUG(1))
fprintf(fp, "find_booted_kernel: check: %s\n",
kernel);
- found = match_file_string(kernel, kt->proc_version, buffer);
+ found = match_file_string(realkernel, kt->proc_version, buffer);
if (found)
break;
+
+ if (kernel_unpacked[0])
+ remove(kernel_unpacked);
}
closedir(dirp);
}
@@ -592,20 +603,23 @@ find_booted_kernel(void)
build_searchdirs(DESTROY, NULL);
if (found) {
- if ((pc->namelist = (char *)malloc
- (strlen(kernel)+1)) == NULL)
+ if ((pc->orig_namelist = strdup(kernel)) == NULL)
+ error(FATAL, "booted kernel real name malloc: %s\n",
+ strerror(errno));
+ else if ((pc->namelist = strdup(realkernel)) == NULL) {
error(FATAL, "booted kernel name malloc: %s\n",
strerror(errno));
- else {
- strcpy(pc->namelist, kernel);
+ } else {
if (CRASHDEBUG(1))
fprintf(fp, "find_booted_kernel: found: %s\n",
- pc->namelist);
- pc->orig_namelist = pc->namelist;
+ pc->orig_namelist);
return TRUE;
}
}
+ if (kernel_unpacked[0])
+ remove(kernel_unpacked);
+
error(INFO,
"cannot find booted kernel -- please enter namelist argument\n\n");
return FALSE;
--- a/defs.h
+++ b/defs.h
@@ -3633,6 +3417,8 @@ void dump_symbol_table(void);
void dump_struct_table(ulong);
void dump_offset_table(char *, ulong);
int is_elf_file(char *);
+int is_gzipped_elf_file(const char *file);
+int uncompress_file(const char *file, char *new_file);
int is_kernel(char *);
int is_kernel_uncompress(char *file, char *new_filename);
int is_shared_object(char *);
--- a/symbols.c
+++ b/symbols.c
@@ -2834,6 +2643,33 @@ int is_gzip_file(const char *file)
}
/*
+ * Checks if the file is gzip-compressed and the compressed data contains
+ * the ELF magic number.
+ */
+int is_gzipped_elf_file(const char *file)
+{
+ gzFile f;
+ char magic[EI_NIDENT];
+
+ if (!is_gzip_file(file))
+ return FALSE;
+
+ if ((f = gzopen(file, "r")) == Z_NULL) {
+ error(INFO, "Cannot open %s: %s\n", file, strerror(errno));
+ return FALSE;
+ }
+ if (gzread(f, magic, EI_NIDENT) != EI_NIDENT) {
+ /* error(INFO, "%s: %s\n", s, strerror(errno)); */
+ gzclose(f);
+ return FALSE;
+ }
+ gzclose(f);
+
+ magic[EI_CLASS] = NULLCHAR;
+ return(STREQ(magic, ELFMAG));
+}
+
+/*
* Uncompresses the given file. Saves the name of the new file in new_file.
* Size of new_file must be large enough for PATH_MAX characters.
*