Thanks Andy, I'll check these out ASAP. BTW, I'd prefer to separate out the search_for_switch_to() patch because it has nothing to do with kaslr. And I really wish I could understand why your kernel shows a "call" instead of a "callq" so I could write up a rationale explanation for it in the changelog. When I questioned you about it earlier, you had responded with this explanation: > crash> dis context_switch > 0xffffffff80278af4 <context_switch+596>: call 0xffffffff80205600 <__switch_to> > > I have no explanation for the difference. I will submit another > version that searches for both strings. Which is strange, since "context_switch" has been an inline function for pretty much ever, and therefore is not even a kernel symbol. But your kernel apparently does have context_switch as a discrete function. What kernel version are you testing with? Is it a google-special that maybe tinkers with the scheduler code? Dave ----- Original Message ----- > [PATCH 1/2] Add support to kaslr for offline vmcore files. > > This patch adds a --kaslr command line parameter for loading x86_64 > crash dumps with kaslr enabled. This reuses the code from 32-bit > x86 relocations with some small changes. The ASLR offset is postive > instead of negative. Also had to move the code to traverse the > kernel section before the symbol storing code to figure out which > symbols were outside any sections and therefore were not relocated. > > Also made a very small change in search_for_switch_to it was > searching through gdb command output for a slightly incorrect syntax. > > Tested: Tested by loading kdump files from kernels with aslr enabled > and not enabled. Ran bt, files, and struct file 0xXXXXXX. > > Signed-off-by: Andy Honig <ahonig@xxxxxxxxxx> > --- > defs.h | 2 ++ > main.c | 8 ++++++-- > symbols.c | 66 > +++++++++++++++++++++++++++++++++++++++++++++------------------ > x86_64.c | 20 +++++++++++++------ > 4 files changed, 69 insertions(+), 27 deletions(-) > > diff --git a/defs.h b/defs.h > index 4cae5e5..c9a4b73 100644 > --- a/defs.h > +++ b/defs.h > @@ -2417,6 +2417,8 @@ struct symbol_table_data { > ulong __per_cpu_end; > off_t dwarf_debug_frame_file_offset; > ulong dwarf_debug_frame_size; > + ulong first_section_start; > + ulong last_section_end; > }; > > /* flags for st */ > diff --git a/main.c b/main.c > index e5829bc..39763da 100644 > --- a/main.c > +++ b/main.c > @@ -57,6 +57,7 @@ static struct option long_options[] = { > {"CRASHPAGER", 0, 0, 0}, > {"no_scroll", 0, 0, 0}, > {"reloc", required_argument, 0, 0}, > + {"kaslr", required_argument, 0, 0}, > {"active", 0, 0, 0}, > {"minimal", 0, 0, 0}, > {"mod", required_argument, 0, 0}, > @@ -216,12 +217,15 @@ main(int argc, char **argv) > else if (STREQ(long_options[option_index].name, "mod")) > kt->module_tree = optarg; > > - else if (STREQ(long_options[option_index].name, "reloc")) { > + else if (STREQ(long_options[option_index].name, "reloc") || > + STREQ(long_options[option_index].name, "kaslr")) { > if (!calculate(optarg, &kt->relocate, NULL, 0)) { > error(INFO, "invalid --reloc argument: %s\n", > optarg); > program_usage(SHORT_FORM); > - } > + } else if (STREQ(long_options[option_index].name, "kaslr")) { > + kt->relocate *= -1; > + } > kt->flags |= RELOC_SET; > } > > diff --git a/symbols.c b/symbols.c > index d063a0a..28378ab 100644 > --- a/symbols.c > +++ b/symbols.c > @@ -198,22 +198,6 @@ symtab_init(void) > no_debugging_data(FATAL); > } > > - symcount = bfd_read_minisymbols(st->bfd, FALSE, &minisyms, &size); > - > - if (symcount <= 0) > - no_debugging_data(FATAL); > - > - sort_x = bfd_make_empty_symbol(st->bfd); > - sort_y = bfd_make_empty_symbol(st->bfd); > - if (sort_x == NULL || sort_y == NULL) > - error(FATAL, "bfd_make_empty_symbol() failed\n"); > - > - gnu_qsort(st->bfd, minisyms, symcount, size, sort_x, sort_y); > - > - store_symbols(st->bfd, FALSE, minisyms, symcount, size); > - > - free(minisyms); > - > /* > * Gather references to the kernel sections. > */ > @@ -222,6 +206,7 @@ symtab_init(void) > error(FATAL, "symbol table section array malloc: %s\n", > strerror(errno)); > BZERO(st->sections, st->bfd->section_count * sizeof(struct sec *)); > + st->first_section_start = st->last_section_end = 0; > > bfd_map_over_sections(st->bfd, section_header_info, KERNEL_SECTIONS); > if ((st->flags & (NO_SEC_LOAD|NO_SEC_CONTENTS)) == > @@ -233,6 +218,22 @@ symtab_init(void) > } > } > > + symcount = bfd_read_minisymbols(st->bfd, FALSE, &minisyms, &size); > + > + if (symcount <= 0) > + no_debugging_data(FATAL); > + > + sort_x = bfd_make_empty_symbol(st->bfd); > + sort_y = bfd_make_empty_symbol(st->bfd); > + if (sort_x == NULL || sort_y == NULL) > + error(FATAL, "bfd_make_empty_symbol() failed\n"); > + > + gnu_qsort(st->bfd, minisyms, symcount, size, sort_x, sort_y); > + > + store_symbols(st->bfd, FALSE, minisyms, symcount, size); > + > + free(minisyms); > + > symname_hash_init(); > symval_hash_init(); > } > @@ -590,7 +591,7 @@ store_symbols(bfd *abfd, int dynamic, void *minisyms, > long symcount, > st->symcnt = 0; > sp = st->symtable; > > - if (machine_type("X86")) { > + if (machine_type("X86") || machine_type("X86_64")) { > if (!(kt->flags & RELOC_SET)) > kt->flags |= RELOC_FORCE; > } else > @@ -663,7 +664,7 @@ store_sysmap_symbols(void) > error(FATAL, "symbol table namespace malloc: %s\n", > strerror(errno)); > > - if (!machine_type("X86")) > + if (!machine_type("X86") && !machine_type("X86_64")) > kt->flags &= ~RELOC_SET; > > first = 0; > @@ -735,7 +736,20 @@ relocate(ulong symval, char *symname, int first_symbol) > break; > } > > - return (symval - kt->relocate); > + if (machine_type("X86_64")) { > + /* > + * There are some symbols which are outside of any section > + * either because they are offsets or because they are absolute > + * addresses. These should not be relocated. > + */ > + if (symval >= st->first_section_start && > + symval <= st->last_section_end) { > + return symval - kt->relocate; > + } else { > + return symval; > + } > + } else > + return symval - kt->relocate; > } > > /* > @@ -9679,6 +9693,7 @@ section_header_info(bfd *bfd, asection *section, void > *reqptr) > struct load_module *lm; > ulong request; > asection **sec; > + ulong section_end_address; > > request = ((ulong)reqptr); > > @@ -9697,6 +9712,11 @@ section_header_info(bfd *bfd, asection *section, void > *reqptr) > kt->etext_init = kt->stext_init + > (ulong)bfd_section_size(bfd, section); > } > + > + if (STREQ(bfd_get_section_name(bfd, section), ".text")) { > + st->first_section_start = (ulong) > + bfd_get_section_vma(bfd, section); > + } > if (STREQ(bfd_get_section_name(bfd, section), ".text") || > STREQ(bfd_get_section_name(bfd, section), ".data")) { > if (!(bfd_get_section_flags(bfd, section) & > SEC_LOAD)) > @@ -9713,6 +9733,14 @@ section_header_info(bfd *bfd, asection *section, void > *reqptr) > st->dwarf_debug_frame_file_offset = (off_t)section->filepos; > st->dwarf_debug_frame_size = (ulong)bfd_section_size(bfd, section); > } > + > + if (st->first_section_start != 0) { > + section_end_address = > + (ulong) bfd_get_section_vma(bfd, section) + > + (ulong) bfd_section_size(bfd, section); > + if (section_end_address > st->last_section_end) > + st->last_section_end = section_end_address; > + } > break; > > case (ulong)MODULE_SECTIONS: > diff --git a/x86_64.c b/x86_64.c > index 8508e4f..b51e285 100644 > --- a/x86_64.c > +++ b/x86_64.c > @@ -5414,16 +5414,22 @@ search_for_switch_to(ulong start, ulong end) > { > ulong max_instructions, address; > char buf1[BUFSIZE]; > - char buf2[BUFSIZE]; > + char search_string1[BUFSIZE]; > + char search_string2[BUFSIZE]; > int found; > > max_instructions = end - start; > found = FALSE; > sprintf(buf1, "x/%ldi 0x%lx", max_instructions, start); > - if (symbol_exists("__switch_to")) > - sprintf(buf2, "callq 0x%lx", symbol_value("__switch_to")); > - else > - buf2[0] = NULLCHAR; > + if (symbol_exists("__switch_to")) { > + sprintf(search_string1, > + "callq 0x%lx", symbol_value("__switch_to")); > + sprintf(search_string2, > + "call 0x%lx", symbol_value("__switch_to")); > + } else { > + search_string1[0] = NULLCHAR; > + search_string2[0] = NULLCHAR; > + } > > open_tmpfile(); > > @@ -5436,7 +5442,9 @@ search_for_switch_to(ulong start, ulong end) > break; > if (strstr(buf1, "<__switch_to>")) > found = TRUE; > - if (strlen(buf2) && strstr(buf1, buf2)) > + if (strlen(search_string1) && strstr(buf1, search_string1)) > + found = TRUE; > + if (strlen(search_string2) && strstr(buf1, search_string2)) > found = TRUE; > } > close_tmpfile(); > -- > 1.9.0.rc1.175.g0b1dcb5 > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility