int main(int argc, char *argv[]) { const char *filename = argv[1]; FILE *obj_file = fopen(filename, "rb"); dump_segments(obj_file); fclose(obj_file); return 0; }
/*===========================================================================* * write_elf_core_file * *===========================================================================*/ void write_elf_core_file(struct filp *f, int csig, char *proc_name) { /* First, fill in all the required headers, second, adjust the offsets, * third, dump everything into the core file */ #define MAX_REGIONS 100 #define NR_NOTE_ENTRIES 2 Elf_Ehdr elf_header; Elf_Phdr phdrs[MAX_REGIONS + 1]; Elf_Nhdr nhdrs[NR_NOTE_ENTRIES]; int phnum; memset(phdrs, 0, sizeof(phdrs)); /* Fill in the NOTE Program Header - at phdrs[0] - and * note entries' headers */ fill_note_segment_and_entries_hdrs(phdrs, nhdrs); /* Get the memory segments and fill in the Program headers */ phnum = get_memory_regions(phdrs) + 1; /* Fill in the ELF header */ fill_elf_header(&elf_header, phnum); /* Adjust offsets in program headers - The layout in the ELF core file * is the following: the ELF Header, the Note Program Header, * the rest of Program Headers (memory segments), Note contents, * the program segments' contents */ adjust_offsets(phdrs, phnum); /* Write ELF header */ dump_elf_header(f, elf_header); /* Write Program headers (Including the NOTE) */ dump_program_headers(f, phdrs, phnum); /* Write NOTE contents */ dump_notes(f, nhdrs, csig, proc_name); /* Write segments' contents */ dump_segments(f, phdrs, phnum); }
int cpu_machinecheck(struct cpu_user_regs *regs) { int recover = 0; u32 dsisr = mfdsisr(); if (regs->msr & MCK_SRR1_RI) recover = 1; printk("MACHINE CHECK: %s Recoverable\n", recover ? "IS": "NOT"); if (mck_cpu_stats[mfpir()] != 0) printk("While in CI IO\n"); show_backtrace_regs(regs); printk("SRR1: 0x%016lx\n", regs->msr); if (regs->msr & MCK_SRR1_INSN_FETCH_UNIT) printk("42: Exception caused by Instruction Fetch Unit (IFU)\n" " detection of a hardware uncorrectable error (UE).\n"); if (regs->msr & MCK_SRR1_LOAD_STORE) printk("43: Exception caused by load/store detection of error\n" " (see DSISR)\n"); switch (regs->msr & MCK_SRR1_CAUSE_MASK) { case 0: printk("0b00: Likely caused by an asynchronous machine check,\n" " see SCOM Asynchronous Machine Check Register\n"); cpu_scom_AMCR(); break; case MCK_SRR1_CAUSE_SLB_PAR: printk("0b01: Exception caused by an SLB parity error detected\n" " while translating an instruction fetch address.\n"); break; case MCK_SRR1_CAUSE_TLB_PAR: printk("0b10: Exception caused by a TLB parity error detected\n" " while translating an instruction fetch address.\n"); break; case MCK_SRR1_CAUSE_UE: printk("0b11: Exception caused by a hardware uncorrectable\n" " error (UE) detected while doing a reload of an\n" " instruction-fetch TLB tablewalk.\n"); break; } printk("\nDSISR: 0x%08x\n", dsisr); if (dsisr & MCK_DSISR_UE) printk("16: Exception caused by a UE deferred error\n" " (DAR is undefined).\n"); if (dsisr & MCK_DSISR_UE_TABLE_WALK) printk("17: Exception caused by a UE deferred error\n" " during a tablewalk (D-side).\n"); if (dsisr & MCK_DSISR_L1_DCACHE_PAR) printk("18: Exception was caused by a software recoverable\n" " parity error in the L1 D-cache.\n"); if (dsisr & MCK_DSISR_L1_DCACHE_TAG_PAR) printk("19: Exception was caused by a software recoverable\n" " parity error in the L1 D-cache tag.\n"); if (dsisr & MCK_DSISR_D_ERAT_PAR) printk("20: Exception was caused by a software recoverable parity\n" " error in the D-ERAT.\n"); if (dsisr & MCK_DSISR_TLB_PAR) printk("21: Exception was caused by a software recoverable parity\n" " error in the TLB.\n"); if (dsisr & MCK_DSISR_SLB_PAR) { printk("23: Exception was caused by an SLB parity error (may not be\n" " recoverable). This condition could occur if the\n" " effective segment ID (ESID) fields of two or more SLB\n" " entries contain the same value.\n"); dump_segments(0); } return 0; /* for now lets not recover */ }
segtable* add_segment (segtable* st, unspos pos1, unspos pos2, unspos length, score s, int id) { u32 newSize; size_t bytesNeeded; segment* seg, *parent; segment tempSeg; int ix, pIx; int tied, stopped; // fprintf (stderr, "add " unsposSlashSFmt " " unsposFmt " " scoreFmtSimple "; id %d\n", // pos1+1, "+", // pos2+1, ((id & rcf_rev) != 0)? "-" : "+", // length, s, id); ////////// // add the segment to the table, enlarging the table if needed, but // discarding the segment if it is low-scoring and the table has met its // coverage limit ////////// // if the table is already full and this segment scores less than the // lowest score in the table, discard it if ((st->len > 0) && (st->coverageLimit != 0) && (st->coverage >= st->coverageLimit) && (s < st->lowScore)) return st; // if there's no room for the new segment, re-allocate if (st->len >= st->size) { newSize = st->size + 100 + (st->size / 3); bytesNeeded = segtable_bytes (newSize); if (bytesNeeded > mallocLimit) goto overflow; st = (segtable*) realloc_or_die ("add_segment", st, bytesNeeded); st->size = newSize; } // add the segment, by appending it at the end seg = &st->seg[st->len++]; seg->pos1 = pos1; seg->pos2 = pos2; seg->length = length; seg->s = s; seg->id = id; seg->filter = false; seg->scoreCov = (possum) length; st->coverage += length; if ((st->len == 1) || (s < st->lowScore)) st->lowScore = s; ////////// // handle the transition between the two table states // below-the-coverage-limit: table is kept as a simple list // met-the-coverage-limit: table is kept as a proper min-heap ////////// // if this segment leaves us below the limit, we're done if ((st->coverageLimit == 0) || (st->coverage < st->coverageLimit)) return st; // if this is the first time we've reached the limit, sort the segments to // create a proper min-heap, and add the tied-score information // nota bene: if we reach here, st->coverageLimit > 0 and // st->coverage >= st->coverageLimit if (st->coverage - length < st->coverageLimit) { sort_segments (st, qSegmentsByIncreasingScore); record_tie_scores (st); #ifdef debugBinaryHeap fprintf (stderr, "\nafter sort:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after sort"); #endif // debugBinaryHeap goto prune; } ////////// // maintain the min-heap property ////////// #ifdef debugBinaryHeap //fprintf (stderr, "\nbefore percolation:\n"); //dump_segments (stderr, st, NULL, NULL); #endif // debugBinaryHeap // the rest of the list is a proper min-heap, so percolate the new segment // up the tree, while maintaining the tied-score information // nota bene: if we reach here, length >= 2 tied = false; for (ix=st->len-1 ; ix>0 ; ) { pIx = (ix-1) / 2; seg = &st->seg[ix]; parent = &st->seg[pIx]; if (seg->s >= parent->s) { tied = (seg->s == parent->s); break; } // swap this segment with its parent, and adjust old parent's tied-score // subheap tempSeg = *seg; *seg = *parent; *parent = tempSeg; record_tie_score (st, ix); ix = pIx; } record_tie_score (st, ix); // if the new segment tied an existing score, we must continue to percolate // the tied-score info up the tree if (tied) { stopped = false; for (ix=(ix-1)/2 ; ix>0 ; ix=(ix-1)/2) { if (!record_tie_score (st, ix)) { stopped = true; break; } } if (!stopped) record_tie_score (st, 0); } #ifdef debugBinaryHeap fprintf (stderr, "\nafter percolation:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after percolation"); #endif // debugBinaryHeap ////////// // remove low-scoring segments ////////// prune: // if removing the minimum scoring subheap would bring us below the // limit, no pruning is necessary if (st->coverage - st->seg[0].scoreCov < st->coverageLimit) return st; // otherwise, we must remove subheaps as long as doing so leaves us at or // above the limit while (st->coverage - st->seg[0].scoreCov >= st->coverageLimit) { s = st->seg[0].s; while (st->seg[0].s == s) { remove_root (st); #ifdef debugBinaryHeap fprintf (stderr, "\nafter a pruning:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after pruning"); #endif // debugBinaryHeap } } st->lowScore = st->seg[0].s; #ifdef debugBinaryHeap fprintf (stderr, "\nafter pruning:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after pruning"); #endif // debugBinaryHeap return st; // failure exits #define suggestions " consider using lastz_m40," \ " or setting max_malloc_index for a special build," \ " or raising scoring threshold (--hspthresh or --exact)," \ " or break your target sequence into smaller pieces" overflow: suicidef ("in add_segment()\n" "table size (%s for %s segments) exceeds allocation limit of %s;\n" suggestions, commatize(bytesNeeded), commatize(newSize), commatize(mallocLimit)); return NULL; // (doesn't get here) }