> > BTW, I'd prefer to separate out the search_for_switch_to() patch because it > has nothing to do with kaslr. Will do. > > 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? Yes I was testing with a Google specific kernel, and yes it 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 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility