--- crash-4.0-3.17/main.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/main.c 2007-01-30 10:26:40.000000000 -0500 @@ -1,8 +1,8 @@ /* main.c - core analysis suite * * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002, 2003, 2004, 2005, 2006 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -989,6 +989,9 @@ if (pc->flags & XEN_CORE) sprintf(&buf[strlen(buf)], "%sXEN_CORE", others++ ? "|" : ""); + if (pc->flags & PLEASE_WAIT) + sprintf(&buf[strlen(buf)], + "%sPLEASE_WAIT", others++ ? "|" : ""); if (pc->flags) strcat(buf, ")"); --- crash-4.0-3.17/tools.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/tools.c 2007-01-30 10:27:20.000000000 -0500 @@ -1,8 +1,8 @@ /* tools.c - core analysis suite * * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002, 2003, 2004, 2005, 2006 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,6 +64,8 @@ if ((new_line = (buf[0] == '\n'))) shift_string_left(buf, 1); + else if (pc->flags & PLEASE_WAIT) + new_line = TRUE; if (pc->stdpipe) { fprintf(pc->stdpipe, "%s%s: %s%s", @@ -2378,6 +2380,7 @@ char *element2; struct syment *sp; + opcode = 0; value1 = value2 = 0; ll_value1 = ll_value2 = 0; @@ -3672,7 +3675,6 @@ struct hash_table *ht; struct hq_entry *list_entry; long hqi; - long index; if (!(pc->flags & HASH)) return FALSE; @@ -3707,8 +3709,6 @@ list_entry = ht->memptr + list_entry->next; } - list_entry->next = index; - return FALSE; } @@ -4479,6 +4479,8 @@ !DUMPFILE() || (pc->flags & RUNTIME)) return; + pc->flags |= PLEASE_WAIT; + fprintf(fp, "\rplease wait... (%s)", s); fflush(fp); } @@ -4490,6 +4492,8 @@ !DUMPFILE() || (pc->flags & RUNTIME)) return; + pc->flags &= ~PLEASE_WAIT; + fprintf(fp, "\r \r"); fflush(fp); } --- crash-4.0-3.17/help.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/help.c 2007-01-30 10:40:04.000000000 -0500 @@ -3375,7 +3375,7 @@ char *help_mod[] = { "mod", "module information and loading of symbols and debugging data", -"[ -s module [objfile] | -d module | -S [directory] | -D | -r ] ", +"[ -s module [objfile] | -d module | -S [directory] | -D | -r | -o ] ", " With no arguments, this command displays basic information of the currently", " installed modules, consisting of the module address, name, size, the", " object file name (if known), and whether the module was compiled with", @@ -3426,6 +3426,7 @@ " -r Reinitialize module data. All currently-loaded symbolic", " and debugging data will be deleted, and the installed", " module list will be updated (live system only).", +" -o Load module symbols with old mechanism.", " ", " After symbolic and debugging data have been loaded, backtraces and text", " disassembly will be displayed appropriately. Depending upon the processor", --- crash-4.0-3.17/task.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/task.c 2007-01-26 14:14:29.000000000 -0500 @@ -1695,6 +1695,8 @@ do_verify = 1; else if (tt->refresh_task_table == refresh_pid_hash_task_table) do_verify = 2; + else if (tt->refresh_task_table == refresh_hlist_task_table_v2) + do_verify = 2; else do_verify = 0; @@ -5040,7 +5042,7 @@ wrap = sizeof(void *) == SIZEOF_32BIT ? 8 : 4; flen = sizeof(void *) == SIZEOF_32BIT ? 8 : 16; - nr_cpus = kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : nr_cpus; + nr_cpus = kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS; for (i = 0; i < nr_cpus; i++) { if ((i % wrap) == 0) @@ -5522,6 +5524,8 @@ if ((tp = fill_task_struct(task))) { if ((tc = store_context(NULL, task, tp))) tt->running_tasks++; + else + continue; } } --- crash-4.0-3.17/kernel.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/kernel.c 2007-01-31 11:18:46.000000000 -0500 @@ -44,6 +44,7 @@ static char *debug_kernel_version(char *); static int restore_stack(struct bt_info *); static ulong __xen_m2p(ulonglong, ulong); +static int search_mapping_page(ulong, ulong *, ulong *, ulong *); static void read_in_kernel_config_err(int, char *); @@ -2066,7 +2067,7 @@ please_wait("gathering module symbol data"); for (mod = kt->module_list; mod != kt->kernel_module; mod = mod_next) { - if (CRASHDEBUG(7)) + if (CRASHDEBUG(3)) fprintf(fp, "module: %lx\n", mod); if (!readmem(mod, KVADDR, modbuf, SIZE(module), @@ -2308,7 +2309,7 @@ address = 0; flag = LIST_MODULE_HDR; - while ((c = getopt(argcnt, args, "rd:Ds:St:")) != EOF) { + while ((c = getopt(argcnt, args, "rd:Ds:St:o")) != EOF) { switch(c) { case 'r': @@ -2341,6 +2342,19 @@ cmd_usage(pc->curcmd, SYNOPSIS); break; + /* + * Revert to using old-style add-symbol-file command + * for KMOD_V2 kernels. + */ + case 'o': + if (flag) + cmd_usage(pc->curcmd, SYNOPSIS); + if (kt->flags & KMOD_V1) + error(INFO, + "-o option is not applicable to this kernel version\n"); + st->flags |= USE_OLD_ADD_SYM; + return; + case 't': if (is_directory(optarg)) tree = optarg; @@ -3572,16 +3586,23 @@ for (i = 0; verbose && (i < P2M_MAPPING_CACHE); i++) { if (!kt->p2m_mapping_cache[i].mapping) continue; - fprintf(fp, " [%d] mapping: %lx mfn: %lx\n", + fprintf(fp, " [%d] mapping: %lx start: %lx end: %lx (%ld mfns)\n", i, kt->p2m_mapping_cache[i].mapping, - kt->p2m_mapping_cache[i].mfn); + kt->p2m_mapping_cache[i].start, + kt->p2m_mapping_cache[i].end, + kt->p2m_mapping_cache[i].end - kt->p2m_mapping_cache[i].start + 1); } fprintf(fp, " last_mapping_read: %lx\n", kt->last_mapping_read); fprintf(fp, " p2m_cache_index: %ld\n", kt->p2m_cache_index); fprintf(fp, " p2m_pages_searched: %ld\n", kt->p2m_pages_searched); - fprintf(fp, " p2m_cache_hits: %ld ", kt->p2m_cache_hits); + fprintf(fp, " p2m_mfn_cache_hits: %ld ", kt->p2m_mfn_cache_hits); if (kt->p2m_pages_searched) - fprintf(fp, "(%ld%%)\n", kt->p2m_cache_hits * 100 / kt->p2m_pages_searched); + fprintf(fp, "(%ld%%)\n", kt->p2m_mfn_cache_hits * 100 / kt->p2m_pages_searched); + else + fprintf(fp, "\n"); + fprintf(fp, " p2m_page_cache_hits: %ld ", kt->p2m_page_cache_hits); + if (kt->p2m_pages_searched) + fprintf(fp, "(%ld%%)\n", kt->p2m_page_cache_hits * 100 / kt->p2m_pages_searched); else fprintf(fp, "\n"); } @@ -5282,6 +5303,7 @@ __xen_m2p(ulonglong machine, ulong mfn) { ulong mapping, kmfn, pfn, p, i, c; + ulong start, end; ulong *mp; mp = (ulong *)kt->m2p_page; @@ -5292,7 +5314,8 @@ */ for (c = 0; c < P2M_MAPPING_CACHE; c++) { if (kt->p2m_mapping_cache[c].mapping && - (kt->p2m_mapping_cache[c].mfn == mfn)) { + ((mfn >= kt->p2m_mapping_cache[c].start) && + (mfn <= kt->p2m_mapping_cache[c].end))) { if (kt->p2m_mapping_cache[c].mapping != kt->last_mapping_read) { if (!readmem(kt->p2m_mapping_cache[c].mapping, KVADDR, @@ -5302,7 +5325,8 @@ "phys_to_machine_mapping page\n"); else kt->last_mapping_read = kt->p2m_mapping_cache[c].mapping; - } + } else + kt->p2m_page_cache_hits++; for (i = 0; i < XEN_PFNS_PER_PAGE; i++) { kmfn = (*(mp+i)) & ~XEN_FOREIGN_FRAME; @@ -5315,7 +5339,7 @@ " i: %ld pfn: %lx (%llx)\n", mfn, machine, p, i, pfn, XEN_PFN_TO_PSEUDO(pfn)); - kt->p2m_cache_hits++; + kt->p2m_mfn_cache_hits++; return pfn; } @@ -5345,24 +5369,21 @@ kt->p2m_pages_searched++; - for (i = 0; i < XEN_PFNS_PER_PAGE; i++) - { - kmfn = (*(mp+i)) & ~XEN_FOREIGN_FRAME; - if (kmfn == mfn) { - pfn = p + i; - if (CRASHDEBUG(1)) - console("pages: %d mfn: %lx (%llx) p: %ld" - " i: %ld pfn: %lx (%llx)\n", - (p/XEN_PFNS_PER_PAGE)+1, mfn, machine, - p, i, pfn, XEN_PFN_TO_PSEUDO(pfn)); - - c = kt->p2m_cache_index; - kt->p2m_mapping_cache[c].mfn = mfn; - kt->p2m_mapping_cache[c].mapping = mapping; - kt->p2m_cache_index = (c+1) % P2M_MAPPING_CACHE; + if (search_mapping_page(mfn, &i, &start, &end)) { + pfn = p + i; + if (CRASHDEBUG(1)) + console("pages: %d mfn: %lx (%llx) p: %ld" + " i: %ld pfn: %lx (%llx)\n", + (p/XEN_PFNS_PER_PAGE)+1, mfn, machine, + p, i, pfn, XEN_PFN_TO_PSEUDO(pfn)); + + c = kt->p2m_cache_index; + kt->p2m_mapping_cache[c].start = start; + kt->p2m_mapping_cache[c].end = end; + kt->p2m_mapping_cache[c].mapping = mapping; + kt->p2m_cache_index = (c+1) % P2M_MAPPING_CACHE; - return pfn; - } + return pfn; } mapping += PAGESIZE(); @@ -5374,6 +5395,113 @@ return (XEN_MFN_NOT_FOUND); } +/* + * Search for an mfn in the current mapping page, and if found, + * determine the range of contiguous mfns that it's contained + * within (if any). + */ +#define PREV_UP 0x1 +#define NEXT_UP 0x2 +#define PREV_DOWN 0x4 +#define NEXT_DOWN 0x8 + +static int +search_mapping_page(ulong mfn, ulong *index, ulong *startptr, ulong *endptr) +{ + int n, found; + ulong i, kmfn; + ulong flags, start, end, next, prev, curr; + ulong *mp; + + mp = (ulong *)kt->m2p_page; + + for (i = 0, found = FALSE; i < XEN_PFNS_PER_PAGE; i++) { + kmfn = (*(mp+i)) & ~XEN_FOREIGN_FRAME; + + if (kmfn == mfn) { + found = TRUE; + *index = i; + break; + } + } + + if (found) { + flags = 0; + next = prev = XEN_MFN_NOT_FOUND; + start = end = kmfn; + + if (i) + prev = (*(mp+(i-1))) & ~XEN_FOREIGN_FRAME; + if ((i+1) != XEN_PFNS_PER_PAGE) + next = (*(mp+(i+1))) & ~XEN_FOREIGN_FRAME; + + if (prev == (kmfn-1)) + flags |= PREV_UP; + else if (prev == (kmfn+1)) + flags |= PREV_DOWN; + + if (next == (kmfn+1)) + flags |= NEXT_UP; + else if (next == (kmfn-1)) + flags |= NEXT_DOWN; + + /* Should be impossible, but just in case... */ + if ((flags & PREV_UP) && (flags & NEXT_DOWN)) + flags &= ~NEXT_DOWN; + else if ((flags & PREV_DOWN) && (flags & NEXT_UP)) + flags &= ~NEXT_UP; + + if (flags & (PREV_UP|PREV_DOWN)) { + start = prev; + + for (n = (i-2); n >= 0; n--) { + curr = (*(mp+n)) & ~XEN_FOREIGN_FRAME; + if (flags & PREV_UP) { + if (curr == (start-1)) + start = curr; + } else { + if (curr == (start+1)) + start = curr; + } + } + + } + + if (flags & (NEXT_UP|NEXT_DOWN)) { + end = next; + + for (n = (i+2); n < XEN_PFNS_PER_PAGE; n++) { + curr = (*(mp+n)) & ~XEN_FOREIGN_FRAME; + if (flags & NEXT_UP) { + if (curr == (end+1)) + end = curr; + } else { + if (curr == (end-1)) + end = curr; + } + } + + + } + + if (start > end) { + curr = start; + start = end; + end = curr; + } + + *startptr = start; + *endptr = end; + + if (CRASHDEBUG(2)) + fprintf(fp, "mfn: %lx -> start: %lx end: %lx (%ld mfns)\n", + mfn, start, end, end - start); + } + + return found; +} + + /* * Read the relevant IKCONFIG (In Kernel Config) data if available. --- crash-4.0-3.17/configure.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/configure.c 2007-01-31 16:56:18.000000000 -0500 @@ -56,7 +56,7 @@ void build_configure(void); void release_configure(char *); -void make_rh_rpm_package(char *); +void make_rh_rpm_package(char *, int); void unconfigure(void); void set_warnings(int); void show_configuration(void); @@ -222,7 +222,7 @@ setup_gdb_defaults(); - while ((c = getopt(argc, argv, "gsqnWwubdr:p:")) > 0) { + while ((c = getopt(argc, argv, "gsqnWwubdr:p:P:")) > 0) { switch (c) { case 'q': target_data.flags |= QUIET; @@ -239,7 +239,10 @@ release_configure(optarg); break; case 'p': - make_rh_rpm_package(optarg); + make_rh_rpm_package(optarg, 0); + break; + case 'P': + make_rh_rpm_package(optarg, 1); break; case 'W': case 'w': @@ -566,10 +569,11 @@ * Create an .rh_rpm_package file if the passed-in variable is set. */ void -make_rh_rpm_package(char *package) +make_rh_rpm_package(char *package, int release) { - char *p; + char *p, *cur; FILE *fp; + char buf[256]; if ((strcmp(package, "remove") == 0)) { if (file_exists(".rh_rpm_package")) { @@ -589,6 +593,33 @@ if (!strlen(++p)) return; + if (release) { + if (!(fp = popen("./crash -v", "r"))) { + fprintf(stderr, "cannot execute \"crash -v\"\n"); + exit(1); + } + cur = NULL; + while (fgets(buf, 256, fp)) { + if (strncmp(buf, "crash ", 6) == 0) { + cur = &buf[6]; + break; + } + } + fclose(fp); + + if (!cur) { + fprintf(stderr, "cannot get version from \"crash -v\"\n"); + exit(1); + } + strip_linefeeds(cur); + + if (strcmp(cur, p) != 0) { + fprintf(stderr, "./crash version: %s\n", cur); + fprintf(stderr, "release version: %s\n", p); + exit(1); + } + } + if ((fp = fopen(".rh_rpm_package", "w")) == NULL) { perror("fopen"); fprintf(stderr, "cannot open .rh_rpm_package\n"); --- crash-4.0-3.17/s390x.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/s390x.c 2007-02-01 09:39:07.000000000 -0500 @@ -730,9 +730,9 @@ backchain = ULONG(&stack[backchain - stack_base + bc_offset]); /* print stack content if -f is specified */ - if((bt->flags & BT_FULL) && !BT_REFERENCE_CHECK(bt)){ + if ((bt->flags & BT_FULL) && !BT_REFERENCE_CHECK(bt)) { int frame_size; - if(backchain == 0){ + if (backchain == 0) { frame_size = stack_base - old_backchain + KERNEL_STACK_SIZE; } else { @@ -740,14 +740,15 @@ (stack_base - old_backchain + KERNEL_STACK_SIZE)); } - for(j=0; j< frame_size; j+=4){ + for (j = 0; j < frame_size; j += 8) { if(j % 16 == 0){ - fprintf(fp,"\n%08lx: ",old_backchain+j); + fprintf(fp, "%s %016lx: ", + j ? "\n" : "", old_backchain + j); } - fprintf(fp," %08lx",ULONG(&stack[old_backchain - - stack_base + j])); + fprintf(fp," %016lx", + ULONG(&stack[old_backchain - stack_base + j])); } - fprintf(fp,"\n\n"); + fprintf(fp, "\n"); } /* Check for interrupt stackframe */ --- crash-4.0-3.17/symbols.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/symbols.c 2007-01-25 11:54:02.000000000 -0500 @@ -1,8 +1,8 @@ /* symbols.c - core analysis suite * * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002, 2003, 2004, 2005, 2006 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,7 +36,9 @@ static int load_module_index(struct syment *); static void section_header_info(bfd *, asection *, void *); static void store_section_data(struct load_module *, bfd *, asection *); -static void calculate_load_order(struct load_module *, bfd *); +static void calculate_load_order_v1(struct load_module *, bfd *); +static void calculate_load_order_v2(struct load_module *, bfd *, int, + void *, long, unsigned int); static void check_insmod_builtin(struct load_module *, int, ulong *); static int is_insmod_builtin(struct load_module *, struct syment *); struct load_module; @@ -2126,6 +2128,8 @@ fprintf(fp, "%sCRC_MATCHES", others++ ? "|" : ""); if (st->flags & ADD_SYMBOL_FILE) fprintf(fp, "%sADD_SYMBOL_FILE", others++ ? "|" : ""); + if (st->flags & USE_OLD_ADD_SYM) + fprintf(fp, "%sUSE_OLD_ADD_SYM", others++ ? "|" : ""); fprintf(fp, ")\n"); fprintf(fp, " bfd: %lx\n", (ulong)st->bfd); @@ -7049,8 +7053,9 @@ i = lm->mod_sections; lm->mod_section_data[i].section = section; lm->mod_section_data[i].priority = prio; - lm->mod_section_data[i].flags = section->flags; + lm->mod_section_data[i].flags = section->flags & ~SEC_FOUND; lm->mod_section_data[i].size = bfd_section_size(bfd, section); + lm->mod_section_data[i].offset = 0; if (strlen(name) < MAX_MOD_SEC_NAME) strcpy(lm->mod_section_data[i].name, name); else @@ -7102,7 +7107,7 @@ */ static void -calculate_load_order(struct load_module *lm, bfd *bfd) +calculate_load_order_v1(struct load_module *lm, bfd *bfd) { int i; asection *section; @@ -7162,6 +7167,131 @@ } /* + * Later versions of kmod no longer get the help from insmod, + * and while the heuristics might work, it's relatively + * straightforward to just try to match the sections in the object file + * with exported symbols. + * + * This works well if kallsyms is set, but may not work so well in other + * instances. + */ +static void +calculate_load_order_v2(struct load_module *lm, bfd *bfd, int dynamic, + void *minisyms, long symcount, unsigned int size) +{ + struct syment *s1, *s2; + ulong sec_start, sec_end; + bfd_byte *from, *fromend; + asymbol *store; + asymbol *sym; + symbol_info syminfo; + char *secname; + int i; + + s1 = lm->mod_symtable; + s2 = lm->mod_symend; + while (s1 < s2) { + ulong sym_offset = s1->value - lm->mod_base; + if (MODULE_PSEUDO_SYMBOL(s1)) { + s1++; + continue; + } + + /* Skip over symbols whose sections have been identified. */ + for (i = 0; i < lm->mod_sections; i++) { + if ((lm->mod_section_data[i].flags & SEC_FOUND) == 0) + continue; + if (sym_offset >= lm->mod_section_data[i].offset + && sym_offset < lm->mod_section_data[i].offset + + lm->mod_section_data[i].size) { + break; + } + } + + /* Matched one of the sections. Skip symbol. */ + if (i < lm->mod_sections) { + if (CRASHDEBUG(2)) { + fprintf(fp, "skip %lx %s %s\n", s1->value, s1->name, + lm->mod_section_data[i].name); + } + s1++; + continue; + } + + /* Find the symbol in the object file. */ + from = (bfd_byte *) minisyms; + fromend = from + symcount * size; + secname = NULL; + for (; from < fromend; from += size) { + if ((sym = bfd_minisymbol_to_symbol(bfd, dynamic, from, + store)) == NULL) + error(FATAL, + "bfd_minisymbol_to_symbol() failed\n"); + + bfd_get_symbol_info(bfd, sym, &syminfo); + if (CRASHDEBUG(3)) { + fprintf(fp,"matching sym %s %lx against bfd %s %lx\n", + s1->name, (long) s1->value, syminfo.name, + (long) syminfo.value); + } + if (strcmp(syminfo.name, s1->name) == 0) { + secname = (char *)bfd_get_section_name(bfd, sym->section); + break; + } + + } + if (secname == NULL) { + if (CRASHDEBUG(1)) { + fprintf(fp, "symbol %s not found in module\n", s1->name); + } + s1++; + continue; + } + + /* Match the section it came in. */ + for (i = 0; i < lm->mod_sections; i++) { + if (STREQ(lm->mod_section_data[i].name, secname)) { + break; + } + } + + if (i == lm->mod_sections) { + fprintf(fp, "?? Section %s not found for symbol %s\n", + secname, s1->name); + s1++; + continue; + } + + /* Update the offset information for the section */ + sec_start = s1->value - syminfo.value; + sec_end = sec_start + lm->mod_section_data[i].size; + lm->mod_section_data[i].offset = sec_start - lm->mod_base; + lm->mod_section_data[i].flags |= SEC_FOUND; + + if (CRASHDEBUG(1)) { + fprintf(fp, "update sec offset sym %s @ %lx val %lx section %s\n", + s1->name, s1->value, syminfo.value, secname); + } + + if (strcmp(secname, ".text") == 0) + lm->mod_text_start = sec_start; + + if (strcmp(secname, ".bss") == 0) + lm->mod_bss_start = sec_start; + + if (strcmp(secname, ".data") == 0) + lm->mod_data_start = sec_start; + + if (strcmp(secname, ".data") == 0) + lm->mod_data_start = sec_start; + + if (strcmp(secname, ".rodata") == 0) + lm->mod_rodata_start = sec_start; + s1++; + } +} + +/* * Later versons of insmod store basic address information of each * module in a format that looks like the following example of the * nfsd module: @@ -7274,8 +7404,8 @@ } if (CRASHDEBUG(1)) - fprintf(fp, "load_module_symbols: %s %s %lx\n", - modref, namelist, base_addr); + fprintf(fp, "load_module_symbols: %s %s %lx %lx\n", + modref, namelist, base_addr, kt->flags); switch (kt->flags & (KMOD_V1|KMOD_V2)) { @@ -7288,7 +7418,8 @@ strcpy(lm->mod_namelist, namelist); else strncpy(lm->mod_namelist, namelist, MAX_MOD_NAMELIST-1); - goto add_symbols; + if (st->flags & USE_OLD_ADD_SYM) + goto add_symbols; } if ((mbfd = bfd_openr(namelist, NULL)) == NULL) @@ -7308,6 +7439,10 @@ else if (symcount == 0) error(FATAL, "no symbols in object file: %s\n", namelist); + if (CRASHDEBUG(1)) { + fprintf(fp, "%ld symbols found in obj file %s\n", symcount, + namelist); + } sort_x = bfd_make_empty_symbol(mbfd); sort_y = bfd_make_empty_symbol(mbfd); if (sort_x == NULL || sort_y == NULL) @@ -7473,7 +7608,12 @@ bfd_map_over_sections(bfd, section_header_info, MODULE_SECTIONS); - calculate_load_order(lm, bfd); + if (kt->flags & KMOD_V1) + calculate_load_order_v1(lm, bfd); + else + calculate_load_order_v2(lm, bfd, dynamic, minisyms, + symcount, size); + from = (bfd_byte *) minisyms; fromend = from + symcount * size; @@ -7486,104 +7626,112 @@ bfd_get_symbol_info(bfd, sym, &syminfo); secname = (char *)bfd_get_section_name(bfd, sym->section); + found = 0; - switch (syminfo.type) - { - case 'b': - case 'B': - if (CRASHDEBUG(2)) - fprintf(fp, "%08lx (%c) [%s] %s\n", - (ulong)syminfo.value, - syminfo.type, secname, syminfo.name); + if (kt->flags & KMOD_V1) { + switch (syminfo.type) + { + case 'b': + case 'B': + if (CRASHDEBUG(2)) + fprintf(fp, "%08lx (%c) [%s] %s\n", + (ulong)syminfo.value, + syminfo.type, secname, syminfo.name); - syminfo.value += lm->mod_bss_start; - strcpy(name, syminfo.name); - strip_module_symbol_end(name); + if (!lm->mod_bss_start) + break; - if (machdep->verify_symbol(name, syminfo.value, - syminfo.type)) { - sp->value = syminfo.value; - sp->type = syminfo.type; - - namespace_ctl(NAMESPACE_INSTALL, - &lm->mod_load_namespace, sp, name); + syminfo.value += lm->mod_bss_start; + found = 1; + break; - if (CRASHDEBUG(1)) - fprintf(fp, "%08lx %s\n", sp->value, - name); + case 'd': + case 'D': + if (CRASHDEBUG(2)) + fprintf(fp, "%08lx (%c) [%s] %s\n", + (ulong)syminfo.value, + syminfo.type, secname, syminfo.name); + + if (STREQ(secname, ".rodata")) { + if (!lm->mod_rodata_start) + break; + syminfo.value += lm->mod_rodata_start; + } else { + if (!lm->mod_data_start) + break; + syminfo.value += lm->mod_data_start; + } + found = 1; + break; - sp++; - lm->mod_load_symcnt++; - } - break; + case 't': + case 'T': + if (CRASHDEBUG(2)) + fprintf(fp, "%08lx (%c) [%s] %s\n", + (ulong)syminfo.value, + syminfo.type, secname, syminfo.name); - case 'd': - case 'D': - if (CRASHDEBUG(2)) - fprintf(fp, "%08lx (%c) [%s] %s\n", - (ulong)syminfo.value, - syminfo.type, secname, syminfo.name); + if (! lm->mod_text_start) { + break; + } - if (STREQ(secname, ".rodata")) - syminfo.value += lm->mod_rodata_start; - else - syminfo.value += lm->mod_data_start; + if ((st->flags & INSMOD_BUILTIN) && + (STREQ(name, "init_module") || + STREQ(name, "cleanup_module"))) + break; + syminfo.value += lm->mod_text_start; + found = 1; + break; + + default: + break; + } + + } else { + /* Match the section it came in. */ + for (i = 0; i < lm->mod_sections; i++) { + if (STREQ(lm->mod_section_data[i].name, secname) + && (lm->mod_section_data[i].flags & SEC_FOUND)) { + break; + } + } + if (i < lm->mod_sections) { + if (CRASHDEBUG(2)) + fprintf(fp, "%08lx (%c) [%s] %s\n", + (ulong)syminfo.value, + syminfo.type, secname, syminfo.name); + + if ((st->flags & INSMOD_BUILTIN) && + (STREQ(name, "init_module") || + STREQ(name, "cleanup_module"))) { + found = 0; + } else { + syminfo.value += lm->mod_section_data[i].offset + lm->mod_base; + found = 1; + } + } + } + + if (found) { strcpy(name, syminfo.name); strip_module_symbol_end(name); - if (machdep->verify_symbol(name, syminfo.value, - syminfo.type)) { + if (machdep->verify_symbol(name, syminfo.value, + syminfo.type)) { sp->value = syminfo.value; - sp->type = syminfo.type; + sp->type = syminfo.type; namespace_ctl(NAMESPACE_INSTALL, - &lm->mod_load_namespace, sp, name); + &lm->mod_load_namespace, sp, name); if (CRASHDEBUG(1)) - fprintf(fp, "%08lx %s\n", sp->value, + fprintf(fp, "installing %c %08lx %s\n", syminfo.type, sp->value, name); sp++; lm->mod_load_symcnt++; } - break; - - case 't': - case 'T': - if (CRASHDEBUG(2)) - fprintf(fp, "%08lx (%c) [%s] %s\n", - (ulong)syminfo.value, - syminfo.type, secname, syminfo.name); - - syminfo.value += lm->mod_text_start; - strcpy(name, syminfo.name); - strip_module_symbol_end(name); - - if ((st->flags & INSMOD_BUILTIN) && - (STREQ(name, "init_module") || - STREQ(name, "cleanup_module"))) - break; - - if (machdep->verify_symbol(name, syminfo.value, - syminfo.type)) { - sp->value = syminfo.value; - sp->type = syminfo.type; - namespace_ctl(NAMESPACE_INSTALL, - &lm->mod_load_namespace, sp, name); - - if (CRASHDEBUG(1)) - fprintf(fp, "%08lx %s\n", sp->value, - name); - - sp++; - lm->mod_load_symcnt++; - } - - break; - - default: - break; - } + } } lm->mod_load_symend = &lm->mod_load_symtable[lm->mod_load_symcnt]; @@ -7804,7 +7952,7 @@ ulong start, end; char *modbuf; ulong maxchunk, alloc; - long offset; + long offset = 0; start = roundup(lm->mod_size_of_struct, sizeof(long)) + lm->mod_base; end = lm->mod_base + lm->mod_size; --- crash-4.0-3.17/cmdline.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/cmdline.c 2007-01-30 10:29:56.000000000 -0500 @@ -1,8 +1,8 @@ /* cmdline.c - core analysis suite * * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002, 2003, 2004, 2005, 2006 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -921,7 +921,7 @@ wait_for_children(ZOMBIES_ONLY); - pc->flags &= ~(INIT_IFILE|RUNTIME_IFILE|_SIGINT_); + pc->flags &= ~(INIT_IFILE|RUNTIME_IFILE|_SIGINT_|PLEASE_WAIT); pc->sigint_cnt = 0; pc->redirect = 0; pc->pipe_command[0] = NULLCHAR; --- crash-4.0-3.17/lkcd_common.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/lkcd_common.c 2007-01-17 10:14:26.000000000 -0500 @@ -3,8 +3,8 @@ * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. * Copyright (C) 2002 Silicon Graphics, Inc. * Copyright (C) 2002 Free Software Foundation, Inc. - * Copyright (C) 2002, 2003, 2004, 2005 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2007 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2007 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -791,7 +791,7 @@ int lkcd_lseek(physaddr_t paddr) { - long i; + long i = 0; int err; int eof; void *dp; @@ -836,7 +836,7 @@ lseek(lkcd->fd, lkcd->page_offset_max, SEEK_SET); eof = FALSE; while (!eof) { - if( (i%2048) == 0) { + if( (i++%2048) == 0) { lkcd_speedo(); } --- crash-4.0-3.17/xendump.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/xendump.c 2007-01-31 11:48:54.000000000 -0500 @@ -1,8 +1,8 @@ /* * xendump.c * - * Copyright (C) 2006 David Anderson - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2006, 2007 David Anderson + * Copyright (C) 2006, 2007 Red Hat, Inc. All rights reserved. * * This software may be freely redistributed under the terms of the * GNU General Public License. @@ -147,6 +147,7 @@ if (read(xd->xfd, xd->page, xd->page_size) != xd->page_size) return READ_ERROR; + xd->last_pfn = pfn; } BCOPY(xd->page + PAGEOFFSET(paddr), bufptr, cnt); @@ -615,6 +616,7 @@ return SEEK_ERROR; if (read(xd->xfd, xd->page, xd->page_size) != xd->page_size) return READ_ERROR; + xd->last_pfn = reqpfn; } else if (CRASHDEBUG(1)) console("READ %ld (0x%lx) skipped!\n", reqpfn, reqpfn); @@ -768,7 +770,6 @@ if (poc->cnt && (poc->pfn == pfn)) { poc->cnt++; xd->cache_hits++; - xd->last_pfn = pfn; return poc->file_offset; } } @@ -1022,7 +1023,7 @@ } fprintf(fp, xd->xc_core.p2m_frames ? "\n" : ""); - if ((xd->flags & XC_CORE) && CRASHDEBUG(2)) + if ((xd->flags & XC_CORE) && CRASHDEBUG(8)) xc_core_mfns(XENDUMP_LOCAL, fp); return 0; @@ -1260,7 +1261,7 @@ break; if (tmp[i] == mfn) { - if (CRASHDEBUG(2)) + if (CRASHDEBUG(4)) fprintf(xd->ofp, "index: batch: %d found mfn %ld (0x%lx) at index %d\n", b/MAX_BATCH_SIZE, mfn, mfn, i+b); --- crash-4.0-3.17/defs.h 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/defs.h 2007-01-31 16:13:52.000000000 -0500 @@ -1,8 +1,8 @@ /* defs.h - core analysis suite * * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002, 2003, 2004, 2005, 2006 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. * Copyright (C) 2002 Silicon Graphics, Inc. * * This program is free software; you can redistribute it and/or modify @@ -176,6 +176,7 @@ #define XENDUMP (0x40000000000000ULL) #define XEN_HYPER (0x80000000000000ULL) #define XEN_CORE (0x100000000000000ULL) +#define PLEASE_WAIT (0x200000000000000ULL) #define ACTIVE() (pc->flags & LIVE_SYSTEM) #define DUMPFILE() (!(pc->flags & LIVE_SYSTEM)) @@ -497,7 +498,8 @@ #define P2M_MAPPING_CACHE (512) struct p2m_mapping_cache { ulong mapping; - ulong mfn; + ulong start; + ulong end; } p2m_mapping_cache[P2M_MAPPING_CACHE]; #define P2M_MAPPING_TO_PAGE_INDEX(c) \ (((kt->p2m_mapping_cache[c].mapping - kt->phys_to_machine_mapping)/PAGESIZE()) \ @@ -505,7 +507,8 @@ ulong last_mapping_read; ulong p2m_cache_index; ulong p2m_pages_searched; - ulong p2m_cache_hits; + ulong p2m_mfn_cache_hits; + ulong p2m_page_cache_hits; }; /* @@ -1759,6 +1762,7 @@ ulong dwarf_eh_frame_size; }; +/* flags for st */ #define KERNEL_SYMS (0x1) #define MODULE_SYMS (0x2) #define LOAD_MODULE_SYMS (0x4) @@ -1770,6 +1774,7 @@ #define FORCE_DEBUGINFO (0x80) #define CRC_MATCHES (0x100) #define ADD_SYMBOL_FILE (0x200) +#define USE_OLD_ADD_SYM (0x400) #endif /* !GDB_COMMON */ @@ -1785,6 +1790,8 @@ #define MOD_KALLSYMS (0x8) #define MOD_INITRD (0x10) +#define SEC_FOUND (0x10000) + struct mod_section_data { #if defined(GDB_6_1) struct bfd_section *section; --- crash-4.0-3.17/xendump.h 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/xendump.h 2007-01-30 10:34:18.000000000 -0500 @@ -1,8 +1,8 @@ /* * xendump.h * - * Copyright (C) 2006 David Anderson - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2006, 2007 David Anderson + * Copyright (C) 2006, 2007 Red Hat, Inc. All rights reserved. * * This software may be freely redistributed under the terms of the * GNU General Public License. @@ -35,7 +35,7 @@ ulong cnt; }; -#define PFN_TO_OFFSET_CACHE_ENTRIES (1024) +#define PFN_TO_OFFSET_CACHE_ENTRIES (5000) struct xendump_data { ulong flags; /* XENDUMP_LOCAL, plus anything else... */ --- crash-4.0-3.17/Makefile 2007-02-01 11:03:03.000000000 -0500 +++ crash-4.0-3.18/Makefile 2007-02-01 11:03:02.000000000 -0500 @@ -3,8 +3,8 @@ # Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. # www.missioncriticallinux.com, info@missioncriticallinux.com # -# Copyright (C) 2002, 2003, 2004, 2005, 2006 David Anderson -# Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 David Anderson +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -475,7 +475,7 @@ release: make_configure @if [ "`id --user`" != "0" ]; then \ echo "make release: must be super-user"; exit 1; fi - @./configure -p "RPMPKG=${RPMPKG}" -u -g + @./configure -P "RPMPKG=${RPMPKG}" -u -g @make --no-print-directory release_configure @echo @echo "cvs tag this release if necessary" @@ -513,7 +513,7 @@ cp ${PROGRAM}-${RELEASE}.tar.gz /usr/src/redhat/SOURCES; \ /usr/bin/rpmbuild -bs ${PROGRAM}.spec > /dev/null; \ rm -f /usr/src/redhat/SOURCES/${PROGRAM}-${RELEASE}.tar.gz; \ - cp /usr/src/redhat/SRPMS/${PROGRAM}-${RELEASE}.src.rpm . ; \ + mv /usr/src/redhat/SRPMS/${PROGRAM}-${RELEASE}.src.rpm . ; \ ls -l ${PROGRAM}-${RELEASE}.src.rpm; \ exit 0; fi --- crash-4.0-3.17/gdb-6.1/gdb/symtab.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/gdb-6.1/gdb/symtab.c 2007-01-23 17:11:34.000000000 -0500 @@ -4,7 +4,7 @@ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Portions Copyright (C) 2001, 2002 Mission Critical Linux, Inc. - Copyright (c) 2002, 2003, 2004, 2005 Red Hat, Inc. All rights reserved. + Copyright (c) 2002, 2003, 2004, 2005, 2007 Red Hat, Inc. All rights reserved. This file is part of GDB. @@ -4523,14 +4523,54 @@ struct symbol *sym; struct expression *expr; struct cleanup *old_chain; - + int i; + int allsect = 0; + char *secname; + char buf[80]; + gdb_current_load_module = lm = (struct load_module *)req->addr; req->name = lm->mod_namelist; gdb_delete_symbol_file(req); - sprintf(req->buf, "add-symbol-file %s 0x%lx", lm->mod_namelist, - lm->mod_text_start); + for (i = 0 ; i < lm->mod_sections; i++) { + if (STREQ(lm->mod_section_data[i].name, ".text") && + (lm->mod_section_data[i].flags & SEC_FOUND)) + allsect = 1; + } + + if (!allsect) { + sprintf(req->buf, "add-symbol-file %s 0x%lx", lm->mod_namelist, + lm->mod_text_start ? lm->mod_text_start : lm->mod_base); + if (lm->mod_data_start) { + sprintf(buf, " -s .data 0x%lx", lm->mod_data_start); + strcat(req->buf, buf); + } + if (lm->mod_bss_start) { + sprintf(buf, " -s .bss 0x%lx", lm->mod_bss_start); + strcat(req->buf, buf); + } + if (lm->mod_rodata_start) { + sprintf(buf, " -s .rodata 0x%lx", lm->mod_rodata_start); + strcat(req->buf, buf); + } + } else { + sprintf(req->buf, "add-symbol-file %s 0x%lx", lm->mod_namelist, + lm->mod_text_start); + for (i = 0; i < lm->mod_sections; i++) { + secname = lm->mod_section_data[i].name; + if ((lm->mod_section_data[i].flags & SEC_FOUND) && + !STREQ(secname, ".text")) { + sprintf(buf, " -s %s 0x%lx", secname, + lm->mod_section_data[i].offset + lm->mod_base); + strcat(req->buf, buf); + } + } + } + + if (gdb_CRASHDEBUG(1)) { + fprintf_filtered(gdb_stdout, "gdb_add_symbol_file: %s\n", req->buf); + } execute_command(req->buf, FALSE); --- crash-4.0-3.17/gdb-6.1/gdb/symfile.c 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/gdb-6.1/gdb/symfile.c 2007-01-23 15:15:36.000000000 -0500 @@ -3,7 +3,7 @@ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Portions Copyright (C) 2001, 2002 Mission Critical Linux, Inc. - Copyright (c) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. + Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -1678,7 +1678,11 @@ to load the program. */ sect_opts[section_index].name = ".text"; sect_opts[section_index].value = arg; +#ifdef CRASH_MERGE + if (++section_index >= num_sect_opts) +#else if (++section_index > num_sect_opts) +#endif { num_sect_opts *= 2; sect_opts = ((struct sect_opt *) @@ -1714,7 +1718,11 @@ { sect_opts[section_index].value = arg; expecting_sec_addr = 0; +#ifdef CRASH_MERGE + if (++section_index >= num_sect_opts) +#else if (++section_index > num_sect_opts) +#endif { num_sect_opts *= 2; sect_opts = ((struct sect_opt *) --- crash-4.0-3.17/gdb-6.1.patch 2007-01-31 16:01:02.000000000 -0500 +++ crash-4.0-3.18/gdb-6.1.patch 2007-01-18 10:05:02.000000000 -0500 @@ -19,3 +19,56 @@ int ppc_trace[nr_trace_options]; +--- gdb-6.1.orig/gdb/remote.c ++++ gdb-6.1/gdb/remote.c +@@ -3445,7 +3445,7 @@ remote_store_registers (int regnum) + { + int i; + regs = alloca (rs->sizeof_g_packet); +- memset (regs, rs->sizeof_g_packet, 0); ++ memset (regs, 0, rs->sizeof_g_packet); + for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++) + { + struct packet_reg *r = &rs->regs[i]; +--- gdb-6.1.orig/gdb/std-regs.c ++++ gdb-6.1/gdb/std-regs.c +@@ -61,7 +61,7 @@ value_of_builtin_frame_reg (struct frame + val = allocate_value (builtin_type_frame_reg); + VALUE_LVAL (val) = not_lval; + buf = VALUE_CONTENTS_RAW (val); +- memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0); ++ memset (buf, 0, TYPE_LENGTH (VALUE_TYPE (val))); + /* frame.base. */ + if (frame != NULL) + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, +@@ -87,7 +87,7 @@ value_of_builtin_frame_fp_reg (struct fr + struct value *val = allocate_value (builtin_type_void_data_ptr); + char *buf = VALUE_CONTENTS_RAW (val); + if (frame == NULL) +- memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0); ++ memset (buf, 0, TYPE_LENGTH (VALUE_TYPE (val))); + else + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, + get_frame_base_address (frame)); +@@ -105,7 +105,7 @@ value_of_builtin_frame_pc_reg (struct fr + struct value *val = allocate_value (builtin_type_void_data_ptr); + char *buf = VALUE_CONTENTS_RAW (val); + if (frame == NULL) +- memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0); ++ memset (buf, 0, TYPE_LENGTH (VALUE_TYPE (val))); + else + ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, + get_frame_pc (frame)); +--- gdb-6.1.orig/gdb/dwarf2-frame.c ++++ gdb-6.1/gdb/dwarf2-frame.c +@@ -1353,7 +1353,9 @@ decode_frame_entry_1 (struct comp_unit * + else if (*augmentation == 'P') + { + /* Skip. */ +- buf += size_of_encoded_value (*buf++); ++// buf += size_of_encoded_value (*buf++); ++ buf += size_of_encoded_value(*buf); ++ buf++; + augmentation++; + } +